11cb0ef41Sopenharmony_ci// Copyright 2021 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_HEAP_PROGRESS_BAR_H_ 61cb0ef41Sopenharmony_ci#define V8_HEAP_PROGRESS_BAR_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <atomic> 91cb0ef41Sopenharmony_ci#include <cstdint> 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ci#include "src/base/logging.h" 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_cinamespace v8 { 141cb0ef41Sopenharmony_cinamespace internal { 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci// The progress bar allows for keeping track of the bytes processed of a single 171cb0ef41Sopenharmony_ci// object. The progress bar itself must be enabled before it's used. 181cb0ef41Sopenharmony_ci// 191cb0ef41Sopenharmony_ci// Only large objects use the progress bar which is stored in their page header. 201cb0ef41Sopenharmony_ci// These objects are scanned in increments and will be kept black while being 211cb0ef41Sopenharmony_ci// scanned. Even if the mutator writes to them they will be kept black and a 221cb0ef41Sopenharmony_ci// white to grey transition is performed in the value. 231cb0ef41Sopenharmony_ci// 241cb0ef41Sopenharmony_ci// The progress bar starts as disabled. After enabling (through `Enable()`), it 251cb0ef41Sopenharmony_ci// can never be disabled again. 261cb0ef41Sopenharmony_ciclass ProgressBar final { 271cb0ef41Sopenharmony_ci public: 281cb0ef41Sopenharmony_ci void Initialize() { value_ = kDisabledSentinel; } 291cb0ef41Sopenharmony_ci void Enable() { value_ = 0; } 301cb0ef41Sopenharmony_ci bool IsEnabled() const { 311cb0ef41Sopenharmony_ci return value_.load(std::memory_order_acquire) != kDisabledSentinel; 321cb0ef41Sopenharmony_ci } 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci size_t Value() const { 351cb0ef41Sopenharmony_ci DCHECK(IsEnabled()); 361cb0ef41Sopenharmony_ci return value_.load(std::memory_order_acquire); 371cb0ef41Sopenharmony_ci } 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci bool TrySetNewValue(size_t old_value, size_t new_value) { 401cb0ef41Sopenharmony_ci DCHECK(IsEnabled()); 411cb0ef41Sopenharmony_ci DCHECK_NE(kDisabledSentinel, new_value); 421cb0ef41Sopenharmony_ci return value_.compare_exchange_strong(old_value, new_value, 431cb0ef41Sopenharmony_ci std::memory_order_acq_rel); 441cb0ef41Sopenharmony_ci } 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci void ResetIfEnabled() { 471cb0ef41Sopenharmony_ci if (IsEnabled()) { 481cb0ef41Sopenharmony_ci value_.store(0, std::memory_order_release); 491cb0ef41Sopenharmony_ci } 501cb0ef41Sopenharmony_ci } 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci private: 531cb0ef41Sopenharmony_ci static constexpr size_t kDisabledSentinel = SIZE_MAX; 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci std::atomic<size_t> value_; 561cb0ef41Sopenharmony_ci}; 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci} // namespace internal 591cb0ef41Sopenharmony_ci} // namespace v8 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci#endif // V8_HEAP_PROGRESS_BAR_H_ 62