Skip to content

Commit

Permalink
Move rest CardTable functions to AlignedHeapSegmentBase
Browse files Browse the repository at this point in the history
  • Loading branch information
lavenzg authored and facebook-github-bot committed Nov 7, 2024
1 parent e7c2aa4 commit 34154c4
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 39 deletions.
61 changes: 32 additions & 29 deletions include/hermes/VM/AlignedHeapSegment.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,38 @@ class AlignedHeapSegmentBase {
return contents()->cardTable_;
}

/// Given a \p cell into the memory region of some valid segment \c s, returns
/// a pointer to the CardTable covering the segment containing the cell.
///
/// \pre There exists a currently alive heap in which \p cell is allocated.
static CardTable *cardTableCovering(const GCCell *cell) {
return &contents(alignedStorageStart(cell))->cardTable_;
}

/// Find the head of the first cell that extends into the card at index
/// \p cardIdx.
/// \return A cell such that
/// cell <= indexToAddress(cardIdx) < cell->nextCell().
GCCell *getFirstCellHead(size_t cardIdx) {
CardTable &cards = cardTable();
GCCell *cell = cards.firstObjForCard(cardIdx);
assert(cell->isValid() && "Object head doesn't point to a valid object");
return cell;
}

/// Record the head of this cell so it can be found by the card scanner.
static void setCellHead(const GCCell *cellStart, const size_t sz) {
const char *start = reinterpret_cast<const char *>(cellStart);
const char *end = start + sz;
CardTable *cards = cardTableCovering(cellStart);
auto boundary = cards->nextBoundary(start);
// If this object crosses a card boundary, then update boundaries
// appropriately.
if (boundary.address() < end) {
cards->updateBoundaries(&boundary, start, end);
}
}

