Index: src/heap.cc |
diff --git a/src/heap.cc b/src/heap.cc |
index c10c43081251de80763f9af2e15c9a6aa2c92fac..069d17e55739ce7a7719dacd87eb5d08ae0cce2e 100644 |
--- a/src/heap.cc |
+++ b/src/heap.cc |
@@ -4394,7 +4394,8 @@ MaybeObject* Heap::AllocateGlobalObject(JSFunction* constructor) { |
} |
-MaybeObject* Heap::CopyJSObject(JSObject* source) { |
+MaybeObject* Heap::CopyJSObject(JSObject* source, |
+ AllocationSiteMode mode) { |
// Never used to copy functions. If functions need to be copied we |
// have to be careful to clear the literals array. |
SLOW_ASSERT(!source->IsJSFunction()); |
@@ -4404,13 +4405,25 @@ MaybeObject* Heap::CopyJSObject(JSObject* source) { |
int object_size = map->instance_size(); |
Object* clone; |
+ bool track_origin = mode == TRACK_ALLOCATION_SITE && |
+ map->CanTrackAllocationSite(); |
+ |
WriteBarrierMode wb_mode = UPDATE_WRITE_BARRIER; |
// If we're forced to always allocate, we use the general allocation |
// functions which may leave us with an object in old space. |
+ int adjusted_object_size = object_size; |
if (always_allocate()) { |
+ // We'll only track origin if we are certain to allocate in new space |
+ if (track_origin) { |
+ const int kMinFreeNewSpaceAfterGC = InitialSemiSpaceSize() * 3/4; |
+ if ((object_size + AllocationSiteInfo::kSize) < kMinFreeNewSpaceAfterGC) { |
+ adjusted_object_size += AllocationSiteInfo::kSize; |
+ } |
+ } |
+ |
{ MaybeObject* maybe_clone = |
- AllocateRaw(object_size, NEW_SPACE, OLD_POINTER_SPACE); |
+ AllocateRaw(adjusted_object_size, NEW_SPACE, OLD_POINTER_SPACE); |
if (!maybe_clone->ToObject(&clone)) return maybe_clone; |
} |
Address clone_address = HeapObject::cast(clone)->address(); |
@@ -4423,7 +4436,11 @@ MaybeObject* Heap::CopyJSObject(JSObject* source) { |
(object_size - JSObject::kHeaderSize) / kPointerSize); |
} else { |
wb_mode = SKIP_WRITE_BARRIER; |
- { MaybeObject* maybe_clone = new_space_.AllocateRaw(object_size); |
+ if (track_origin) { |
+ adjusted_object_size += AllocationSiteInfo::kSize; |
+ } |
+ |
+ { MaybeObject* maybe_clone = new_space_.AllocateRaw(adjusted_object_size); |
if (!maybe_clone->ToObject(&clone)) return maybe_clone; |
} |
SLOW_ASSERT(InNewSpace(clone)); |
@@ -4434,6 +4451,13 @@ MaybeObject* Heap::CopyJSObject(JSObject* source) { |
object_size); |
} |
+ if (adjusted_object_size > object_size) { |
+ AllocationSiteInfo* alloc_info = reinterpret_cast<AllocationSiteInfo*>( |
+ reinterpret_cast<Address>(clone) + object_size); |
+ alloc_info->set_map(allocation_site_info_map()); |
+ alloc_info->set_payload(source); |
+ } |
+ |
SLOW_ASSERT( |
JSObject::cast(clone)->GetElementsKind() == source->GetElementsKind()); |
FixedArrayBase* elements = FixedArrayBase::cast(source->elements()); |