Unify mechanism to find trailing AllocationMementos

R=hpayer@chromium.org

Review URL: https://codereview.chromium.org/234703003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20675 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
danno@chromium.org 2014-04-11 09:20:56 +00:00
parent c5231ccba6
commit 6f2bea967c
3 changed files with 43 additions and 42 deletions

View File

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

View File

@ -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.

View File

@ -12778,30 +12778,9 @@ void JSObject::UpdateAllocationSite(Handle<JSObject> object,
Handle<AllocationSite> 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());