Bug 1341752 - Assert that thing has correct runtime in js::TraceChildren. r=jonco
authorPaul Bone <pbone@mozilla.com>
Tue, 23 May 2017 01:25:11 +1000
changeset 408449 fac6b111e23b34d227f1862ba3188a578b709756
parent 408448 76e550bb72f7ec284b336f71c5f9674023c6e551
child 408450 3fe3c5c6e25186295221c5c55f13af0f04afed28
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1341752
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1341752 - Assert that thing has correct runtime in js::TraceChildren. r=jonco
js/src/gc/Marking.cpp
js/src/gc/Marking.h
js/src/gc/Tracer.cpp
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -152,33 +152,32 @@ IsThingPoisoned(T* thing)
 static bool
 IsMovingTracer(JSTracer *trc)
 {
     return trc->isCallbackTracer() &&
            trc->asCallbackTracer()->getTracerKind() == JS::CallbackTracer::TracerKind::Moving;
 }
 #endif
 
-template <typename T> bool ThingIsPermanentAtomOrWellKnownSymbol(T* thing) { return false; }
-template <> bool ThingIsPermanentAtomOrWellKnownSymbol<JSString>(JSString* str) {
+bool ThingIsPermanentAtomOrWellKnownSymbol(JSString* str) {
     return str->isPermanentAtom();
 }
-template <> bool ThingIsPermanentAtomOrWellKnownSymbol<JSFlatString>(JSFlatString* str) {
+bool ThingIsPermanentAtomOrWellKnownSymbol(JSFlatString* str) {
     return str->isPermanentAtom();
 }
-template <> bool ThingIsPermanentAtomOrWellKnownSymbol<JSLinearString>(JSLinearString* str) {
+bool ThingIsPermanentAtomOrWellKnownSymbol(JSLinearString* str) {
     return str->isPermanentAtom();
 }
-template <> bool ThingIsPermanentAtomOrWellKnownSymbol<JSAtom>(JSAtom* atom) {
+bool ThingIsPermanentAtomOrWellKnownSymbol(JSAtom* atom) {
     return atom->isPermanent();
 }
-template <> bool ThingIsPermanentAtomOrWellKnownSymbol<PropertyName>(PropertyName* name) {
+bool ThingIsPermanentAtomOrWellKnownSymbol(PropertyName* name) {
     return name->isPermanent();
 }
-template <> bool ThingIsPermanentAtomOrWellKnownSymbol<JS::Symbol>(JS::Symbol* sym) {
+bool ThingIsPermanentAtomOrWellKnownSymbol(JS::Symbol* sym) {
     return sym->isWellKnownSymbol();
 }
 
 template <typename T>
 static inline bool
 IsOwnedByOtherRuntime(JSRuntime* rt, T thing)
 {
     bool other = thing->runtimeFromAnyThread() != rt;
--- a/js/src/gc/Marking.h
+++ b/js/src/gc/Marking.h
@@ -497,9 +497,22 @@ void
 CheckTracedThing(JSTracer* trc, T* thing);
 
 template<typename T>
 void
 CheckTracedThing(JSTracer* trc, T thing);
 
 } /* namespace js */
 
+namespace JS {
+class Symbol;
+}
+
+// Exported for Tracer.cpp
+inline bool ThingIsPermanentAtomOrWellKnownSymbol(js::gc::Cell* thing) { return false; }
+bool ThingIsPermanentAtomOrWellKnownSymbol(JSString*);
+bool ThingIsPermanentAtomOrWellKnownSymbol(JSFlatString*);
+bool ThingIsPermanentAtomOrWellKnownSymbol(JSLinearString*);
+bool ThingIsPermanentAtomOrWellKnownSymbol(JSAtom*);
+bool ThingIsPermanentAtomOrWellKnownSymbol(js::PropertyName*);
+bool ThingIsPermanentAtomOrWellKnownSymbol(JS::Symbol*);
+
 #endif /* gc_Marking_h */
--- a/js/src/gc/Tracer.cpp
+++ b/js/src/gc/Tracer.cpp
@@ -108,18 +108,23 @@ JS::CallbackTracer::getTracingEdgeName(c
 JS_PUBLIC_API(void)
 JS::TraceChildren(JSTracer* trc, GCCellPtr thing)
 {
     js::TraceChildren(trc, thing.asCell(), thing.kind());
 }
 
 struct TraceChildrenFunctor {
     template <typename T>
-    void operator()(JSTracer* trc, void* thing) {
-        static_cast<T*>(thing)->traceChildren(trc);
+    void operator()(JSTracer* trc, void* thingArg) {
+        T* thing = static_cast<T*>(thingArg);
+        MOZ_ASSERT_IF(thing->runtimeFromAnyThread() != trc->runtime(),
+            ThingIsPermanentAtomOrWellKnownSymbol(thing) ||
+            thing->zoneFromAnyThread()->isSelfHostingZone());
+
+        thing->traceChildren(trc);
     }
 };
 
 void
 js::TraceChildren(JSTracer* trc, void* thing, JS::TraceKind kind)
 {
     MOZ_ASSERT(thing);
     TraceChildrenFunctor f;