From b6e779a5c508e251c7179583e07b1def6f09b8c9 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Fri, 20 Dec 2013 09:34:00 +0000 Subject: [PATCH] Bug 951722 - Add asserts that hash table postbarriers are working for new type objects r=terrence --- js/src/gc/Nursery.cpp | 14 ++++++++++++++ js/src/gc/StoreBuffer.cpp | 7 ------- js/src/jscompartment.h | 3 +++ js/src/jsinfer.cpp | 23 +++++++++++++++++++++++ 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp index 8517626d35ba..6f55e6aa3dda 100644 --- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -591,6 +591,19 @@ js::Nursery::MinorGCCallback(JSTracer *jstrc, void **thingp, JSGCTraceKind kind) *thingp = trc->nursery->moveToTenured(trc, static_cast(*thingp)); } +static void +CheckHashTablesAfterMovingGC(JSRuntime *rt) +{ +#if defined(DEBUG) + /* Check that internal hash tables no longer have any pointers into the nursery. */ + for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) { + c->checkNewTypeObjectTableAfterMovingGC(); + if (c->debugScopes) + c->debugScopes->checkHashTablesAfterMovingGC(rt); + } +#endif +} + void js::Nursery::collect(JSRuntime *rt, JS::gcreason::Reason reason, TypeObjectList *pretenureTypes) { @@ -612,6 +625,7 @@ js::Nursery::collect(JSRuntime *rt, JS::gcreason::Reason reason, TypeObjectList /* Move objects pointed to by roots from the nursery to the major heap. */ MinorCollectionTracer trc(rt, this); rt->gcStoreBuffer.mark(&trc); // This must happen first. + CheckHashTablesAfterMovingGC(rt); MarkRuntime(&trc); Debugger::markAll(&trc); for (CompartmentsIter comp(rt, SkipAtoms); !comp.done(); comp.next()) { diff --git a/js/src/gc/StoreBuffer.cpp b/js/src/gc/StoreBuffer.cpp index 1c4af15627d4..98dc19ec06f5 100644 --- a/js/src/gc/StoreBuffer.cpp +++ b/js/src/gc/StoreBuffer.cpp @@ -290,13 +290,6 @@ 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/jscompartment.h b/js/src/jscompartment.h index f44c2b09e390..d6a67fb25f13 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -247,6 +247,9 @@ struct JSCompartment js::types::TypeObjectWithNewScriptSet newTypeObjects; js::types::TypeObjectWithNewScriptSet lazyTypeObjects; void sweepNewTypeObjectTable(js::types::TypeObjectWithNewScriptSet &table); +#if defined(DEBUG) && defined(JSGC_GENERATIONAL) + void checkNewTypeObjectTableAfterMovingGC(); +#endif /* * Hash table of all manually call site-cloned functions from within diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index d9c0c0d0c177..685f8d49a7e4 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -3960,6 +3960,29 @@ ExclusiveContext::getNewType(const Class *clasp, TaggedProto proto, JSFunction * return type; } +#if defined(DEBUG) && defined(JSGC_GENERATIONAL) +void +JSCompartment::checkNewTypeObjectTableAfterMovingGC() +{ + /* + * Assert that the postbarriers have worked and that nothing is left in + * newTypeObjects that points into the nursery, and that the hash table + * entries are discoverable. + */ + JS::shadow::Runtime *rt = JS::shadow::Runtime::asShadowRuntime(runtimeFromMainThread()); + for (TypeObjectWithNewScriptSet::Enum e(newTypeObjects); !e.empty(); e.popFront()) { + TypeObjectWithNewScriptEntry entry = e.front(); + JS_ASSERT(!IsInsideNursery(rt, entry.newFunction)); + TaggedProto proto = entry.object->proto(); + JS_ASSERT_IF(proto.isObject(), !IsInsideNursery(rt, proto.toObject())); + TypeObjectWithNewScriptEntry::Lookup + lookup(entry.object->clasp(), proto, entry.newFunction); + TypeObjectWithNewScriptSet::Ptr ptr = newTypeObjects.lookup(lookup); + JS_ASSERT(ptr.found() && &*ptr == &e.front()); + } +} +#endif + TypeObject * ExclusiveContext::getLazyType(const Class *clasp, TaggedProto proto) {