• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_HEAP_CPPGC_GC_INFO_TABLE_H_
6 #define V8_HEAP_CPPGC_GC_INFO_TABLE_H_
7 
8 #include <stdint.h>
9 
10 #include "include/cppgc/internal/gc-info.h"
11 #include "include/cppgc/platform.h"
12 #include "include/v8config.h"
13 #include "src/base/logging.h"
14 #include "src/base/macros.h"
15 #include "src/base/platform/mutex.h"
16 #include "src/base/platform/platform.h"
17 
18 namespace cppgc {
19 namespace internal {
20 
21 // GCInfo contains metadata for objects that are instantiated from classes that
22 // inherit from GarbageCollected.
23 struct GCInfo final {
24   FinalizationCallback finalize;
25   TraceCallback trace;
26   NameCallback name;
27   bool has_v_table;
28 };
29 
30 class V8_EXPORT GCInfoTable final {
31  public:
32   // At maximum |kMaxIndex - 1| indices are supported.
33   //
34   // We assume that 14 bits are enough to represent all possible types.
35   //
36   // For Blink during telemetry runs, we see about 1,000 different types;
37   // looking at the output of the Oilpan GC clang plugin, there appear to be at
38   // most about 6,000 types. Thus 14 bits should be more than twice as many bits
39   // as we will ever need. Different contexts may require adjusting this limit.
40   static constexpr GCInfoIndex kMaxIndex = 1 << 14;
41 
42   // Minimum index returned. Values smaller |kMinIndex| may be used as
43   // sentinels.
44   static constexpr GCInfoIndex kMinIndex = 1;
45 
46   // (Light) experimentation suggests that Blink doesn't need more than this
47   // while handling content on popular web properties.
48   static constexpr GCInfoIndex kInitialWantedLimit = 512;
49 
50   // Refer through GlobalGCInfoTable for retrieving the global table outside
51   // of testing code.
52   explicit GCInfoTable(PageAllocator* page_allocator);
53   ~GCInfoTable();
54 
55   GCInfoIndex RegisterNewGCInfo(const GCInfo& info);
56 
GCInfoFromIndex(GCInfoIndex index)57   const GCInfo& GCInfoFromIndex(GCInfoIndex index) const {
58     DCHECK_GE(index, kMinIndex);
59     DCHECK_LT(index, kMaxIndex);
60     DCHECK(table_);
61     return table_[index];
62   }
63 
NumberOfGCInfosForTesting()64   GCInfoIndex NumberOfGCInfosForTesting() const { return current_index_; }
LimitForTesting()65   GCInfoIndex LimitForTesting() const { return limit_; }
TableSlotForTesting(GCInfoIndex index)66   GCInfo& TableSlotForTesting(GCInfoIndex index) { return table_[index]; }
67 
68  private:
69   void Resize();
70 
71   GCInfoIndex InitialTableLimit() const;
72   size_t MaxTableSize() const;
73 
74   void CheckMemoryIsZeroed(uintptr_t* base, size_t len);
75 
76   PageAllocator* page_allocator_;
77   // Holds the per-class GCInfo descriptors; each HeapObjectHeader keeps an
78   // index into this table.
79   GCInfo* table_;
80   uint8_t* read_only_table_end_;
81   // Current index used when requiring a new GCInfo object.
82   GCInfoIndex current_index_ = kMinIndex;
83   // The limit (exclusive) of the currently allocated table.
84   GCInfoIndex limit_ = 0;
85 
86   v8::base::Mutex table_mutex_;
87 
88   DISALLOW_COPY_AND_ASSIGN(GCInfoTable);
89 };
90 
91 class V8_EXPORT GlobalGCInfoTable final {
92  public:
93   // Sets up a singleton table that can be acquired using Get().
94   static void Create(PageAllocator* page_allocator);
95 
96   // Accessors for the singleton table.
GetMutable()97   static GCInfoTable& GetMutable() { return *global_table_; }
Get()98   static const GCInfoTable& Get() { return *global_table_; }
99 
GCInfoFromIndex(GCInfoIndex index)100   static const GCInfo& GCInfoFromIndex(GCInfoIndex index) {
101     return Get().GCInfoFromIndex(index);
102   }
103 
104  private:
105   // Singleton for each process. Retrieved through Get().
106   static GCInfoTable* global_table_;
107 
108   DISALLOW_NEW_AND_DELETE()
109   DISALLOW_COPY_AND_ASSIGN(GlobalGCInfoTable);
110 };
111 
112 }  // namespace internal
113 }  // namespace cppgc
114 
115 #endif  // V8_HEAP_CPPGC_GC_INFO_TABLE_H_
116