Bug 782818 - Temporarily enable compartment assertions (r=luke)
authorBill McCloskey <wmccloskey@mozilla.com>
Wed, 12 Dec 2012 12:59:51 -0800
changeset 115837 a94cbe677ea7420d0ae41841cab19c4f54971999
parent 115836 8c749372d5a7bbfdf12d2b8de327a7848822ed50
child 115838 1d6f209c9067a7f7e82e7c9d9178d596e4dc3b19
push id24028
push useremorley@mozilla.com
push dateThu, 13 Dec 2012 15:56:02 +0000
treeherderautoland@9db79b97abbb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs782818
milestone20.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 782818 - Temporarily enable compartment assertions (r=luke)
js/src/jscntxtinlines.h
js/src/jsinterp.cpp
js/src/jsinterpinlines.h
js/src/jsscope.cpp
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -179,34 +179,34 @@ class AutoPtr
     operator ConvertibleToBool() const { return (ConvertibleToBool) value; }
 
     const T *operator->() const { return value; }
     T *operator->() { return value; }
 
     T *get() { return value; }
 };
 
-#ifdef DEBUG
+#ifdef JS_CRASH_DIAGNOSTICS
 class CompartmentChecker
 {
     JSContext *context;
     JSCompartment *compartment;
 
   public:
     explicit CompartmentChecker(JSContext *cx)
       : context(cx), compartment(cx->compartment)
     {}
 
     /*
      * Set a breakpoint here (break js::CompartmentChecker::fail) to debug
      * compartment mismatches.
      */
     static void fail(JSCompartment *c1, JSCompartment *c2) {
         printf("*** Compartment mismatch %p vs. %p\n", (void *) c1, (void *) c2);
-        JS_NOT_REACHED("compartment mismatched");
+        MOZ_CRASH();
     }
 
     /* Note: should only be used when neither c1 nor c2 may be the default compartment. */
     static void check(JSCompartment *c1, JSCompartment *c2) {
         JS_ASSERT(c1 != c1->rt->atomsCompartment);
         JS_ASSERT(c2 != c2->rt->atomsCompartment);
         if (c1 != c2)
             fail(c1, c2);
@@ -277,74 +277,82 @@ class CompartmentChecker
             check(script->compartment());
     }
 
     void check(StackFrame *fp) {
         if (fp)
             check(fp->scopeChain());
     }
 };
-
-#endif
+#endif /* JS_CRASH_DIAGNOSTICS */
 
 /*
  * Don't perform these checks when called from a finalizer. The checking
  * depends on other objects not having been swept yet.
  */
 #define START_ASSERT_SAME_COMPARTMENT()                                       \
     if (cx->runtime->isHeapBusy())                                            \
         return;                                                               \
     CompartmentChecker c(cx)
 
 template <class T1> inline void
 assertSameCompartment(JSContext *cx, const T1 &t1)
 {
+#ifdef JS_CRASH_DIAGNOSTICS
+    START_ASSERT_SAME_COMPARTMENT();
+    c.check(t1);
+#endif
+}
+
+template <class T1> inline void
+assertSameCompartmentDebugOnly(JSContext *cx, const T1 &t1)
+{
 #ifdef DEBUG
     START_ASSERT_SAME_COMPARTMENT();
     c.check(t1);
 #endif
 }
 
 template <class T1, class T2> inline void
 assertSameCompartment(JSContext *cx, const T1 &t1, const T2 &t2)
 {
-#ifdef DEBUG
+#ifdef JS_CRASH_DIAGNOSTICS
     START_ASSERT_SAME_COMPARTMENT();
     c.check(t1);
     c.check(t2);
 #endif
 }
 
 template <class T1, class T2, class T3> inline void
 assertSameCompartment(JSContext *cx, const T1 &t1, const T2 &t2, const T3 &t3)
 {
-#ifdef DEBUG
+#ifdef JS_CRASH_DIAGNOSTICS
     START_ASSERT_SAME_COMPARTMENT();
     c.check(t1);
     c.check(t2);
     c.check(t3);
 #endif
 }
 
 template <class T1, class T2, class T3, class T4> inline void
 assertSameCompartment(JSContext *cx, const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4)
 {
-#ifdef DEBUG
+#ifdef JS_CRASH_DIAGNOSTICS
     START_ASSERT_SAME_COMPARTMENT();
     c.check(t1);
     c.check(t2);
     c.check(t3);
     c.check(t4);
 #endif
 }
 
 template <class T1, class T2, class T3, class T4, class T5> inline void
 assertSameCompartment(JSContext *cx, const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5)
 {
-#ifdef DEBUG
+#ifdef JS_CRASH_DIAGNOSTICS
     START_ASSERT_SAME_COMPARTMENT();
     c.check(t1);
     c.check(t2);
     c.check(t3);
     c.check(t4);
     c.check(t5);
 #endif
 }
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -882,26 +882,26 @@ TryNoteIter::settle()
          * depth exceeding the current one and this condition is what we use to
          * filter them out.
          */
         if (tn->stackDepth <= regs.stackDepth())
             break;
     }
 }
 
-#define PUSH_COPY(v)             do { *regs.sp++ = v; assertSameCompartment(cx, regs.sp[-1]); } while (0)
+#define PUSH_COPY(v)             do { *regs.sp++ = v; assertSameCompartmentDebugOnly(cx, regs.sp[-1]); } while (0)
 #define PUSH_COPY_SKIP_CHECK(v)  *regs.sp++ = v
 #define PUSH_NULL()              regs.sp++->setNull()
 #define PUSH_UNDEFINED()         regs.sp++->setUndefined()
 #define PUSH_BOOLEAN(b)          regs.sp++->setBoolean(b)
 #define PUSH_DOUBLE(d)           regs.sp++->setDouble(d)
 #define PUSH_INT32(i)            regs.sp++->setInt32(i)
