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

Unified Diff: src/mark-compact.cc

Issue 6685088: Merge isolates to bleeding_edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 9 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/messages.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/mark-compact.cc
===================================================================
--- src/mark-compact.cc (revision 7267)
+++ src/mark-compact.cc (working copy)
@@ -44,28 +44,27 @@
// -------------------------------------------------------------------------
// MarkCompactCollector
-bool MarkCompactCollector::force_compaction_ = false;
-bool MarkCompactCollector::compacting_collection_ = false;
-bool MarkCompactCollector::compact_on_next_gc_ = false;
-
-int MarkCompactCollector::previous_marked_count_ = 0;
-GCTracer* MarkCompactCollector::tracer_ = NULL;
-
-
+MarkCompactCollector::MarkCompactCollector() : // NOLINT
#ifdef DEBUG
-MarkCompactCollector::CollectorState MarkCompactCollector::state_ = IDLE;
-
-// Counters used for debugging the marking phase of mark-compact or mark-sweep
-// collection.
-int MarkCompactCollector::live_bytes_ = 0;
-int MarkCompactCollector::live_young_objects_size_ = 0;
-int MarkCompactCollector::live_old_data_objects_size_ = 0;
-int MarkCompactCollector::live_old_pointer_objects_size_ = 0;
-int MarkCompactCollector::live_code_objects_size_ = 0;
-int MarkCompactCollector::live_map_objects_size_ = 0;
-int MarkCompactCollector::live_cell_objects_size_ = 0;
-int MarkCompactCollector::live_lo_objects_size_ = 0;
+ state_(IDLE),
#endif
+ force_compaction_(false),
+ compacting_collection_(false),
+ compact_on_next_gc_(false),
+ previous_marked_count_(0),
+ tracer_(NULL),
+#ifdef DEBUG
+ live_young_objects_size_(0),
+ live_old_pointer_objects_size_(0),
+ live_old_data_objects_size_(0),
+ live_code_objects_size_(0),
+ live_map_objects_size_(0),
+ live_cell_objects_size_(0),
+ live_lo_objects_size_(0),
+ live_bytes_(0),
+#endif
+ heap_(NULL),
+ code_flusher_(NULL) { }
void MarkCompactCollector::CollectGarbage() {
@@ -87,15 +86,15 @@
GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_COMPACT);
EncodeForwardingAddresses();
- Heap::MarkMapPointersAsEncoded(true);
+ heap_->MarkMapPointersAsEncoded(true);
UpdatePointers();
- Heap::MarkMapPointersAsEncoded(false);
- PcToCodeCache::FlushPcToCodeCache();
+ heap_->MarkMapPointersAsEncoded(false);
+ heap_->isolate()->pc_to_code_cache()->Flush();
RelocateObjects();
} else {
SweepSpaces();
- PcToCodeCache::FlushPcToCodeCache();
+ heap_->isolate()->pc_to_code_cache()->Flush();
}
Finish();
@@ -124,7 +123,7 @@
compact_on_next_gc_ = false;
if (FLAG_never_compact) compacting_collection_ = false;
- if (!Heap::map_space()->MapPointersEncodable())
+ if (!HEAP->map_space()->MapPointersEncodable())
compacting_collection_ = false;
if (FLAG_collect_maps) CreateBackPointers();
#ifdef ENABLE_GDB_JIT_INTERFACE
@@ -162,9 +161,9 @@
// force lazy re-initialization of it. This must be done after the
// GC, because it relies on the new address of certain old space
// objects (empty string, illegal builtin).
- StubCache::Clear();
+ Isolate::Current()->stub_cache()->Clear();
- ExternalStringTable::CleanUp();
+ heap_->external_string_table_.CleanUp();
// If we've just compacted old space there's no reason to check the
// fragmentation limit. Just return.
@@ -221,17 +220,19 @@
// and continue with marking. This process repeats until all reachable
// objects have been marked.
-static MarkingStack marking_stack;
+class CodeFlusher {
+ public:
+ explicit CodeFlusher(Isolate* isolate)
+ : isolate_(isolate),
+ jsfunction_candidates_head_(NULL),
+ shared_function_info_candidates_head_(NULL) {}
-class FlushCode : public AllStatic {
- public:
- static void AddCandidate(SharedFunctionInfo* shared_info) {
+ void AddCandidate(SharedFunctionInfo* shared_info) {
SetNextCandidate(shared_info, shared_function_info_candidates_head_);
shared_function_info_candidates_head_ = shared_info;
}
-
- static void AddCandidate(JSFunction* function) {
+ void AddCandidate(JSFunction* function) {
ASSERT(function->unchecked_code() ==
function->unchecked_shared()->unchecked_code());
@@ -239,15 +240,14 @@
jsfunction_candidates_head_ = function;
}
-
- static void ProcessCandidates() {
+ void ProcessCandidates() {
ProcessSharedFunctionInfoCandidates();
ProcessJSFunctionCandidates();
}
private:
- static void ProcessJSFunctionCandidates() {
- Code* lazy_compile = Builtins::builtin(Builtins::LazyCompile);
+ void ProcessJSFunctionCandidates() {
+ Code* lazy_compile = isolate_->builtins()->builtin(Builtins::LazyCompile);
JSFunction* candidate = jsfunction_candidates_head_;
JSFunction* next_candidate;
@@ -271,8 +271,8 @@
}
- static void ProcessSharedFunctionInfoCandidates() {
- Code* lazy_compile = Builtins::builtin(Builtins::LazyCompile);
+ void ProcessSharedFunctionInfoCandidates() {
+ Code* lazy_compile = isolate_->builtins()->builtin(Builtins::LazyCompile);
SharedFunctionInfo* candidate = shared_function_info_candidates_head_;
SharedFunctionInfo* next_candidate;
@@ -291,27 +291,22 @@
shared_function_info_candidates_head_ = NULL;
}
-
static JSFunction** GetNextCandidateField(JSFunction* candidate) {
return reinterpret_cast<JSFunction**>(
candidate->address() + JSFunction::kCodeEntryOffset);
}
-
static JSFunction* GetNextCandidate(JSFunction* candidate) {
return *GetNextCandidateField(candidate);
}
-
static void SetNextCandidate(JSFunction* candidate,
JSFunction* next_candidate) {
*GetNextCandidateField(candidate) = next_candidate;
}
-
STATIC_ASSERT(kPointerSize <= Code::kHeaderSize - Code::kHeaderPaddingStart);
-
static SharedFunctionInfo** GetNextCandidateField(
SharedFunctionInfo* candidate) {
Code* code = candidate->unchecked_code();
@@ -319,29 +314,34 @@
code->address() + Code::kHeaderPaddingStart);
}
-
static SharedFunctionInfo* GetNextCandidate(SharedFunctionInfo* candidate) {
return *GetNextCandidateField(candidate);
}
-
static void SetNextCandidate(SharedFunctionInfo* candidate,
SharedFunctionInfo* next_candidate) {
*GetNextCandidateField(candidate) = next_candidate;
}
- static JSFunction* jsfunction_candidates_head_;
+ Isolate* isolate_;
+ JSFunction* jsfunction_candidates_head_;
+ SharedFunctionInfo* shared_function_info_candidates_head_;
- static SharedFunctionInfo* shared_function_info_candidates_head_;
+ DISALLOW_COPY_AND_ASSIGN(CodeFlusher);
};
-JSFunction* FlushCode::jsfunction_candidates_head_ = NULL;
-SharedFunctionInfo* FlushCode::shared_function_info_candidates_head_ = NULL;
+MarkCompactCollector::~MarkCompactCollector() {
+ if (code_flusher_ != NULL) {
+ delete code_flusher_;
+ code_flusher_ = NULL;
+ }
+}
+
static inline HeapObject* ShortCircuitConsString(Object** p) {
// Optimization: If the heap object pointed to by p is a non-symbol
- // cons string whose right substring is Heap::empty_string, update
+ // cons string whose right substring is HEAP->empty_string, update
// it in place to its left substring. Return the updated value.
//
// Here we assume that if we change *p, we replace it with a heap object
@@ -349,7 +349,7 @@
//
// The check performed is:
// object->IsConsString() && !object->IsSymbol() &&
- // (ConsString::cast(object)->second() == Heap::empty_string())
+ // (ConsString::cast(object)->second() == HEAP->empty_string())
// except the maps for the object and its possible substrings might be
// marked.
HeapObject* object = HeapObject::cast(*p);
@@ -359,7 +359,8 @@
if ((type & kShortcutTypeMask) != kShortcutTypeTag) return object;
Object* second = reinterpret_cast<ConsString*>(object)->unchecked_second();
- if (second != Heap::raw_unchecked_empty_string()) {
+ Heap* heap = map_word.ToMap()->heap();
+ if (second != heap->raw_unchecked_empty_string()) {
return object;
}
@@ -367,7 +368,7 @@
// page dirty marks. Therefore, we only replace the string with its left
// substring when page dirty marks do not change.
Object* first = reinterpret_cast<ConsString*>(object)->unchecked_first();
- if (!Heap::InNewSpace(object) && Heap::InNewSpace(first)) return object;
+ if (!heap->InNewSpace(object) && heap->InNewSpace(first)) return object;
*p = first;
return HeapObject::cast(first);
@@ -380,19 +381,6 @@
table_.GetVisitor(map)(map, obj);
}
- static void EnableCodeFlushing(bool enabled) {
- if (enabled) {
- table_.Register(kVisitJSFunction, &VisitJSFunctionAndFlushCode);
- table_.Register(kVisitSharedFunctionInfo,
- &VisitSharedFunctionInfoAndFlushCode);
-
- } else {
- table_.Register(kVisitJSFunction, &VisitJSFunction);
- table_.Register(kVisitSharedFunctionInfo,
- &VisitSharedFunctionInfoGeneric);
- }
- }
-
static void Initialize() {
table_.Register(kVisitShortcutCandidate,
&FixedBodyVisitor<StaticMarkingVisitor,
@@ -454,18 +442,18 @@
kVisitStructGeneric>();
}
- INLINE(static void VisitPointer(Object** p)) {
- MarkObjectByPointer(p);
+ INLINE(static void VisitPointer(Heap* heap, Object** p)) {
+ MarkObjectByPointer(heap, p);
}
- INLINE(static void VisitPointers(Object** start, Object** end)) {
+ INLINE(static void VisitPointers(Heap* heap, Object** start, Object** end)) {
// Mark all objects pointed to in [start, end).
const int kMinRangeForMarkingRecursion = 64;
if (end - start >= kMinRangeForMarkingRecursion) {
- if (VisitUnmarkedObjects(start, end)) return;
+ if (VisitUnmarkedObjects(heap, start, end)) return;
// We are close to a stack overflow, so just mark the objects.
}
- for (Object** p = start; p < end; p++) MarkObjectByPointer(p);
+ for (Object** p = start; p < end; p++) MarkObjectByPointer(heap, p);
}
static inline void VisitCodeTarget(RelocInfo* rinfo) {
@@ -474,9 +462,9 @@
if (FLAG_cleanup_ics_at_gc && code->is_inline_cache_stub()) {
IC::Clear(rinfo->pc());
// Please note targets for cleared inline cached do not have to be
- // marked since they are contained in Heap::non_monomorphic_cache().
+ // marked since they are contained in HEAP->non_monomorphic_cache().
} else {
- MarkCompactCollector::MarkObject(code);
+ HEAP->mark_compact_collector()->MarkObject(code);
}
}
@@ -484,7 +472,7 @@
ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL);
Object* cell = rinfo->target_cell();
Object* old_cell = cell;
- VisitPointer(&cell);
+ VisitPointer(HEAP, &cell);
if (cell != old_cell) {
rinfo->set_target_cell(reinterpret_cast<JSGlobalPropertyCell*>(cell));
}
@@ -496,34 +484,38 @@
(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
rinfo->IsPatchedDebugBreakSlotSequence()));
HeapObject* code = Code::GetCodeFromTargetAddress(rinfo->call_address());
- MarkCompactCollector::MarkObject(code);
+ HEAP->mark_compact_collector()->MarkObject(code);
}
// Mark object pointed to by p.
- INLINE(static void MarkObjectByPointer(Object** p)) {
+ INLINE(static void MarkObjectByPointer(Heap* heap, Object** p)) {
if (!(*p)->IsHeapObject()) return;
HeapObject* object = ShortCircuitConsString(p);
- MarkCompactCollector::MarkObject(object);
+ heap->mark_compact_collector()->MarkObject(object);
}
+
// Visit an unmarked object.
static inline void VisitUnmarkedObject(HeapObject* obj) {
#ifdef DEBUG
- ASSERT(Heap::Contains(obj));
+ ASSERT(HEAP->Contains(obj));
ASSERT(!obj->IsMarked());
#endif
Map* map = obj->map();
- MarkCompactCollector::SetMark(obj);
+ MarkCompactCollector* collector = map->heap()->mark_compact_collector();
+ collector->SetMark(obj);
// Mark the map pointer and the body.
- MarkCompactCollector::MarkObject(map);
+ collector->MarkObject(map);
IterateBody(map, obj);
}
// Visit all unmarked objects pointed to by [start, end).
// Returns false if the operation fails (lack of stack space).
- static inline bool VisitUnmarkedObjects(Object** start, Object** end) {
+ static inline bool VisitUnmarkedObjects(Heap* heap,
+ Object** start,
+ Object** end) {
// Return false is we are close to the stack limit.
- StackLimitCheck check;
+ StackLimitCheck check(heap->isolate());
if (check.HasOverflowed()) return false;
// Visit the unmarked objects.
@@ -559,7 +551,8 @@
void> StructObjectVisitor;
static void VisitCode(Map* map, HeapObject* object) {
- reinterpret_cast<Code*>(object)->CodeIterateBody<StaticMarkingVisitor>();
+ reinterpret_cast<Code*>(object)->CodeIterateBody<StaticMarkingVisitor>(
+ map->heap());
}
// Code flushing support.
@@ -569,21 +562,20 @@
static const int kCodeAgeThreshold = 5;
inline static bool HasSourceCode(SharedFunctionInfo* info) {
- Object* undefined = Heap::raw_unchecked_undefined_value();
+ Object* undefined = HEAP->raw_unchecked_undefined_value();
return (info->script() != undefined) &&
(reinterpret_cast<Script*>(info->script())->source() != undefined);
}
inline static bool IsCompiled(JSFunction* function) {
- return
- function->unchecked_code() != Builtins::builtin(Builtins::LazyCompile);
+ return function->unchecked_code() !=
+ Isolate::Current()->builtins()->builtin(Builtins::LazyCompile);
}
-
inline static bool IsCompiled(SharedFunctionInfo* function) {
- return
- function->unchecked_code() != Builtins::builtin(Builtins::LazyCompile);
+ return function->unchecked_code() !=
+ Isolate::Current()->builtins()->builtin(Builtins::LazyCompile);
}
inline static bool IsFlushable(JSFunction* function) {
@@ -645,7 +637,7 @@
}
- static bool FlushCodeForFunction(JSFunction* function) {
+ static bool FlushCodeForFunction(Heap* heap, JSFunction* function) {
if (!IsFlushable(function)) return false;
// This function's code looks flushable. But we have to postpone the
@@ -653,7 +645,7 @@
// SharedFunctionInfo because some of them might be optimized.
// That would make the nonoptimized version of the code nonflushable,
// because it is required for bailing out from optimized code.
- FlushCode::AddCandidate(function);
+ heap->mark_compact_collector()->code_flusher()->AddCandidate(function);
return true;
}
@@ -676,9 +668,9 @@
if (!ctx->IsHeapObject()) return false;
Map* map = SafeMap(ctx);
- if (!(map == Heap::raw_unchecked_context_map() ||
- map == Heap::raw_unchecked_catch_context_map() ||
- map == Heap::raw_unchecked_global_context_map())) {
+ if (!(map == HEAP->raw_unchecked_context_map() ||
+ map == HEAP->raw_unchecked_catch_context_map() ||
+ map == HEAP->raw_unchecked_global_context_map())) {
return false;
}
@@ -705,29 +697,37 @@
static void VisitSharedFunctionInfoAndFlushCode(Map* map,
HeapObject* object) {
+ MarkCompactCollector* collector = map->heap()->mark_compact_collector();
+ if (!collector->is_code_flushing_enabled()) {
+ VisitSharedFunctionInfoGeneric(map, object);
+ return;
+ }
VisitSharedFunctionInfoAndFlushCodeGeneric(map, object, false);
}
static void VisitSharedFunctionInfoAndFlushCodeGeneric(
Map* map, HeapObject* object, bool known_flush_code_candidate) {
+ Heap* heap = map->heap();
SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(object);
if (shared->IsInobjectSlackTrackingInProgress()) shared->DetachInitialMap();
if (!known_flush_code_candidate) {
known_flush_code_candidate = IsFlushable(shared);
- if (known_flush_code_candidate) FlushCode::AddCandidate(shared);
+ if (known_flush_code_candidate) {
+ heap->mark_compact_collector()->code_flusher()->AddCandidate(shared);
+ }
}
- VisitSharedFunctionInfoFields(object, known_flush_code_candidate);
+ VisitSharedFunctionInfoFields(heap, object, known_flush_code_candidate);
}
- static void VisitCodeEntry(Address entry_address) {
+ static void VisitCodeEntry(Heap* heap, Address entry_address) {
Object* code = Code::GetObjectFromEntryAddress(entry_address);
Object* old_code = code;
- VisitPointer(&code);
+ VisitPointer(heap, &code);
if (code != old_code) {
Memory::Address_at(entry_address) =
reinterpret_cast<Code*>(code)->entry();
@@ -736,16 +736,22 @@
static void VisitJSFunctionAndFlushCode(Map* map, HeapObject* object) {
+ Heap* heap = map->heap();
+ MarkCompactCollector* collector = heap->mark_compact_collector();
+ if (!collector->is_code_flushing_enabled()) {
+ VisitJSFunction(map, object);
+ return;
+ }
+
JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object);
// The function must have a valid context and not be a builtin.
bool flush_code_candidate = false;
if (IsValidNotBuiltinContext(jsfunction->unchecked_context())) {
- flush_code_candidate = FlushCodeForFunction(jsfunction);
+ flush_code_candidate = FlushCodeForFunction(heap, jsfunction);
}
if (!flush_code_candidate) {
- MarkCompactCollector::MarkObject(
- jsfunction->unchecked_shared()->unchecked_code());
+ collector->MarkObject(jsfunction->unchecked_shared()->unchecked_code());
if (jsfunction->unchecked_code()->kind() == Code::OPTIMIZED_FUNCTION) {
// For optimized functions we should retain both non-optimized version
@@ -761,8 +767,7 @@
i < count;
i++) {
JSFunction* inlined = reinterpret_cast<JSFunction*>(literals->get(i));
- MarkCompactCollector::MarkObject(
- inlined->unchecked_shared()->unchecked_code());
+ collector->MarkObject(inlined->unchecked_shared()->unchecked_code());
}
}
}
@@ -787,11 +792,15 @@
static inline void VisitJSFunctionFields(Map* map,
JSFunction* object,
bool flush_code_candidate) {
- VisitPointers(SLOT_ADDR(object, JSFunction::kPropertiesOffset),
+ Heap* heap = map->heap();
+ MarkCompactCollector* collector = heap->mark_compact_collector();
+
+ VisitPointers(heap,
+ SLOT_ADDR(object, JSFunction::kPropertiesOffset),
SLOT_ADDR(object, JSFunction::kCodeEntryOffset));
if (!flush_code_candidate) {
- VisitCodeEntry(object->address() + JSFunction::kCodeEntryOffset);
+ VisitCodeEntry(heap, object->address() + JSFunction::kCodeEntryOffset);
} else {
// Don't visit code object.
@@ -800,15 +809,16 @@
SharedFunctionInfo* shared_info = object->unchecked_shared();
if (!shared_info->IsMarked()) {
Map* shared_info_map = shared_info->map();
- MarkCompactCollector::SetMark(shared_info);
- MarkCompactCollector::MarkObject(shared_info_map);
+ collector->SetMark(shared_info);
+ collector->MarkObject(shared_info_map);
VisitSharedFunctionInfoAndFlushCodeGeneric(shared_info_map,
shared_info,
true);
}
}
- VisitPointers(SLOT_ADDR(object,
+ VisitPointers(heap,
+ SLOT_ADDR(object,
JSFunction::kCodeEntryOffset + kPointerSize),
SLOT_ADDR(object, JSFunction::kNonWeakFieldsEndOffset));
@@ -816,15 +826,17 @@
}
- static void VisitSharedFunctionInfoFields(HeapObject* object,
+ static void VisitSharedFunctionInfoFields(Heap* heap,
+ HeapObject* object,
bool flush_code_candidate) {
- VisitPointer(SLOT_ADDR(object, SharedFunctionInfo::kNameOffset));
+ VisitPointer(heap, SLOT_ADDR(object, SharedFunctionInfo::kNameOffset));
if (!flush_code_candidate) {
- VisitPointer(SLOT_ADDR(object, SharedFunctionInfo::kCodeOffset));
+ VisitPointer(heap, SLOT_ADDR(object, SharedFunctionInfo::kCodeOffset));
}
- VisitPointers(SLOT_ADDR(object, SharedFunctionInfo::kScopeInfoOffset),
+ VisitPointers(heap,
+ SLOT_ADDR(object, SharedFunctionInfo::kScopeInfoOffset),
SLOT_ADDR(object, SharedFunctionInfo::kSize));
}
@@ -842,12 +854,14 @@
class MarkingVisitor : public ObjectVisitor {
public:
+ explicit MarkingVisitor(Heap* heap) : heap_(heap) { }
+
void VisitPointer(Object** p) {
- StaticMarkingVisitor::VisitPointer(p);
+ StaticMarkingVisitor::VisitPointer(heap_, p);
}
void VisitPointers(Object** start, Object** end) {
- StaticMarkingVisitor::VisitPointers(start, end);
+ StaticMarkingVisitor::VisitPointers(heap_, start, end);
}
void VisitCodeTarget(RelocInfo* rinfo) {
@@ -861,21 +875,33 @@
void VisitDebugTarget(RelocInfo* rinfo) {
StaticMarkingVisitor::VisitDebugTarget(rinfo);
}
+
+ private:
+ Heap* heap_;
};
class CodeMarkingVisitor : public ThreadVisitor {
public:
+ explicit CodeMarkingVisitor(MarkCompactCollector* collector)
+ : collector_(collector) {}
+
void VisitThread(ThreadLocalTop* top) {
for (StackFrameIterator it(top); !it.done(); it.Advance()) {
- MarkCompactCollector::MarkObject(it.frame()->unchecked_code());
+ collector_->MarkObject(it.frame()->unchecked_code());
}
}
+
+ private:
+ MarkCompactCollector* collector_;
};
class SharedFunctionInfoMarkingVisitor : public ObjectVisitor {
public:
+ explicit SharedFunctionInfoMarkingVisitor(MarkCompactCollector* collector)
+ : collector_(collector) {}
+
void VisitPointers(Object** start, Object** end) {
for (Object** p = start; p < end; p++) VisitPointer(p);
}
@@ -884,44 +910,52 @@
Object* obj = *slot;
if (obj->IsSharedFunctionInfo()) {
SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj);
- MarkCompactCollector::MarkObject(shared->unchecked_code());
- MarkCompactCollector::MarkObject(shared);
+ collector_->MarkObject(shared->unchecked_code());
+ collector_->MarkObject(shared);
}
}
+
+ private:
+ MarkCompactCollector* collector_;
};
void MarkCompactCollector::PrepareForCodeFlushing() {
+ ASSERT(heap_ == Isolate::Current()->heap());
+
if (!FLAG_flush_code) {
- StaticMarkingVisitor::EnableCodeFlushing(false);
+ EnableCodeFlushing(false);
return;
}
#ifdef ENABLE_DEBUGGER_SUPPORT
- if (Debug::IsLoaded() || Debug::has_break_points()) {
- StaticMarkingVisitor::EnableCodeFlushing(false);
+ if (heap_->isolate()->debug()->IsLoaded() ||
+ heap_->isolate()->debug()->has_break_points()) {
+ EnableCodeFlushing(false);
return;
}
#endif
- StaticMarkingVisitor::EnableCodeFlushing(true);
+ EnableCodeFlushing(true);
// Ensure that empty descriptor array is marked. Method MarkDescriptorArray
// relies on it being marked before any other descriptor array.
- MarkObject(Heap::raw_unchecked_empty_descriptor_array());
+ MarkObject(heap_->raw_unchecked_empty_descriptor_array());
// Make sure we are not referencing the code from the stack.
+ ASSERT(this == heap_->mark_compact_collector());
for (StackFrameIterator it; !it.done(); it.Advance()) {
MarkObject(it.frame()->unchecked_code());
}
// Iterate the archived stacks in all threads to check if
// the code is referenced.
- CodeMarkingVisitor code_marking_visitor;
- ThreadManager::IterateArchivedThreads(&code_marking_visitor);
+ CodeMarkingVisitor code_marking_visitor(this);
+ heap_->isolate()->thread_manager()->IterateArchivedThreads(
+ &code_marking_visitor);
- SharedFunctionInfoMarkingVisitor visitor;
- CompilationCache::IterateFunctions(&visitor);
- HandleScopeImplementer::Iterate(&visitor);
+ SharedFunctionInfoMarkingVisitor visitor(this);
+ heap_->isolate()->compilation_cache()->IterateFunctions(&visitor);
+ heap_->isolate()->handle_scope_implementer()->Iterate(&visitor);
ProcessMarkingStack();
}
@@ -930,6 +964,9 @@
// Visitor class for marking heap roots.
class RootMarkingVisitor : public ObjectVisitor {
public:
+ explicit RootMarkingVisitor(Heap* heap)
+ : collector_(heap->mark_compact_collector()) { }
+
void VisitPointer(Object** p) {
MarkObjectByPointer(p);
}
@@ -948,16 +985,18 @@
Map* map = object->map();
// Mark the object.
- MarkCompactCollector::SetMark(object);
+ collector_->SetMark(object);
// Mark the map pointer and body, and push them on the marking stack.
- MarkCompactCollector::MarkObject(map);
+ collector_->MarkObject(map);
StaticMarkingVisitor::IterateBody(map, object);
// Mark all the objects reachable from the map and body. May leave
// overflowed objects in the heap.
- MarkCompactCollector::EmptyMarkingStack();
+ collector_->EmptyMarkingStack();
}
+
+ MarkCompactCollector* collector_;
};
@@ -976,10 +1015,10 @@
// Since no objects have yet been moved we can safely access the map of
// the object.
if ((*p)->IsExternalString()) {
- Heap::FinalizeExternalString(String::cast(*p));
+ HEAP->FinalizeExternalString(String::cast(*p));
}
// Set the entry to null_value (as deleted).
- *p = Heap::raw_unchecked_null_value();
+ *p = HEAP->raw_unchecked_null_value();
pointers_removed_++;
}
}
@@ -1010,11 +1049,11 @@
void MarkCompactCollector::MarkUnmarkedObject(HeapObject* object) {
ASSERT(!object->IsMarked());
- ASSERT(Heap::Contains(object));
+ ASSERT(HEAP->Contains(object));
if (object->IsMap()) {
Map* map = Map::cast(object);
if (FLAG_cleanup_caches_in_maps_at_gc) {
- map->ClearCodeCache();
+ map->ClearCodeCache(heap_);
}
SetMark(map);
if (FLAG_collect_maps &&
@@ -1022,11 +1061,11 @@
map->instance_type() <= JS_FUNCTION_TYPE) {
MarkMapContents(map);
} else {
- marking_stack.Push(map);
+ marking_stack_.Push(map);
}
} else {
SetMark(object);
- marking_stack.Push(object);
+ marking_stack_.Push(object);
}
}
@@ -1043,7 +1082,7 @@
Object** end_slot = HeapObject::RawField(map, Map::kPointerFieldsEndOffset);
- StaticMarkingVisitor::VisitPointers(start_slot, end_slot);
+ StaticMarkingVisitor::VisitPointers(map->heap(), start_slot, end_slot);
}
@@ -1051,7 +1090,7 @@
DescriptorArray* descriptors) {
if (descriptors->IsMarked()) return;
// Empty descriptor array is marked as a root before any maps are marked.
- ASSERT(descriptors != Heap::raw_unchecked_empty_descriptor_array());
+ ASSERT(descriptors != HEAP->raw_unchecked_empty_descriptor_array());
SetMark(descriptors);
FixedArray* contents = reinterpret_cast<FixedArray*>(
@@ -1074,18 +1113,18 @@
HeapObject* object = reinterpret_cast<HeapObject*>(contents->get(i));
if (object->IsHeapObject() && !object->IsMarked()) {
SetMark(object);
- marking_stack.Push(object);
+ marking_stack_.Push(object);
}
}
}
// The DescriptorArray descriptors contains a pointer to its contents array,
// but the contents array is already marked.
- marking_stack.Push(descriptors);
+ marking_stack_.Push(descriptors);
}
void MarkCompactCollector::CreateBackPointers() {
- HeapObjectIterator iterator(Heap::map_space());
+ HeapObjectIterator iterator(HEAP->map_space());
for (HeapObject* next_object = iterator.next();
next_object != NULL; next_object = iterator.next()) {
if (next_object->IsMap()) { // Could also be ByteArray on free list.
@@ -1094,7 +1133,7 @@
map->instance_type() <= JS_FUNCTION_TYPE) {
map->CreateBackPointers();
} else {
- ASSERT(map->instance_descriptors() == Heap::empty_descriptor_array());
+ ASSERT(map->instance_descriptors() == HEAP->empty_descriptor_array());
}
}
}
@@ -1111,25 +1150,29 @@
}
-// Fill the marking stack with overflowed objects returned by the given
-// iterator. Stop when the marking stack is filled or the end of the space
-// is reached, whichever comes first.
-template<class T>
-static void ScanOverflowedObjects(T* it) {
- // The caller should ensure that the marking stack is initially not full,
- // so that we don't waste effort pointlessly scanning for objects.
- ASSERT(!marking_stack.is_full());
+class OverflowedObjectsScanner : public AllStatic {
+ public:
+ // Fill the marking stack with overflowed objects returned by the given
+ // iterator. Stop when the marking stack is filled or the end of the space
+ // is reached, whichever comes first.
+ template<class T>
+ static inline void ScanOverflowedObjects(MarkCompactCollector* collector,
+ T* it) {
+ // The caller should ensure that the marking stack is initially not full,
+ // so that we don't waste effort pointlessly scanning for objects.
+ ASSERT(!collector->marking_stack_.is_full());
- for (HeapObject* object = it->next(); object != NULL; object = it->next()) {
- if (object->IsOverflowed()) {
- object->ClearOverflow();
- ASSERT(object->IsMarked());
- ASSERT(Heap::Contains(object));
- marking_stack.Push(object);
- if (marking_stack.is_full()) return;
+ for (HeapObject* object = it->next(); object != NULL; object = it->next()) {
+ if (object->IsOverflowed()) {
+ object->ClearOverflow();
+ ASSERT(object->IsMarked());
+ ASSERT(HEAP->Contains(object));
+ collector->marking_stack_.Push(object);
+ if (collector->marking_stack_.is_full()) return;
+ }
}
}
-}
+};
bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) {
@@ -1138,11 +1181,11 @@
void MarkCompactCollector::MarkSymbolTable() {
- SymbolTable* symbol_table = Heap::raw_unchecked_symbol_table();
+ SymbolTable* symbol_table = heap_->raw_unchecked_symbol_table();
// Mark the symbol table itself.
SetMark(symbol_table);
// Explicitly mark the prefix.
- MarkingVisitor marker;
+ MarkingVisitor marker(heap_);
symbol_table->IteratePrefix(&marker);
ProcessMarkingStack();
}
@@ -1151,13 +1194,13 @@
void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) {
// Mark the heap roots including global variables, stack variables,
// etc., and all objects reachable from them.
- Heap::IterateStrongRoots(visitor, VISIT_ONLY_STRONG);
+ HEAP->IterateStrongRoots(visitor, VISIT_ONLY_STRONG);
// Handle the symbol table specially.
MarkSymbolTable();
// There may be overflowed objects in the heap. Visit them now.
- while (marking_stack.overflowed()) {
+ while (marking_stack_.overflowed()) {
RefillMarkingStack();
EmptyMarkingStack();
}
@@ -1165,7 +1208,8 @@
void MarkCompactCollector::MarkObjectGroups() {
- List<ObjectGroup*>* object_groups = GlobalHandles::ObjectGroups();
+ List<ObjectGroup*>* object_groups =
+ heap_->isolate()->global_handles()->object_groups();
for (int i = 0; i < object_groups->length(); i++) {
ObjectGroup* entry = object_groups->at(i);
@@ -1200,7 +1244,8 @@
void MarkCompactCollector::MarkImplicitRefGroups() {
- List<ImplicitRefGroup*>* ref_groups = GlobalHandles::ImplicitRefGroups();
+ List<ImplicitRefGroup*>* ref_groups =
+ heap_->isolate()->global_handles()->implicit_ref_groups();
for (int i = 0; i < ref_groups->length(); i++) {
ImplicitRefGroup* entry = ref_groups->at(i);
@@ -1230,10 +1275,10 @@
// 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() {
- while (!marking_stack.is_empty()) {
- HeapObject* object = marking_stack.Pop();
+ while (!marking_stack_.is_empty()) {
+ HeapObject* object = marking_stack_.Pop();
ASSERT(object->IsHeapObject());
- ASSERT(Heap::Contains(object));
+ ASSERT(heap_->Contains(object));
ASSERT(object->IsMarked());
ASSERT(!object->IsOverflowed());
@@ -1255,38 +1300,38 @@
// overflowed objects in the heap so the overflow flag on the markings stack
// is cleared.
void MarkCompactCollector::RefillMarkingStack() {
- ASSERT(marking_stack.overflowed());
+ ASSERT(marking_stack_.overflowed());
- SemiSpaceIterator new_it(Heap::new_space(), &OverflowObjectSize);
- ScanOverflowedObjects(&new_it);
- if (marking_stack.is_full()) return;
+ SemiSpaceIterator new_it(HEAP->new_space(), &OverflowObjectSize);
+ OverflowedObjectsScanner::ScanOverflowedObjects(this, &new_it);
+ if (marking_stack_.is_full()) return;
- HeapObjectIterator old_pointer_it(Heap::old_pointer_space(),
+ HeapObjectIterator old_pointer_it(HEAP->old_pointer_space(),
&OverflowObjectSize);
- ScanOverflowedObjects(&old_pointer_it);
- if (marking_stack.is_full()) return;
+ OverflowedObjectsScanner::ScanOverflowedObjects(this, &old_pointer_it);
+ if (marking_stack_.is_full()) return;
- HeapObjectIterator old_data_it(Heap::old_data_space(), &OverflowObjectSize);
- ScanOverflowedObjects(&old_data_it);
- if (marking_stack.is_full()) return;
+ HeapObjectIterator old_data_it(HEAP->old_data_space(), &OverflowObjectSize);
+ OverflowedObjectsScanner::ScanOverflowedObjects(this, &old_data_it);
+ if (marking_stack_.is_full()) return;
- HeapObjectIterator code_it(Heap::code_space(), &OverflowObjectSize);
- ScanOverflowedObjects(&code_it);
- if (marking_stack.is_full()) return;
+ HeapObjectIterator code_it(HEAP->code_space(), &OverflowObjectSize);
+ OverflowedObjectsScanner::ScanOverflowedObjects(this, &code_it);
+ if (marking_stack_.is_full()) return;
- HeapObjectIterator map_it(Heap::map_space(), &OverflowObjectSize);
- ScanOverflowedObjects(&map_it);
- if (marking_stack.is_full()) return;
+ HeapObjectIterator map_it(HEAP->map_space(), &OverflowObjectSize);
+ OverflowedObjectsScanner::ScanOverflowedObjects(this, &map_it);
+ if (marking_stack_.is_full()) return;
- HeapObjectIterator cell_it(Heap::cell_space(), &OverflowObjectSize);
- ScanOverflowedObjects(&cell_it);
- if (marking_stack.is_full()) return;
+ HeapObjectIterator cell_it(HEAP->cell_space(), &OverflowObjectSize);
+ OverflowedObjectsScanner::ScanOverflowedObjects(this, &cell_it);
+ if (marking_stack_.is_full()) return;
- LargeObjectIterator lo_it(Heap::lo_space(), &OverflowObjectSize);
- ScanOverflowedObjects(&lo_it);
- if (marking_stack.is_full()) return;
+ LargeObjectIterator lo_it(HEAP->lo_space(), &OverflowObjectSize);
+ OverflowedObjectsScanner::ScanOverflowedObjects(this, &lo_it);
+ if (marking_stack_.is_full()) return;
- marking_stack.clear_overflowed();
+ marking_stack_.clear_overflowed();
}
@@ -1296,7 +1341,7 @@
// objects in the heap.
void MarkCompactCollector::ProcessMarkingStack() {
EmptyMarkingStack();
- while (marking_stack.overflowed()) {
+ while (marking_stack_.overflowed()) {
RefillMarkingStack();
EmptyMarkingStack();
}
@@ -1305,11 +1350,11 @@
void MarkCompactCollector::ProcessExternalMarking() {
bool work_to_do = true;
- ASSERT(marking_stack.is_empty());
+ ASSERT(marking_stack_.is_empty());
while (work_to_do) {
MarkObjectGroups();
MarkImplicitRefGroups();
- work_to_do = !marking_stack.is_empty();
+ work_to_do = !marking_stack_.is_empty();
ProcessMarkingStack();
}
}
@@ -1320,7 +1365,7 @@
// The recursive GC marker detects when it is nearing stack overflow,
// and switches to a different marking system. JS interrupts interfere
// with the C stack limit check.
- PostponeInterruptsScope postpone;
+ PostponeInterruptsScope postpone(heap_->isolate());
#ifdef DEBUG
ASSERT(state_ == PREPARE_GC);
@@ -1328,14 +1373,14 @@
#endif
// The to space contains live objects, the from space is used as a marking
// stack.
- marking_stack.Initialize(Heap::new_space()->FromSpaceLow(),
- Heap::new_space()->FromSpaceHigh());
+ marking_stack_.Initialize(heap_->new_space()->FromSpaceLow(),
+ heap_->new_space()->FromSpaceHigh());
- ASSERT(!marking_stack.overflowed());
+ ASSERT(!marking_stack_.overflowed());
PrepareForCodeFlushing();
- RootMarkingVisitor root_visitor;
+ RootMarkingVisitor root_visitor(heap_);
MarkRoots(&root_visitor);
// The objects reachable from the roots are marked, yet unreachable
@@ -1349,10 +1394,11 @@
//
// First we identify nonlive weak handles and mark them as pending
// destruction.
- GlobalHandles::IdentifyWeakHandles(&IsUnmarkedHeapObject);
+ heap_->isolate()->global_handles()->IdentifyWeakHandles(
+ &IsUnmarkedHeapObject);
// Then we mark the objects and process the transitive closure.
- GlobalHandles::IterateWeakRoots(&root_visitor);
- while (marking_stack.overflowed()) {
+ heap_->isolate()->global_handles()->IterateWeakRoots(&root_visitor);
+ while (marking_stack_.overflowed()) {
RefillMarkingStack();
EmptyMarkingStack();
}
@@ -1364,47 +1410,49 @@
// Prune the symbol table removing all symbols only pointed to by the
// symbol table. Cannot use symbol_table() here because the symbol
// table is marked.
- SymbolTable* symbol_table = Heap::raw_unchecked_symbol_table();
+ SymbolTable* symbol_table = heap_->raw_unchecked_symbol_table();
SymbolTableCleaner v;
symbol_table->IterateElements(&v);
symbol_table->ElementsRemoved(v.PointersRemoved());
- ExternalStringTable::Iterate(&v);
- ExternalStringTable::CleanUp();
+ heap_->external_string_table_.Iterate(&v);
+ heap_->external_string_table_.CleanUp();
// Process the weak references.
MarkCompactWeakObjectRetainer mark_compact_object_retainer;
- Heap::ProcessWeakReferences(&mark_compact_object_retainer);
+ heap_->ProcessWeakReferences(&mark_compact_object_retainer);
// Remove object groups after marking phase.
- GlobalHandles::RemoveObjectGroups();
- GlobalHandles::RemoveImplicitRefGroups();
+ heap_->isolate()->global_handles()->RemoveObjectGroups();
+ heap_->isolate()->global_handles()->RemoveImplicitRefGroups();
// Flush code from collected candidates.
- FlushCode::ProcessCandidates();
+ if (is_code_flushing_enabled()) {
+ code_flusher_->ProcessCandidates();
+ }
// Clean up dead objects from the runtime profiler.
- RuntimeProfiler::RemoveDeadSamples();
+ heap_->isolate()->runtime_profiler()->RemoveDeadSamples();
}
#ifdef DEBUG
void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj) {
live_bytes_ += obj->Size();
- if (Heap::new_space()->Contains(obj)) {
+ if (HEAP->new_space()->Contains(obj)) {
live_young_objects_size_ += obj->Size();
- } else if (Heap::map_space()->Contains(obj)) {
+ } else if (HEAP->map_space()->Contains(obj)) {
ASSERT(obj->IsMap());
live_map_objects_size_ += obj->Size();
- } else if (Heap::cell_space()->Contains(obj)) {
+ } else if (HEAP->cell_space()->Contains(obj)) {
ASSERT(obj->IsJSGlobalPropertyCell());
live_cell_objects_size_ += obj->Size();
- } else if (Heap::old_pointer_space()->Contains(obj)) {
+ } else if (HEAP->old_pointer_space()->Contains(obj)) {
live_old_pointer_objects_size_ += obj->Size();
- } else if (Heap::old_data_space()->Contains(obj)) {
+ } else if (HEAP->old_data_space()->Contains(obj)) {
live_old_data_objects_size_ += obj->Size();
- } else if (Heap::code_space()->Contains(obj)) {
+ } else if (HEAP->code_space()->Contains(obj)) {
live_code_objects_size_ += obj->Size();
- } else if (Heap::lo_space()->Contains(obj)) {
+ } else if (HEAP->lo_space()->Contains(obj)) {
live_lo_objects_size_ += obj->Size();
} else {
UNREACHABLE();
@@ -1420,7 +1468,7 @@
compacting_collection_ ? ENCODE_FORWARDING_ADDRESSES : SWEEP_SPACES;
#endif
// Deallocate unmarked objects and clear marked bits for marked objects.
- Heap::lo_space()->FreeUnmarkedObjects();
+ HEAP->lo_space()->FreeUnmarkedObjects();
}
@@ -1433,7 +1481,7 @@
void MarkCompactCollector::ClearNonLiveTransitions() {
- HeapObjectIterator map_iterator(Heap::map_space(), &SizeOfMarkedObject);
+ HeapObjectIterator map_iterator(HEAP->map_space(), &SizeOfMarkedObject);
// Iterate over the map space, setting map transitions that go from
// a marked map to an unmarked map to null transitions. At the same time,
// set all the prototype fields of maps back to their original value,
@@ -1483,7 +1531,7 @@
// This test will always be false on the first iteration.
if (on_dead_path && current->IsMarked()) {
on_dead_path = false;
- current->ClearNonLiveTransitions(real_prototype);
+ current->ClearNonLiveTransitions(heap_, real_prototype);
}
*HeapObject::RawField(current, Map::kPrototypeOffset) =
real_prototype;
@@ -1545,20 +1593,21 @@
// Try to promote all objects in new space. Heap numbers and sequential
// strings are promoted to the code space, large objects to large object space,
// and all others to the old space.
-inline MaybeObject* MCAllocateFromNewSpace(HeapObject* object,
+inline MaybeObject* MCAllocateFromNewSpace(Heap* heap,
+ HeapObject* object,
int object_size) {
MaybeObject* forwarded;
- if (object_size > Heap::MaxObjectSizeInPagedSpace()) {
+ if (object_size > heap->MaxObjectSizeInPagedSpace()) {
forwarded = Failure::Exception();
} else {
- OldSpace* target_space = Heap::TargetSpace(object);
- ASSERT(target_space == Heap::old_pointer_space() ||
- target_space == Heap::old_data_space());
+ OldSpace* target_space = heap->TargetSpace(object);
+ ASSERT(target_space == heap->old_pointer_space() ||
+ target_space == heap->old_data_space());
forwarded = target_space->MCAllocateRaw(object_size);
}
Object* result;
if (!forwarded->ToObject(&result)) {
- result = Heap::new_space()->MCAllocateRaw(object_size)->ToObjectUnchecked();
+ result = heap->new_space()->MCAllocateRaw(object_size)->ToObjectUnchecked();
}
return result;
}
@@ -1566,48 +1615,53 @@
// Allocation functions for the paged spaces call the space's MCAllocateRaw.
MUST_USE_RESULT inline MaybeObject* MCAllocateFromOldPointerSpace(
+ Heap *heap,
HeapObject* ignore,
int object_size) {
- return Heap::old_pointer_space()->MCAllocateRaw(object_size);
+ return heap->old_pointer_space()->MCAllocateRaw(object_size);
}
MUST_USE_RESULT inline MaybeObject* MCAllocateFromOldDataSpace(
+ Heap* heap,
HeapObject* ignore,
int object_size) {
- return Heap::old_data_space()->MCAllocateRaw(object_size);
+ return heap->old_data_space()->MCAllocateRaw(object_size);
}
MUST_USE_RESULT inline MaybeObject* MCAllocateFromCodeSpace(
+ Heap* heap,
HeapObject* ignore,
int object_size) {
- return Heap::code_space()->MCAllocateRaw(object_size);
+ return heap->code_space()->MCAllocateRaw(object_size);
}
MUST_USE_RESULT inline MaybeObject* MCAllocateFromMapSpace(
+ Heap* heap,
HeapObject* ignore,
int object_size) {
- return Heap::map_space()->MCAllocateRaw(object_size);
+ return heap->map_space()->MCAllocateRaw(object_size);
}
-MUST_USE_RESULT inline MaybeObject* MCAllocateFromCellSpace(HeapObject* ignore,
- int object_size) {
- return Heap::cell_space()->MCAllocateRaw(object_size);
+MUST_USE_RESULT inline MaybeObject* MCAllocateFromCellSpace(
+ Heap* heap, HeapObject* ignore, int object_size) {
+ return heap->cell_space()->MCAllocateRaw(object_size);
}
// The forwarding address is encoded at the same offset as the current
// to-space object, but in from space.
-inline void EncodeForwardingAddressInNewSpace(HeapObject* old_object,
+inline void EncodeForwardingAddressInNewSpace(Heap* heap,
+ HeapObject* old_object,
int object_size,
Object* new_object,
int* ignored) {
int offset =
- Heap::new_space()->ToSpaceOffsetForAddress(old_object->address());
- Memory::Address_at(Heap::new_space()->FromSpaceLow() + offset) =
+ heap->new_space()->ToSpaceOffsetForAddress(old_object->address());
+ Memory::Address_at(heap->new_space()->FromSpaceLow() + offset) =
HeapObject::cast(new_object)->address();
}
@@ -1615,7 +1669,8 @@
// The forwarding address is encoded in the map pointer of the object as an
// offset (in terms of live bytes) from the address of the first live object
// in the page.
-inline void EncodeForwardingAddressInPagedSpace(HeapObject* old_object,
+inline void EncodeForwardingAddressInPagedSpace(Heap* heap,
+ HeapObject* old_object,
int object_size,
Object* new_object,
int* offset) {
@@ -1648,7 +1703,8 @@
template<MarkCompactCollector::AllocationFunction Alloc,
MarkCompactCollector::EncodingFunction Encode,
MarkCompactCollector::ProcessNonLiveFunction ProcessNonLive>
-inline void EncodeForwardingAddressesInRange(Address start,
+inline void EncodeForwardingAddressesInRange(MarkCompactCollector* collector,
+ Address start,
Address end,
int* offset) {
// The start address of the current free region while sweeping the space.
@@ -1668,12 +1724,12 @@
HeapObject* object = HeapObject::FromAddress(current);
if (object->IsMarked()) {
object->ClearMark();
- MarkCompactCollector::tracer()->decrement_marked_count();
+ collector->tracer()->decrement_marked_count();
object_size = object->Size();
- // Allocation cannot fail, because we are compacting the space.
- Object* forwarded = Alloc(object, object_size)->ToObjectUnchecked();
- Encode(object, object_size, forwarded, offset);
+ Object* forwarded =
+ Alloc(collector->heap(), object, object_size)->ToObjectUnchecked();
+ Encode(collector->heap(), object, object_size, forwarded, offset);
#ifdef DEBUG
if (FLAG_gc_verbose) {
@@ -1709,8 +1765,9 @@
EncodeForwardingAddressesInRange<MCAllocateFromNewSpace,
EncodeForwardingAddressInNewSpace,
IgnoreNonLiveObject>(
- Heap::new_space()->bottom(),
- Heap::new_space()->top(),
+ this,
+ heap_->new_space()->bottom(),
+ heap_->new_space()->top(),
&ignored);
}
@@ -1729,6 +1786,7 @@
EncodeForwardingAddressesInRange<Alloc,
EncodeForwardingAddressInPagedSpace,
ProcessNonLive>(
+ this,
p->ObjectAreaStart(),
p->AllocationTop(),
&offset);
@@ -1746,14 +1804,15 @@
// to encounter pointers to dead objects during traversal of dirty regions we
// should clear them to avoid encountering them during next dirty regions
// iteration.
-static void MigrateObject(Address dst,
+static void MigrateObject(Heap* heap,
+ Address dst,
Address src,
int size,
bool to_old_space) {
if (to_old_space) {
- Heap::CopyBlockToOldSpaceAndUpdateRegionMarks(dst, src, size);
+ heap->CopyBlockToOldSpaceAndUpdateRegionMarks(dst, src, size);
} else {
- Heap::CopyBlock(dst, src, size);
+ heap->CopyBlock(dst, src, size);
}
Memory::Address_at(src) = dst;
@@ -1763,14 +1822,14 @@
class StaticPointersToNewGenUpdatingVisitor : public
StaticNewSpaceVisitor<StaticPointersToNewGenUpdatingVisitor> {
public:
- static inline void VisitPointer(Object** p) {
+ static inline void VisitPointer(Heap* heap, 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));
+ if (heap->new_space()->Contains(obj)) {
+ ASSERT(heap->InFromSpace(*p));
*p = HeapObject::FromAddress(Memory::Address_at(old_addr));
}
}
@@ -1781,13 +1840,15 @@
// It does not expect to encounter pointers to dead objects.
class PointersToNewGenUpdatingVisitor: public ObjectVisitor {
public:
+ explicit PointersToNewGenUpdatingVisitor(Heap* heap) : heap_(heap) { }
+
void VisitPointer(Object** p) {
- StaticPointersToNewGenUpdatingVisitor::VisitPointer(p);
+ StaticPointersToNewGenUpdatingVisitor::VisitPointer(heap_, p);
}
void VisitPointers(Object** start, Object** end) {
for (Object** p = start; p < end; p++) {
- StaticPointersToNewGenUpdatingVisitor::VisitPointer(p);
+ StaticPointersToNewGenUpdatingVisitor::VisitPointer(heap_, p);
}
}
@@ -1807,6 +1868,8 @@
VisitPointer(&target);
rinfo->set_call_address(Code::cast(target)->instruction_start());
}
+ private:
+ Heap* heap_;
};
@@ -1817,7 +1880,7 @@
if (!(*p)->IsHeapObject()) return;
Address old_addr = (*p)->address();
- ASSERT(Heap::InFromSpace(*p));
+ ASSERT(HEAP->InFromSpace(*p));
Address new_addr = Memory::Address_at(old_addr);
@@ -1831,39 +1894,42 @@
}
-static String* UpdateNewSpaceReferenceInExternalStringTableEntry(Object **p) {
+static String* UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap,
+ Object** p) {
Address old_addr = HeapObject::cast(*p)->address();
Address new_addr = Memory::Address_at(old_addr);
return String::cast(HeapObject::FromAddress(new_addr));
}
-static bool TryPromoteObject(HeapObject* object, int object_size) {
+static bool TryPromoteObject(Heap* heap, HeapObject* object, int object_size) {
Object* result;
- if (object_size > Heap::MaxObjectSizeInPagedSpace()) {
+ if (object_size > heap->MaxObjectSizeInPagedSpace()) {
MaybeObject* maybe_result =
- Heap::lo_space()->AllocateRawFixedArray(object_size);
+ heap->lo_space()->AllocateRawFixedArray(object_size);
if (maybe_result->ToObject(&result)) {
HeapObject* target = HeapObject::cast(result);
- MigrateObject(target->address(), object->address(), object_size, true);
- MarkCompactCollector::tracer()->
+ MigrateObject(heap, target->address(), object->address(), object_size,
+ true);
+ heap->mark_compact_collector()->tracer()->
increment_promoted_objects_size(object_size);
return true;
}
} else {
- OldSpace* target_space = Heap::TargetSpace(object);
+ OldSpace* target_space = heap->TargetSpace(object);
- ASSERT(target_space == Heap::old_pointer_space() ||
- target_space == Heap::old_data_space());
+ ASSERT(target_space == heap->old_pointer_space() ||
+ target_space == heap->old_data_space());
MaybeObject* maybe_result = target_space->AllocateRaw(object_size);
if (maybe_result->ToObject(&result)) {
HeapObject* target = HeapObject::cast(result);
- MigrateObject(target->address(),
+ MigrateObject(heap,
+ target->address(),
object->address(),
object_size,
- target_space == Heap::old_pointer_space());
- MarkCompactCollector::tracer()->
+ target_space == heap->old_pointer_space());
+ heap->mark_compact_collector()->tracer()->
increment_promoted_objects_size(object_size);
return true;
}
@@ -1873,8 +1939,8 @@
}
-static void SweepNewSpace(NewSpace* space) {
- Heap::CheckNewSpaceExpansionCriteria();
+static void SweepNewSpace(Heap* heap, NewSpace* space) {
+ heap->CheckNewSpaceExpansionCriteria();
Address from_bottom = space->bottom();
Address from_top = space->top();
@@ -1894,13 +1960,13 @@
if (object->IsMarked()) {
object->ClearMark();
- MarkCompactCollector::tracer()->decrement_marked_count();
+ heap->mark_compact_collector()->tracer()->decrement_marked_count();
size = object->Size();
survivors_size += size;
// Aggressively promote young survivors to the old space.
- if (TryPromoteObject(object, size)) {
+ if (TryPromoteObject(heap, object, size)) {
continue;
}
@@ -1908,7 +1974,8 @@
// Allocation cannot fail at this point: semispaces are of equal size.
Object* target = space->AllocateRaw(size)->ToObjectUnchecked();
- MigrateObject(HeapObject::cast(target)->address(),
+ MigrateObject(heap,
+ HeapObject::cast(target)->address(),
current,
size,
false);
@@ -1922,7 +1989,7 @@
}
// Second pass: find pointers to new space and update them.
- PointersToNewGenUpdatingVisitor updating_visitor;
+ PointersToNewGenUpdatingVisitor updating_visitor(heap);
// Update pointers in to space.
Address current = space->bottom();
@@ -1934,19 +2001,19 @@
}
// Update roots.
- Heap::IterateRoots(&updating_visitor, VISIT_ALL_IN_SCAVENGE);
+ heap->IterateRoots(&updating_visitor, VISIT_ALL_IN_SCAVENGE);
LiveObjectList::IterateElements(&updating_visitor);
// Update pointers in old spaces.
- Heap::IterateDirtyRegions(Heap::old_pointer_space(),
+ heap->IterateDirtyRegions(heap->old_pointer_space(),
&Heap::IteratePointersInDirtyRegion,
&UpdatePointerToNewGen,
- Heap::WATERMARK_SHOULD_BE_VALID);
+ heap->WATERMARK_SHOULD_BE_VALID);
- Heap::lo_space()->IterateDirtyRegions(&UpdatePointerToNewGen);
+ heap->lo_space()->IterateDirtyRegions(&UpdatePointerToNewGen);
// Update pointers from cells.
- HeapObjectIterator cell_iterator(Heap::cell_space());
+ HeapObjectIterator cell_iterator(heap->cell_space());
for (HeapObject* cell = cell_iterator.next();
cell != NULL;
cell = cell_iterator.next()) {
@@ -1959,22 +2026,22 @@
}
// Update pointer from the global contexts list.
- updating_visitor.VisitPointer(Heap::global_contexts_list_address());
+ updating_visitor.VisitPointer(heap->global_contexts_list_address());
// Update pointers from external string table.
- Heap::UpdateNewSpaceReferencesInExternalStringTable(
+ heap->UpdateNewSpaceReferencesInExternalStringTable(
&UpdateNewSpaceReferenceInExternalStringTableEntry);
// All pointers were updated. Update auxiliary allocation info.
- Heap::IncrementYoungSurvivorsCounter(survivors_size);
+ heap->IncrementYoungSurvivorsCounter(survivors_size);
space->set_age_mark(space->top());
// Update JSFunction pointers from the runtime profiler.
- RuntimeProfiler::UpdateSamplesAfterScavenge();
+ heap->isolate()->runtime_profiler()->UpdateSamplesAfterScavenge();
}
-static void SweepSpace(PagedSpace* space) {
+static void SweepSpace(Heap* heap, PagedSpace* space) {
PageIterator it(space, PageIterator::PAGES_IN_USE);
// During sweeping of paged space we are trying to find longest sequences
@@ -2012,7 +2079,7 @@
object = HeapObject::FromAddress(current);
if (object->IsMarked()) {
object->ClearMark();
- MarkCompactCollector::tracer()->decrement_marked_count();
+ heap->mark_compact_collector()->tracer()->decrement_marked_count();
if (!is_previous_alive) { // Transition from free to live.
space->DeallocateBlock(free_start,
@@ -2021,7 +2088,7 @@
is_previous_alive = true;
}
} else {
- MarkCompactCollector::ReportDeleteIfNeeded(object);
+ heap->mark_compact_collector()->ReportDeleteIfNeeded(object);
if (is_previous_alive) { // Transition from live to free.
free_start = current;
is_previous_alive = false;
@@ -2121,24 +2188,24 @@
// Objects in the active semispace of the young generation may be
// relocated to the inactive semispace (if not promoted). Set the
// relocation info to the beginning of the inactive semispace.
- Heap::new_space()->MCResetRelocationInfo();
+ heap_->new_space()->MCResetRelocationInfo();
// Compute the forwarding pointers in each space.
EncodeForwardingAddressesInPagedSpace<MCAllocateFromOldPointerSpace,
ReportDeleteIfNeeded>(
- Heap::old_pointer_space());
+ heap_->old_pointer_space());
EncodeForwardingAddressesInPagedSpace<MCAllocateFromOldDataSpace,
IgnoreNonLiveObject>(
- Heap::old_data_space());
+ heap_->old_data_space());
EncodeForwardingAddressesInPagedSpace<MCAllocateFromCodeSpace,
ReportDeleteIfNeeded>(
- Heap::code_space());
+ heap_->code_space());
EncodeForwardingAddressesInPagedSpace<MCAllocateFromCellSpace,
IgnoreNonLiveObject>(
- Heap::cell_space());
+ heap_->cell_space());
// Compute new space next to last after the old and code spaces have been
@@ -2150,25 +2217,25 @@
// non-live map pointers to get the sizes of non-live objects.
EncodeForwardingAddressesInPagedSpace<MCAllocateFromMapSpace,
IgnoreNonLiveObject>(
- Heap::map_space());
+ heap_->map_space());
// Write relocation info to the top page, so we can use it later. This is
// done after promoting objects from the new space so we get the correct
// allocation top.
- Heap::old_pointer_space()->MCWriteRelocationInfoToPage();
- Heap::old_data_space()->MCWriteRelocationInfoToPage();
- Heap::code_space()->MCWriteRelocationInfoToPage();
- Heap::map_space()->MCWriteRelocationInfoToPage();
- Heap::cell_space()->MCWriteRelocationInfoToPage();
+ heap_->old_pointer_space()->MCWriteRelocationInfoToPage();
+ heap_->old_data_space()->MCWriteRelocationInfoToPage();
+ heap_->code_space()->MCWriteRelocationInfoToPage();
+ heap_->map_space()->MCWriteRelocationInfoToPage();
+ heap_->cell_space()->MCWriteRelocationInfoToPage();
}
class MapIterator : public HeapObjectIterator {
public:
- MapIterator() : HeapObjectIterator(Heap::map_space(), &SizeCallback) { }
+ MapIterator() : HeapObjectIterator(HEAP->map_space(), &SizeCallback) { }
explicit MapIterator(Address start)
- : HeapObjectIterator(Heap::map_space(), start, &SizeCallback) { }
+ : HeapObjectIterator(HEAP->map_space(), start, &SizeCallback) { }
private:
static int SizeCallback(HeapObject* unused) {
@@ -2180,9 +2247,10 @@
class MapCompact {
public:
- explicit MapCompact(int live_maps)
- : live_maps_(live_maps),
- to_evacuate_start_(Heap::map_space()->TopAfterCompaction(live_maps)),
+ explicit MapCompact(Heap* heap, int live_maps)
+ : heap_(heap),
+ live_maps_(live_maps),
+ to_evacuate_start_(heap->map_space()->TopAfterCompaction(live_maps)),
map_to_evacuate_it_(to_evacuate_start_),
first_map_to_evacuate_(
reinterpret_cast<Map*>(HeapObject::FromAddress(to_evacuate_start_))) {
@@ -2203,37 +2271,39 @@
}
void UpdateMapPointersInRoots() {
- Heap::IterateRoots(&map_updating_visitor_, VISIT_ONLY_STRONG);
- GlobalHandles::IterateWeakRoots(&map_updating_visitor_);
- LiveObjectList::IterateElements(&map_updating_visitor_);
+ MapUpdatingVisitor map_updating_visitor;
+ heap_->IterateRoots(&map_updating_visitor, VISIT_ONLY_STRONG);
+ heap_->isolate()->global_handles()->IterateWeakRoots(&map_updating_visitor);
+ LiveObjectList::IterateElements(&map_updating_visitor);
}
void UpdateMapPointersInPagedSpace(PagedSpace* space) {
- ASSERT(space != Heap::map_space());
+ ASSERT(space != heap_->map_space());
PageIterator it(space, PageIterator::PAGES_IN_USE);
while (it.has_next()) {
Page* p = it.next();
- UpdateMapPointersInRange(p->ObjectAreaStart(), p->AllocationTop());
+ UpdateMapPointersInRange(heap_, p->ObjectAreaStart(), p->AllocationTop());
}
}
void UpdateMapPointersInNewSpace() {
- NewSpace* space = Heap::new_space();
- UpdateMapPointersInRange(space->bottom(), space->top());
+ NewSpace* space = heap_->new_space();
+ UpdateMapPointersInRange(heap_, space->bottom(), space->top());
}
void UpdateMapPointersInLargeObjectSpace() {
- LargeObjectIterator it(Heap::lo_space());
+ LargeObjectIterator it(heap_->lo_space());
for (HeapObject* obj = it.next(); obj != NULL; obj = it.next())
- UpdateMapPointersInObject(obj);
+ UpdateMapPointersInObject(heap_, obj);
}
void Finish() {
- Heap::map_space()->FinishCompaction(to_evacuate_start_, live_maps_);
+ heap_->map_space()->FinishCompaction(to_evacuate_start_, live_maps_);
}
private:
+ Heap* heap_;
int live_maps_;
Address to_evacuate_start_;
MapIterator vacant_map_it_;
@@ -2243,6 +2313,8 @@
// Helper class for updating map pointers in HeapObjects.
class MapUpdatingVisitor: public ObjectVisitor {
public:
+ MapUpdatingVisitor() {}
+
void VisitPointer(Object** p) {
UpdateMapPointer(p);
}
@@ -2265,8 +2337,6 @@
}
};
- static MapUpdatingVisitor map_updating_visitor_;
-
static Map* NextMap(MapIterator* it, HeapObject* last, bool live) {
while (true) {
HeapObject* next = it->next();
@@ -2300,9 +2370,8 @@
ASSERT(Map::kSize % 4 == 0);
- Heap::CopyBlockToOldSpaceAndUpdateRegionMarks(vacant_map->address(),
- map_to_evacuate->address(),
- Map::kSize);
+ map_to_evacuate->heap()->CopyBlockToOldSpaceAndUpdateRegionMarks(
+ vacant_map->address(), map_to_evacuate->address(), Map::kSize);
ASSERT(vacant_map->IsMap()); // Due to memcpy above.
@@ -2322,15 +2391,15 @@
return new_map;
}
- static int UpdateMapPointersInObject(HeapObject* obj) {
+ static int UpdateMapPointersInObject(Heap* heap, HeapObject* obj) {
ASSERT(!obj->IsMarked());
Map* map = obj->map();
- ASSERT(Heap::map_space()->Contains(map));
+ ASSERT(heap->map_space()->Contains(map));
MapWord map_word = map->map_word();
ASSERT(!map_word.IsMarked());
if (map_word.IsOverflowed()) {
Map* new_map = GetForwardedMap(map_word);
- ASSERT(Heap::map_space()->Contains(new_map));
+ ASSERT(heap->map_space()->Contains(new_map));
obj->set_map(new_map);
#ifdef DEBUG
@@ -2344,16 +2413,17 @@
}
int size = obj->SizeFromMap(map);
- obj->IterateBody(map->instance_type(), size, &map_updating_visitor_);
+ MapUpdatingVisitor map_updating_visitor;
+ obj->IterateBody(map->instance_type(), size, &map_updating_visitor);
return size;
}
- static void UpdateMapPointersInRange(Address start, Address end) {
+ static void UpdateMapPointersInRange(Heap* heap, Address start, Address end) {
HeapObject* object;
int size;
for (Address current = start; current < end; current += size) {
object = HeapObject::FromAddress(current);
- size = UpdateMapPointersInObject(object);
+ size = UpdateMapPointersInObject(heap, object);
ASSERT(size > 0);
}
}
@@ -2370,9 +2440,7 @@
#endif
};
-MapCompact::MapUpdatingVisitor MapCompact::map_updating_visitor_;
-
void MarkCompactCollector::SweepSpaces() {
GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP);
@@ -2383,26 +2451,26 @@
// the map space last because freeing non-live maps overwrites them and
// the other spaces rely on possibly non-live maps to get the sizes for
// non-live objects.
- SweepSpace(Heap::old_pointer_space());
- SweepSpace(Heap::old_data_space());
- SweepSpace(Heap::code_space());
- SweepSpace(Heap::cell_space());
+ SweepSpace(heap_, heap_->old_pointer_space());
+ SweepSpace(heap_, heap_->old_data_space());
+ SweepSpace(heap_, heap_->code_space());
+ SweepSpace(heap_, heap_->cell_space());
{ GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP_NEWSPACE);
- SweepNewSpace(Heap::new_space());
+ SweepNewSpace(heap_, heap_->new_space());
}
- SweepSpace(Heap::map_space());
+ SweepSpace(heap_, heap_->map_space());
- Heap::IterateDirtyRegions(Heap::map_space(),
- &Heap::IteratePointersInDirtyMapsRegion,
- &UpdatePointerToNewGen,
- Heap::WATERMARK_SHOULD_BE_VALID);
+ heap_->IterateDirtyRegions(heap_->map_space(),
+ &heap_->IteratePointersInDirtyMapsRegion,
+ &UpdatePointerToNewGen,
+ heap_->WATERMARK_SHOULD_BE_VALID);
- intptr_t live_maps_size = Heap::map_space()->Size();
+ intptr_t live_maps_size = heap_->map_space()->Size();
int live_maps = static_cast<int>(live_maps_size / Map::kSize);
ASSERT(live_map_objects_size_ == live_maps_size);
- if (Heap::map_space()->NeedsCompaction(live_maps)) {
- MapCompact map_compact(live_maps);
+ if (heap_->map_space()->NeedsCompaction(live_maps)) {
+ MapCompact map_compact(heap_, live_maps);
map_compact.CompactMaps();
map_compact.UpdateMapPointersInRoots();
@@ -2410,7 +2478,7 @@
PagedSpaces spaces;
for (PagedSpace* space = spaces.next();
space != NULL; space = spaces.next()) {
- if (space == Heap::map_space()) continue;
+ if (space == heap_->map_space()) continue;
map_compact.UpdateMapPointersInPagedSpace(space);
}
map_compact.UpdateMapPointersInNewSpace();
@@ -2429,7 +2497,7 @@
int MarkCompactCollector::IterateLiveObjectsInRange(
Address start,
Address end,
- HeapObjectCallback size_func) {
+ LiveObjectCallback size_func) {
int live_objects_size = 0;
Address current = start;
while (current < end) {
@@ -2439,7 +2507,7 @@
} else if (encoded_map == kMultiFreeEncoding) {
current += Memory::int_at(current + kIntSize);
} else {
- int size = size_func(HeapObject::FromAddress(current));
+ int size = (this->*size_func)(HeapObject::FromAddress(current));
current += size;
live_objects_size += size;
}
@@ -2448,15 +2516,15 @@
}
-int MarkCompactCollector::IterateLiveObjects(NewSpace* space,
- HeapObjectCallback size_f) {
+int MarkCompactCollector::IterateLiveObjects(
+ NewSpace* space, LiveObjectCallback size_f) {
ASSERT(MARK_LIVE_OBJECTS < state_ && state_ <= RELOCATE_OBJECTS);
return IterateLiveObjectsInRange(space->bottom(), space->top(), size_f);
}
-int MarkCompactCollector::IterateLiveObjects(PagedSpace* space,
- HeapObjectCallback size_f) {
+int MarkCompactCollector::IterateLiveObjects(
+ PagedSpace* space, LiveObjectCallback size_f) {
ASSERT(MARK_LIVE_OBJECTS < state_ && state_ <= RELOCATE_OBJECTS);
int total = 0;
PageIterator it(space, PageIterator::PAGES_IN_USE);
@@ -2476,6 +2544,8 @@
// Helper class for updating pointers in HeapObjects.
class UpdatingVisitor: public ObjectVisitor {
public:
+ explicit UpdatingVisitor(Heap* heap) : heap_(heap) {}
+
void VisitPointer(Object** p) {
UpdatePointer(p);
}
@@ -2511,27 +2581,27 @@
HeapObject* obj = HeapObject::cast(*p);
Address old_addr = obj->address();
Address new_addr;
- ASSERT(!Heap::InFromSpace(obj));
+ ASSERT(!heap_->InFromSpace(obj));
- if (Heap::new_space()->Contains(obj)) {
+ if (heap_->new_space()->Contains(obj)) {
Address forwarding_pointer_addr =
- Heap::new_space()->FromSpaceLow() +
- Heap::new_space()->ToSpaceOffsetForAddress(old_addr);
+ heap_->new_space()->FromSpaceLow() +
+ heap_->new_space()->ToSpaceOffsetForAddress(old_addr);
new_addr = Memory::Address_at(forwarding_pointer_addr);
#ifdef DEBUG
- ASSERT(Heap::old_pointer_space()->Contains(new_addr) ||
- Heap::old_data_space()->Contains(new_addr) ||
- Heap::new_space()->FromSpaceContains(new_addr) ||
- Heap::lo_space()->Contains(HeapObject::FromAddress(new_addr)));
+ ASSERT(heap_->old_pointer_space()->Contains(new_addr) ||
+ heap_->old_data_space()->Contains(new_addr) ||
+ heap_->new_space()->FromSpaceContains(new_addr) ||
+ heap_->lo_space()->Contains(HeapObject::FromAddress(new_addr)));
- if (Heap::new_space()->FromSpaceContains(new_addr)) {
- ASSERT(Heap::new_space()->FromSpaceOffsetForAddress(new_addr) <=
- Heap::new_space()->ToSpaceOffsetForAddress(old_addr));
+ if (heap_->new_space()->FromSpaceContains(new_addr)) {
+ ASSERT(heap_->new_space()->FromSpaceOffsetForAddress(new_addr) <=
+ heap_->new_space()->ToSpaceOffsetForAddress(old_addr));
}
#endif
- } else if (Heap::lo_space()->Contains(obj)) {
+ } else if (heap_->lo_space()->Contains(obj)) {
// Don't move objects in the large object space.
return;
@@ -2560,6 +2630,8 @@
}
#endif
}
+
+ Heap* heap_;
};
@@ -2568,31 +2640,34 @@
ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES);
state_ = UPDATE_POINTERS;
#endif
- UpdatingVisitor updating_visitor;
- RuntimeProfiler::UpdateSamplesAfterCompact(&updating_visitor);
- Heap::IterateRoots(&updating_visitor, VISIT_ONLY_STRONG);
- GlobalHandles::IterateWeakRoots(&updating_visitor);
+ UpdatingVisitor updating_visitor(heap_);
+ heap_->isolate()->runtime_profiler()->UpdateSamplesAfterCompact(
+ &updating_visitor);
+ heap_->IterateRoots(&updating_visitor, VISIT_ONLY_STRONG);
+ heap_->isolate()->global_handles()->IterateWeakRoots(&updating_visitor);
// Update the pointer to the head of the weak list of global contexts.
- updating_visitor.VisitPointer(&Heap::global_contexts_list_);
+ updating_visitor.VisitPointer(&heap_->global_contexts_list_);
LiveObjectList::IterateElements(&updating_visitor);
- int live_maps_size = IterateLiveObjects(Heap::map_space(),
- &UpdatePointersInOldObject);
- int live_pointer_olds_size = IterateLiveObjects(Heap::old_pointer_space(),
- &UpdatePointersInOldObject);
- int live_data_olds_size = IterateLiveObjects(Heap::old_data_space(),
- &UpdatePointersInOldObject);
- int live_codes_size = IterateLiveObjects(Heap::code_space(),
- &UpdatePointersInOldObject);
- int live_cells_size = IterateLiveObjects(Heap::cell_space(),
- &UpdatePointersInOldObject);
- int live_news_size = IterateLiveObjects(Heap::new_space(),
- &UpdatePointersInNewObject);
+ int live_maps_size = IterateLiveObjects(
+ heap_->map_space(), &MarkCompactCollector::UpdatePointersInOldObject);
+ int live_pointer_olds_size = IterateLiveObjects(
+ heap_->old_pointer_space(),
+ &MarkCompactCollector::UpdatePointersInOldObject);
+ int live_data_olds_size = IterateLiveObjects(
+ heap_->old_data_space(),
+ &MarkCompactCollector::UpdatePointersInOldObject);
+ int live_codes_size = IterateLiveObjects(
+ heap_->code_space(), &MarkCompactCollector::UpdatePointersInOldObject);
+ int live_cells_size = IterateLiveObjects(
+ heap_->cell_space(), &MarkCompactCollector::UpdatePointersInOldObject);
+ int live_news_size = IterateLiveObjects(
+ heap_->new_space(), &MarkCompactCollector::UpdatePointersInNewObject);
// Large objects do not move, the map word can be updated directly.
- LargeObjectIterator it(Heap::lo_space());
+ LargeObjectIterator it(heap_->lo_space());
for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) {
UpdatePointersInNewObject(obj);
}
@@ -2619,8 +2694,8 @@
Address forwarded = GetForwardingAddressInOldSpace(old_map);
- ASSERT(Heap::map_space()->Contains(old_map));
- ASSERT(Heap::map_space()->Contains(forwarded));
+ ASSERT(heap_->map_space()->Contains(old_map));
+ ASSERT(heap_->map_space()->Contains(forwarded));
#ifdef DEBUG
if (FLAG_gc_verbose) {
PrintF("update %p : %p -> %p\n", obj->address(), old_map->address(),
@@ -2635,7 +2710,7 @@
int obj_size = obj->SizeFromMap(old_map);
// Update pointers in the object body.
- UpdatingVisitor updating_visitor;
+ UpdatingVisitor updating_visitor(heap_);
obj->IterateBody(old_map->instance_type(), obj_size, &updating_visitor);
return obj_size;
}
@@ -2644,8 +2719,8 @@
int MarkCompactCollector::UpdatePointersInOldObject(HeapObject* obj) {
// Decode the map pointer.
MapWord encoding = obj->map_word();
- Address map_addr = encoding.DecodeMapAddress(Heap::map_space());
- ASSERT(Heap::map_space()->Contains(HeapObject::FromAddress(map_addr)));
+ Address map_addr = encoding.DecodeMapAddress(heap_->map_space());
+ ASSERT(heap_->map_space()->Contains(HeapObject::FromAddress(map_addr)));
// At this point, the first word of map_addr is also encoded, cannot
// cast it to Map* using Map::cast.
@@ -2666,7 +2741,7 @@
#endif
// Update pointers in the object body.
- UpdatingVisitor updating_visitor;
+ UpdatingVisitor updating_visitor(heap_);
obj->IterateBody(type, obj_size, &updating_visitor);
return obj_size;
}
@@ -2722,18 +2797,19 @@
#endif
// Relocates objects, always relocate map objects first. Relocating
// objects in other space relies on map objects to get object size.
- int live_maps_size = IterateLiveObjects(Heap::map_space(),
- &RelocateMapObject);
- int live_pointer_olds_size = IterateLiveObjects(Heap::old_pointer_space(),
- &RelocateOldPointerObject);
- int live_data_olds_size = IterateLiveObjects(Heap::old_data_space(),
- &RelocateOldDataObject);
- int live_codes_size = IterateLiveObjects(Heap::code_space(),
- &RelocateCodeObject);
- int live_cells_size = IterateLiveObjects(Heap::cell_space(),
- &RelocateCellObject);
- int live_news_size = IterateLiveObjects(Heap::new_space(),
- &RelocateNewObject);
+ int live_maps_size = IterateLiveObjects(
+ heap_->map_space(), &MarkCompactCollector::RelocateMapObject);
+ int live_pointer_olds_size = IterateLiveObjects(
+ heap_->old_pointer_space(),
+ &MarkCompactCollector::RelocateOldPointerObject);
+ int live_data_olds_size = IterateLiveObjects(
+ heap_->old_data_space(), &MarkCompactCollector::RelocateOldDataObject);
+ int live_codes_size = IterateLiveObjects(
+ heap_->code_space(), &MarkCompactCollector::RelocateCodeObject);
+ int live_cells_size = IterateLiveObjects(
+ heap_->cell_space(), &MarkCompactCollector::RelocateCellObject);
+ int live_news_size = IterateLiveObjects(
+ heap_->new_space(), &MarkCompactCollector::RelocateNewObject);
USE(live_maps_size);
USE(live_pointer_olds_size);
@@ -2749,28 +2825,28 @@
ASSERT(live_news_size == live_young_objects_size_);
// Flip from and to spaces
- Heap::new_space()->Flip();
+ heap_->new_space()->Flip();
- Heap::new_space()->MCCommitRelocationInfo();
+ heap_->new_space()->MCCommitRelocationInfo();
// Set age_mark to bottom in to space
- Address mark = Heap::new_space()->bottom();
- Heap::new_space()->set_age_mark(mark);
+ Address mark = heap_->new_space()->bottom();
+ heap_->new_space()->set_age_mark(mark);
PagedSpaces spaces;
for (PagedSpace* space = spaces.next(); space != NULL; space = spaces.next())
space->MCCommitRelocationInfo();
- Heap::CheckNewSpaceExpansionCriteria();
- Heap::IncrementYoungSurvivorsCounter(live_news_size);
+ heap_->CheckNewSpaceExpansionCriteria();
+ heap_->IncrementYoungSurvivorsCounter(live_news_size);
}
int MarkCompactCollector::RelocateMapObject(HeapObject* obj) {
// Recover map pointer.
MapWord encoding = obj->map_word();
- Address map_addr = encoding.DecodeMapAddress(Heap::map_space());
- ASSERT(Heap::map_space()->Contains(HeapObject::FromAddress(map_addr)));
+ Address map_addr = encoding.DecodeMapAddress(heap_->map_space());
+ ASSERT(heap_->map_space()->Contains(HeapObject::FromAddress(map_addr)));
// Get forwarding address before resetting map pointer
Address new_addr = GetForwardingAddressInOldSpace(obj);
@@ -2783,9 +2859,9 @@
if (new_addr != old_addr) {
// Move contents.
- Heap::MoveBlockToOldSpaceAndUpdateRegionMarks(new_addr,
- old_addr,
- Map::kSize);
+ heap_->MoveBlockToOldSpaceAndUpdateRegionMarks(new_addr,
+ old_addr,
+ Map::kSize);
}
#ifdef DEBUG
@@ -2829,8 +2905,8 @@
PagedSpace* space) {
// Recover map pointer.
MapWord encoding = obj->map_word();
- Address map_addr = encoding.DecodeMapAddress(Heap::map_space());
- ASSERT(Heap::map_space()->Contains(map_addr));
+ Address map_addr = encoding.DecodeMapAddress(heap_->map_space());
+ ASSERT(heap_->map_space()->Contains(map_addr));
// Get forwarding address before resetting map pointer.
Address new_addr = GetForwardingAddressInOldSpace(obj);
@@ -2842,12 +2918,12 @@
if (new_addr != old_addr) {
// Move contents.
- if (space == Heap::old_data_space()) {
- Heap::MoveBlock(new_addr, old_addr, obj_size);
+ if (space == heap_->old_data_space()) {
+ heap_->MoveBlock(new_addr, old_addr, obj_size);
} else {
- Heap::MoveBlockToOldSpaceAndUpdateRegionMarks(new_addr,
- old_addr,
- obj_size);
+ heap_->MoveBlockToOldSpaceAndUpdateRegionMarks(new_addr,
+ old_addr,
+ obj_size);
}
}
@@ -2855,46 +2931,47 @@
HeapObject* copied_to = HeapObject::FromAddress(new_addr);
if (copied_to->IsSharedFunctionInfo()) {
- PROFILE(SharedFunctionInfoMoveEvent(old_addr, new_addr));
+ PROFILE(heap_->isolate(),
+ SharedFunctionInfoMoveEvent(old_addr, new_addr));
}
- HEAP_PROFILE(ObjectMoveEvent(old_addr, new_addr));
+ HEAP_PROFILE(heap_, ObjectMoveEvent(old_addr, new_addr));
return obj_size;
}
int MarkCompactCollector::RelocateOldPointerObject(HeapObject* obj) {
- return RelocateOldNonCodeObject(obj, Heap::old_pointer_space());
+ return RelocateOldNonCodeObject(obj, heap_->old_pointer_space());
}
int MarkCompactCollector::RelocateOldDataObject(HeapObject* obj) {
- return RelocateOldNonCodeObject(obj, Heap::old_data_space());
+ return RelocateOldNonCodeObject(obj, heap_->old_data_space());
}
int MarkCompactCollector::RelocateCellObject(HeapObject* obj) {
- return RelocateOldNonCodeObject(obj, Heap::cell_space());
+ return RelocateOldNonCodeObject(obj, heap_->cell_space());
}
int MarkCompactCollector::RelocateCodeObject(HeapObject* obj) {
// Recover map pointer.
MapWord encoding = obj->map_word();
- Address map_addr = encoding.DecodeMapAddress(Heap::map_space());
- ASSERT(Heap::map_space()->Contains(HeapObject::FromAddress(map_addr)));
+ Address map_addr = encoding.DecodeMapAddress(heap_->map_space());
+ ASSERT(heap_->map_space()->Contains(HeapObject::FromAddress(map_addr)));
// Get forwarding address before resetting map pointer
Address new_addr = GetForwardingAddressInOldSpace(obj);
// Reset the map pointer.
- int obj_size = RestoreMap(obj, Heap::code_space(), new_addr, map_addr);
+ int obj_size = RestoreMap(obj, heap_->code_space(), new_addr, map_addr);
Address old_addr = obj->address();
if (new_addr != old_addr) {
// Move contents.
- Heap::MoveBlock(new_addr, old_addr, obj_size);
+ heap_->MoveBlock(new_addr, old_addr, obj_size);
}
HeapObject* copied_to = HeapObject::FromAddress(new_addr);
@@ -2902,9 +2979,9 @@
// May also update inline cache target.
Code::cast(copied_to)->Relocate(new_addr - old_addr);
// Notify the logger that compiled code has moved.
- PROFILE(CodeMoveEvent(old_addr, new_addr));
+ PROFILE(heap_->isolate(), CodeMoveEvent(old_addr, new_addr));
}
- HEAP_PROFILE(ObjectMoveEvent(old_addr, new_addr));
+ HEAP_PROFILE(heap_, ObjectMoveEvent(old_addr, new_addr));
return obj_size;
}
@@ -2915,28 +2992,28 @@
// Get forwarding address
Address old_addr = obj->address();
- int offset = Heap::new_space()->ToSpaceOffsetForAddress(old_addr);
+ int offset = heap_->new_space()->ToSpaceOffsetForAddress(old_addr);
Address new_addr =
- Memory::Address_at(Heap::new_space()->FromSpaceLow() + offset);
+ Memory::Address_at(heap_->new_space()->FromSpaceLow() + offset);
#ifdef DEBUG
- if (Heap::new_space()->FromSpaceContains(new_addr)) {
- ASSERT(Heap::new_space()->FromSpaceOffsetForAddress(new_addr) <=
- Heap::new_space()->ToSpaceOffsetForAddress(old_addr));
+ if (heap_->new_space()->FromSpaceContains(new_addr)) {
+ ASSERT(heap_->new_space()->FromSpaceOffsetForAddress(new_addr) <=
+ heap_->new_space()->ToSpaceOffsetForAddress(old_addr));
} else {
- ASSERT(Heap::TargetSpace(obj) == Heap::old_pointer_space() ||
- Heap::TargetSpace(obj) == Heap::old_data_space());
+ ASSERT(heap_->TargetSpace(obj) == heap_->old_pointer_space() ||
+ heap_->TargetSpace(obj) == heap_->old_data_space());
}
#endif
// New and old addresses cannot overlap.
- if (Heap::InNewSpace(HeapObject::FromAddress(new_addr))) {
- Heap::CopyBlock(new_addr, old_addr, obj_size);
+ if (heap_->InNewSpace(HeapObject::FromAddress(new_addr))) {
+ heap_->CopyBlock(new_addr, old_addr, obj_size);
} else {
- Heap::CopyBlockToOldSpaceAndUpdateRegionMarks(new_addr,
- old_addr,
- obj_size);
+ heap_->CopyBlockToOldSpaceAndUpdateRegionMarks(new_addr,
+ old_addr,
+ obj_size);
}
#ifdef DEBUG
@@ -2947,14 +3024,27 @@
HeapObject* copied_to = HeapObject::FromAddress(new_addr);
if (copied_to->IsSharedFunctionInfo()) {
- PROFILE(SharedFunctionInfoMoveEvent(old_addr, new_addr));
+ PROFILE(heap_->isolate(),
+ SharedFunctionInfoMoveEvent(old_addr, new_addr));
}
- HEAP_PROFILE(ObjectMoveEvent(old_addr, new_addr));
+ HEAP_PROFILE(heap_, ObjectMoveEvent(old_addr, new_addr));
return obj_size;
}
+void MarkCompactCollector::EnableCodeFlushing(bool enable) {
+ if (enable) {
+ if (code_flusher_ != NULL) return;
+ code_flusher_ = new CodeFlusher(heap_->isolate());
+ } else {
+ if (code_flusher_ == NULL) return;
+ delete code_flusher_;
+ code_flusher_ = NULL;
+ }
+}
+
+
void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj) {
#ifdef ENABLE_GDB_JIT_INTERFACE
if (obj->IsCode()) {
@@ -2963,7 +3053,7 @@
#endif
#ifdef ENABLE_LOGGING_AND_PROFILING
if (obj->IsCode()) {
- PROFILE(CodeDeleteEvent(obj->address()));
+ PROFILE(ISOLATE, CodeDeleteEvent(obj->address()));
}
#endif
}
« no previous file with comments | « src/mark-compact.h ('k') | src/messages.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698