diff --git a/src/heap-inl.h b/src/heap-inl.h index f3ac56a8d4..8c94013149 100644 --- a/src/heap-inl.h +++ b/src/heap-inl.h @@ -490,6 +490,41 @@ void Heap::ScavengePointer(HeapObject** p) { } +AllocationMemento* Heap::FindAllocationMemento(HeapObject* object) { + // Check if there is potentially a memento behind the object. If + // the last word of the momento is on another page we return + // immediately. + Address object_address = object->address(); + Address memento_address = object_address + object->Size(); + Address last_memento_word_address = memento_address + kPointerSize; + if (!NewSpacePage::OnSamePage(object_address, + last_memento_word_address)) { + return NULL; + } + + HeapObject* candidate = HeapObject::FromAddress(memento_address); + if (candidate->map() != allocation_memento_map()) return NULL; + + // Either the object is the last object in the new space, or there is another + // object of at least word size (the header map word) following it, so + // suffices to compare ptr and top here. Note that technically we do not have + // to compare with the current top pointer of the from space page during GC, + // since we always install filler objects above the top pointer of a from + // space page when performing a garbage collection. However, always performing + // the test makes it possible to have a single, unified version of + // FindAllocationMemento that is used both by the GC and the mutator. + Address top = NewSpaceTop(); + ASSERT(memento_address == top || + memento_address + HeapObject::kHeaderSize <= top || + !NewSpacePage::OnSamePage(memento_address, top)); + if (memento_address == top) return NULL; + + AllocationMemento* memento = AllocationMemento::cast(candidate); + if (!memento->IsValid()) return NULL; + return memento; +} + + void Heap::UpdateAllocationSiteFeedback(HeapObject* object, ScratchpadSlotMode mode) { Heap* heap = object->GetHeap(); @@ -498,25 +533,8 @@ void Heap::UpdateAllocationSiteFeedback(HeapObject* object, if (!FLAG_allocation_site_pretenuring || !AllocationSite::CanTrack(object->map()->instance_type())) return; - // Check if there is potentially a memento behind the object. If - // the last word of the momento is on another page we return - // immediatelly. Note that we do not have to compare with the current - // top pointer of the from space page, since we always install filler - // objects above the top pointer of a from space page when performing - // a garbage collection. - Address object_address = object->address(); - Address memento_address = object_address + object->Size(); - Address last_memento_word_address = memento_address + kPointerSize; - if (!NewSpacePage::OnSamePage(object_address, - last_memento_word_address)) { - return; - } - - HeapObject* candidate = HeapObject::FromAddress(memento_address); - if (candidate->map() != heap->allocation_memento_map()) return; - - AllocationMemento* memento = AllocationMemento::cast(candidate); - if (!memento->IsValid()) return; + AllocationMemento* memento = heap->FindAllocationMemento(object); + if (memento == NULL) return; if (memento->GetAllocationSite()->IncrementMementoFoundCount()) { heap->AddAllocationSiteToScratchpad(memento->GetAllocationSite(), mode); diff --git a/src/heap.h b/src/heap.h index 7b3fed9f01..1f7526e71a 100644 --- a/src/heap.h +++ b/src/heap.h @@ -1452,6 +1452,10 @@ class Heap { RECORD_SCRATCHPAD_SLOT }; + // If an object has an AllocationMemento trailing it, return it, otherwise + // return NULL; + inline AllocationMemento* FindAllocationMemento(HeapObject* object); + // An object may have an AllocationSite associated with it through a trailing // AllocationMemento. Its feedback should be updated when objects are found // in the heap. diff --git a/src/objects.cc b/src/objects.cc index 402d8ae399..725ff9ca14 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -12778,30 +12778,9 @@ void JSObject::UpdateAllocationSite(Handle object, Handle site; { DisallowHeapAllocation no_allocation; - // Check if there is potentially a memento behind the object. If - // the last word of the momento is on another page we return - // immediatelly. - Address object_address = object->address(); - Address memento_address = object_address + JSArray::kSize; - Address last_memento_word_address = memento_address + kPointerSize; - if (!NewSpacePage::OnSamePage(object_address, - last_memento_word_address)) { - return; - } - // Either object is the last object in the new space, or there is another - // object of at least word size (the header map word) following it, so - // suffices to compare ptr and top here. - Address top = heap->NewSpaceTop(); - ASSERT(memento_address == top || - memento_address + HeapObject::kHeaderSize <= top); - if (memento_address == top) return; - - HeapObject* candidate = HeapObject::FromAddress(memento_address); - if (candidate->map() != heap->allocation_memento_map()) return; - - AllocationMemento* memento = AllocationMemento::cast(candidate); - if (!memento->IsValid()) return; + AllocationMemento* memento = heap->FindAllocationMemento(*object); + if (memento == NULL) return; // Walk through to the Allocation Site site = handle(memento->GetAllocationSite());