| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index c02cdd944934dbefdd02b5872735526e5a2f3f20..bbbc8f92796272eeab7ff93d97beebdff015d318 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -7902,6 +7902,31 @@ String* SeqString::Truncate(int new_length) {
|
| }
|
|
|
|
|
| +AllocationSiteInfo* AllocationSiteInfo::FindForJSObject(JSObject* object) {
|
| + // Currently, AllocationSiteInfo objects are only allocated immediately
|
| + // after JSArrays in NewSpace, and detecting whether a JSArray has one
|
| + // involves carefully checking the object immediately after the JSArray
|
| + // (if there is one) to see if it's an AllocationSiteInfo.
|
| + if (FLAG_track_allocation_sites && object->GetHeap()->InNewSpace(object)) {
|
| + Address ptr_end = (reinterpret_cast<Address>(object) - kHeapObjectTag) +
|
| + object->Size();
|
| + if ((ptr_end + AllocationSiteInfo::kSize) <=
|
| + object->GetHeap()->NewSpaceTop()) {
|
| + // There is room in newspace for allocation info. Do we have some?
|
| + Map** possible_allocation_site_info_map =
|
| + reinterpret_cast<Map**>(ptr_end);
|
| + if (*possible_allocation_site_info_map ==
|
| + object->GetHeap()->allocation_site_info_map()) {
|
| + AllocationSiteInfo* info = AllocationSiteInfo::cast(
|
| + reinterpret_cast<Object*>(ptr_end + 1));
|
| + return info;
|
| + }
|
| + }
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| +
|
| uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) {
|
| // For array indexes mix the length into the hash as an array index could
|
| // be zero.
|
| @@ -10248,6 +10273,14 @@ MaybeObject* JSObject::SetFastElement(uint32_t index,
|
| }
|
| // Convert to fast double elements if appropriate.
|
| if (HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) {
|
| + // Consider fixing the boilerplate as well if we have one.
|
| + ElementsKind to_kind = IsHoleyElementsKind(elements_kind)
|
| + ? FAST_HOLEY_DOUBLE_ELEMENTS
|
| + : FAST_DOUBLE_ELEMENTS;
|
| +
|
| + MaybeObject* trans = PossiblyTransitionArrayBoilerplate(to_kind);
|
| + if (trans != NULL && trans->IsFailure()) return trans;
|
| +
|
| MaybeObject* maybe =
|
| SetFastDoubleElementsCapacityAndLength(new_capacity, array_length);
|
| if (maybe->IsFailure()) return maybe;
|
| @@ -10789,6 +10822,24 @@ Handle<Object> JSObject::TransitionElementsKind(Handle<JSObject> object,
|
| }
|
|
|
|
|
| +MaybeObject* JSObject::PossiblyTransitionArrayBoilerplate(
|
| + ElementsKind to_kind) {
|
| + ASSERT(IsJSArray());
|
| + MaybeObject* ret = NULL;
|
| + AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(this);
|
| + if (info != NULL) {
|
| + JSObject* payload = JSObject::cast(info->payload());
|
| + if (payload->GetElementsKind() != to_kind) {
|
| + if (IsMoreGeneralElementsKindTransition(payload->GetElementsKind(),
|
| + to_kind)) {
|
| + ret = payload->TransitionElementsKind(to_kind);
|
| + }
|
| + }
|
| + }
|
| + return ret;
|
| +}
|
| +
|
| +
|
| MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) {
|
| ASSERT(!map()->is_observed());
|
| ElementsKind from_kind = map()->elements_kind();
|
| @@ -10799,6 +10850,9 @@ MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) {
|
|
|
| if (from_kind == to_kind) return this;
|
|
|
| + MaybeObject* trans = PossiblyTransitionArrayBoilerplate(to_kind);
|
| + if (trans != NULL && trans->IsFailure()) return trans;
|
| +
|
| Isolate* isolate = GetIsolate();
|
| if (elements() == isolate->heap()->empty_fixed_array() ||
|
| (IsFastSmiOrObjectElementsKind(from_kind) &&
|
|
|