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
This commit is contained in:
parent
891f0efa3f
commit
6859247172
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user