Reviewers: Michael Starzinger,
Description:
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.
Please review this at https://chromiumcodereview.appspot.com/9212045/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/mark-compact.h
M src/mark-compact.cc
Index: src/mark-compact.cc
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index
93614aceba272263c529d86ed1982be323c68c74..1af1b632ab2a672c526d5e0de252a47fe7cfbcba
100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -1672,6 +1672,32 @@ void MarkCompactCollector::MarkMapContents(Map* map)
{
}
+bool MarkCompactCollector::MarkUnmarked(Object* value) {
+ HeapObject* object = HeapObject::cast(value);
+ MarkBit mark = Marking::MarkBitFrom(object);
+ bool old_mark = mark.Get();
+ if (!old_mark) SetMark(object, mark);
+ return old_mark;
+}
+
+
+bool MarkCompactCollector::MarkUnmarkedAndPush(Object* value) {
+ bool old_mark = MarkUnmarked(value);
+ if (!old_mark) marking_deque_.PushBlack(HeapObject::cast(value));
+ return old_mark;
+}
+
+
+void MarkCompactCollector::MarkAccessorPairSlot(AccessorPair* accessors,
+ int offset) {
+ Object** slot = HeapObject::RawField(accessors, offset);
+ Object* accessor = *slot;
+ if (accessor->IsMap()) return;
+ RecordSlot(slot, slot, accessor);
+ MarkUnmarkedAndPush(accessor);
+}
+
+
void MarkCompactCollector::MarkDescriptorArray(
DescriptorArray* descriptors) {
MarkBit descriptors_mark = Marking::MarkBitFrom(descriptors);
@@ -1704,22 +1730,33 @@ void MarkCompactCollector::MarkDescriptorArray(
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:
+ MarkUnmarkedAndPush(value);
+ break;
+ case CALLBACKS:
+ if (!value->IsAccessorPair()) {
+ MarkUnmarkedAndPush(value);
+ } else if (!MarkUnmarked(value)) {
+ AccessorPair* accessors = AccessorPair::cast(value);
+ MarkAccessorPairSlot(accessors, AccessorPair::kGetterOffset);
+ MarkAccessorPairSlot(accessors, 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()) MarkUnmarked(value);
+ break;
+ case MAP_TRANSITION:
+ case CONSTANT_TRANSITION:
+ case NULL_DESCRIPTOR:
+ break;
}
}
// The DescriptorArray descriptors contains a pointer to its contents
array,
Index: src/mark-compact.h
diff --git a/src/mark-compact.h b/src/mark-compact.h
index
85a4a3b7060cbf57509a5a14055f2ebe1596a89a..aa6fe80e530bd19cb9dce977787ad884e33d70c0
100644
--- a/src/mark-compact.h
+++ b/src/mark-compact.h
@@ -645,6 +645,9 @@ class MarkCompactCollector {
// Mark a Map and its DescriptorArray together, skipping transitions.
void MarkMapContents(Map* map);
+ bool MarkUnmarked(Object* value);
+ bool MarkUnmarkedAndPush(Object* value);
+ void MarkAccessorPairSlot(AccessorPair* accessors, int offset);
void MarkDescriptorArray(DescriptorArray* descriptors);
// Mark the heap roots and all objects reachable from them.
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev