Refactor incremental marking to use static visitor.

This is a refactoring only change that switches incremental marking to
use a static object visitor. It also shares the common code between the
non-incremental and the incremental marker. Sharing that would require
semantical changes will be done later.

R=verwaest@chromium.org

Review URL: https://chromiumcodereview.appspot.com/10816007

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12193 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
mstarzinger@chromium.org 2012-07-25 15:23:07 +00:00
parent c1b91ad60d
commit abede994d9
9 changed files with 331 additions and 279 deletions

View File

@ -2108,7 +2108,7 @@ class Heap {
friend class Page;
friend class Isolate;
friend class MarkCompactCollector;
friend class StaticMarkingVisitor;
friend class MarkCompactMarkingVisitor;
friend class MapCompact;
DISALLOW_COPY_AND_ASSIGN(Heap);

View File

@ -31,6 +31,8 @@
#include "code-stubs.h"
#include "compilation-cache.h"
#include "objects-visiting.h"
#include "objects-visiting-inl.h"
#include "v8conversions.h"
namespace v8 {
@ -160,93 +162,109 @@ void IncrementalMarking::RecordWriteIntoCodeSlow(HeapObject* obj,
}
class IncrementalMarkingMarkingVisitor : public ObjectVisitor {
class IncrementalMarkingMarkingVisitor
: public StaticMarkingVisitor<IncrementalMarkingMarkingVisitor> {
public:
IncrementalMarkingMarkingVisitor(Heap* heap,
IncrementalMarking* incremental_marking)
: heap_(heap),
incremental_marking_(incremental_marking) {
static void Initialize() {
StaticMarkingVisitor<IncrementalMarkingMarkingVisitor>::Initialize();
table_.Register(kVisitSharedFunctionInfo, &VisitSharedFunctionInfo);
table_.Register(kVisitJSFunction, &VisitJSFunction);
table_.Register(kVisitJSRegExp, &VisitJSRegExp);
}
void VisitEmbeddedPointer(RelocInfo* rinfo) {
static inline void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo) {
ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
Object* target = rinfo->target_object();
if (target->NonFailureIsHeapObject()) {
heap_->mark_compact_collector()->RecordRelocSlot(rinfo, target);
MarkObject(target);
heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
MarkObject(heap, target);
}
}
void VisitCodeTarget(RelocInfo* rinfo) {
static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) {
ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub()
&& (target->ic_age() != heap_->global_ic_age())) {
&& (target->ic_age() != heap->global_ic_age())) {
IC::Clear(rinfo->pc());
target = Code::GetCodeFromTargetAddress(rinfo->target_address());
}
heap_->mark_compact_collector()->RecordRelocSlot(rinfo, Code::cast(target));
MarkObject(target);
heap->mark_compact_collector()->RecordRelocSlot(rinfo, Code::cast(target));
MarkObject(heap, target);
}
void VisitDebugTarget(RelocInfo* rinfo) {
ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) &&
rinfo->IsPatchedReturnSequence()) ||
(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
rinfo->IsPatchedDebugBreakSlotSequence()));
Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
heap_->mark_compact_collector()->RecordRelocSlot(rinfo, Code::cast(target));
MarkObject(target);
static void VisitCode(Map* map, HeapObject* object) {
Heap* heap = map->GetHeap();
Code* code = reinterpret_cast<Code*>(object);
code->CodeIterateBody<IncrementalMarkingMarkingVisitor>(heap);
}
void VisitCodeEntry(Address entry_address) {
Object* target = Code::GetObjectFromEntryAddress(entry_address);
heap_->mark_compact_collector()->
RecordCodeEntrySlot(entry_address, Code::cast(target));
MarkObject(target);
static void VisitJSWeakMap(Map* map, HeapObject* object) {
Heap* heap = map->GetHeap();
VisitPointers(heap,
HeapObject::RawField(object, JSWeakMap::kPropertiesOffset),
HeapObject::RawField(object, JSWeakMap::kSize));
}
void VisitSharedFunctionInfo(SharedFunctionInfo* shared) {
if (shared->ic_age() != heap_->global_ic_age()) {
shared->ResetForNewContext(heap_->global_ic_age());
static void VisitSharedFunctionInfo(Map* map, HeapObject* object) {
Heap* heap = map->GetHeap();
SharedFunctionInfo* shared = SharedFunctionInfo::cast(object);
if (shared->ic_age() != heap->global_ic_age()) {
shared->ResetForNewContext(heap->global_ic_age());
}
FixedBodyVisitor<IncrementalMarkingMarkingVisitor,
SharedFunctionInfo::BodyDescriptor,
void>::Visit(map, object);
}
void VisitPointer(Object** p) {
static inline void VisitJSFunction(Map* map, HeapObject* object) {
Heap* heap = map->GetHeap();
// Iterate over all fields in the body but take care in dealing with
// the code entry and skip weak fields.
VisitPointers(heap,
HeapObject::RawField(object, JSFunction::kPropertiesOffset),
HeapObject::RawField(object, JSFunction::kCodeEntryOffset));
VisitCodeEntry(heap, object->address() + JSFunction::kCodeEntryOffset);
VisitPointers(heap,
HeapObject::RawField(object,
JSFunction::kCodeEntryOffset + kPointerSize),
HeapObject::RawField(object,
JSFunction::kNonWeakFieldsEndOffset));
}
INLINE(static void VisitPointer(Heap* heap, Object** p)) {
Object* obj = *p;
if (obj->NonFailureIsHeapObject()) {
heap_->mark_compact_collector()->RecordSlot(p, p, obj);
MarkObject(obj);
heap->mark_compact_collector()->RecordSlot(p, p, obj);
MarkObject(heap, obj);
}
}
void VisitPointers(Object** start, Object** end) {
INLINE(static void VisitPointers(Heap* heap, Object** start, Object** end)) {
for (Object** p = start; p < end; p++) {
Object* obj = *p;
if (obj->NonFailureIsHeapObject()) {
heap_->mark_compact_collector()->RecordSlot(start, p, obj);
MarkObject(obj);
heap->mark_compact_collector()->RecordSlot(start, p, obj);
MarkObject(heap, obj);
}
}
}
private:
// Mark object pointed to by p.
INLINE(void MarkObject(Object* obj)) {
INLINE(static void MarkObject(Heap* heap, Object* obj)) {
HeapObject* heap_object = HeapObject::cast(obj);
MarkBit mark_bit = Marking::MarkBitFrom(heap_object);
if (mark_bit.data_only()) {
if (incremental_marking_->MarkBlackOrKeepGrey(mark_bit)) {
if (heap->incremental_marking()->MarkBlackOrKeepGrey(mark_bit)) {
MemoryChunk::IncrementLiveBytesFromGC(heap_object->address(),
heap_object->Size());
}
} else if (Marking::IsWhite(mark_bit)) {
incremental_marking_->WhiteToGreyAndPush(heap_object, mark_bit);
heap->incremental_marking()->WhiteToGreyAndPush(heap_object, mark_bit);
}
}
Heap* heap_;
IncrementalMarking* incremental_marking_;
};
@ -290,6 +308,11 @@ class IncrementalMarkingRootMarkingVisitor : public ObjectVisitor {
};
void IncrementalMarking::Initialize() {
IncrementalMarkingMarkingVisitor::Initialize();
}
void IncrementalMarking::SetOldSpacePageFlags(MemoryChunk* chunk,
bool is_marking,
bool is_compacting) {
@ -623,24 +646,6 @@ void IncrementalMarking::UpdateMarkingDequeAfterScavenge() {
}
void IncrementalMarking::VisitGlobalContext(Context* ctx, ObjectVisitor* v) {
v->VisitPointers(
HeapObject::RawField(
ctx, Context::MarkCompactBodyDescriptor::kStartOffset),
HeapObject::RawField(
ctx, Context::MarkCompactBodyDescriptor::kEndOffset));
MarkCompactCollector* collector = heap_->mark_compact_collector();
for (int idx = Context::FIRST_WEAK_SLOT;
idx < Context::GLOBAL_CONTEXT_SLOTS;
++idx) {
Object** slot =
HeapObject::RawField(ctx, FixedArray::OffsetOfElementAt(idx));
collector->RecordSlot(slot, slot, *slot);
}
}
void IncrementalMarking::Hurry() {
if (state() == MARKING) {
double start = 0.0;
@ -652,7 +657,6 @@ void IncrementalMarking::Hurry() {
// was stopped.
Map* filler_map = heap_->one_pointer_filler_map();
Map* global_context_map = heap_->global_context_map();
IncrementalMarkingMarkingVisitor marking_visitor(heap_, this);
while (!marking_deque_.IsEmpty()) {
HeapObject* obj = marking_deque_.Pop();
@ -663,7 +667,7 @@ void IncrementalMarking::Hurry() {
continue;
} else if (map == global_context_map) {
// Global contexts have weak fields.
VisitGlobalContext(Context::cast(obj), &marking_visitor);
IncrementalMarkingMarkingVisitor::VisitGlobalContext(map, obj);
} else if (map->instance_type() == MAP_TYPE) {
Map* map = Map::cast(obj);
heap_->ClearCacheOnMap(map);
@ -676,12 +680,17 @@ void IncrementalMarking::Hurry() {
map->instance_type() >= FIRST_JS_RECEIVER_TYPE) {
marker_.MarkMapContents(map);
} else {
marking_visitor.VisitPointers(
IncrementalMarkingMarkingVisitor::VisitPointers(
heap_,
HeapObject::RawField(map, Map::kPointerFieldsBeginOffset),
HeapObject::RawField(map, Map::kPointerFieldsEndOffset));
}
} else {
obj->Iterate(&marking_visitor);
MarkBit map_mark_bit = Marking::MarkBitFrom(map);
if (Marking::IsWhite(map_mark_bit)) {
WhiteToGreyAndPush(map, map_mark_bit);
}
IncrementalMarkingMarkingVisitor::IterateBody(map, obj);
}
MarkBit mark_bit = Marking::MarkBitFrom(obj);
@ -815,7 +824,6 @@ void IncrementalMarking::Step(intptr_t allocated_bytes,
} else if (state_ == MARKING) {
Map* filler_map = heap_->one_pointer_filler_map();
Map* global_context_map = heap_->global_context_map();
IncrementalMarkingMarkingVisitor marking_visitor(heap_, this);
while (!marking_deque_.IsEmpty() && bytes_to_process > 0) {
HeapObject* obj = marking_deque_.Pop();
@ -840,7 +848,7 @@ void IncrementalMarking::Step(intptr_t allocated_bytes,
// when we finish marking.
MarkObjectGreyDoNotEnqueue(ctx->normalized_map_cache());
VisitGlobalContext(ctx, &marking_visitor);
IncrementalMarkingMarkingVisitor::VisitGlobalContext(map, ctx);
} else if (map->instance_type() == MAP_TYPE) {
Map* map = Map::cast(obj);
heap_->ClearCacheOnMap(map);
@ -853,25 +861,13 @@ void IncrementalMarking::Step(intptr_t allocated_bytes,
map->instance_type() >= FIRST_JS_RECEIVER_TYPE) {
marker_.MarkMapContents(map);
} else {
marking_visitor.VisitPointers(
IncrementalMarkingMarkingVisitor::VisitPointers(
heap_,
HeapObject::RawField(map, Map::kPointerFieldsBeginOffset),
HeapObject::RawField(map, Map::kPointerFieldsEndOffset));
}
} else if (map->instance_type() == JS_FUNCTION_TYPE) {
marking_visitor.VisitPointers(
HeapObject::RawField(obj, JSFunction::kPropertiesOffset),
HeapObject::RawField(obj, JSFunction::kCodeEntryOffset));
marking_visitor.VisitCodeEntry(
obj->address() + JSFunction::kCodeEntryOffset);
marking_visitor.VisitPointers(
HeapObject::RawField(obj,
JSFunction::kCodeEntryOffset + kPointerSize),
HeapObject::RawField(obj,
JSFunction::kNonWeakFieldsEndOffset));
} else {
obj->IterateBody(map->instance_type(), size, &marking_visitor);
IncrementalMarkingMarkingVisitor::IterateBody(map, obj);
}
MarkBit obj_mark_bit = Marking::MarkBitFrom(obj);

View File

@ -53,6 +53,8 @@ class IncrementalMarking {
explicit IncrementalMarking(Heap* heap);
static void Initialize();
void TearDown();
State state() {
@ -259,8 +261,6 @@ class IncrementalMarking {
void EnsureMarkingDequeIsCommitted();
void VisitGlobalContext(Context* ctx, ObjectVisitor* v);
Heap* heap_;
State state_;

View File

@ -938,12 +938,9 @@ static inline HeapObject* ShortCircuitConsString(Object** p) {
}
class StaticMarkingVisitor : public StaticVisitorBase {
class MarkCompactMarkingVisitor
: public StaticMarkingVisitor<MarkCompactMarkingVisitor> {
public:
static inline void IterateBody(Map* map, HeapObject* obj) {
table_.GetVisitor(map)(map, obj);
}
static void ObjectStatsVisitBase(StaticVisitorBase::VisitorId id,
Map* map, HeapObject* obj);
@ -952,7 +949,7 @@ class StaticMarkingVisitor : public StaticVisitorBase {
FixedArraySubInstanceType fast_type,
FixedArraySubInstanceType dictionary_type);
template<StaticMarkingVisitor::VisitorId id>
template<MarkCompactMarkingVisitor::VisitorId id>
class ObjectStatsTracker {
public:
static inline void Visit(Map* map, HeapObject* obj);
@ -977,12 +974,9 @@ class StaticMarkingVisitor : public StaticVisitorBase {
}
}
static void VisitGlobalPropertyCell(Heap* heap, RelocInfo* rinfo) {
ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL);
JSGlobalPropertyCell* cell =
JSGlobalPropertyCell::cast(rinfo->target_cell());
MarkBit mark = Marking::MarkBitFrom(cell);
heap->mark_compact_collector()->MarkObject(cell, mark);
INLINE(static void MarkObject(Heap* heap, HeapObject* object)) {
MarkBit mark = Marking::MarkBitFrom(object);
heap->mark_compact_collector()->MarkObject(object, mark);
}
static inline void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo) {
@ -991,8 +985,7 @@ class StaticMarkingVisitor : public StaticVisitorBase {
// that there can be no such embedded pointers and add assertion here.
HeapObject* object = HeapObject::cast(rinfo->target_object());
heap->mark_compact_collector()->RecordRelocSlot(rinfo, object);
MarkBit mark = Marking::MarkBitFrom(object);
heap->mark_compact_collector()->MarkObject(object, mark);
MarkObject(heap, object);
}
static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) {
@ -1005,20 +998,8 @@ class StaticMarkingVisitor : public StaticVisitorBase {
IC::Clear(rinfo->pc());
target = Code::GetCodeFromTargetAddress(rinfo->target_address());
}
MarkBit code_mark = Marking::MarkBitFrom(target);
heap->mark_compact_collector()->MarkObject(target, code_mark);
heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
}
static inline void VisitDebugTarget(Heap* heap, RelocInfo* rinfo) {
ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) &&
rinfo->IsPatchedReturnSequence()) ||
(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
rinfo->IsPatchedDebugBreakSlotSequence()));
Code* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
MarkBit code_mark = Marking::MarkBitFrom(target);
heap->mark_compact_collector()->MarkObject(target, code_mark);
heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
MarkObject(heap, target);
}
// Mark object pointed to by p.
@ -1073,28 +1054,14 @@ class StaticMarkingVisitor : public StaticVisitorBase {
return true;
}
static inline void VisitExternalReference(Address* p) { }
static inline void VisitExternalReference(RelocInfo* rinfo) { }
static inline void VisitRuntimeEntry(RelocInfo* rinfo) { }
private:
class DataObjectVisitor {
public:
template<int size>
static void VisitSpecialized(Map* map, HeapObject* object) {
static void VisitCode(Map* map, HeapObject* object) {
Heap* heap = map->GetHeap();
Code* code = reinterpret_cast<Code*>(object);
if (FLAG_cleanup_code_caches_at_gc) {
code->ClearTypeFeedbackCells(heap);
}
static void Visit(Map* map, HeapObject* object) {
}
};
typedef FlexibleBodyVisitor<StaticMarkingVisitor,
JSObject::BodyDescriptor,
void> JSObjectVisitor;
typedef FlexibleBodyVisitor<StaticMarkingVisitor,
StructBodyDescriptor,
void> StructObjectVisitor;
code->CodeIterateBody<MarkCompactMarkingVisitor>(heap);
}
static void VisitJSWeakMap(Map* map, HeapObject* object) {
MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector();
@ -1108,12 +1075,12 @@ class StaticMarkingVisitor : public StaticVisitorBase {
// Skip visiting the backing hash table containing the mappings.
int object_size = JSWeakMap::BodyDescriptor::SizeOf(map, object);
BodyVisitorBase<StaticMarkingVisitor>::IteratePointers(
BodyVisitorBase<MarkCompactMarkingVisitor>::IteratePointers(
map->GetHeap(),
object,
JSWeakMap::BodyDescriptor::kStartOffset,
JSWeakMap::kTableOffset);
BodyVisitorBase<StaticMarkingVisitor>::IteratePointers(
BodyVisitorBase<MarkCompactMarkingVisitor>::IteratePointers(
map->GetHeap(),
object,
JSWeakMap::kTableOffset + kPointerSize,
@ -1133,14 +1100,9 @@ class StaticMarkingVisitor : public StaticVisitorBase {
ASSERT(MarkCompactCollector::IsMarked(table->map()));
}
static void VisitCode(Map* map, HeapObject* object) {
Heap* heap = map->GetHeap();
Code* code = reinterpret_cast<Code*>(object);
if (FLAG_cleanup_code_caches_at_gc) {
code->ClearTypeFeedbackCells(heap);
}
code->CodeIterateBody<StaticMarkingVisitor>(heap);
}
private:
template<int id>
static inline void TrackObjectStatsAndVisit(Map* map, HeapObject* obj);
// Code flushing support.
@ -1255,7 +1217,7 @@ class StaticMarkingVisitor : public StaticVisitorBase {
static void VisitSharedFunctionInfoGeneric(Map* map, HeapObject* object) {
SharedFunctionInfo::cast(object)->BeforeVisitingPointers();
FixedBodyVisitor<StaticMarkingVisitor,
FixedBodyVisitor<MarkCompactMarkingVisitor,
SharedFunctionInfo::BodyDescriptor,
void>::Visit(map, object);
}
@ -1323,7 +1285,7 @@ class StaticMarkingVisitor : public StaticVisitorBase {
Heap* heap = map->GetHeap();
MarkCompactCollector* collector = heap->mark_compact_collector();
if (!collector->is_code_flushing_enabled()) {
VisitJSRegExpFields(map, object);
VisitJSRegExp(map, object);
return;
}
JSRegExp* re = reinterpret_cast<JSRegExp*>(object);
@ -1331,7 +1293,7 @@ class StaticMarkingVisitor : public StaticVisitorBase {
UpdateRegExpCodeAgeAndFlush(heap, re, true);
UpdateRegExpCodeAgeAndFlush(heap, re, false);
// Visit the fields of the RegExp, including the updated FixedArray.
VisitJSRegExpFields(map, object);
VisitJSRegExp(map, object);
}
@ -1370,29 +1332,6 @@ class StaticMarkingVisitor : public StaticVisitorBase {
}
static void VisitCodeEntry(Heap* heap, Address entry_address) {
Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address));
MarkBit mark = Marking::MarkBitFrom(code);
heap->mark_compact_collector()->MarkObject(code, mark);
heap->mark_compact_collector()->
RecordCodeEntrySlot(entry_address, code);
}
static void VisitGlobalContext(Map* map, HeapObject* object) {
FixedBodyVisitor<StaticMarkingVisitor,
Context::MarkCompactBodyDescriptor,
void>::Visit(map, object);
MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector();
for (int idx = Context::FIRST_WEAK_SLOT;
idx < Context::GLOBAL_CONTEXT_SLOTS;
++idx) {
Object** slot =
HeapObject::RawField(object, FixedArray::OffsetOfElementAt(idx));
collector->RecordSlot(slot, slot, *slot);
}
}
static void VisitJSFunctionAndFlushCode(Map* map, HeapObject* object) {
Heap* heap = map->GetHeap();
MarkCompactCollector* collector = heap->mark_compact_collector();
@ -1474,15 +1413,6 @@ class StaticMarkingVisitor : public StaticVisitorBase {
JSFunction::kNonWeakFieldsEndOffset));
}
static inline void VisitJSRegExpFields(Map* map,
HeapObject* object) {
int last_property_offset =
JSRegExp::kSize + kPointerSize * map->inobject_properties();
VisitPointers(map->GetHeap(),
SLOT_ADDR(object, JSRegExp::kPropertiesOffset),
SLOT_ADDR(object, last_property_offset));
}
static void VisitSharedFunctionInfoFields(Heap* heap,
HeapObject* object,
@ -1500,14 +1430,11 @@ class StaticMarkingVisitor : public StaticVisitorBase {
#undef SLOT_ADDR
typedef void (*Callback)(Map* map, HeapObject* object);
static VisitorDispatchTable<Callback> table_;
static VisitorDispatchTable<Callback> non_count_table_;
};
void StaticMarkingVisitor::ObjectStatsCountFixedArray(
void MarkCompactMarkingVisitor::ObjectStatsCountFixedArray(
FixedArrayBase* fixed_array,
FixedArraySubInstanceType fast_type,
FixedArraySubInstanceType dictionary_type) {
@ -1528,8 +1455,8 @@ void StaticMarkingVisitor::ObjectStatsCountFixedArray(
}
void StaticMarkingVisitor::ObjectStatsVisitBase(
StaticVisitorBase::VisitorId id, Map* map, HeapObject* obj) {
void MarkCompactMarkingVisitor::ObjectStatsVisitBase(
MarkCompactMarkingVisitor::VisitorId id, Map* map, HeapObject* obj) {
Heap* heap = map->GetHeap();
int object_size = obj->Size();
heap->RecordObjectStats(map->instance_type(), -1, object_size);
@ -1546,16 +1473,16 @@ void StaticMarkingVisitor::ObjectStatsVisitBase(
}
template<StaticMarkingVisitor::VisitorId id>
void StaticMarkingVisitor::ObjectStatsTracker<id>::Visit(
template<MarkCompactMarkingVisitor::VisitorId id>
void MarkCompactMarkingVisitor::ObjectStatsTracker<id>::Visit(
Map* map, HeapObject* obj) {
ObjectStatsVisitBase(id, map, obj);
}
template<>
class StaticMarkingVisitor::ObjectStatsTracker<
StaticMarkingVisitor::kVisitMap> {
class MarkCompactMarkingVisitor::ObjectStatsTracker<
MarkCompactMarkingVisitor::kVisitMap> {
public:
static inline void Visit(Map* map, HeapObject* obj) {
Heap* heap = map->GetHeap();
@ -1586,8 +1513,8 @@ class StaticMarkingVisitor::ObjectStatsTracker<
template<>
class StaticMarkingVisitor::ObjectStatsTracker<
StaticMarkingVisitor::kVisitCode> {
class MarkCompactMarkingVisitor::ObjectStatsTracker<
MarkCompactMarkingVisitor::kVisitCode> {
public:
static inline void Visit(Map* map, HeapObject* obj) {
Heap* heap = map->GetHeap();
@ -1600,8 +1527,8 @@ class StaticMarkingVisitor::ObjectStatsTracker<
template<>
class StaticMarkingVisitor::ObjectStatsTracker<
StaticMarkingVisitor::kVisitSharedFunctionInfo> {
class MarkCompactMarkingVisitor::ObjectStatsTracker<
MarkCompactMarkingVisitor::kVisitSharedFunctionInfo> {
public:
static inline void Visit(Map* map, HeapObject* obj) {
Heap* heap = map->GetHeap();
@ -1618,8 +1545,8 @@ class StaticMarkingVisitor::ObjectStatsTracker<
template<>
class StaticMarkingVisitor::ObjectStatsTracker<
StaticMarkingVisitor::kVisitFixedArray> {
class MarkCompactMarkingVisitor::ObjectStatsTracker<
MarkCompactMarkingVisitor::kVisitFixedArray> {
public:
static inline void Visit(Map* map, HeapObject* obj) {
Heap* heap = map->GetHeap();
@ -1635,48 +1562,8 @@ class StaticMarkingVisitor::ObjectStatsTracker<
};
void StaticMarkingVisitor::Initialize() {
table_.Register(kVisitShortcutCandidate,
&FixedBodyVisitor<StaticMarkingVisitor,
ConsString::BodyDescriptor,
void>::Visit);
table_.Register(kVisitConsString,
&FixedBodyVisitor<StaticMarkingVisitor,
ConsString::BodyDescriptor,
void>::Visit);
table_.Register(kVisitSlicedString,
&FixedBodyVisitor<StaticMarkingVisitor,
SlicedString::BodyDescriptor,
void>::Visit);
table_.Register(kVisitFixedArray,
&FlexibleBodyVisitor<StaticMarkingVisitor,
FixedArray::BodyDescriptor,
void>::Visit);
table_.Register(kVisitGlobalContext, &VisitGlobalContext);
table_.Register(kVisitFixedDoubleArray, DataObjectVisitor::Visit);
table_.Register(kVisitByteArray, &DataObjectVisitor::Visit);
table_.Register(kVisitFreeSpace, &DataObjectVisitor::Visit);
table_.Register(kVisitSeqAsciiString, &DataObjectVisitor::Visit);
table_.Register(kVisitSeqTwoByteString, &DataObjectVisitor::Visit);
table_.Register(kVisitJSWeakMap, &VisitJSWeakMap);
table_.Register(kVisitOddball,
&FixedBodyVisitor<StaticMarkingVisitor,
Oddball::BodyDescriptor,
void>::Visit);
table_.Register(kVisitMap,
&FixedBodyVisitor<StaticMarkingVisitor,
Map::BodyDescriptor,
void>::Visit);
table_.Register(kVisitCode, &VisitCode);
void MarkCompactMarkingVisitor::Initialize() {
StaticMarkingVisitor<MarkCompactMarkingVisitor>::Initialize();
table_.Register(kVisitSharedFunctionInfo,
&VisitSharedFunctionInfoAndFlushCode);
@ -1687,23 +1574,6 @@ void StaticMarkingVisitor::Initialize() {
table_.Register(kVisitJSRegExp,
&VisitRegExpAndFlushCode);
table_.Register(kVisitPropertyCell,
&FixedBodyVisitor<StaticMarkingVisitor,
JSGlobalPropertyCell::BodyDescriptor,
void>::Visit);
table_.RegisterSpecializations<DataObjectVisitor,
kVisitDataObject,
kVisitDataObjectGeneric>();
table_.RegisterSpecializations<JSObjectVisitor,
kVisitJSObject,
kVisitJSObjectGeneric>();
table_.RegisterSpecializations<StructObjectVisitor,
kVisitStruct,
kVisitStructGeneric>();
if (FLAG_track_gc_object_stats) {
// Copy the visitor table to make call-through possible.
non_count_table_.CopyFrom(&table_);
@ -1715,10 +1585,8 @@ void StaticMarkingVisitor::Initialize() {
}
VisitorDispatchTable<StaticMarkingVisitor::Callback>
StaticMarkingVisitor::table_;
VisitorDispatchTable<StaticMarkingVisitor::Callback>
StaticMarkingVisitor::non_count_table_;
VisitorDispatchTable<MarkCompactMarkingVisitor::Callback>
MarkCompactMarkingVisitor::non_count_table_;
class MarkingVisitor : public ObjectVisitor {
@ -1726,11 +1594,11 @@ class MarkingVisitor : public ObjectVisitor {
explicit MarkingVisitor(Heap* heap) : heap_(heap) { }
void VisitPointer(Object** p) {
StaticMarkingVisitor::VisitPointer(heap_, p);
MarkCompactMarkingVisitor::VisitPointer(heap_, p);
}
void VisitPointers(Object** start, Object** end) {
StaticMarkingVisitor::VisitPointers(heap_, start, end);
MarkCompactMarkingVisitor::VisitPointers(heap_, start, end);
}
private:
@ -1889,7 +1757,7 @@ class RootMarkingVisitor : public ObjectVisitor {
// Mark the map pointer and body, and push them on the marking stack.
MarkBit map_mark = Marking::MarkBitFrom(map);
collector_->MarkObject(map, map_mark);
StaticMarkingVisitor::IterateBody(map, object);
MarkCompactMarkingVisitor::IterateBody(map, object);
// Mark all the objects reachable from the map and body. May leave
// overflowed objects in the heap.
@ -2342,7 +2210,7 @@ void MarkCompactCollector::EmptyMarkingDeque() {
MarkBit map_mark = Marking::MarkBitFrom(map);
MarkObject(map, map_mark);
StaticMarkingVisitor::IterateBody(map, object);
MarkCompactMarkingVisitor::IterateBody(map, object);
}
// Process encountered weak maps, mark objects only reachable by those
@ -2481,7 +2349,7 @@ void MarkCompactCollector::MarkLiveObjects() {
ASSERT(cell->IsJSGlobalPropertyCell());
if (IsMarked(cell)) {
int offset = JSGlobalPropertyCell::kValueOffset;
StaticMarkingVisitor::VisitPointer(
MarkCompactMarkingVisitor::VisitPointer(
heap(),
reinterpret_cast<Object**>(cell->address() + offset));
}
@ -2740,7 +2608,8 @@ void MarkCompactCollector::ProcessWeakMaps() {
Object** value_slot =
HeapObject::RawField(table, FixedArray::OffsetOfElementAt(
ObjectHashTable::EntryToValueIndex(i)));
StaticMarkingVisitor::MarkObjectByPointer(this, anchor, value_slot);
MarkCompactMarkingVisitor::MarkObjectByPointer(
this, anchor, value_slot);
}
}
weak_map_obj = weak_map->next();
@ -4141,7 +4010,8 @@ void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj,
void MarkCompactCollector::Initialize() {
StaticMarkingVisitor::Initialize();
MarkCompactMarkingVisitor::Initialize();
IncrementalMarking::Initialize();
}

View File

@ -636,7 +636,7 @@ class MarkCompactCollector {
friend class RootMarkingVisitor;
friend class MarkingVisitor;
friend class StaticMarkingVisitor;
friend class MarkCompactMarkingVisitor;
friend class CodeMarkingVisitor;
friend class SharedFunctionInfoMarkingVisitor;
friend class Marker<IncrementalMarking>;

View File

@ -1,4 +1,4 @@
// Copyright 2011 the V8 project authors. All rights reserved.
// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@ -93,6 +93,139 @@ void StaticNewSpaceVisitor<StaticVisitor>::Initialize() {
}
template<typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::Initialize() {
table_.Register(kVisitShortcutCandidate,
&FixedBodyVisitor<StaticVisitor,
ConsString::BodyDescriptor,
void>::Visit);
table_.Register(kVisitConsString,
&FixedBodyVisitor<StaticVisitor,
ConsString::BodyDescriptor,
void>::Visit);
table_.Register(kVisitSlicedString,
&FixedBodyVisitor<StaticVisitor,
SlicedString::BodyDescriptor,
void>::Visit);
table_.Register(kVisitFixedArray,
&FlexibleBodyVisitor<StaticVisitor,
FixedArray::BodyDescriptor,
void>::Visit);
table_.Register(kVisitFixedDoubleArray, &DataObjectVisitor::Visit);
table_.Register(kVisitGlobalContext, &VisitGlobalContext);
table_.Register(kVisitByteArray, &DataObjectVisitor::Visit);
table_.Register(kVisitFreeSpace, &DataObjectVisitor::Visit);
table_.Register(kVisitSeqAsciiString, &DataObjectVisitor::Visit);
table_.Register(kVisitSeqTwoByteString, &DataObjectVisitor::Visit);
table_.Register(kVisitJSWeakMap, &StaticVisitor::VisitJSWeakMap);
table_.Register(kVisitOddball,
&FixedBodyVisitor<StaticVisitor,
Oddball::BodyDescriptor,
void>::Visit);
table_.Register(kVisitMap,
&FixedBodyVisitor<StaticVisitor,
Map::BodyDescriptor,
void>::Visit);
table_.Register(kVisitCode, &StaticVisitor::VisitCode);
// Registration for kVisitSharedFunctionInfo is done by StaticVisitor.
// Registration for kVisitJSFunction is done by StaticVisitor.
// Registration for kVisitJSRegExp is done by StaticVisitor.
table_.Register(kVisitPropertyCell,
&FixedBodyVisitor<StaticVisitor,
JSGlobalPropertyCell::BodyDescriptor,
void>::Visit);
table_.template RegisterSpecializations<DataObjectVisitor,
kVisitDataObject,
kVisitDataObjectGeneric>();
table_.template RegisterSpecializations<JSObjectVisitor,
kVisitJSObject,
kVisitJSObjectGeneric>();
table_.template RegisterSpecializations<StructObjectVisitor,
kVisitStruct,
kVisitStructGeneric>();
}
template<typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitCodeEntry(
Heap* heap, Address entry_address) {
Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address));
heap->mark_compact_collector()->RecordCodeEntrySlot(entry_address, code);
StaticVisitor::MarkObject(heap, code);
}
template<typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitGlobalPropertyCell(
Heap* heap, RelocInfo* rinfo) {
ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL);
JSGlobalPropertyCell* cell = rinfo->target_cell();
StaticVisitor::MarkObject(heap, cell);
}
template<typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitDebugTarget(
Heap* heap, RelocInfo* rinfo) {
ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) &&
rinfo->IsPatchedReturnSequence()) ||
(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
rinfo->IsPatchedDebugBreakSlotSequence()));
Code* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
StaticVisitor::MarkObject(heap, target);
}
template<typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitGlobalContext(
Map* map, HeapObject* object) {
FixedBodyVisitor<StaticVisitor,
Context::MarkCompactBodyDescriptor,
void>::Visit(map, object);
MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector();
for (int idx = Context::FIRST_WEAK_SLOT;
idx < Context::GLOBAL_CONTEXT_SLOTS;
++idx) {
Object** slot =
HeapObject::RawField(object, FixedArray::OffsetOfElementAt(idx));
collector->RecordSlot(slot, slot, *slot);
}
}
template<typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitJSRegExp(
Map* map, HeapObject* object) {
int last_property_offset =
JSRegExp::kSize + kPointerSize * map->inobject_properties();
StaticVisitor::VisitPointers(map->GetHeap(),
HeapObject::RawField(object, JSRegExp::kPropertiesOffset),
HeapObject::RawField(object, last_property_offset));
}
void Code::CodeIterateBody(ObjectVisitor* v) {
int mode_mask = RelocInfo::kCodeTargetMask |
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |

View File

@ -1,4 +1,4 @@
// Copyright 2011 the V8 project authors. All rights reserved.
// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@ -360,7 +360,71 @@ class StaticNewSpaceVisitor : public StaticVisitorBase {
template<typename StaticVisitor>
VisitorDispatchTable<typename StaticNewSpaceVisitor<StaticVisitor>::Callback>
StaticNewSpaceVisitor<StaticVisitor>::table_;
StaticNewSpaceVisitor<StaticVisitor>::table_;
// Base class for visitors used to transitively mark the entire heap.
// IterateBody returns nothing.
// Certain types of objects might not be handled by this base class and
// no visitor function is registered by the generic initialization. A
// specialized visitor function needs to be provided by the inheriting
// class itself for those cases.
//
// This class is intended to be used in the following way:
//
// class SomeVisitor : public StaticMarkingVisitor<SomeVisitor> {
// ...
// }
//
// This is an example of Curiously recurring template pattern.
template<typename StaticVisitor>
class StaticMarkingVisitor : public StaticVisitorBase {
public:
static void Initialize();
static inline void IterateBody(Map* map, HeapObject* obj) {
table_.GetVisitor(map)(map, obj);
}
static inline void VisitCodeEntry(Heap* heap, Address entry_address);
static inline void VisitGlobalPropertyCell(Heap* heap, RelocInfo* rinfo);
static inline void VisitDebugTarget(Heap* heap, RelocInfo* rinfo);
static inline void VisitExternalReference(RelocInfo* rinfo) { }
static inline void VisitRuntimeEntry(RelocInfo* rinfo) { }
// TODO(mstarzinger): This should be made protected once refactoring is done.
static inline void VisitGlobalContext(Map* map, HeapObject* object);
protected:
static inline void VisitJSRegExp(Map* map, HeapObject* object);
class DataObjectVisitor {
public:
template<int size>
static inline void VisitSpecialized(Map* map, HeapObject* object) {
}
static inline void Visit(Map* map, HeapObject* object) {
}
};
typedef FlexibleBodyVisitor<StaticVisitor,
JSObject::BodyDescriptor,
void> JSObjectVisitor;
typedef FlexibleBodyVisitor<StaticVisitor,
StructBodyDescriptor,
void> StructObjectVisitor;
typedef void (*Callback)(Map* map, HeapObject* object);
static VisitorDispatchTable<Callback> table_;
};
template<typename StaticVisitor>
VisitorDispatchTable<typename StaticMarkingVisitor<StaticVisitor>::Callback>
StaticMarkingVisitor<StaticVisitor>::table_;
} } // namespace v8::internal

View File

@ -1398,8 +1398,7 @@ void HeapObject::IterateBody(InstanceType type, int object_size,
case EXTERNAL_DOUBLE_ARRAY_TYPE:
break;
case SHARED_FUNCTION_INFO_TYPE: {
SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(this);
shared->SharedFunctionInfoIterateBody(v);
SharedFunctionInfo::BodyDescriptor::IterateBody(this, v);
break;
}
@ -7996,12 +7995,6 @@ int SharedFunctionInfo::SearchOptimizedCodeMap(Context* global_context) {
}
void SharedFunctionInfo::SharedFunctionInfoIterateBody(ObjectVisitor* v) {
v->VisitSharedFunctionInfo(this);
SharedFunctionInfo::BodyDescriptor::IterateBody(this, v);
}
#define DECLARE_TAG(ignore1, name, ignore2) name,
const char* const VisitorSynchronization::kTags[
VisitorSynchronization::kNumberOfSyncTags] = {

View File

@ -5724,8 +5724,6 @@ class SharedFunctionInfo: public HeapObject {
static bool CompileLazy(Handle<SharedFunctionInfo> shared,
ClearExceptionFlag flag);
void SharedFunctionInfoIterateBody(ObjectVisitor* v);
// Casting.
static inline SharedFunctionInfo* cast(Object* obj);
@ -8853,8 +8851,6 @@ class ObjectVisitor BASE_EMBEDDED {
// Visit pointer embedded into a code object.
virtual void VisitEmbeddedPointer(RelocInfo* rinfo);
virtual void VisitSharedFunctionInfo(SharedFunctionInfo* shared) {}
// Visits a contiguous arrays of external references (references to the C++
// heap) in the half-open range [start, end). Any or all of the values
// may be modified on return.