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:
parent
c1b91ad60d
commit
abede994d9
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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_;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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>;
|
||||
|
@ -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) |
|
||||
|
@ -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
|
||||
|
@ -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] = {
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user