Index: src/mark-compact.h |
diff --git a/src/mark-compact.h b/src/mark-compact.h |
index f65aeaea67d80acc0d71f277c45bb48542e5886d..17e2e19057254b7e192a54d052b5a3588f3ec1a1 100644 |
--- a/src/mark-compact.h |
+++ b/src/mark-compact.h |
@@ -41,6 +41,122 @@ class RootMarkingVisitor; |
class MarkingVisitor; |
+class Marking { |
+ public: |
+ INLINE(static bool IsMarked(HeapObject* obj)) { |
+ return IsMarked(obj->address()); |
+ } |
+ |
+ INLINE(static void SetMark(HeapObject* obj)) { |
+ SetMark(obj->address()); |
+ } |
+ |
+ INLINE(static void ClearMark(HeapObject* obj)) { |
+ ClearMark(obj->address()); |
+ } |
+ |
+ INLINE(static bool TestAndMark(Address addr)) { |
+ if (Heap::InNewSpace(addr)) { |
+ uint32_t index = Heap::new_space()->Address2MarkbitIndex(addr); |
+ return new_space_bitmap_->TestAndSet(index); |
+ } else { |
+ Page *p = Page::FromAddress(addr); |
+ return p->markbits()->TestAndSet(p->Address2Markbit(addr)); |
+ } |
+ } |
+ |
+ INLINE(static bool IsMarked(Address addr)) { |
+ if (Heap::InNewSpace(addr)) { |
+ uint32_t index = Heap::new_space()->Address2MarkbitIndex(addr); |
+ return new_space_bitmap_->Get(index); |
+ } else { |
+ Page *p = Page::FromAddress(addr); |
+ return p->markbits()->Get(p->Address2Markbit(addr)); |
+ } |
+ } |
+ |
+ INLINE(static void SetMark(Address addr)) { |
+ if (Heap::InNewSpace(addr)) { |
+ uint32_t index = Heap::new_space()->Address2MarkbitIndex(addr); |
+ new_space_bitmap_->Set(index, true); |
+ } else { |
+ Page *p = Page::FromAddress(addr); |
+ p->markbits()->Set(p->FastAddress2Markbit(addr), true); |
+ } |
+ } |
+ |
+ INLINE(static void ClearMark(Address addr)) { |
+ if (Heap::InNewSpace(addr)) { |
+ uint32_t index = Heap::new_space()->Address2MarkbitIndex(addr); |
+ new_space_bitmap_->Set(index, false); |
+ } else { |
+ Page *p = Page::FromAddress(addr); |
+ p->markbits()->Set(p->FastAddress2Markbit(addr), false); |
+ } |
+ } |
+ |
+ INLINE(static void ClearRange(Address addr, int size)) { |
+ if (Heap::InNewSpace(addr)) { |
+ uint32_t index = Heap::new_space()->Address2MarkbitIndex(addr); |
+ new_space_bitmap_->ClearRange(index, size >> kPointerSizeLog2); |
+ } else { |
+ Page *p = Page::FromAddress(addr); |
+ p->markbits()->ClearRange(p->FastAddress2Markbit(addr), |
+ size >> kPointerSizeLog2); |
+ } |
+ } |
+ |
+ static bool Setup(); |
+ |
+ static void TearDown(); |
+ |
+ private: |
+ class BitmapStorageDescriptor { |
+ public: |
+ INLINE(static int CellsCount(Address addr)) { |
+ return HeaderOf(addr)->cells_count_; |
+ } |
+ |
+ static Bitmap<BitmapStorageDescriptor>* Allocate(int cells_count) { |
+ VirtualMemory* memory = new VirtualMemory(SizeFor(cells_count)); |
+ |
+ if (!memory->Commit(memory->address(), memory->size(), false)) { |
+ delete memory; |
+ return NULL; |
+ } |
+ |
+ Address bitmap_address = |
+ reinterpret_cast<Address>(memory->address()) + sizeof(Header); |
+ HeaderOf(bitmap_address)->cells_count_ = cells_count; |
+ HeaderOf(bitmap_address)->storage_ = memory; |
+ return Bitmap<BitmapStorageDescriptor>::FromAddress(bitmap_address); |
+ } |
+ |
+ static void Free(Bitmap<BitmapStorageDescriptor>* bitmap) { |
+ delete HeaderOf(bitmap->address())->storage_; |
+ } |
+ |
+ private: |
+ struct Header { |
+ VirtualMemory* storage_; |
+ int cells_count_; |
+ }; |
+ |
+ static int SizeFor(int cell_count) { |
+ return sizeof(Header) + |
+ Bitmap<BitmapStorageDescriptor>::SizeFor(cell_count); |
+ } |
+ |
+ static Header* HeaderOf(Address addr) { |
+ return reinterpret_cast<Header*>(addr - sizeof(Header)); |
+ } |
+ }; |
+ |
+ typedef Bitmap<BitmapStorageDescriptor> NewSpaceMarkbitsBitmap; |
+ |
+ static NewSpaceMarkbitsBitmap* new_space_bitmap_; |
+}; |
+ |
// ------------------------------------------------------------------------- |
// Mark-Compact collector |
// |
@@ -102,10 +218,6 @@ class MarkCompactCollector: public AllStatic { |
#endif |
} |
- // The count of the number of objects left marked at the end of the last |
- // completed full GC (expected to be zero). |
- static int previous_marked_count() { return previous_marked_count_; } |
- |
// During a full GC, there is a stack-allocated GCTracer that is used for |
// bookkeeping information. Return a pointer to that tracer. |
static GCTracer* tracer() { return tracer_; } |
@@ -152,10 +264,6 @@ class MarkCompactCollector: public AllStatic { |
// Global flag indicating whether spaces will be compacted on the next GC. |
static bool compact_on_next_gc_; |
- // The number of objects left marked at the end of the last completed full |
- // GC (expected to be zero). |
- static int previous_marked_count_; |
- |
// A pointer to the current stack-allocated GC tracer object during a full |
// collection (NULL before and after). |
static GCTracer* tracer_; |
@@ -184,20 +292,26 @@ class MarkCompactCollector: public AllStatic { |
// Marking operations for objects reachable from roots. |
static void MarkLiveObjects(); |
- static void MarkUnmarkedObject(HeapObject* obj); |
- |
static inline void MarkObject(HeapObject* obj) { |
- if (!obj->IsMarked()) MarkUnmarkedObject(obj); |
+ if (!Marking::TestAndMark(obj->address())) { |
+ tracer_->increment_marked_count(); |
+#ifdef DEBUG |
+ UpdateLiveObjectCount(obj); |
+#endif |
+ ProcessNewlyMarkedObject(obj); |
+ } |
} |
static inline void SetMark(HeapObject* obj) { |
+ Marking::SetMark(obj); |
tracer_->increment_marked_count(); |
#ifdef DEBUG |
UpdateLiveObjectCount(obj); |
#endif |
- obj->SetMark(); |
} |
+ static void ProcessNewlyMarkedObject(HeapObject* obj); |
+ |
// Creates back pointers for all map transitions, stores them in |
// the prototype field. The original prototype pointers are restored |
// in ClearNonLiveTransitions(). All JSObject maps |
@@ -286,6 +400,9 @@ class MarkCompactCollector: public AllStatic { |
// regions to each space's free list. |
static void SweepSpaces(); |
+ static void SweepNewSpace(NewSpace* space); |
+ static void SweepSpace(PagedSpace* space); |
+ |
#ifdef DEBUG |
// ----------------------------------------------------------------------- |
// Debugging variables, functions and classes |