28 #ifndef V8_MARK_COMPACT_H_
29 #define V8_MARK_COMPACT_H_
65 return !mark_bit.
Get() && mark_bit.
Next().
Get();
71 return mark_bit.
Get() && !mark_bit.
Next().
Get();
77 return !mark_bit.
Get();
83 return mark_bit.
Get() && mark_bit.
Next().
Get();
124 static const char* ColorName(ObjectColor color) {
126 case BLACK_OBJECT:
return "black";
127 case WHITE_OBJECT:
return "white";
128 case GREY_OBJECT:
return "grey";
129 case IMPOSSIBLE_COLOR:
return "impossible";
134 static ObjectColor Color(HeapObject* obj) {
138 static ObjectColor Color(MarkBit mark_bit) {
139 if (
IsBlack(mark_bit))
return BLACK_OBJECT;
140 if (
IsWhite(mark_bit))
return WHITE_OBJECT;
141 if (
IsGrey(mark_bit))
return GREY_OBJECT;
143 return IMPOSSIBLE_COLOR;
152 bool is_black =
false;
153 if (from_mark_bit.
Get()) {
157 if (from_mark_bit.
Next().
Get()) {
173 : array_(
NULL), top_(0), bottom_(0), mask_(0), overflowed_(
false) { }
184 inline bool IsFull() {
return ((top_ + 1) & mask_) == bottom_; }
186 inline bool IsEmpty() {
return top_ == bottom_; }
198 ASSERT(object->IsHeapObject());
204 array_[top_] = object;
205 top_ = ((top_ + 1) & mask_);
210 ASSERT(object->IsHeapObject());
214 array_[top_] = object;
215 top_ = ((top_ + 1) & mask_);
221 top_ = ((top_ - 1) & mask_);
223 ASSERT(object->IsHeapObject());
228 ASSERT(object->IsHeapObject());
232 bottom_ = ((bottom_ - 1) & mask_);
233 array_[bottom_] = object;
239 int top() {
return top_; }
283 : idx_(0), chain_length_(1), next_(next_buffer) {
285 chain_length_ = next_->chain_length_ + 1;
294 slots_[idx_++] = slot;
314 if (buffer ==
NULL)
return 0;
315 return static_cast<int>(buffer->idx_ +
329 bool code_slots_filtering_required) {
330 while (buffer !=
NULL) {
331 if (code_slots_filtering_required) {
336 buffer = buffer->
next();
346 return buffer !=
NULL && buffer->chain_length_ >= kChainLengthThreshold;
360 *buffer_address = buffer;
377 static const int kChainLengthThreshold = 15;
380 intptr_t chain_length_;
388 template<
class BaseMarker>
class Marker {
391 : base_marker_(base_marker),
392 mark_compact_collector_(mark_compact_collector) {}
401 BaseMarker* base_marker() {
405 MarkCompactCollector* mark_compact_collector() {
406 return mark_compact_collector_;
409 BaseMarker* base_marker_;
410 MarkCompactCollector* mark_compact_collector_;
415 class ThreadLocalTop;
427 typedef MaybeObject* (*AllocationFunction)(
Heap*
heap,
482 bool in_use() {
return state_ > PREPARE_GC; }
483 bool are_map_pointers_encoded() {
return state_ == UPDATE_POINTERS; }
509 void VerifyMarkbitsAreClean();
510 static void VerifyMarkbitsAreClean(
PagedSpace* space);
511 static void VerifyMarkbitsAreClean(
NewSpace* space);
518 INLINE(
static bool ShouldSkipEvacuationSlotRecording(
Object** anchor)) {
520 ShouldSkipEvacuationSlotRecording();
525 ShouldSkipEvacuationSlotRecording();
530 IsEvacuationCandidate();
534 if (FLAG_trace_fragmentation) {
535 PrintF(
"Page %p is too popular. Disabling evacuation.\n",
536 reinterpret_cast<void*>(page));
548 evacuation_candidates_.RemoveElement(page);
568 encountered_weak_maps_ = weak_map;
581 bool MarkInvalidatedCode();
582 void RemoveDeadInvalidatedCode();
583 void ProcessInvalidatedCode(ObjectVisitor* visitor);
587 enum CollectorState {
592 ENCODE_FORWARDING_ADDRESSES,
598 CollectorState state_;
603 bool sweep_precisely_;
605 bool reduce_memory_footprint_;
607 bool abort_incremental_marking_;
613 bool was_marked_incrementally_;
615 bool flush_monomorphic_ics_;
621 SlotsBufferAllocator slots_buffer_allocator_;
623 SlotsBuffer* migration_slots_buffer_;
647 void MarkInlinedFunctionsCode(
Code* code);
651 void PrepareThreadForCodeFlushing(
Isolate* isolate, ThreadLocalTop* top);
653 void PrepareForCodeFlushing();
656 void MarkLiveObjects();
678 void ProcessNewlyMarkedObject(
HeapObject* obj);
685 void MarkSymbolTable();
689 void MarkObjectGroups();
693 void MarkImplicitRefGroups();
697 void ProcessExternalMarking();
701 void ProcessMarkingDeque();
707 void EmptyMarkingDeque();
712 void RefillMarkingDeque();
716 void ProcessMapCaches();
720 static bool IsUnmarkedHeapObject(
Object** p);
724 void ClearNonLiveTransitions();
725 void ClearNonLivePrototypeTransitions(
Map* map);
726 void ClearNonLiveMapTransitions(
Map* map,
MarkBit map_mark);
732 void ReattachInitialMaps();
737 void ProcessWeakMaps();
742 void ClearWeakMaps();
760 void EvacuateNewSpace();
762 void EvacuateLiveObjectsFromPage(
Page* p);
764 void EvacuatePages();
766 void EvacuateNewSpaceAndCandidates();
771 friend class MarkObjectVisitor;
774 friend class UnmarkObjectVisitor;
781 Object* encountered_weak_maps_;
795 #endif // V8_MARK_COMPACT_H_
static bool IsBlack(MarkBit mark_bit)
static void BlackToGrey(HeapObject *obj)
void ClearEvacuationCandidate()
static const char * kGreyBitPattern
static bool IsTypedSlot(ObjectSlot slot)
uint32_t RoundDownToPowerOf2(uint32_t x)
static void ReportDeleteIfNeeded(HeapObject *obj, Isolate *isolate)
void PrintF(const char *format,...)
static const char * kWhiteBitPattern
void Prepare(GCTracer *tracer)
static const uint32_t kSingleFreeEncoding
static void WhiteToGrey(MarkBit markbit)
static MemoryChunk * FromAddress(Address a)
static void BlackToGrey(MarkBit markbit)
CodeFlusher * code_flusher()
static MarkBit MarkBitFrom(HeapObject *obj)
const char * AllocationSpaceName(AllocationSpace space)
void UpdateSlots(Heap *heap)
#define ASSERT(condition)
static void IncrementLiveBytesFromGC(Address address, int by)
bool StartCompaction(CompactionMode mode)
void UpdateSlotsWithFilter(Heap *heap)
static void AnyToGrey(MarkBit markbit)
static bool IsGrey(MarkBit mark_bit)
static const char * kBlackBitPattern
static bool IsWhite(MarkBit mark_bit)
INLINE(static bool ShouldSkipEvacuationSlotRecording(Object *host))
static int SizeOfChain(SlotsBuffer *buffer)
static MarkBit MarkBitFrom(Address addr)
bool TryPromoteObject(HeapObject *object, int object_size)
INLINE(static bool TransferColor(HeapObject *from, HeapObject *to))
INLINE(static bool ShouldSkipEvacuationSlotRecording(Object **anchor))
static bool IsMarked(Object *obj)
SlotsBuffer * AllocateBuffer(SlotsBuffer *next_buffer)
bool HasSpaceForTypedSlot()
void(* EncodingFunction)(Heap *heap, HeapObject *old_object, int object_size, Object *new_object, int *offset)
SlotsBuffer(SlotsBuffer *next_buffer)
void AddEvacuationCandidate(Page *p)
void PushBlack(HeapObject *object)
void Initialize(Address low, Address high)
void CollectEvacuationCandidates(PagedSpace *space)
void InvalidateCode(Code *code)
static const uint32_t kMultiFreeEncoding
bool TransferMark(Address old_start, Address new_start)
static void MarkBlack(MarkBit mark_bit)
static void GreyToBlack(MarkBit markbit)
void DeallocateBuffer(SlotsBuffer *buffer)
void MarkDescriptorArray(DescriptorArray *descriptors)
void(* ProcessNonLiveFunction)(HeapObject *object, Isolate *isolate)
static const int kNumberOfElements
static bool IsImpossible(MarkBit mark_bit)
static intptr_t SweepConservatively(PagedSpace *space, Page *p)
void RecordRelocSlot(RelocInfo *rinfo, Object *target)
void DeallocateChain(SlotsBuffer **buffer_address)
void MigrateObject(Address dst, Address src, int size, AllocationSpace to_old_space)
bool(* IsAliveFunction)(HeapObject *obj, int *size, int *offset)
bool is_code_flushing_enabled() const
bool is_compacting() const
void Add(ObjectSlot slot)
void set_encountered_weak_maps(Object *weak_map)
static bool ChainLengthThresholdReached(SlotsBuffer *buffer)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
void EvictEvacuationCandidate(Page *page)
void PushGrey(HeapObject *object)
static const char * kImpossibleBitPattern
void MarkAccessorPairSlot(AccessorPair *accessors, int offset)
void MarkMapContents(Map *map)
static void UpdateSlotsRecordedIn(Heap *heap, SlotsBuffer *buffer, bool code_slots_filtering_required)
INLINE(static bool IsOnEvacuationCandidate(Object *obj))
static bool AddTo(SlotsBufferAllocator *allocator, SlotsBuffer **buffer_address, ObjectSlot slot, AdditionMode mode)
Marker(BaseMarker *base_marker, MarkCompactCollector *mark_compact_collector)
void EnableCodeFlushing(bool enable)
AllocationSpace identity()
void UnshiftGrey(HeapObject *object)
void RecordCodeEntrySlot(Address slot, Code *target)
int(MarkCompactCollector::* LiveObjectCallback)(HeapObject *obj)
Object * encountered_weak_maps()