/// Return a reference to the mark bit array covering the memory region
/// managed by this segment.
Contents::MarkBitArray &markBitArray() const {
Expand Down Expand Up @@ -395,15 +427,6 @@ class AlignedHeapSegment : public AlignedHeapSegmentBase {
/// \pre There exists a currently alive heap that claims to contain \c ptr.
inline static CardTable *cardTableCovering(const void *ptr);

/// Find the head of the first cell that extends into the card at index
/// \p cardIdx.
/// \return A cell such that
/// cell <= indexToAddress(cardIdx) < cell->nextCell().
inline GCCell *getFirstCellHead(size_t cardIdx);

/// Record the head of this cell so it can be found by the card scanner.
static inline void setCellHead(const GCCell *start, const size_t sz);

/// The largest size the allocation region of an aligned heap segment could
/// be. This is a static override of AlignedHeapSegmentBase::maxSize(), which
/// reads the storage size from SHSegmentInfo.
Expand Down Expand Up @@ -542,26 +565,6 @@ AllocResult AlignedHeapSegment::alloc(uint32_t size) {
return {cell, true};
}

GCCell *AlignedHeapSegment::getFirstCellHead(size_t cardIdx) {
CardTable &cards = cardTable();
GCCell *cell = cards.firstObjForCard(cardIdx);
assert(cell->isValid() && "Object head doesn't point to a valid object");
return cell;
}

/* static */
void AlignedHeapSegment::setCellHead(const GCCell *cellStart, const size_t sz) {
const char *start = reinterpret_cast<const char *>(cellStart);
const char *end = start + sz;
CardTable *cards = cardTableCovering(start);
auto boundary = cards->nextBoundary(start);
// If this object crosses a card boundary, then update boundaries
// appropriately.
if (boundary.address() < end) {
cards->updateBoundaries(&boundary, start, end);
}
}

/* static */ CardTable *AlignedHeapSegment::cardTableCovering(const void *ptr) {
return &AlignedHeapSegment::contents(storageStart(ptr))->cardTable_;
}
Expand Down
20 changes: 10 additions & 10 deletions lib/VM/gcs/HadesGC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void HadesGC::OldGen::addCellToFreelist(
sz >= sizeof(FreelistCell) &&
"Cannot construct a FreelistCell into an allocation in the OG");
FreelistCell *newFreeCell = constructCell<FreelistCell>(addr, sz);
AlignedHeapSegment::setCellHead(static_cast<GCCell *>(addr), sz);
AlignedHeapSegmentBase::setCellHead(static_cast<GCCell *>(addr), sz);
addCellToFreelist(newFreeCell, segBucket);
}

Expand Down Expand Up @@ -125,7 +125,7 @@ void HadesGC::OldGen::addCellToFreelistFromSweep(
// While coalescing, sweeping may generate new cells, so make sure the cell
// head is updated.
if (setHead)
AlignedHeapSegment::setCellHead(
AlignedHeapSegmentBase::setCellHead(
reinterpret_cast<GCCell *>(freeRangeStart), newCellSize);
auto *newCell = constructCell<FreelistCell>(freeRangeStart, newCellSize);
// Get the size bucket for the cell being added;
Expand Down Expand Up @@ -218,7 +218,7 @@ GCCell *HadesGC::OldGen::FreelistCell::carve(uint32_t sz) {
char *newCellAddress = reinterpret_cast<char *>(this) + finalSize;
GCCell *const newCell = reinterpret_cast<GCCell *>(newCellAddress);
setSizeFromGC(finalSize);
AlignedHeapSegment::setCellHead(newCell, sz);
AlignedHeapSegmentBase::setCellHead(newCell, sz);
return newCell;
}

Expand Down Expand Up @@ -416,7 +416,7 @@ class HadesGC::EvacAcceptor final : public RootAndSlotAcceptor,
if (CompactionEnabled && gc.compactee_.contains(ptr)) {
// If a compaction is about to take place, dirty the card for any newly
// evacuated cells, since the marker may miss them.
AlignedHeapSegment::cardTableCovering(heapLoc)
AlignedHeapSegmentBase::cardTableCovering(currentCell)
->dirtyCardForAddressInLargeObj(heapLoc);
}
return ptr;
Expand All @@ -435,7 +435,7 @@ class HadesGC::EvacAcceptor final : public RootAndSlotAcceptor,
if (CompactionEnabled && gc.compactee_.contains(cptr)) {
// If a compaction is about to take place, dirty the card for any newly
// evacuated cells, since the marker may miss them.
AlignedHeapSegment::cardTableCovering(heapLoc)
AlignedHeapSegmentBase::cardTableCovering(currentCell)
->dirtyCardForAddressInLargeObj(heapLoc);
}
return cptr;
Expand Down Expand Up @@ -649,7 +649,7 @@ class HadesGC::MarkAcceptor final : public RootAndSlotAcceptor {
if (gc.compactee_.contains(cell) && !gc.compactee_.contains(heapLoc)) {
// This is a pointer in the heap pointing into the compactee, dirty the
// corresponding card.
AlignedHeapSegment::cardTableCovering(heapLoc)
AlignedHeapSegmentBase::cardTableCovering(currentCell)
->dirtyCardForAddressInLargeObj(heapLoc);
}
if (AlignedHeapSegmentBase::getCellMarkBit(cell)) {
Expand Down Expand Up @@ -1085,7 +1085,7 @@ bool HadesGC::OldGen::sweepNext(bool backgroundThread) {
assert(
!AlignedHeapSegmentBase::getCellMarkBit(newCell) &&
"Trimmed space cannot be marked");
AlignedHeapSegment::setCellHead(newCell, trimmableBytes);
AlignedHeapSegmentBase::setCellHead(newCell, trimmableBytes);
#ifndef NDEBUG
sweepIterator_.trimmedBytes += trimmableBytes;
#endif
Expand Down Expand Up @@ -2228,7 +2228,7 @@ GCCell *HadesGC::OldGen::alloc(uint32_t sz) {
"A newly created segment should always be able to allocate");
// Set the cell head for any successful alloc, so that write barriers can
// move from dirty cards to the head of the object.
AlignedHeapSegment::setCellHead(static_cast<GCCell *>(res.ptr), sz);
AlignedHeapSegmentBase::setCellHead(static_cast<GCCell *>(res.ptr), sz);
// Add the segment to segments_ and add the remainder of the segment to the
// free list.
addSegment(std::move(seg.get()));
Expand Down Expand Up @@ -2616,7 +2616,7 @@ bool HadesGC::promoteYoungGenToOldGen() {
// going into OG. This could be done at allocation time, but at a cost
// to YG alloc times for a case that might not come up.
forAllObjsInSegment(youngGen_, [](GCCell *cell) {
AlignedHeapSegment::setCellHead(cell, cell->getAllocatedSize());
AlignedHeapSegmentBase::setCellHead(cell, cell->getAllocatedSize());
});
// It is important that this operation is just a move of pointers to
// segments. The addresses have to stay the same or else it would
Expand Down Expand Up @@ -3100,7 +3100,7 @@ void HadesGC::verifyCardTable() {
gc.compactee_.evacContains(valuePtr);
if (!gc.inYoungGen(locPtr) &&
(gc.inYoungGen(valuePtr) || crossRegionCompacteePtr)) {
assert(AlignedHeapSegment::cardTableCovering(locPtr)
assert(AlignedHeapSegmentBase::cardTableCovering(currentCell)
->isCardForAddressDirtyInLargeObj(locPtr));
}
}
Expand Down

0 comments on commit 34154c4

Please sign in to comment.