-#define PUSH_STRING(s)           do { regs.sp++->setString(s); assertSameCompartment(cx, regs.sp[-1]); } while (0)
-#define PUSH_OBJECT(obj)         do { regs.sp++->setObject(obj); assertSameCompartment(cx, regs.sp[-1]); } while (0)
-#define PUSH_OBJECT_OR_NULL(obj) do { regs.sp++->setObjectOrNull(obj); assertSameCompartment(cx, regs.sp[-1]); } while (0)
+#define PUSH_STRING(s)           do { regs.sp++->setString(s); assertSameCompartmentDebugOnly(cx, regs.sp[-1]); } while (0)
+#define PUSH_OBJECT(obj)         do { regs.sp++->setObject(obj); assertSameCompartmentDebugOnly(cx, regs.sp[-1]); } while (0)
+#define PUSH_OBJECT_OR_NULL(obj) do { regs.sp++->setObjectOrNull(obj); assertSameCompartmentDebugOnly(cx, regs.sp[-1]); } while (0)
 #define PUSH_HOLE()              regs.sp++->setMagic(JS_ARRAY_HOLE)
 #define POP_COPY_TO(v)           v = *--regs.sp
 #define POP_RETURN_VALUE()       regs.fp()->setReturnValue(*--regs.sp)
 
 #define FETCH_OBJECT(cx, n, obj)                                              \
     JS_BEGIN_MACRO                                                            \
         HandleValue val = HandleValue::fromMarkedLocation(&regs.sp[n]);       \
         obj = ToObject(cx, (val));                                            \
@@ -2225,17 +2225,17 @@ BEGIN_CASE(JSOP_CALLPROP)
 
     RootedValue rval(cx);
     if (!GetPropertyOperation(cx, script, regs.pc, &lval, &rval))
         goto error;
 
     TypeScript::Monitor(cx, script, regs.pc, rval);
 
     regs.sp[-1] = rval;
-    assertSameCompartment(cx, regs.sp[-1]);
+    assertSameCompartmentDebugOnly(cx, regs.sp[-1]);
 }
 END_CASE(JSOP_GETPROP)
 
 BEGIN_CASE(JSOP_SETGNAME)
 BEGIN_CASE(JSOP_SETNAME)
 {
     RootedObject &scope = rootObject0;
     scope = &regs.sp[-2].toObject();
@@ -2727,17 +2727,17 @@ BEGIN_CASE(JSOP_CALLLOCAL)
 
     /*
      * Skip the same-compartment assertion if the local will be immediately
      * popped. We do not guarantee sync for dead locals when coming in from the
      * method JIT, and a GETLOCAL followed by POP is not considered to be
      * a use of the variable.
      */
     if (regs.pc[JSOP_GETLOCAL_LENGTH] != JSOP_POP)
-        assertSameCompartment(cx, regs.sp[-1]);
+        assertSameCompartmentDebugOnly(cx, regs.sp[-1]);
 }
 END_CASE(JSOP_GETLOCAL)
 
 BEGIN_CASE(JSOP_SETLOCAL)
 {
     unsigned i = GET_SLOTNO(regs.pc);
     regs.fp()->unaliasedLocal(i) = regs.sp[-1];
 }
@@ -2970,17 +2970,17 @@ BEGIN_CASE(JSOP_SETTER)
     scratch.setUndefined();
     if (!JSObject::defineGeneric(cx, obj, id, scratch, getter, setter, attrs))
         goto error;
 
     regs.sp += i;
     if (js_CodeSpec[op2].ndefs > js_CodeSpec[op2].nuses) {
         JS_ASSERT(js_CodeSpec[op2].ndefs == js_CodeSpec[op2].nuses + 1);
         regs.sp[-1] = rval;
-        assertSameCompartment(cx, regs.sp[-1]);
+        assertSameCompartmentDebugOnly(cx, regs.sp[-1]);
     }
     len = js_CodeSpec[op2].length;
     DO_NEXT_OP(len);
 }
 
 BEGIN_CASE(JSOP_HOLE)
     PUSH_HOLE();
 END_CASE(JSOP_HOLE)
--- a/js/src/jsinterpinlines.h
+++ b/js/src/jsinterpinlines.h
@@ -774,17 +774,17 @@ GetObjectElementOperation(JSContext *cx,
                     return false;
             } else {
                 if (!JSObject::getProperty(cx, obj, obj, name->asPropertyName(), res))
                     return false;
             }
         }
     }
 
-    assertSameCompartment(cx, res);
+    assertSameCompartmentDebugOnly(cx, res);
     return true;
 }
 
 static JS_ALWAYS_INLINE bool
 GetElementOperation(JSContext *cx, JSOp op, HandleValue lref, HandleValue rref,
                     MutableHandleValue res)
 {
     AssertCanGC();
--- a/js/src/jsscope.cpp
+++ b/js/src/jsscope.cpp
@@ -72,17 +72,17 @@ ShapeTable::init(JSRuntime *rt, Shape *l
     }
     return true;
 }
 
 /* static */ bool
 Shape::makeOwnBaseShape(JSContext *cx, HandleShape shape)
 {
     JS_ASSERT(!shape->base()->isOwned());
-    assertSameCompartment(cx, shape->compartment());
+    assertSameCompartmentDebugOnly(cx, shape->compartment());
 
     UnrootedBaseShape nbase = js_NewGCBaseShape(cx);
     if (!nbase)
         return false;
 
     new (nbase) BaseShape(StackBaseShape(shape));
     nbase->setOwned(shape->base()->toUnowned());