| 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,
|
| + 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);
|
|
|