Chromium Code Reviews| Index: src/heap.cc |
| diff --git a/src/heap.cc b/src/heap.cc |
| index ba5b6903984c205a04417d7be075ac1e6f7ac860..fa26b1c8bbef3de29ec171ace7bb2c154b0f88ad 100644 |
| --- a/src/heap.cc |
| +++ b/src/heap.cc |
| @@ -179,6 +179,7 @@ Heap::Heap() |
| memset(roots_, 0, sizeof(roots_[0]) * kRootListLength); |
| native_contexts_list_ = NULL; |
| + array_buffers_list_ = Smi::FromInt(0); |
| mark_compact_collector_.heap_ = this; |
| external_string_table_.heap_ = this; |
| // Put a dummy entry in the remembered pages so we can find the list the |
| @@ -1538,11 +1539,6 @@ static Object* ProcessFunctionWeakReferences(Heap* heap, |
| void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) { |
| - Object* undefined = undefined_value(); |
| - Object* head = undefined; |
| - Context* tail = NULL; |
| - Object* candidate = native_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 no effect if we are already in the middle of |
| @@ -1550,6 +1546,16 @@ void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) { |
| bool record_slots = |
| gc_state() == MARK_COMPACT && |
| mark_compact_collector()->is_compacting(); |
| + ProcessArrayBuffers(retainer, record_slots); |
| + ProcessNativeContexts(retainer, record_slots); |
| +} |
| + |
| +void Heap::ProcessNativeContexts(WeakObjectRetainer* retainer, |
| + bool record_slots) { |
| + Object* undefined = undefined_value(); |
| + Object* head = undefined; |
| + Context* tail = NULL; |
| + Object* candidate = native_contexts_list_; |
| while (candidate != undefined) { |
| // Check whether to keep the candidate in the list. |
| @@ -1618,6 +1624,101 @@ void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) { |
| } |
| +template <class T> |
| +struct WeakListVisitor; |
| + |
| + |
| +template <class T> |
| +static Object* VisitWeakList(Object* list, |
|
Dmitry Lomov (no reviews)
2013/06/04 15:15:52
This is a unified weak list visitor.
I hope to sw
|
| + MarkCompactCollector* collector, |
| + WeakObjectRetainer* retainer, bool record_slots) { |
| + Object* head = Smi::FromInt(0); |
| + T* tail = NULL; |
| + while (list != Smi::FromInt(0)) { |
| + Object* retained = retainer->RetainAs(list); |
| + if (retained != NULL) { |
| + if (head == Smi::FromInt(0)) { |
| + head = retained; |
| + } else { |
| + ASSERT(tail != NULL); |
| + WeakListVisitor<T>::set_weak_next(tail, retained); |
| + if (record_slots) { |
| + Object** next_slot = |
| + HeapObject::RawField(tail, WeakListVisitor<T>::kWeakNextOffset); |
| + collector->RecordSlot(next_slot, next_slot, retained); |
| + } |
| + } |
| + tail = reinterpret_cast<T*>(retained); |
| + WeakListVisitor<T>::VisitLiveObject( |
| + tail, collector, retainer, record_slots); |
| + } |
| + list = WeakListVisitor<T>::get_weak_next(reinterpret_cast<T*>(list)); |
| + } |
| + if (tail != NULL) { |
| + tail->set_weak_next(Smi::FromInt(0)); |
| + } |
| + return head; |
| +} |
| + |
| + |
| +template<> |
| +struct WeakListVisitor<JSTypedArray> { |
| + static void set_weak_next(JSTypedArray* obj, Object* next) { |
| + obj->set_weak_next(next); |
| + } |
| + |
| + static Object* get_weak_next(JSTypedArray* obj) { |
| + return obj->weak_next(); |
| + } |
| + |
| + static void VisitLiveObject(JSTypedArray* obj, |
| + MarkCompactCollector* collector, |
| + WeakObjectRetainer* retainer, |
| + bool record_slots) {} |
| + |
| + static const int kWeakNextOffset = JSTypedArray::kWeakNextOffset; |
| +}; |
| + |
| + |
| +template<> |
| +struct WeakListVisitor<JSArrayBuffer> { |
| + static void set_weak_next(JSArrayBuffer* obj, Object* next) { |
| + obj->set_weak_next(next); |
| + } |
| + |
| + static Object* get_weak_next(JSArrayBuffer* obj) { |
| + return obj->weak_next(); |
| + } |
| + |
| + static void VisitLiveObject(JSArrayBuffer* array_buffer, |
| + MarkCompactCollector* collector, |
| + WeakObjectRetainer* retainer, |
| + bool record_slots) { |
| + Object* typed_array_obj = |
| + VisitWeakList<JSTypedArray>(array_buffer->weak_first_array(), |
| + collector, retainer, record_slots); |
| + array_buffer->set_weak_first_array(typed_array_obj); |
| + if (typed_array_obj != Smi::FromInt(0) && record_slots) { |
| + Object** slot = HeapObject::RawField( |
| + array_buffer, JSArrayBuffer::kWeakFirstArrayOffset); |
| + collector->RecordSlot(slot, slot, typed_array_obj); |
| + } |
| + } |
| + |
| + static const int kWeakNextOffset = JSArrayBuffer::kWeakNextOffset; |
| +}; |
| + |
| + |
| +void Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer, |
| + bool record_slots) { |
| + Object* array_buffer_obj = |
| + VisitWeakList<JSArrayBuffer>(array_buffers_list(), |
| + mark_compact_collector(), |
| + retainer, record_slots); |
| + set_array_buffers_list(array_buffer_obj); |
| +} |
| + |
| + |
| void Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) { |
| DisallowHeapAllocation no_allocation; |
| @@ -1793,6 +1894,14 @@ class ScavengingVisitor : public StaticVisitorBase { |
| &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
| Visit); |
| + table_.Register(kVisitJSArrayBuffer, |
| + &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
| + Visit); |
| + |
| + table_.Register(kVisitJSTypedArray, |
| + &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
| + Visit); |
| + |
| table_.Register(kVisitJSRegExp, |
| &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
| Visit); |