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) {
|
void MarkCompactCollector::SetMark(HeapObject* obj, MarkBit mark_bit) {
|
||||||
ASSERT(!mark_bit.Get());
|
ASSERT(!mark_bit.Get());
|
||||||
ASSERT(Marking::MarkBitFrom(obj) == mark_bit);
|
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(
|
void MarkCompactCollector::MarkDescriptorArray(
|
||||||
DescriptorArray* descriptors) {
|
DescriptorArray* descriptors) {
|
||||||
MarkBit descriptors_mark = Marking::MarkBitFrom(descriptors);
|
MarkBit descriptors_mark = Marking::MarkBitFrom(descriptors);
|
||||||
@ -1699,27 +1709,37 @@ void MarkCompactCollector::MarkDescriptorArray(
|
|||||||
PropertyDetails details(Smi::cast(contents->get(i + 1)));
|
PropertyDetails details(Smi::cast(contents->get(i + 1)));
|
||||||
|
|
||||||
Object** slot = contents->data_start() + i;
|
Object** slot = contents->data_start() + i;
|
||||||
Object* value = *slot;
|
if (!(*slot)->IsHeapObject()) continue;
|
||||||
if (!value->IsHeapObject()) continue;
|
HeapObject* value = HeapObject::cast(*slot);
|
||||||
|
|
||||||
RecordSlot(slot, slot, *slot);
|
RecordSlot(slot, slot, *slot);
|
||||||
|
|
||||||
if (details.IsProperty()) {
|
switch (details.type()) {
|
||||||
HeapObject* object = HeapObject::cast(value);
|
case NORMAL:
|
||||||
MarkBit mark = Marking::MarkBitFrom(HeapObject::cast(object));
|
case FIELD:
|
||||||
if (!mark.Get()) {
|
case CONSTANT_FUNCTION:
|
||||||
SetMark(HeapObject::cast(object), mark);
|
case HANDLER:
|
||||||
marking_deque_.PushBlack(object);
|
case INTERCEPTOR:
|
||||||
|
MarkObjectAndPush(value);
|
||||||
|
break;
|
||||||
|
case CALLBACKS:
|
||||||
|
if (!value->IsAccessorPair()) {
|
||||||
|
MarkObjectAndPush(value);
|
||||||
|
} else if (!MarkObjectWithoutPush(value)) {
|
||||||
|
MarkAccessorPairSlot(value, AccessorPair::kGetterOffset);
|
||||||
|
MarkAccessorPairSlot(value, AccessorPair::kSetterOffset);
|
||||||
}
|
}
|
||||||
} else if (details.type() == ELEMENTS_TRANSITION && value->IsFixedArray()) {
|
break;
|
||||||
|
case ELEMENTS_TRANSITION:
|
||||||
// For maps with multiple elements transitions, the transition maps are
|
// For maps with multiple elements transitions, the transition maps are
|
||||||
// stored in a FixedArray. Keep the fixed array alive but not the maps
|
// stored in a FixedArray. Keep the fixed array alive but not the maps
|
||||||
// that it refers to.
|
// that it refers to.
|
||||||
HeapObject* object = HeapObject::cast(value);
|
if (value->IsFixedArray()) MarkObjectWithoutPush(value);
|
||||||
MarkBit mark = Marking::MarkBitFrom(HeapObject::cast(object));
|
break;
|
||||||
if (!mark.Get()) {
|
case MAP_TRANSITION:
|
||||||
SetMark(HeapObject::cast(object), mark);
|
case CONSTANT_TRANSITION:
|
||||||
}
|
case NULL_DESCRIPTOR:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// The DescriptorArray descriptors contains a pointer to its contents array,
|
// The DescriptorArray descriptors contains a pointer to its contents array,
|
||||||
|
@ -628,6 +628,9 @@ class MarkCompactCollector {
|
|||||||
// This is for non-incremental marking.
|
// This is for non-incremental marking.
|
||||||
INLINE(void MarkObject(HeapObject* obj, MarkBit mark_bit));
|
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.
|
// Marks the object black. This is for non-incremental marking.
|
||||||
INLINE(void SetMark(HeapObject* obj, MarkBit mark_bit));
|
INLINE(void SetMark(HeapObject* obj, MarkBit mark_bit));
|
||||||
|
|
||||||
@ -645,6 +648,7 @@ class MarkCompactCollector {
|
|||||||
|
|
||||||
// Mark a Map and its DescriptorArray together, skipping transitions.
|
// Mark a Map and its DescriptorArray together, skipping transitions.
|
||||||
void MarkMapContents(Map* map);
|
void MarkMapContents(Map* map);
|
||||||
|
void MarkAccessorPairSlot(HeapObject* accessors, int offset);
|
||||||
void MarkDescriptorArray(DescriptorArray* descriptors);
|
void MarkDescriptorArray(DescriptorArray* descriptors);
|
||||||
|
|
||||||
// Mark the heap roots and all objects reachable from them.
|
// Mark the heap roots and all objects reachable from them.
|
||||||
|
Loading…
Reference in New Issue
Block a user