11cb0ef41Sopenharmony_ci// Copyright 2020 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_CPPGC_GC_INFO_TABLE_H_ 61cb0ef41Sopenharmony_ci#define V8_HEAP_CPPGC_GC_INFO_TABLE_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <stdint.h> 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include "include/cppgc/internal/gc-info.h" 111cb0ef41Sopenharmony_ci#include "include/cppgc/platform.h" 121cb0ef41Sopenharmony_ci#include "include/v8config.h" 131cb0ef41Sopenharmony_ci#include "src/base/logging.h" 141cb0ef41Sopenharmony_ci#include "src/base/macros.h" 151cb0ef41Sopenharmony_ci#include "src/base/platform/mutex.h" 161cb0ef41Sopenharmony_ci#include "src/base/platform/platform.h" 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_cinamespace cppgc { 191cb0ef41Sopenharmony_cinamespace internal { 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci// GCInfo contains metadata for objects that are instantiated from classes that 221cb0ef41Sopenharmony_ci// inherit from GarbageCollected. 231cb0ef41Sopenharmony_cistruct GCInfo final { 241cb0ef41Sopenharmony_ci FinalizationCallback finalize; 251cb0ef41Sopenharmony_ci TraceCallback trace; 261cb0ef41Sopenharmony_ci NameCallback name; 271cb0ef41Sopenharmony_ci bool has_v_table; 281cb0ef41Sopenharmony_ci}; 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ciclass V8_EXPORT GCInfoTable final { 311cb0ef41Sopenharmony_ci public: 321cb0ef41Sopenharmony_ci // At maximum |kMaxIndex - 1| indices are supported. 331cb0ef41Sopenharmony_ci // 341cb0ef41Sopenharmony_ci // We assume that 14 bits are enough to represent all possible types. 351cb0ef41Sopenharmony_ci // 361cb0ef41Sopenharmony_ci // For Blink during telemetry runs, we see about 1,000 different types; 371cb0ef41Sopenharmony_ci // looking at the output of the Oilpan GC clang plugin, there appear to be at 381cb0ef41Sopenharmony_ci // most about 6,000 types. Thus 14 bits should be more than twice as many bits 391cb0ef41Sopenharmony_ci // as we will ever need. Different contexts may require adjusting this limit. 401cb0ef41Sopenharmony_ci static constexpr GCInfoIndex kMaxIndex = 1 << 14; 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci // Minimum index returned. Values smaller |kMinIndex| may be used as 431cb0ef41Sopenharmony_ci // sentinels. 441cb0ef41Sopenharmony_ci static constexpr GCInfoIndex kMinIndex = 1; 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci // (Light) experimentation suggests that Blink doesn't need more than this 471cb0ef41Sopenharmony_ci // while handling content on popular web properties. 481cb0ef41Sopenharmony_ci static constexpr GCInfoIndex kInitialWantedLimit = 512; 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ci // Refer through GlobalGCInfoTable for retrieving the global table outside 511cb0ef41Sopenharmony_ci // of testing code. 521cb0ef41Sopenharmony_ci explicit GCInfoTable(PageAllocator* page_allocator); 531cb0ef41Sopenharmony_ci ~GCInfoTable(); 541cb0ef41Sopenharmony_ci GCInfoTable(const GCInfoTable&) = delete; 551cb0ef41Sopenharmony_ci GCInfoTable& operator=(const GCInfoTable&) = delete; 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci GCInfoIndex RegisterNewGCInfo(std::atomic<uint16_t>&, const GCInfo& info); 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci const GCInfo& GCInfoFromIndex(GCInfoIndex index) const { 601cb0ef41Sopenharmony_ci DCHECK_GE(index, kMinIndex); 611cb0ef41Sopenharmony_ci DCHECK_LT(index, kMaxIndex); 621cb0ef41Sopenharmony_ci DCHECK(table_); 631cb0ef41Sopenharmony_ci return table_[index]; 641cb0ef41Sopenharmony_ci } 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci GCInfoIndex NumberOfGCInfos() const { return current_index_; } 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci GCInfoIndex LimitForTesting() const { return limit_; } 691cb0ef41Sopenharmony_ci GCInfo& TableSlotForTesting(GCInfoIndex index) { return table_[index]; } 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci PageAllocator* allocator() const { return page_allocator_; } 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci private: 741cb0ef41Sopenharmony_ci void Resize(); 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci GCInfoIndex InitialTableLimit() const; 771cb0ef41Sopenharmony_ci size_t MaxTableSize() const; 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci void CheckMemoryIsZeroed(uintptr_t* base, size_t len); 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci PageAllocator* page_allocator_; 821cb0ef41Sopenharmony_ci // Holds the per-class GCInfo descriptors; each HeapObjectHeader keeps an 831cb0ef41Sopenharmony_ci // index into this table. 841cb0ef41Sopenharmony_ci GCInfo* table_; 851cb0ef41Sopenharmony_ci uint8_t* read_only_table_end_; 861cb0ef41Sopenharmony_ci // Current index used when requiring a new GCInfo object. 871cb0ef41Sopenharmony_ci GCInfoIndex current_index_ = kMinIndex; 881cb0ef41Sopenharmony_ci // The limit (exclusive) of the currently allocated table. 891cb0ef41Sopenharmony_ci GCInfoIndex limit_ = 0; 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci v8::base::Mutex table_mutex_; 921cb0ef41Sopenharmony_ci}; 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ciclass V8_EXPORT GlobalGCInfoTable final { 951cb0ef41Sopenharmony_ci public: 961cb0ef41Sopenharmony_ci GlobalGCInfoTable(const GlobalGCInfoTable&) = delete; 971cb0ef41Sopenharmony_ci GlobalGCInfoTable& operator=(const GlobalGCInfoTable&) = delete; 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci // Sets up the table with the provided `page_allocator`. Will use an internal 1001cb0ef41Sopenharmony_ci // allocator in case no PageAllocator is provided. May be called multiple 1011cb0ef41Sopenharmony_ci // times with the same `page_allocator` argument. 1021cb0ef41Sopenharmony_ci static void Initialize(PageAllocator* page_allocator); 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci // Accessors for the singleton table. 1051cb0ef41Sopenharmony_ci static GCInfoTable& GetMutable() { return *global_table_; } 1061cb0ef41Sopenharmony_ci static const GCInfoTable& Get() { return *global_table_; } 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci static const GCInfo& GCInfoFromIndex(GCInfoIndex index) { 1091cb0ef41Sopenharmony_ci return Get().GCInfoFromIndex(index); 1101cb0ef41Sopenharmony_ci } 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci private: 1131cb0ef41Sopenharmony_ci // Singleton for each process. Retrieved through Get(). 1141cb0ef41Sopenharmony_ci static GCInfoTable* global_table_; 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci DISALLOW_NEW_AND_DELETE() 1171cb0ef41Sopenharmony_ci}; 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci} // namespace internal 1201cb0ef41Sopenharmony_ci} // namespace cppgc 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci#endif // V8_HEAP_CPPGC_GC_INFO_TABLE_H_ 123