Bug 1191482 - Improve WeakCache sweep code and add assertions r=terence

This commit is contained in:
Jon Coppeard 2015-08-11 12:41:14 +01:00
parent 5e60a8d34d
commit b17cbec1ce
3 changed files with 37 additions and 28 deletions

View File

@ -466,12 +466,8 @@ class JitCompartment
return nullptr;
}
bool putStubCode(uint32_t key, Handle<JitCode*> stubCode) {
// Make sure to do a lookupForAdd(key) and then insert into that slot, because
// that way if stubCode gets moved due to a GC caused by lookupForAdd, then
// we still write the correct pointer.
MOZ_ASSERT(!stubCodes_->has(key));
ICStubCodeMap::AddPtr p = stubCodes_->lookupForAdd(key);
return stubCodes_->add(p, key, stubCode.get());
MOZ_ASSERT(stubCode);
return stubCodes_->putNew(key, stubCode.get());
}
void initBaselineCallReturnAddr(void* addr, bool constructing) {
MOZ_ASSERT(baselineCallReturnAddrs_[constructing] == nullptr);

View File

@ -1229,6 +1229,13 @@ CheckGCThingAfterMovingGC(T* t)
}
}
template <typename T>
inline void
CheckGCThingAfterMovingGC(const ReadBarriered<T*>& t)
{
CheckGCThingAfterMovingGC(t.get());
}
struct CheckValueAfterMovingGCFunctor : public VoidDefaultAdaptor<Value> {
template <typename T> void operator()(T* t) { CheckGCThingAfterMovingGC(t); }
};

View File

@ -38,32 +38,31 @@ class WeakCache : public HashMap<Key, Value, HashPolicy, AllocPolicy> {
void sweep(FreeOp* fop) {
// Remove all entries whose keys/values remain unmarked.
for (Enum e(*this); !e.empty(); e.popFront()) {
// Checking IsMarked() may update the location of the Key (or Value).
// IsAboutToBeFinalized() may update the location of the Key (or Value).
// Pass in a stack local, then manually update the backing heap store.
Key k(e.front().key);
bool isKeyDying = gc::IsAboutToBeFinalized(&k);
if (isKeyDying || gc::IsAboutToBeFinalized(e.front().value)) {
Key key(e.front().key);
MOZ_ASSERT(key);
MOZ_ASSERT(e.front().value());
if (gc::IsAboutToBeFinalized(&key) || gc::IsAboutToBeFinalized(e.front().value))
e.removeFront();
} else {
// Potentially update the location of the Key.
// The Value had its heap addresses correctly passed to IsMarked(),
// and therefore has already been updated if necessary.
// e.rekeyFront(k);
}
else if (key != e.front().key)
e.rekeyFront(key);
}
#if DEBUG
#ifdef DEBUG
// Once we've swept, all remaining edges should stay within the
// known-live part of the graph.
for (Range r = Base::all(); !r.empty(); r.popFront()) {
Key k(r.front().key);
MOZ_ASSERT(!gc::IsAboutToBeFinalized(&k));
MOZ_ASSERT(!gc::IsAboutToBeFinalized(r.front().value));
// Assert that IsMarked() did not perform relocation.
MOZ_ASSERT(k == r.front().key);
Key key(r.front().key);
Value value(r.front().value);
MOZ_ASSERT(key);
MOZ_ASSERT(value);
MOZ_ASSERT(!gc::IsAboutToBeFinalized(&key));
MOZ_ASSERT(!gc::IsAboutToBeFinalized(&value));
CheckGCThingAfterMovingGC(key);
CheckGCThingAfterMovingGC(value);
auto ptr = this->lookup(key);
MOZ_ASSERT(ptr.found() && &*ptr == &r.front());
}
#endif
}
@ -89,15 +88,22 @@ class WeakValueCache : public HashMap<Key, Value, HashPolicy, AllocPolicy>
void sweep(FreeOp* fop) {
// Remove all entries whose values remain unmarked.
for (Enum e(*this); !e.empty(); e.popFront()) {
MOZ_ASSERT(e.front().value());
if (gc::IsAboutToBeFinalized(&e.front().value()))
e.removeFront();
}
#if DEBUG
#ifdef DEBUG
// Once we've swept, all remaining edges should stay within the
// known-live part of the graph.
for (Range r = Base::all(); !r.empty(); r.popFront())
MOZ_ASSERT(!gc::IsAboutToBeFinalized(&r.front().value()));
for (Range r = Base::all(); !r.empty(); r.popFront()) {
Value value(r.front().value());
MOZ_ASSERT(value);
MOZ_ASSERT(!gc::IsAboutToBeFinalized(&value));
CheckGCThingAfterMovingGC(value);
auto ptr = this->lookup(r.front().key());
MOZ_ASSERT(ptr.found() && &*ptr == &r.front());
}
#endif
}
};