aboutsummaryrefslogtreecommitdiff
path: root/src/heap/mark-compact.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/heap/mark-compact.h')
-rw-r--r--src/heap/mark-compact.h153
1 files changed, 112 insertions, 41 deletions
diff --git a/src/heap/mark-compact.h b/src/heap/mark-compact.h
index de182073..86d0b961 100644
--- a/src/heap/mark-compact.h
+++ b/src/heap/mark-compact.h
@@ -17,6 +17,8 @@
namespace v8 {
namespace internal {
+enum class MarkCompactMode { FULL, YOUNG_GENERATION };
+
// Callback function, returns whether an object is alive. The heap size
// of the object is returned in size. It optionally updates the offset
// to the first live object in the page (only used for old and map objects).
@@ -29,23 +31,91 @@ typedef void (*MarkObjectFunction)(Heap* heap, HeapObject* object);
class CodeFlusher;
class MarkCompactCollector;
class MarkingVisitor;
+template <MarkCompactMode mode>
class RootMarkingVisitor;
class ObjectMarking : public AllStatic {
public:
- INLINE(static MarkBit MarkBitFrom(Address addr)) {
- MemoryChunk* p = MemoryChunk::FromAddress(addr);
- return p->markbits()->MarkBitFromIndex(p->AddressToMarkbitIndex(addr));
- }
-
- INLINE(static MarkBit MarkBitFrom(HeapObject* obj)) {
- return MarkBitFrom(reinterpret_cast<Address>(obj));
+ V8_INLINE static MarkBit MarkBitFrom(HeapObject* obj) {
+ const Address address = obj->address();
+ MemoryChunk* p = MemoryChunk::FromAddress(address);
+ return p->markbits()->MarkBitFromIndex(p->AddressToMarkbitIndex(address));
}
static Marking::ObjectColor Color(HeapObject* obj) {
return Marking::Color(ObjectMarking::MarkBitFrom(obj));
}
+ V8_INLINE static bool IsImpossible(HeapObject* obj) {
+ return Marking::IsImpossible(MarkBitFrom(obj));
+ }
+
+ V8_INLINE static bool IsBlack(HeapObject* obj) {
+ return Marking::IsBlack(MarkBitFrom(obj));
+ }
+
+ V8_INLINE static bool IsWhite(HeapObject* obj) {
+ return Marking::IsWhite(MarkBitFrom(obj));
+ }
+
+ V8_INLINE static bool IsGrey(HeapObject* obj) {
+ return Marking::IsGrey(MarkBitFrom(obj));
+ }
+
+ V8_INLINE static bool IsBlackOrGrey(HeapObject* obj) {
+ return Marking::IsBlackOrGrey(MarkBitFrom(obj));
+ }
+
+ V8_INLINE static void ClearMarkBit(HeapObject* obj) {
+ Marking::MarkWhite(MarkBitFrom(obj));
+ }
+
+ V8_INLINE static void BlackToWhite(HeapObject* obj) {
+ DCHECK(IsBlack(obj));
+ MarkBit markbit = MarkBitFrom(obj);
+ Marking::BlackToWhite(markbit);
+ MemoryChunk::IncrementLiveBytes(obj, -obj->Size());
+ }
+
+ V8_INLINE static void GreyToWhite(HeapObject* obj) {
+ DCHECK(IsGrey(obj));
+ Marking::GreyToWhite(MarkBitFrom(obj));
+ }
+
+ V8_INLINE static void BlackToGrey(HeapObject* obj) {
+ DCHECK(IsBlack(obj));
+ MarkBit markbit = MarkBitFrom(obj);
+ Marking::BlackToGrey(markbit);
+ MemoryChunk::IncrementLiveBytes(obj, -obj->Size());
+ }
+
+ V8_INLINE static void WhiteToGrey(HeapObject* obj) {
+ DCHECK(IsWhite(obj));
+ Marking::WhiteToGrey(MarkBitFrom(obj));
+ }
+
+ V8_INLINE static void WhiteToBlack(HeapObject* obj) {
+ DCHECK(IsWhite(obj));
+ MarkBit markbit = MarkBitFrom(obj);
+ Marking::WhiteToBlack(markbit);
+ MemoryChunk::IncrementLiveBytes(obj, obj->Size());
+ }
+
+ V8_INLINE static void GreyToBlack(HeapObject* obj) {
+ DCHECK(IsGrey(obj));
+ MarkBit markbit = MarkBitFrom(obj);
+ Marking::GreyToBlack(markbit);
+ MemoryChunk::IncrementLiveBytes(obj, obj->Size());
+ }
+
+ V8_INLINE static void AnyToGrey(HeapObject* obj) {
+ MarkBit markbit = MarkBitFrom(obj);
+ if (Marking::IsBlack(markbit)) {
+ MemoryChunk::IncrementLiveBytes(obj, -obj->Size());
+ }
+ Marking::AnyToGrey(markbit);
+ }
+
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectMarking);
};
@@ -416,6 +486,9 @@ class MarkCompactCollector {
static void Initialize();
+ static SlotCallbackResult CheckAndMarkObject(Heap* heap,
+ Address slot_address);
+
void SetUp();
void TearDown();
@@ -435,12 +508,6 @@ class MarkCompactCollector {
void AbortCompaction();
-#ifdef DEBUG
- // Checks whether performing mark-compact collection.
- bool in_use() { return state_ > PREPARE_GC; }
- bool are_map_pointers_encoded() { return state_ == UPDATE_POINTERS; }
-#endif
-
// Determine type of object and emit deletion log event.
static void ReportDeleteIfNeeded(HeapObject* obj, Isolate* isolate);
@@ -449,7 +516,6 @@ class MarkCompactCollector {
static const uint32_t kSingleFreeEncoding = 0;
static const uint32_t kMultiFreeEncoding = 1;
- static inline bool IsMarked(Object* obj);
static bool IsUnmarkedHeapObjectWithHeap(Heap* heap, Object** p);
inline Heap* heap() const { return heap_; }
@@ -458,15 +524,6 @@ class MarkCompactCollector {
CodeFlusher* code_flusher() { return code_flusher_; }
inline bool is_code_flushing_enabled() const { return code_flusher_ != NULL; }
-#ifdef VERIFY_HEAP
- void VerifyValidStoreAndSlotsBufferEntries();
- void VerifyMarkbitsAreClean();
- static void VerifyMarkbitsAreClean(PagedSpace* space);
- static void VerifyMarkbitsAreClean(NewSpace* space);
- void VerifyWeakEmbeddedObjectsInCode();
- void VerifyOmittedMapChecks();
-#endif
-
INLINE(static bool ShouldSkipEvacuationSlotRecording(Object* host)) {
return Page::FromAddress(reinterpret_cast<Address>(host))
->ShouldSkipEvacuationSlotRecording();
@@ -483,6 +540,7 @@ class MarkCompactCollector {
INLINE(void RecordSlot(HeapObject* object, Object** slot, Object* target));
INLINE(void ForceRecordSlot(HeapObject* object, Object** slot,
Object* target));
+ void RecordLiveSlotsOnPage(Page* page);
void UpdateSlots(SlotsBuffer* buffer);
void UpdateSlotsRecordedIn(SlotsBuffer* buffer);
@@ -493,8 +551,6 @@ class MarkCompactCollector {
bool is_compacting() const { return compacting_; }
- MarkingParity marking_parity() { return marking_parity_; }
-
// Ensures that sweeping is finished.
//
// Note: Can only be called safely from main thread.
@@ -513,10 +569,6 @@ class MarkCompactCollector {
bool evacuation() const { return evacuation_; }
- // Special case for processing weak references in a full collection. We need
- // to artificially keep AllocationSites alive for a time.
- void MarkAllocationSite(AllocationSite* site);
-
// Mark objects in implicit references groups if their parent object
// is marked.
void MarkImplicitRefGroups(MarkObjectFunction mark_object);
@@ -525,6 +577,21 @@ class MarkCompactCollector {
Sweeper& sweeper() { return sweeper_; }
+#ifdef DEBUG
+ // Checks whether performing mark-compact collection.
+ bool in_use() { return state_ > PREPARE_GC; }
+ bool are_map_pointers_encoded() { return state_ == UPDATE_POINTERS; }
+#endif
+
+#ifdef VERIFY_HEAP
+ void VerifyValidStoreAndSlotsBufferEntries();
+ void VerifyMarkbitsAreClean();
+ static void VerifyMarkbitsAreClean(PagedSpace* space);
+ static void VerifyMarkbitsAreClean(NewSpace* space);
+ void VerifyWeakEmbeddedObjectsInCode();
+ void VerifyOmittedMapChecks();
+#endif
+
private:
template <PageEvacuationMode mode>
class EvacuateNewSpacePageVisitor;
@@ -564,8 +631,10 @@ class MarkCompactCollector {
friend class MarkCompactMarkingVisitor;
friend class MarkingVisitor;
friend class RecordMigratedSlotVisitor;
+ template <MarkCompactMode mode>
friend class RootMarkingVisitor;
friend class SharedFunctionInfoMarkingVisitor;
+ friend class StaticYoungGenerationMarkingVisitor;
// Mark code objects that are active on the stack to prevent them
// from being flushed.
@@ -575,6 +644,8 @@ class MarkCompactCollector {
// Marking operations for objects reachable from roots.
void MarkLiveObjects();
+ // Mark the young generation.
+ void MarkLiveObjectsInYoungGeneration();
// Pushes a black object onto the marking stack and accounts for live bytes.
// Note that this assumes live bytes have not yet been counted.
@@ -586,21 +657,18 @@ class MarkCompactCollector {
// Marks the object black and pushes it on the marking stack.
// This is for non-incremental marking only.
- INLINE(void MarkObject(HeapObject* obj, MarkBit mark_bit));
-
- // Marks the object black assuming that it is not yet marked.
- // This is for non-incremental marking only.
- INLINE(void SetMark(HeapObject* obj, MarkBit mark_bit));
+ INLINE(void MarkObject(HeapObject* obj));
// Mark the heap roots and all objects reachable from them.
- void MarkRoots(RootMarkingVisitor* visitor);
+ void MarkRoots(RootMarkingVisitor<MarkCompactMode::FULL>* visitor);
// Mark the string table specially. References to internalized strings from
// the string table are weak.
- void MarkStringTable(RootMarkingVisitor* visitor);
+ void MarkStringTable(RootMarkingVisitor<MarkCompactMode::FULL>* visitor);
// Mark objects reachable (transitively) from objects in the marking stack
// or overflowed in the heap.
+ template <MarkCompactMode mode>
void ProcessMarkingDeque();
// Mark objects reachable (transitively) from objects in the marking stack
@@ -624,11 +692,13 @@ class MarkCompactCollector {
// stack. This function empties the marking stack, but may leave
// overflowed objects in the heap, in which case the marking stack's
// overflow flag will be set.
+ template <MarkCompactMode mode>
void EmptyMarkingDeque();
// Refill the marking stack with overflowed objects from the heap. This
// function either leaves the marking stack full or clears the overflow
// flag on the marking stack.
+ template <MarkCompactMode mode>
void RefillMarkingDeque();
// Helper methods for refilling the marking stack by discovering grey objects
@@ -684,8 +754,8 @@ class MarkCompactCollector {
void StartSweepSpaces();
void StartSweepSpace(PagedSpace* space);
- void EvacuateNewSpacePrologue();
-
+ void EvacuatePrologue();
+ void EvacuateEpilogue();
void EvacuatePagesInParallel();
// The number of parallel compaction tasks, including the main thread.
@@ -733,8 +803,6 @@ class MarkCompactCollector {
CollectorState state_;
#endif
- MarkingParity marking_parity_;
-
bool was_marked_incrementally_;
bool evacuation_;
@@ -751,8 +819,11 @@ class MarkCompactCollector {
CodeFlusher* code_flusher_;
+ // Candidates for pages that should be evacuated.
List<Page*> evacuation_candidates_;
- List<Page*> newspace_evacuation_candidates_;
+ // Pages that are actually processed during evacuation.
+ List<Page*> old_space_evacuation_pages_;
+ List<Page*> new_space_evacuation_pages_;
Sweeper sweeper_;