Skip to content

Commit ef83673

Browse files
Riley Dulinfacebook-github-bot
authored andcommitted
Move untrackSymbol to IdentifierTable::freeUnmarkedSymbols
Summary: This diff fixes two problems: * Hades never untracked symbols for heap snapshot purposes * GenGC and Malloc accidentally untracked "permanent" symbols, or ones that aren't actually freed To avoid the latter problem from occurring, have `IdentifierTable` itself be the one who calls `untrackSymbol`. An alternative would be to have IdentifierTable modify and return a new bitset. That might be cleaner (more separation of concerns), but also seems like extra cost. Reviewed By: neildhar Differential Revision: D25291784 fbshipit-source-id: 46be72f1b7e21da640002f7306b2a09a94abad10
1 parent f58d99d commit ef83673

7 files changed

Lines changed: 20 additions & 28 deletions

File tree

include/hermes/VM/GCBase.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -543,10 +543,9 @@ class GCBase {
543543
/// tracking working set small.
544544
inline void untrackObject(const void *cell);
545545

546-
/// For a symbol index \p i, \p markedSymbols[i] indicates whether
547-
/// the symbol was reachable in a GC. Untrack all symbols whose
548-
/// index is not marked.
549-
void untrackUnmarkedSymbols(const llvh::BitVector &markedSymbols);
546+
/// Remove the symbol from being tracked. This needs to be done to allow
547+
/// symbols to be re-used.
548+
inline void untrackSymbol(uint32_t symIdx);
550549

551550
/// Remove the native memory from being tracked. This should be done to keep
552551
/// the tracking working set small. It is also required to be done when
@@ -1667,6 +1666,11 @@ inline void GCBase::IDTracker::untrackNative(const void *mem) {
16671666
untrackObject(mem);
16681667
}
16691668

1669+
inline void GCBase::IDTracker::untrackSymbol(uint32_t symIdx) {
1670+
std::lock_guard<Mutex> lk{mtx_};
1671+
symbolIDMap_.erase(symIdx);
1672+
}
1673+
16701674
inline const GCExecTrace &GCBase::getGCExecTrace() const {
16711675
return execTrace_;
16721676
}

include/hermes/VM/IdentifierTable.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,9 @@ class IdentifierTable {
165165
void unmarkSymbols();
166166

167167
/// Invoked at the end of a GC to free all unmarked symbols.
168-
void freeUnmarkedSymbols(const llvh::BitVector &markedSymbols);
168+
void freeUnmarkedSymbols(
169+
const llvh::BitVector &markedSymbols,
170+
GC::IDTracker &gc);
169171

170172
#ifdef HERMES_SLOW_DEBUG
171173
/// \return true if the given symbol is a live entry in the identifier

lib/VM/GCBase.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -916,20 +916,6 @@ void GCBase::IDTracker::deserialize(Deserializer &d) {
916916
}
917917
#endif
918918

919-
void GCBase::IDTracker::untrackUnmarkedSymbols(
920-
const llvh::BitVector &markedSymbols) {
921-
std::lock_guard<Mutex> lk{mtx_};
922-
std::vector<uint32_t> toUntrack;
923-
for (const auto &pair : symbolIDMap_) {
924-
if (!markedSymbols.test(pair.first)) {
925-
toUntrack.push_back(pair.first);
926-
}
927-
}
928-
for (uint32_t symIdx : toUntrack) {
929-
symbolIDMap_.erase(symIdx);
930-
}
931-
}
932-
933919
HeapSnapshot::NodeID GCBase::IDTracker::getNumberID(double num) {
934920
std::lock_guard<Mutex> lk{mtx_};
935921
auto &numberRef = numberIDMap_[num];

lib/VM/IdentifierTable.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,8 @@ void IdentifierTable::unmarkSymbols() {
518518
}
519519

520520
void IdentifierTable::freeUnmarkedSymbols(
521-
const llvh::BitVector &markedSymbols) {
521+
const llvh::BitVector &markedSymbols,
522+
GC::IDTracker &tracker) {
522523
assert(
523524
markedSymbols.size() <= lookupVector_.size() &&
524525
"Size of markedSymbols must be less than the current lookupVector");
@@ -529,6 +530,7 @@ void IdentifierTable::freeUnmarkedSymbols(
529530
// Flip and find set bits, which will correspond to symbols that weren't
530531
// marked.
531532
markedSymbols_.flip();
533+
const bool isTrackingIDs = tracker.isTrackingIDs();
532534
const uint32_t markedSymbolsSize = markedSymbols.size();
533535
for (const uint32_t i : markedSymbols_.set_bits()) {
534536
// Don't check any bits after the passed-in bits, which represent the number
@@ -538,8 +540,12 @@ void IdentifierTable::freeUnmarkedSymbols(
538540
}
539541
// We never free StringPrimitives that are materialized from a lazy
540542
// identifier.
541-
if (lookupVector_[i].isNonLazyStringPrim())
543+
if (lookupVector_[i].isNonLazyStringPrim()) {
544+
if (isTrackingIDs) {
545+
tracker.untrackSymbol(i);
546+
}
542547
freeSymbol(i);
548+
}
543549
}
544550
markedSymbols_.reset();
545551
}

lib/VM/Runtime.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,7 @@ void Runtime::unmarkSymbols() {
753753
}
754754

755755
void Runtime::freeSymbols(const llvh::BitVector &markedSymbols) {
756-
identifierTable_.freeUnmarkedSymbols(markedSymbols);
756+
identifierTable_.freeUnmarkedSymbols(markedSymbols, heap_.getIDTracker());
757757
}
758758

759759
#ifdef HERMES_SLOW_DEBUG

lib/VM/gcs/GenGCNC.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -377,9 +377,6 @@ void GenGC::collect(std::string cause, bool canEffectiveOOM) {
377377
/* youngGenIsEmpty */ youngGen_.usedDirect() == 0);
378378

379379
gcCallbacks_->freeSymbols(markedSymbols_);
380-
if (idTracker_.isTrackingIDs()) {
381-
idTracker_.untrackUnmarkedSymbols(markedSymbols_);
382-
}
383380

384381
// Update the exponential weighted average of live size, which we'll
385382
// consult if we need to shrink the heap.

lib/VM/gcs/MallocGC.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,6 @@ void MallocGC::collect(std::string cause) {
292292
resetWeakReferences();
293293
// Free the unused symbols.
294294
gcCallbacks_->freeSymbols(acceptor.markedSymbols_);
295-
if (idTracker_.isTrackingIDs()) {
296-
idTracker_.untrackUnmarkedSymbols(acceptor.markedSymbols_);
297-
}
298295
// By the end of the marking loop, all pointers left in pointers_ are dead.
299296
for (CellHeader *header : pointers_) {
300297
#ifndef HERMESVM_SANITIZE_HANDLES

0 commit comments

Comments
 (0)