| Index: src/objects.cc | 
| diff --git a/src/objects.cc b/src/objects.cc | 
| index 2f2bd643484eec81d25a54b241841dfb0d4bdb25..fcaa88cd4ecb83b061fcaab6608b66ec69945b01 100644 | 
| --- a/src/objects.cc | 
| +++ b/src/objects.cc | 
| @@ -7508,6 +7508,31 @@ AllocationSiteInfo* AllocationSiteInfo::FindForJSObject(JSObject* object) { | 
| } | 
|  | 
|  | 
| +// Heuristic: We only need to create allocation site info if the boilerplate | 
| +// elements kind is the initial elements kind. | 
| +AllocationSiteMode AllocationSiteInfo::GetMode( | 
| +    ElementsKind boilerplate_elements_kind) { | 
| +  if (FLAG_track_allocation_sites && | 
| +      IsFastSmiElementsKind(boilerplate_elements_kind)) { | 
| +    return TRACK_ALLOCATION_SITE; | 
| +  } | 
| + | 
| +  return DONT_TRACK_ALLOCATION_SITE; | 
| +} | 
| + | 
| + | 
| +AllocationSiteMode AllocationSiteInfo::GetMode(ElementsKind from, | 
| +                                               ElementsKind to) { | 
| +  if (FLAG_track_allocation_sites && | 
| +      IsFastSmiElementsKind(from) && | 
| +      (IsFastObjectElementsKind(to) || IsFastDoubleElementsKind(to))) { | 
| +    return TRACK_ALLOCATION_SITE; | 
| +  } | 
| + | 
| +  return DONT_TRACK_ALLOCATION_SITE; | 
| +} | 
| + | 
| + | 
| 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. | 
| @@ -9875,6 +9900,10 @@ MaybeObject* JSObject::SetFastElement(uint32_t index, | 
| ElementsKind kind = HasFastHoleyElements() | 
| ? FAST_HOLEY_ELEMENTS | 
| : FAST_ELEMENTS; | 
| + | 
| +    MaybeObject* trans = PossiblyTransitionArrayBoilerplate(kind); | 
| +    if (trans->IsFailure()) return trans; | 
| + | 
| MaybeObject* maybe_new_map = GetElementsTransitionMap(GetIsolate(), | 
| kind); | 
| if (!maybe_new_map->To(&new_map)) return maybe_new_map; | 
| @@ -10406,15 +10435,31 @@ Handle<Object> JSObject::TransitionElementsKind(Handle<JSObject> object, | 
| MaybeObject* JSObject::PossiblyTransitionArrayBoilerplate( | 
| ElementsKind to_kind) { | 
| MaybeObject* ret = NULL; | 
| -  if (IsJSArray()) { | 
| -    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); | 
| -        } | 
| +  if (!FLAG_track_allocation_sites || !IsJSArray()) { | 
| +    return ret; | 
| +  } | 
| + | 
| +  AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(this); | 
| +  if (info == NULL) { | 
| +    return ret; | 
| +  } | 
| + | 
| +  ASSERT(info->payload()->IsJSArray()); | 
| +  JSArray* payload = JSArray::cast(info->payload()); | 
| +  ElementsKind kind = payload->GetElementsKind(); | 
| +  if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { | 
| +    // If the array is huge, it's not likely to be defined in a local | 
| +    // function, so we shouldn't make new instances of it very often. | 
| +    uint32_t length = 0; | 
| +    CHECK(payload->length()->ToArrayIndex(&length)); | 
| +    if (length <= 8 * 1024) { | 
| +      ret = payload->TransitionElementsKind(to_kind); | 
| +      if (FLAG_trace_track_allocation_sites) { | 
| +        PrintF( | 
| +            "AllocationSiteInfo: JSArray %p boilerplate updated %s->%s\n", | 
| +            reinterpret_cast<void*>(this), | 
| +            ElementsKindToString(kind), | 
| +            ElementsKindToString(to_kind)); | 
| } | 
| } | 
| } | 
|  |