Index: src/heap.cc |
diff --git a/src/heap.cc b/src/heap.cc |
index 4da83e859e3ddff3f2988c00f066ab63ddf58c04..6fe4928f23dc06cb26ff2305f0e86998f6700c7e 100644 |
--- a/src/heap.cc |
+++ b/src/heap.cc |
@@ -143,6 +143,7 @@ Heap::Heap() |
number_idle_notifications_(0), |
last_idle_notification_gc_count_(0), |
last_idle_notification_gc_count_init_(false), |
+ promotion_queue_(this), |
configured_(false), |
chunks_queued_for_free_(NULL) { |
// Allow build-time customization of the max semispace size. Building |
@@ -988,6 +989,41 @@ void StoreBufferRebuilder::Callback(MemoryChunk* page, StoreBufferEvent event) { |
} |
+void PromotionQueue::Initialize() { |
+ // Assumes that a NewSpacePage exactly fits a number of promotion queue |
+ // entries (where each is a pair of intptr_t). This allows us to simplify |
+ // the test fpr when to switch pages. |
+ ASSERT((Page::kPageSize - MemoryChunk::kBodyOffset) % (2 * kPointerSize) |
+ == 0); |
+ limit_ = reinterpret_cast<intptr_t*>(heap_->new_space()->ToSpaceStart()); |
+ front_ = rear_ = |
+ reinterpret_cast<intptr_t*>(heap_->new_space()->ToSpaceEnd()); |
+ emergency_stack_ = NULL; |
+ guard_ = false; |
+} |
+ |
+ |
+void PromotionQueue::RelocateQueueHead() { |
+ ASSERT(emergency_stack_ == NULL); |
+ |
+ Page* p = Page::FromAllocationTop(reinterpret_cast<Address>(rear_)); |
+ intptr_t* head_start = rear_; |
+ intptr_t* head_end = |
+ Min(front_, reinterpret_cast<intptr_t*>(p->body_limit())); |
+ |
+ int entries_count = (head_end - head_start) / kEntrySizeInWords; |
+ |
+ emergency_stack_ = new List<Entry>(2 * entries_count); |
+ |
+ while (head_start != head_end) { |
+ int size = *(head_start++); |
+ HeapObject* obj = reinterpret_cast<HeapObject*>(*(head_start++)); |
+ emergency_stack_->Add(Entry(obj, size)); |
+ } |
+ rear_ = head_end; |
+} |
+ |
+ |
void Heap::Scavenge() { |
#ifdef DEBUG |
if (FLAG_verify_heap) VerifyNonPointerSpacePointers(); |
@@ -1036,7 +1072,7 @@ void Heap::Scavenge() { |
// frees up its size in bytes from the top of the new space, and |
// objects are at least one pointer in size. |
Address new_space_front = new_space_.ToSpaceStart(); |
- promotion_queue_.Initialize(new_space_.ToSpaceEnd()); |
+ promotion_queue_.Initialize(); |
#ifdef DEBUG |
store_buffer()->Clean(); |
@@ -1076,10 +1112,11 @@ void Heap::Scavenge() { |
&scavenge_visitor); |
new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
- |
UpdateNewSpaceReferencesInExternalStringTable( |
&UpdateNewSpaceReferenceInExternalStringTableEntry); |
+ promotion_queue_.Destroy(); |
+ |
LiveObjectList::UpdateReferencesForScavengeGC(); |
isolate()->runtime_profiler()->UpdateSamplesAfterScavenge(); |
incremental_marking()->UpdateMarkingDequeAfterScavenge(); |
@@ -1486,6 +1523,7 @@ class ScavengingVisitor : public StaticVisitorBase { |
} |
} |
MaybeObject* allocation = heap->new_space()->AllocateRaw(object_size); |
+ heap->promotion_queue()->SetNewLimit(heap->new_space()->top()); |
Object* result = allocation->ToObjectUnchecked(); |
*slot = MigrateObject(heap, object, HeapObject::cast(result), object_size); |