Chromium Code Reviews| Index: src/heap.cc |
| diff --git a/src/heap.cc b/src/heap.cc |
| index 4000548c5b4a860faa940725fa573e3380ba0aa7..886354e8b98a0df16c936e991b59c0e703833465 100644 |
| --- a/src/heap.cc |
| +++ b/src/heap.cc |
| @@ -1124,6 +1124,27 @@ void PromotionQueue::RelocateQueueHead() { |
| } |
| +class ScavengeWeakObjectRetainer : public WeakObjectRetainer { |
| + public: |
| + explicit ScavengeWeakObjectRetainer(Heap* heap) : heap_(heap) { } |
| + |
| + virtual Object* RetainAs(Object* object) { |
| + if (!heap_->InFromSpace(object)) { |
| + return object; |
| + } |
| + |
| + MapWord map_word = HeapObject::cast(object)->map_word(); |
| + if (map_word.IsForwardingAddress()) { |
| + return map_word.ToForwardingAddress(); |
| + } |
| + return NULL; |
| + } |
| + |
| + private: |
| + Heap* heap_; |
| +}; |
| + |
| + |
| void Heap::Scavenge() { |
| #ifdef DEBUG |
| if (FLAG_verify_heap) VerifyNonPointerSpacePointers(); |
| @@ -1222,6 +1243,9 @@ void Heap::Scavenge() { |
| } |
| incremental_marking()->UpdateMarkingDequeAfterScavenge(); |
| + ScavengeWeakObjectRetainer weak_object_retainer(this); |
| + ProcessWeakReferences(&weak_object_retainer); |
| + |
| ASSERT(new_space_front == new_space_.top()); |
| // Set age mark. |
| @@ -1308,7 +1332,8 @@ void Heap::UpdateReferencesInExternalStringTable( |
| static Object* ProcessFunctionWeakReferences(Heap* heap, |
| Object* function, |
| - WeakObjectRetainer* retainer) { |
| + WeakObjectRetainer* retainer, |
| + bool record_slots) { |
| Object* undefined = heap->undefined_value(); |
| Object* head = undefined; |
| JSFunction* tail = NULL; |
| @@ -1325,6 +1350,12 @@ static Object* ProcessFunctionWeakReferences(Heap* heap, |
| // Subsequent elements in the list. |
| ASSERT(tail != NULL); |
| tail->set_next_function_link(retain); |
| + if (record_slots) { |
| + Object** next_function = |
| + HeapObject::RawField(tail, JSFunction::kNextFunctionLinkOffset); |
| + heap->mark_compact_collector()->RecordSlot( |
| + next_function, next_function, retain); |
| + } |
| } |
| // Retained function is new tail. |
| candidate_function = reinterpret_cast<JSFunction*>(retain); |
| @@ -1353,6 +1384,15 @@ void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) { |
| Object* head = undefined; |
| Context* tail = NULL; |
| Object* candidate = global_contexts_list_; |
| + |
| + // We don't record weak slots during marking or scavenges. |
| + // Instead we do it once when we complete mark-compact cycle. |
| + // Note that write barrier has not effect if we are already the middle of |
|
Michael Starzinger
2012/04/17 09:53:18
Missing "in" and s/not/no/
|
| + // compacting mark-sweep cycle and we have to record slots manually. |
| + bool record_slots = |
| + gc_state() == MARK_COMPACT && |
| + mark_compact_collector()->is_compacting(); |
| + |
| while (candidate != undefined) { |
| // Check whether to keep the candidate in the list. |
| Context* candidate_context = reinterpret_cast<Context*>(candidate); |
| @@ -1368,6 +1408,14 @@ void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) { |
| Context::NEXT_CONTEXT_LINK, |
| retain, |
| UPDATE_WRITE_BARRIER); |
| + |
| + if (record_slots) { |
| + Object** next_context = |
| + HeapObject::RawField( |
| + tail, FixedArray::SizeFor(Context::NEXT_CONTEXT_LINK)); |
| + mark_compact_collector()->RecordSlot( |
| + next_context, next_context, retain); |
| + } |
| } |
| // Retained context is new tail. |
| candidate_context = reinterpret_cast<Context*>(retain); |
| @@ -1380,11 +1428,19 @@ void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) { |
| ProcessFunctionWeakReferences( |
| this, |
| candidate_context->get(Context::OPTIMIZED_FUNCTIONS_LIST), |
| - retainer); |
| + retainer, |
| + record_slots); |
| candidate_context->set_unchecked(this, |
| Context::OPTIMIZED_FUNCTIONS_LIST, |
| function_list_head, |
| UPDATE_WRITE_BARRIER); |
| + if (record_slots) { |
| + Object** optimized_functions = |
| + HeapObject::RawField( |
| + tail, FixedArray::SizeFor(Context::OPTIMIZED_FUNCTIONS_LIST)); |
| + mark_compact_collector()->RecordSlot( |
| + optimized_functions, optimized_functions, function_list_head); |
| + } |
| } |
| // Move to next element in the list. |
| @@ -1643,7 +1699,12 @@ class ScavengingVisitor : public StaticVisitorBase { |
| MigrateObject(heap, object, target, object_size); |
| if (object_contents == POINTER_OBJECT) { |
| - heap->promotion_queue()->insert(target, object_size); |
| + if (map->instance_type() == JS_FUNCTION_TYPE) { |
| + heap->promotion_queue()->insert( |
| + target, JSFunction::kNonWeakFieldsEndOffset); |
| + } else { |
| + heap->promotion_queue()->insert(target, object_size); |
| + } |
| } |
| heap->tracer()->increment_promoted_objects_size(object_size); |