From 6859247172add31af320038d8a2b79cbb0d860dc Mon Sep 17 00:00:00 2001 From: "svenpanne@chromium.org" Date: Wed, 25 Jan 2012 08:50:55 +0000 Subject: [PATCH] Do not follow accessor map transitions when marking descriptor arrays. Note that we currently have no such transitions, but we will in the future, and we have to avoid keeping maps live too long. Review URL: https://chromiumcodereview.appspot.com/9212045 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10495 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/mark-compact-inl.h | 13 ++++++++++ src/mark-compact.cc | 56 ++++++++++++++++++++++++++++-------------- src/mark-compact.h | 4 +++ 3 files changed, 55 insertions(+), 18 deletions(-) diff --git a/src/mark-compact-inl.h b/src/mark-compact-inl.h index 64faf82dad..a9107bd277 100644 --- a/src/mark-compact-inl.h +++ b/src/mark-compact-inl.h @@ -66,6 +66,19 @@ void MarkCompactCollector::MarkObject(HeapObject* obj, MarkBit mark_bit) { } +bool MarkCompactCollector::MarkObjectWithoutPush(HeapObject* object) { + MarkBit mark = Marking::MarkBitFrom(object); + bool old_mark = mark.Get(); + if (!old_mark) SetMark(object, mark); + return old_mark; +} + + +void MarkCompactCollector::MarkObjectAndPush(HeapObject* object) { + if (!MarkObjectWithoutPush(object)) marking_deque_.PushBlack(object); +} + + void MarkCompactCollector::SetMark(HeapObject* obj, MarkBit mark_bit) { ASSERT(!mark_bit.Get()); ASSERT(Marking::MarkBitFrom(obj) == mark_bit); diff --git a/src/mark-compact.cc b/src/mark-compact.cc index 93614aceba..16e51468cb 100644 --- a/src/mark-compact.cc +++ b/src/mark-compact.cc @@ -1672,6 +1672,16 @@ void MarkCompactCollector::MarkMapContents(Map* map) { } +void MarkCompactCollector::MarkAccessorPairSlot(HeapObject* accessors, + int offset) { + Object** slot = HeapObject::RawField(accessors, offset); + HeapObject* accessor = HeapObject::cast(*slot); + if (accessor->IsMap()) return; + RecordSlot(slot, slot, accessor); + MarkObjectAndPush(accessor); +} + + void MarkCompactCollector::MarkDescriptorArray( DescriptorArray* descriptors) { MarkBit descriptors_mark = Marking::MarkBitFrom(descriptors); @@ -1699,27 +1709,37 @@ void MarkCompactCollector::MarkDescriptorArray( PropertyDetails details(Smi::cast(contents->get(i + 1))); Object** slot = contents->data_start() + i; - Object* value = *slot; - if (!value->IsHeapObject()) continue; + if (!(*slot)->IsHeapObject()) continue; + HeapObject* value = HeapObject::cast(*slot); RecordSlot(slot, slot, *slot); - if (details.IsProperty()) { - HeapObject* object = HeapObject::cast(value); - MarkBit mark = Marking::MarkBitFrom(HeapObject::cast(object)); - if (!mark.Get()) { - SetMark(HeapObject::cast(object), mark); - marking_deque_.PushBlack(object); - } - } else if (details.type() == ELEMENTS_TRANSITION && value->IsFixedArray()) { - // For maps with multiple elements transitions, the transition maps are - // stored in a FixedArray. Keep the fixed array alive but not the maps - // that it refers to. - HeapObject* object = HeapObject::cast(value); - MarkBit mark = Marking::MarkBitFrom(HeapObject::cast(object)); - if (!mark.Get()) { - SetMark(HeapObject::cast(object), mark); - } + switch (details.type()) { + case NORMAL: + case FIELD: + case CONSTANT_FUNCTION: + case HANDLER: + case INTERCEPTOR: + MarkObjectAndPush(value); + break; + case CALLBACKS: + if (!value->IsAccessorPair()) { + MarkObjectAndPush(value); + } else if (!MarkObjectWithoutPush(value)) { + MarkAccessorPairSlot(value, AccessorPair::kGetterOffset); + MarkAccessorPairSlot(value, AccessorPair::kSetterOffset); + } + break; + case ELEMENTS_TRANSITION: + // For maps with multiple elements transitions, the transition maps are + // stored in a FixedArray. Keep the fixed array alive but not the maps + // that it refers to. + if (value->IsFixedArray()) MarkObjectWithoutPush(value); + break; + case MAP_TRANSITION: + case CONSTANT_TRANSITION: + case NULL_DESCRIPTOR: + break; } } // The DescriptorArray descriptors contains a pointer to its contents array, diff --git a/src/mark-compact.h b/src/mark-compact.h index 85a4a3b706..93f3fd2548 100644 --- a/src/mark-compact.h +++ b/src/mark-compact.h @@ -628,6 +628,9 @@ class MarkCompactCollector { // This is for non-incremental marking. INLINE(void MarkObject(HeapObject* obj, MarkBit mark_bit)); + INLINE(bool MarkObjectWithoutPush(HeapObject* object)); + INLINE(void MarkObjectAndPush(HeapObject* value)); + // Marks the object black. This is for non-incremental marking. INLINE(void SetMark(HeapObject* obj, MarkBit mark_bit)); @@ -645,6 +648,7 @@ class MarkCompactCollector { // Mark a Map and its DescriptorArray together, skipping transitions. void MarkMapContents(Map* map); + void MarkAccessorPairSlot(HeapObject* accessors, int offset); void MarkDescriptorArray(DescriptorArray* descriptors); // Mark the heap roots and all objects reachable from them.