Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(534)

Unified Diff: src/mark-compact.cc

Issue 3066044: Generalize virtually dispatched scavenger to virtually dispatched specialized visitors. (Closed)
Patch Set: cleanup Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/mark-compact.h ('k') | src/objects.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/mark-compact.cc
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index d9b0222a4084b810fe6254b43a358882a2b11ec8..f92ecbdc2983c72e89f4644665a4038928c79eaa 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -32,6 +32,7 @@
#include "global-handles.h"
#include "ic-inl.h"
#include "mark-compact.h"
+#include "objects-visiting.h"
#include "stub-cache.h"
namespace v8 {
@@ -63,6 +64,7 @@ int MarkCompactCollector::live_cell_objects_size_ = 0;
int MarkCompactCollector::live_lo_objects_size_ = 0;
#endif
+
void MarkCompactCollector::CollectGarbage() {
// Make sure that Prepare() has been called. The individual steps below will
// update the state as they proceed.
@@ -244,14 +246,72 @@ static inline HeapObject* ShortCircuitConsString(Object** p) {
}
-// Helper class for marking pointers in HeapObjects.
-class MarkingVisitor : public ObjectVisitor {
+class StaticMarkingVisitor : public StaticVisitorBase {
public:
- void VisitPointer(Object** p) {
+ static inline void IterateBody(Map* map, HeapObject* obj) {
+ table_.GetVisitor(map)(map, obj);
+ }
+
+ static void Initialize() {
+ table_.Register(kVisitShortcutCandidate,
+ &FixedBodyVisitor<StaticMarkingVisitor,
+ ConsString::BodyDescriptor,
+ void>::Visit);
+
+ table_.Register(kVisitConsString,
+ &FixedBodyVisitor<StaticMarkingVisitor,
+ ConsString::BodyDescriptor,
+ void>::Visit);
+
+
+ table_.Register(kVisitFixedArray,
+ &FlexibleBodyVisitor<StaticMarkingVisitor,
+ FixedArray::BodyDescriptor,
+ void>::Visit);
+
+ table_.Register(kVisitSharedFunctionInfo,
+ &FixedBodyVisitor<StaticMarkingVisitor,
+ SharedFunctionInfo::BodyDescriptor,
+ void>::Visit);
+
+ table_.Register(kVisitByteArray, &DataObjectVisitor::Visit);
+ table_.Register(kVisitSeqAsciiString, &DataObjectVisitor::Visit);
+ table_.Register(kVisitSeqTwoByteString, &DataObjectVisitor::Visit);
+
+ table_.Register(kVisitOddball,
+ &FixedBodyVisitor<StaticMarkingVisitor,
+ Oddball::BodyDescriptor,
+ void>::Visit);
+ table_.Register(kVisitMap,
+ &FixedBodyVisitor<StaticMarkingVisitor,
+ Map::BodyDescriptor,
+ void>::Visit);
+
+ table_.Register(kVisitCode, &VisitCode);
+
+ table_.Register(kVisitPropertyCell,
+ &FixedBodyVisitor<StaticMarkingVisitor,
+ JSGlobalPropertyCell::BodyDescriptor,
+ void>::Visit);
+
+ table_.RegisterSpecializations<DataObjectVisitor,
+ kVisitDataObject,
+ kVisitDataObjectGeneric>();
+
+ table_.RegisterSpecializations<JSObjectVisitor,
+ kVisitJSObject,
+ kVisitJSObjectGeneric>();
+
+ table_.RegisterSpecializations<StructObjectVisitor,
+ kVisitStruct,
+ kVisitStructGeneric>();
+ }
+
+ INLINE(static void VisitPointer(Object** p)) {
MarkObjectByPointer(p);
}
- void VisitPointers(Object** start, Object** end) {
+ INLINE(static void VisitPointers(Object** start, Object** end)) {
// Mark all objects pointed to in [start, end).
const int kMinRangeForMarkingRecursion = 64;
if (end - start >= kMinRangeForMarkingRecursion) {
@@ -261,7 +321,7 @@ class MarkingVisitor : public ObjectVisitor {
for (Object** p = start; p < end; p++) MarkObjectByPointer(p);
}
- void VisitCodeTarget(RelocInfo* rinfo) {
+ static inline void VisitCodeTarget(RelocInfo* rinfo) {
ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
Code* code = Code::GetCodeFromTargetAddress(rinfo->target_address());
if (FLAG_cleanup_ics_at_gc && code->is_inline_cache_stub()) {
@@ -273,7 +333,7 @@ class MarkingVisitor : public ObjectVisitor {
}
}
- void VisitDebugTarget(RelocInfo* rinfo) {
+ static inline void VisitDebugTarget(RelocInfo* rinfo) {
ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) &&
rinfo->IsPatchedReturnSequence()) ||
(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
@@ -282,19 +342,15 @@ class MarkingVisitor : public ObjectVisitor {
MarkCompactCollector::MarkObject(code);
}
- private:
// Mark object pointed to by p.
- void MarkObjectByPointer(Object** p) {
+ INLINE(static void MarkObjectByPointer(Object** p)) {
if (!(*p)->IsHeapObject()) return;
HeapObject* object = ShortCircuitConsString(p);
MarkCompactCollector::MarkObject(object);
}
- // Tells whether the mark sweep collection will perform compaction.
- bool IsCompacting() { return MarkCompactCollector::IsCompacting(); }
-
// Visit an unmarked object.
- void VisitUnmarkedObject(HeapObject* obj) {
+ static inline void VisitUnmarkedObject(HeapObject* obj) {
#ifdef DEBUG
ASSERT(Heap::Contains(obj));
ASSERT(!obj->IsMarked());
@@ -303,12 +359,12 @@ class MarkingVisitor : public ObjectVisitor {
MarkCompactCollector::SetMark(obj);
// Mark the map pointer and the body.
MarkCompactCollector::MarkObject(map);
- obj->IterateBody(map->instance_type(), obj->SizeFromMap(map), this);
+ IterateBody(map, obj);
}
// Visit all unmarked objects pointed to by [start, end).
// Returns false if the operation fails (lack of stack space).
- inline bool VisitUnmarkedObjects(Object** start, Object** end) {
+ static inline bool VisitUnmarkedObjects(Object** start, Object** end) {
// Return false is we are close to the stack limit.
StackLimitCheck check;
if (check.HasOverflowed()) return false;
@@ -322,6 +378,60 @@ class MarkingVisitor : public ObjectVisitor {
}
return true;
}
+
+ static inline void VisitExternalReference(Address* p) { }
+ static inline void VisitRuntimeEntry(RelocInfo* rinfo) { }
+
+ private:
+ class DataObjectVisitor {
+ public:
+ template<int size>
+ static void VisitSpecialized(Map* map, HeapObject* object) {
+ }
+
+ static void Visit(Map* map, HeapObject* object) {
+ }
+ };
+
+ typedef FlexibleBodyVisitor<StaticMarkingVisitor,
+ JSObject::BodyDescriptor,
+ void> JSObjectVisitor;
+
+ typedef FlexibleBodyVisitor<StaticMarkingVisitor,
+ StructBodyDescriptor,
+ void> StructObjectVisitor;
+
+ static void VisitCode(Map* map, HeapObject* object) {
+ reinterpret_cast<Code*>(object)->CodeIterateBody<StaticMarkingVisitor>();
+ }
+
+ typedef void (*Callback)(Map* map, HeapObject* object);
+
+ static VisitorDispatchTable<Callback> table_;
+};
+
+
+VisitorDispatchTable<StaticMarkingVisitor::Callback>
+ StaticMarkingVisitor::table_;
+
+
+class MarkingVisitor : public ObjectVisitor {
+ public:
+ void VisitPointer(Object** p) {
+ StaticMarkingVisitor::VisitPointer(p);
+ }
+
+ void VisitPointers(Object** start, Object** end) {
+ StaticMarkingVisitor::VisitPointers(start, end);
+ }
+
+ void VisitCodeTarget(RelocInfo* rinfo) {
+ StaticMarkingVisitor::VisitCodeTarget(rinfo);
+ }
+
+ void VisitDebugTarget(RelocInfo* rinfo) {
+ StaticMarkingVisitor::VisitDebugTarget(rinfo);
+ }
};
@@ -336,11 +446,7 @@ class RootMarkingVisitor : public ObjectVisitor {
for (Object** p = start; p < end; p++) MarkObjectByPointer(p);
}
- MarkingVisitor* stack_visitor() { return &stack_visitor_; }
-
private:
- MarkingVisitor stack_visitor_;
-
void MarkObjectByPointer(Object** p) {
if (!(*p)->IsHeapObject()) return;
@@ -351,14 +457,14 @@ class RootMarkingVisitor : public ObjectVisitor {
Map* map = object->map();
// Mark the object.
MarkCompactCollector::SetMark(object);
+
// Mark the map pointer and body, and push them on the marking stack.
MarkCompactCollector::MarkObject(map);
- object->IterateBody(map->instance_type(), object->SizeFromMap(map),
- &stack_visitor_);
+ StaticMarkingVisitor::IterateBody(map, object);
// Mark all the objects reachable from the map and body. May leave
// overflowed objects in the heap.
- MarkCompactCollector::EmptyMarkingStack(&stack_visitor_);
+ MarkCompactCollector::EmptyMarkingStack();
}
};
@@ -425,11 +531,12 @@ void MarkCompactCollector::MarkMapContents(Map* map) {
// Mark the Object* fields of the Map.
// Since the descriptor array has been marked already, it is fine
// that one of these fields contains a pointer to it.
- MarkingVisitor visitor; // Has no state or contents.
- visitor.VisitPointers(HeapObject::RawField(map,
- Map::kPointerFieldsBeginOffset),
- HeapObject::RawField(map,
- Map::kPointerFieldsEndOffset));
+ Object** start_slot = HeapObject::RawField(map,
+ Map::kPointerFieldsBeginOffset);
+
+ Object** end_slot = HeapObject::RawField(map, Map::kPointerFieldsEndOffset);
+
+ StaticMarkingVisitor::VisitPointers(start_slot, end_slot);
}
@@ -529,7 +636,7 @@ void MarkCompactCollector::MarkSymbolTable() {
// Explicitly mark the prefix.
MarkingVisitor marker;
symbol_table->IteratePrefix(&marker);
- ProcessMarkingStack(&marker);
+ ProcessMarkingStack();
}
@@ -544,7 +651,7 @@ void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) {
// There may be overflowed objects in the heap. Visit them now.
while (marking_stack.overflowed()) {
RefillMarkingStack();
- EmptyMarkingStack(visitor->stack_visitor());
+ EmptyMarkingStack();
}
}
@@ -587,7 +694,7 @@ void MarkCompactCollector::MarkObjectGroups() {
// Before: the marking stack contains zero or more heap object pointers.
// After: the marking stack is empty, and all objects reachable from the
// marking stack have been marked, or are overflowed in the heap.
-void MarkCompactCollector::EmptyMarkingStack(MarkingVisitor* visitor) {
+void MarkCompactCollector::EmptyMarkingStack() {
while (!marking_stack.is_empty()) {
HeapObject* object = marking_stack.Pop();
ASSERT(object->IsHeapObject());
@@ -601,8 +708,8 @@ void MarkCompactCollector::EmptyMarkingStack(MarkingVisitor* visitor) {
map_word.ClearMark();
Map* map = map_word.ToMap();
MarkObject(map);
- object->IterateBody(map->instance_type(), object->SizeFromMap(map),
- visitor);
+
+ StaticMarkingVisitor::IterateBody(map, object);
}
}
@@ -652,22 +759,22 @@ void MarkCompactCollector::RefillMarkingStack() {
// stack. Before: the marking stack contains zero or more heap object
// pointers. After: the marking stack is empty and there are no overflowed
// objects in the heap.
-void MarkCompactCollector::ProcessMarkingStack(MarkingVisitor* visitor) {
- EmptyMarkingStack(visitor);
+void MarkCompactCollector::ProcessMarkingStack() {
+ EmptyMarkingStack();
while (marking_stack.overflowed()) {
RefillMarkingStack();
- EmptyMarkingStack(visitor);
+ EmptyMarkingStack();
}
}
-void MarkCompactCollector::ProcessObjectGroups(MarkingVisitor* visitor) {
+void MarkCompactCollector::ProcessObjectGroups() {
bool work_to_do = true;
ASSERT(marking_stack.is_empty());
while (work_to_do) {
MarkObjectGroups();
work_to_do = !marking_stack.is_empty();
- ProcessMarkingStack(visitor);
+ ProcessMarkingStack();
}
}
@@ -692,7 +799,7 @@ void MarkCompactCollector::MarkLiveObjects() {
// objects are unmarked. Mark objects reachable from object groups
// containing at least one marked object, and continue until no new
// objects are reachable from the object groups.
- ProcessObjectGroups(root_visitor.stack_visitor());
+ ProcessObjectGroups();
// The objects reachable from the roots or object groups are marked,
// yet unreachable objects are unmarked. Mark objects reachable
@@ -705,12 +812,12 @@ void MarkCompactCollector::MarkLiveObjects() {
GlobalHandles::IterateWeakRoots(&root_visitor);
while (marking_stack.overflowed()) {
RefillMarkingStack();
- EmptyMarkingStack(root_visitor.stack_visitor());
+ EmptyMarkingStack();
}
// Repeat the object groups to mark unmarked groups reachable from the
// weak roots.
- ProcessObjectGroups(root_visitor.stack_visitor());
+ ProcessObjectGroups();
// Prune the symbol table removing all symbols only pointed to by the
// symbol table. Cannot use symbol_table() here because the symbol
@@ -1091,16 +1198,35 @@ static void MigrateObject(Address dst,
}
+class StaticPointersToNewGenUpdatingVisitor : public
+ StaticNewSpaceVisitor<StaticPointersToNewGenUpdatingVisitor> {
+ public:
+ static inline void VisitPointer(Object** p) {
+ if (!(*p)->IsHeapObject()) return;
+
+ HeapObject* obj = HeapObject::cast(*p);
+ Address old_addr = obj->address();
+
+ if (Heap::new_space()->Contains(obj)) {
+ ASSERT(Heap::InFromSpace(*p));
+ *p = HeapObject::FromAddress(Memory::Address_at(old_addr));
+ }
+ }
+};
+
+
// Visitor for updating pointers from live objects in old spaces to new space.
// It does not expect to encounter pointers to dead objects.
class PointersToNewGenUpdatingVisitor: public ObjectVisitor {
public:
void VisitPointer(Object** p) {
- UpdatePointer(p);
+ StaticPointersToNewGenUpdatingVisitor::VisitPointer(p);
}
void VisitPointers(Object** start, Object** end) {
- for (Object** p = start; p < end; p++) UpdatePointer(p);
+ for (Object** p = start; p < end; p++) {
+ StaticPointersToNewGenUpdatingVisitor::VisitPointer(p);
+ }
}
void VisitCodeTarget(RelocInfo* rinfo) {
@@ -1119,19 +1245,6 @@ class PointersToNewGenUpdatingVisitor: public ObjectVisitor {
VisitPointer(&target);
rinfo->set_call_address(Code::cast(target)->instruction_start());
}
-
- private:
- void UpdatePointer(Object** p) {
- if (!(*p)->IsHeapObject()) return;
-
- HeapObject* obj = HeapObject::cast(*p);
- Address old_addr = obj->address();
-
- if (Heap::new_space()->Contains(obj)) {
- ASSERT(Heap::InFromSpace(*p));
- *p = HeapObject::FromAddress(Memory::Address_at(old_addr));
- }
- }
};
@@ -1248,15 +1361,12 @@ static void SweepNewSpace(NewSpace* space) {
PointersToNewGenUpdatingVisitor updating_visitor;
// Update pointers in to space.
- HeapObject* object;
- for (Address current = space->bottom();
- current < space->top();
- current += object->Size()) {
- object = HeapObject::FromAddress(current);
-
- object->IterateBody(object->map()->instance_type(),
- object->Size(),
- &updating_visitor);
+ Address current = space->bottom();
+ while (current < space->top()) {
+ HeapObject* object = HeapObject::FromAddress(current);
+ current +=
+ StaticPointersToNewGenUpdatingVisitor::IterateBody(object->map(),
+ object);
}
// Update roots.
@@ -1758,7 +1868,9 @@ void MarkCompactCollector::SweepSpaces() {
SweepSpace(Heap::old_data_space(), &DeallocateOldDataBlock);
SweepSpace(Heap::code_space(), &DeallocateCodeBlock);
SweepSpace(Heap::cell_space(), &DeallocateCellBlock);
- SweepNewSpace(Heap::new_space());
+ { GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP_NEWSPACE);
+ SweepNewSpace(Heap::new_space());
+ }
SweepSpace(Heap::map_space(), &DeallocateMapBlock);
Heap::IterateDirtyRegions(Heap::map_space(),
@@ -2327,4 +2439,11 @@ void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj) {
#endif
}
+
+void MarkCompactCollector::Initialize() {
+ StaticPointersToNewGenUpdatingVisitor::Initialize();
+ StaticMarkingVisitor::Initialize();
+}
+
+
} } // namespace v8::internal
« no previous file with comments | « src/mark-compact.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698