5#ifndef RUNTIME_VM_HEAP_SCAVENGER_H_
6#define RUNTIME_VM_HEAP_SCAVENGER_H_
30template <
bool parallel>
31class ScavengerVisitorBase;
33template <
typename Type,
typename PtrType>
49 for (
const Page* p = head_; p !=
nullptr; p = p->next()) {
63 intptr_t capacity_in_words_ = 0;
67 intptr_t gc_threshold_in_words_;
69 Page* head_ =
nullptr;
70 Page* tail_ =
nullptr;
81 intptr_t promo_candidates_in_words,
82 intptr_t promoted_in_words,
83 intptr_t abandoned_in_words)
84 : start_micros_(start_micros),
85 end_micros_(end_micros),
88 promo_candidates_in_words_(promo_candidates_in_words),
89 promoted_in_words_(promoted_in_words),
90 abandoned_in_words_(abandoned_in_words) {}
97 after_.
used_in_words + promoted_in_words_ + abandoned_in_words_;
98 return 1.0 - (work / old_threshold_in_words);
104 return promo_candidates_in_words_ > 0
105 ? promoted_in_words_ /
106 static_cast<double>(promo_candidates_in_words_)
115 int64_t start_micros_;
119 intptr_t promo_candidates_in_words_;
120 intptr_t promoted_in_words_;
121 intptr_t abandoned_in_words_;
126 static constexpr intptr_t kTLABSize = 512 *
KB;
139 uword addr = TryAllocateFromTLAB(thread, size);
143 TryAllocateNewTLAB(thread, size,
true);
144 return TryAllocateFromTLAB(thread, size);
147 uword addr = TryAllocateFromTLAB(thread, size);
151 TryAllocateNewTLAB(thread, size,
false);
152 return TryAllocateFromTLAB(thread, size);
187 void AddGCTime(int64_t micros) { gc_time_micros_ += micros; }
204 intptr_t expected = external_size_.
load();
207 intptr_t next_external_size_in_words =
209 if (next_external_size_in_words < 0 ||
213 desired = expected + size;
220 external_size_ -= size;
221 ASSERT(external_size_ >= 0);
231 const intptr_t max_parallel_tlab_usage =
232 (FLAG_new_gen_semi_max_size *
MB) / Scavenger::kTLABSize;
233 const intptr_t max_pool_size = max_parallel_tlab_usage / 4;
234 return max_pool_size > 0 ? max_pool_size : 1;
242 template <
typename Type,
typename PtrType>
249 kDummyScavengeTime = 0,
251 kVisitIsolateRoots = 2,
252 kIterateStoreBuffers = 3,
257 uword TryAllocateFromTLAB(Thread* thread, intptr_t size) {
262 const intptr_t remaining =
static_cast<intptr_t
>(thread->end()) -
result;
269 thread->set_top(
result + size);
272 void TryAllocateNewTLAB(Thread* thread, intptr_t size,
bool can_safepoint);
274 SemiSpace* Prologue(
GCReason reason);
275 intptr_t ParallelScavenge(SemiSpace* from);
276 intptr_t SerialScavenge(SemiSpace* from);
277 void ReverseScavenge(SemiSpace** from);
278 void IterateIsolateRoots(ObjectPointerVisitor* visitor);
279 template <
bool parallel>
280 void IterateStoreBuffers(ScavengerVisitorBase<parallel>* visitor);
281 template <
bool parallel>
282 void IterateRememberedCards(ScavengerVisitorBase<parallel>* visitor);
283 void IterateObjectIdTable(ObjectPointerVisitor* visitor);
284 template <
bool parallel>
285 void IterateRoots(ScavengerVisitorBase<parallel>* visitor);
287 void MournWeakHandles();
288 void MournWeakTables();
289 void Epilogue(SemiSpace* from);
291 void VerifyStoreBuffers(
const char* msg);
293 void UpdateMaxHeapCapacity();
294 void UpdateMaxHeapUsage();
296 intptr_t NewSizeInWords(intptr_t old_size_in_words,
GCReason reason)
const;
302 PromotionStack promotion_stack_;
304 intptr_t max_semi_capacity_in_words_;
307 bool scavenging_ =
false;
308 bool early_tenure_ =
false;
309 RelaxedAtomic<intptr_t> root_slices_started_ = {0};
310 RelaxedAtomic<intptr_t> weak_slices_started_ = {0};
316 int64_t gc_time_micros_ = 0;
317 intptr_t collections_ = 0;
318 static constexpr int kStatsHistoryCapacity = 4;
319 RingBuffer<ScavengeStats, kStatsHistoryCapacity> stats_history_;
321 intptr_t scavenge_words_per_micro_;
322 intptr_t idle_scavenge_threshold_in_words_ = 0;
325 RelaxedAtomic<intptr_t> external_size_ = {0};
326 intptr_t freed_in_words_ = 0;
328 RelaxedAtomic<bool> failed_to_promote_ = {
false};
329 RelaxedAtomic<bool> abort_ = {
false};
332 mutable Mutex space_lock_;
static IsolateGroup * vm_isolate_group()
T load(std::memory_order order=std::memory_order_relaxed) const
bool compare_exchange_weak(T &expected, T desired, std::memory_order order=std::memory_order_relaxed)
ScavengeStats(int64_t start_micros, int64_t end_micros, SpaceUsage before, SpaceUsage after, intptr_t promo_candidates_in_words, intptr_t promoted_in_words, intptr_t abandoned_in_words)
intptr_t UsedBeforeInWords() const
double ExpectedGarbageFraction(intptr_t old_threshold_in_words) const
int64_t DurationMicros() const
double PromoCandidatesSuccessFraction() const
void Scavenge(Thread *thread, GCType type, GCReason reason)
bool Contains(uword addr) const
void Prune(MarkingStackBlock **from, MarkingStack *to)
static intptr_t MaxMutatorThreadCount()
intptr_t ExternalInWords() const
void VisitObjects(ObjectVisitor *visitor) const
void VisitObjectPointers(ObjectPointerVisitor *visitor) const
void PruneWeak(GCLinkedLists *delayed)
void AddGCTime(int64_t micros)
void WriteProtect(bool read_only)
void AbandonRemainingTLABForDebugging(Thread *thread)
bool ShouldPerformIdleScavenge(int64_t deadline)
uword TryAllocate(Thread *thread, intptr_t size)
void AddRegionsToObjectSet(ObjectSet *set) const
void set_freed_in_words(intptr_t value)
intptr_t CapacityInWords() const
intptr_t UsedInWords() const
SpaceUsage GetCurrentUsage() const
bool AllocatedExternal(intptr_t size)
void FreedExternal(intptr_t size)
int64_t gc_time_micros() const
void IncrementCollections()
intptr_t AbandonRemainingTLAB(Thread *thread)
intptr_t ThresholdInWords() const
uword TryAllocateNoSafepoint(Thread *thread, intptr_t size)
intptr_t collections() const
void PrintToJSONObject(JSONObject *object) const
void Forward(MarkingStack *stack)
void AddList(Page *head, Page *tail)
void WriteProtect(bool read_only)
intptr_t gc_threshold_in_words() const
Page * TryAllocatePageLocked(bool link)
bool Contains(uword addr) const
intptr_t capacity_in_words() const
intptr_t used_in_words() const
RelaxedAtomic< intptr_t > used_in_words
static constexpr bool IsAligned(T x, uintptr_t alignment, uintptr_t offset=0)
StoreBuffer::Block StoreBufferBlock
static constexpr intptr_t kNewObjectAlignmentOffset
MarkingStack::Block MarkingStackBlock
constexpr intptr_t kWordSizeLog2
static constexpr intptr_t kObjectAlignmentMask
static constexpr intptr_t kObjectAlignment
const intptr_t kMaxAddrSpaceInWords
static void usage(char *argv0)