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)); |
} |
} |
} |