From 66d25c1b3e902999f3ca10a316818a0c4d3f85ff Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Thu, 19 Dec 2013 10:46:41 +0000 Subject: [PATCH] Bug 951722 - Add asserts that hash table postbarriers are working for debug scopes r=terrence --- js/src/gc/StoreBuffer.cpp | 7 +++++++ js/src/vm/ScopeObject.cpp | 27 +++++++++++++++++++++++++++ js/src/vm/ScopeObject.h | 4 ++++ 3 files changed, 38 insertions(+) diff --git a/js/src/gc/StoreBuffer.cpp b/js/src/gc/StoreBuffer.cpp index 67a227ee823..090c815c4a2 100644 --- a/js/src/gc/StoreBuffer.cpp +++ b/js/src/gc/StoreBuffer.cpp @@ -290,6 +290,13 @@ StoreBuffer::mark(JSTracer *trc) bufferRelocVal.mark(this, trc); bufferRelocCell.mark(this, trc); bufferGeneric.mark(this, trc); + +#if defined(DEBUG) + for (CompartmentsIter c(runtime_, SkipAtoms); !c.done(); c.next()) { + if (c->debugScopes) + c->debugScopes->checkHashTablesAfterMovingGC(runtime_); + } +#endif } void diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index 18dfcf6e6a7..9a93cea655e 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -1693,6 +1693,33 @@ DebugScopes::sweep(JSRuntime *rt) } } +#if defined(DEBUG) && defined(JSGC_GENERATIONAL) +void +DebugScopes::checkHashTablesAfterMovingGC(JSRuntime *runtime) +{ + /* + * This is called at the end of StoreBuffer::mark() to check that our + * postbarriers have worked and that no hashtable keys (or values) are left + * pointing into the nursery. + */ + JS::shadow::Runtime *rt = JS::shadow::Runtime::asShadowRuntime(runtime); + for (ObjectWeakMap::Range r = proxiedScopes.all(); !r.empty(); r.popFront()) { + JS_ASSERT(!IsInsideNursery(rt, r.front().key().get())); + JS_ASSERT(!IsInsideNursery(rt, r.front().value().get())); + } + for (MissingScopeMap::Range r = missingScopes.all(); !r.empty(); r.popFront()) { + JS_ASSERT(!IsInsideNursery(rt, r.front().key().cur())); + JS_ASSERT(!IsInsideNursery(rt, r.front().key().block())); + JS_ASSERT(!IsInsideNursery(rt, r.front().value().get())); + } + for (LiveScopeMap::Range r = liveScopes.all(); !r.empty(); r.popFront()) { + JS_ASSERT(!IsInsideNursery(rt, r.front().key())); + JS_ASSERT(!IsInsideNursery(rt, r.front().value().cur_.get())); + JS_ASSERT(!IsInsideNursery(rt, r.front().value().block_.get())); + } +} +#endif + /* * Unfortunately, GetDebugScopeForFrame needs to work even outside debug mode * (in particular, JS_GetFrameScopeChain does not require debug mode). Since diff --git a/js/src/vm/ScopeObject.h b/js/src/vm/ScopeObject.h index e6a5f4c4f68..7228735aeaf 100644 --- a/js/src/vm/ScopeObject.h +++ b/js/src/vm/ScopeObject.h @@ -618,6 +618,7 @@ class ScopeIterKey class ScopeIterVal { friend class ScopeIter; + friend class DebugScopes; AbstractFramePtr frame_; RelocatablePtr cur_; @@ -746,6 +747,9 @@ class DebugScopes public: void mark(JSTracer *trc); void sweep(JSRuntime *rt); +#if defined(DEBUG) && defined(JSGC_GENERATIONAL) + void checkHashTablesAfterMovingGC(JSRuntime *rt); +#endif static DebugScopeObject *hasDebugScope(JSContext *cx, ScopeObject &scope); static bool addDebugScope(JSContext *cx, ScopeObject &scope, DebugScopeObject &debugScope);