@@ -63,11 +63,9 @@ class CardTable {
63
63
static constexpr size_t kCardSize = 1 << kLogCardSize ; // ==> 512-byte cards.
64
64
static constexpr size_t kSegmentSize = 1 << HERMESVM_LOG_HEAP_SEGMENT_SIZE;
65
65
66
- // / The number of valid indices into the card table.
67
- static constexpr size_t kValidIndices = kSegmentSize >> kLogCardSize ;
68
-
69
- // / The size of the card table.
70
- static constexpr size_t kCardTableSize = kValidIndices ;
66
+ // / The size of the maximum inline card table. CardStatus array and boundary
67
+ // / array for larger segment has larger size and is storage separately.
68
+ static constexpr size_t kInlineCardTableSize = kSegmentSize >> kLogCardSize ;
71
69
72
70
// / For convenience, this is a conversion factor to determine how many bytes
73
71
// / in the heap correspond to a single byte in the card table. This is
@@ -91,10 +89,14 @@ class CardTable {
91
89
// / Note that the total size of the card table is 2 times kCardTableSize,
92
90
// / since the CardTable contains two byte arrays of that size (cards_ and
93
91
// / boundaries_).
94
- static constexpr size_t kFirstUsedIndex =
95
- std::max (sizeof (SHSegmentInfo), (2 * kCardTableSize ) >> kLogCardSize );
92
+ static constexpr size_t kFirstUsedIndex = std::max(
93
+ sizeof (SHSegmentInfo),
94
+ (2 * kInlineCardTableSize ) >> kLogCardSize );
96
95
97
- CardTable () = default ;
96
+ CardTable () {
97
+ // Preserve the segment size.
98
+ segmentInfo_.segmentSize = kSegmentSize ;
99
+ }
98
100
// / CardTable is not copyable or movable: It must be constructed in-place.
99
101
CardTable (const CardTable &) = delete;
100
102
CardTable (CardTable &&) = delete;
@@ -185,6 +187,11 @@ class CardTable {
185
187
// / is the first object.)
186
188
GCCell *firstObjForCard (unsigned index) const ;
187
189
190
+ // / The end index of the card table (all valid indices should be smaller).
191
+ size_t getEndIndex () const {
192
+ return getSegmentSize () >> kLogCardSize ;
193
+ }
194
+
188
195
#ifdef HERMES_EXTRA_DEBUG
189
196
// / Temporary debugging hack: yield the numeric value of the boundaries_ array
190
197
// / for the given \p index.
@@ -215,10 +222,16 @@ class CardTable {
215
222
#endif // HERMES_SLOW_DEBUG
216
223
217
224
private:
225
+ unsigned getSegmentSize () const {
226
+ return segmentInfo_.segmentSize ;
227
+ }
228
+
218
229
#ifndef NDEBUG
219
- // / Returns the pointer to the end of the storage containing \p ptr
220
- // / (exclusive).
221
- static void *storageEnd (const void *ptr);
230
+ // / Returns the pointer to the end of the storage starting at \p lowLim.
231
+ void *storageEnd (const void *lowLim) const {
232
+ return reinterpret_cast <char *>(
233
+ reinterpret_cast <uintptr_t >(lowLim) + getSegmentSize ());
234
+ }
222
235
#endif
223
236
224
237
enum class CardStatus : char { Clean = 0 , Dirty = 1 };
@@ -262,7 +275,7 @@ class CardTable {
262
275
SHSegmentInfo segmentInfo_;
263
276
// / This needs to be atomic so that the background thread in Hades can
264
277
// / safely dirty cards when compacting.
265
- std::array<AtomicIfConcurrentGC<CardStatus>, kCardTableSize > cards_{};
278
+ std::array<AtomicIfConcurrentGC<CardStatus>, kInlineCardTableSize > cards_{};
266
279
};
267
280
268
281
// / See the comment at kHeapBytesPerCardByte above to see why this is
@@ -281,7 +294,7 @@ class CardTable {
281
294
// / time: If we allocate a large object that crosses many cards, the first
282
295
// / crossed cards gets a non-negative value, and each subsequent one uses the
283
296
// / maximum exponent that stays within the card range for the object.
284
- int8_t boundaries_[kCardTableSize ];
297
+ int8_t boundaries_[kInlineCardTableSize ];
285
298
};
286
299
287
300
// / Implementations of inlines.
@@ -311,7 +324,7 @@ inline size_t CardTable::addressToIndex(const void *addr) const {
311
324
}
312
325
313
326
inline const char *CardTable::indexToAddress (size_t index) const {
314
- assert (index <= kValidIndices && " index must be within the index range" );
327
+ assert (index <= getEndIndex () && " index must be within the index range" );
315
328
const char *res = base () + (index << kLogCardSize );
316
329
assert (
317
330
base () <= res && res <= storageEnd (base ()) &&
@@ -329,7 +342,7 @@ inline bool CardTable::isCardForAddressDirty(const void *addr) const {
329
342
}
330
343
331
344
inline bool CardTable::isCardForIndexDirty (size_t index) const {
332
- assert (index < kValidIndices && " index is required to be in range." );
345
+ assert (index < getEndIndex () && " index is required to be in range." );
333
346
return cards_[index ].load (std::memory_order_relaxed) == CardStatus::Dirty;
334
347
}
335
348
0 commit comments