Back out 305a3a0e26fd (bug 680428).
authorJason Orendorff <jorendorff@mozilla.com>
Tue, 23 Aug 2011 15:36:48 -0500
changeset 77085 dff3ecc0451a911ea5f96c2cd8b8a9cdcc28584b
parent 77084 f7697e32bbf5908d821cb528a66835beb5d8e7c6
child 77086 6e7449c449ba336e49e2167d8edf3c28169c9962
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs680428
milestone9.0a1
backs out305a3a0e26fdeb31669d76ee901d84073aadeb00
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
Back out 305a3a0e26fd (bug 680428).
js/src/jit-test/tests/debug/onEnterFrame-04.js
js/src/jit-test/tests/debug/onEnterFrame-05.js
js/src/jit-test/tests/debug/onEnterFrame-06.js
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jscompartment.cpp
js/src/jsdbgapi.cpp
deleted file mode 100644
--- a/js/src/jit-test/tests/debug/onEnterFrame-04.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// We detect and stop the runaway recursion caused by making onEnterFrame a wrapper of a debuggee function.
-
-var g = newGlobal('new-compartment');
-g.n = 0;
-g.eval("function f(frame) { n++; return 42; }");
-print('ok');
-var dbg = Debugger(g);
-dbg.onEnterFrame = g.f;
-
-// Since enterFrame cannot throw, the InternalError is reported and execution proceeds.
-var x = g.f();
-assertEq(x, 42);
-assertEq(g.n > 20, true);
-
-// When an error is reported, the shell usually exits with a nonzero exit
-// code. If we get here, the test passed, so override that behavior.
-quit(0);
--- a/js/src/jit-test/tests/debug/onEnterFrame-05.js
+++ b/js/src/jit-test/tests/debug/onEnterFrame-05.js
@@ -1,15 +1,17 @@
-// The tracejit does not prevent onEnterFrame from being called.
+// We detect and stop the runaway recursion caused by making onEnterFrame a wrapper of a debuggee function.
 
 var g = newGlobal('new-compartment');
-g.eval("function f() { return 1; }\n");
-var N = g.N = RUNLOOP + 2;
-g.eval("function h() {\n" +
-       "    for (var i = 0; i < N; i += f()) {}\n" +
-       "}");
-g.h(); // record loop
+g.n = 0;
+g.eval("function f(frame) { n++; return 42; }");
+print('ok');
+var dbg = Debugger(g);
+dbg.onEnterFrame = g.f;
 
-var dbg = Debugger(g);
-var log = '';
-dbg.onEnterFrame = function (frame) { log += frame.callee.name; };
-g.h();
-assertEq(log, 'h' + Array(N + 1).join('f'));
+// Since enterFrame cannot throw, the InternalError is reported and execution proceeds.
+var x = g.f();
+assertEq(x, 42);
+assertEq(g.n > 20, true);
+
+// When an error is reported, the shell usually exits with a nonzero exit
+// code. If we get here, the test passed, so override that behavior.
+quit(0);
deleted file mode 100644
--- a/js/src/jit-test/tests/debug/onEnterFrame-06.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// The tracejit does not prevent onEnterFrame from being called after entering
-// a debuggee compartment from a non-debuggee compartment.
-
-var g1 = newGlobal('new-compartment');
-var g2 = newGlobal('new-compartment');
-var dbg = Debugger(g1, g2);
-dbg.removeDebuggee(g2); // turn off debug mode in g2
-
-g1.eval("function f() { return 1; }\n");
-var N = g1.N = RUNLOOP + 2;
-g1.eval("function h() {\n" +
-       "    for (var i = 0; i < N; i += f()) {}\n" +
-       "}");
-g1.h(); // record loop
-
-var log = '';
-dbg.onEnterFrame = function (frame) { log += frame.callee.name; };
-g1.h();
-assertEq(log, 'h' + Array(N + 1).join('f'));
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -565,17 +565,17 @@ js_DestroyContext(JSContext *cx, JSDestr
 JSContext *
 js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp)
 {
     JSContext *cx = *iterp;
 
     Maybe<AutoLockGC> lockIf;
     if (unlocked)
         lockIf.construct(rt);
-    cx = JSContext::fromLinkField(cx ? cx->link.next : rt->contextList.next);
+    cx = js_ContextFromLinkField(cx ? cx->link.next : rt->contextList.next);
     if (&cx->link == &rt->contextList)
         cx = NULL;
     *iterp = cx;
     return cx;
 }
 
 JS_FRIEND_API(JSContext *)
 js_NextActiveContext(JSRuntime *rt, JSContext *cx)
@@ -1382,19 +1382,19 @@ JSContext::resetCompartment()
          * can only fail due to bugs in the engine or embedding.)
          */
         OBJ_TO_INNER_OBJECT(this, scopeobj);
         if (!scopeobj)
             goto error;
     }
 
     compartment = scopeobj->compartment();
+
     if (isExceptionPending())
         wrapPendingException();
-    updateJITEnabled();
     return;
 
 error:
 
     /*
      * If we try to use the context without a selected compartment,
      * we will crash.
      */
@@ -1575,18 +1575,16 @@ IsJITBrokenHere()
 #endif
 
 void
 JSContext::updateJITEnabled()
 {
 #ifdef JS_TRACER
     traceJitEnabled = ((runOptions & JSOPTION_JIT) &&
                        !IsJITBrokenHere() &&
-                       compartment &&
-                       !compartment->debugMode() &&
                        (debugHooks == &js_NullDebugHooks ||
                         (debugHooks == &runtime->globalDebugHooks &&
                          !runtime->debuggerInhibitsJIT())));
 #endif
 #ifdef JS_METHODJIT
     methodJitEnabled = (runOptions & JSOPTION_METHODJIT) &&
                        !IsJITBrokenHere()
 # if defined JS_CPU_X86 || defined JS_CPU_X64
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -1139,16 +1139,19 @@ struct JSContext
 
     void setThread(JSThread *thread);
     static const size_t threadOffset() { return offsetof(JSContext, thread_); }
 
     unsigned            outstandingRequests;/* number of JS_BeginRequest calls
                                                without the corresponding
                                                JS_EndRequest. */
     JSCList             threadLinks;        /* JSThread contextList linkage */
+
+#define CX_FROM_THREAD_LINKS(tl) \
+    ((JSContext *)((char *)(tl) - offsetof(JSContext, threadLinks)))
 #endif
 
     /* Stack of thread-stack-allocated GC roots. */
     js::AutoGCRooter   *autoGCRooters;
 
     /* Debug hooks associated with the current context. */
     const JSDebugHooks  *debugHooks;
 
@@ -1317,28 +1320,16 @@ struct JSContext
 #endif
 
     /*
      * See JS_SetTrustedPrincipals in jsapi.h.
      * Note: !cx->compartment is treated as trusted.
      */
     bool runningWithTrustedPrincipals() const;
 
-    static inline JSContext *fromLinkField(JSCList *link) {
-        JS_ASSERT(link);
-        return reinterpret_cast<JSContext *>(uintptr_t(link) - offsetof(JSContext, link));
-    }
-
-#ifdef JS_THREADSAFE
-    static inline JSContext *fromThreadLinks(JSCList *link) {
-        JS_ASSERT(link);
-        return reinterpret_cast<JSContext *>(uintptr_t(link) - offsetof(JSContext, threadLinks));
-    }
-#endif
-
   private:
     /*
      * The allocation code calls the function to indicate either OOM failure
      * when p is null or that a memory pressure counter has reached some
      * threshold when p is not null. The function takes the pointer and not
      * a boolean flag to minimize the amount of code in its inlined callers.
      */
     JS_FRIEND_API(void) checkMallocGCPressure(void *p);
@@ -2141,58 +2132,35 @@ class ThreadDataIter
     ThreadData *threadData() const {
         JS_ASSERT(!done);
         return &runtime->threadData;
     }
 };
 
 #endif  /* !JS_THREADSAFE */
 
-/*
- * Enumerate all contexts in a runtime that are in the same thread as a given
- * context.
- */
-class ThreadContextRange {
-    JSCList *begin;
-    JSCList *end;
-
-public:
-    explicit ThreadContextRange(JSContext *cx) {
-#ifdef JS_THREADSAFE
-        end = &cx->thread()->contextList;
-#else
-        end = &cx->runtime->contextList;
-#endif
-        begin = end->next;
-    }
-
-    bool empty() const { return begin == end; }
-    void popFront() { JS_ASSERT(!empty()); begin = begin->next; }
-
-    JSContext *front() const {
-#ifdef JS_THREADSAFE
-        return JSContext::fromThreadLinks(begin);
-#else
-        return JSContext::fromLinkField(begin);
-#endif
-    }
-};
-
 } /* namespace js */
 
 /*
  * Create and destroy functions for JSContext, which is manually allocated
  * and exclusively owned.
  */
 extern JSContext *
 js_NewContext(JSRuntime *rt, size_t stackChunkSize);
 
 extern void
 js_DestroyContext(JSContext *cx, JSDestroyContextMode mode);
 
+static JS_INLINE JSContext *
+js_ContextFromLinkField(JSCList *link)
+{
+    JS_ASSERT(link);
+    return reinterpret_cast<JSContext *>(uintptr_t(link) - offsetof(JSContext, link));
+}
+
 /*
  * If unlocked, acquire and release rt->gcLock around *iterp update; otherwise
  * the caller must be holding rt->gcLock.
  */
 extern JSContext *
 js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp);
 
 /*
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -662,30 +662,24 @@ JSCompartment::setDebugModeFromC(JSConte
         if (b && onStack) {
             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_DEBUG_NOT_IDLE);
             return false;
         }
     }
 
     debugModeBits = (debugModeBits & ~uintN(DebugFromC)) | (b ? DebugFromC : 0);
     JS_ASSERT(debugMode() == enabledAfter);
-    if (enabledBefore != enabledAfter)
+    if (enabledBefore != enabledAfter && !onStack)
         updateForDebugMode(cx);
     return true;
 }
 
 void
 JSCompartment::updateForDebugMode(JSContext *cx)
 {
-    for (ThreadContextRange r(cx); !r.empty(); r.popFront()) {
-        JSContext *cx = r.front();
-        if (cx->compartment == this) 
-            cx->updateJITEnabled();
-    }
-
 #ifdef JS_METHODJIT
     bool enabled = debugMode();
 
     if (enabled) {
         JS_ASSERT(!hasScriptsOnStack(cx));
     } else if (hasScriptsOnStack(cx)) {
         hasDebugModeCodeToDrop = true;
         return;
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -284,21 +284,21 @@ JS_ClearAllTrapsForCompartment(JSContext
 
 #ifdef JS_TRACER
 static void
 JITInhibitingHookChange(JSRuntime *rt, bool wasInhibited)
 {
     if (wasInhibited) {
         if (!rt->debuggerInhibitsJIT()) {
             for (JSCList *cl = rt->contextList.next; cl != &rt->contextList; cl = cl->next)
-                JSContext::fromLinkField(cl)->updateJITEnabled();
+                js_ContextFromLinkField(cl)->updateJITEnabled();
         }
     } else if (rt->debuggerInhibitsJIT()) {
         for (JSCList *cl = rt->contextList.next; cl != &rt->contextList; cl = cl->next)
-            JSContext::fromLinkField(cl)->traceJitEnabled = false;
+            js_ContextFromLinkField(cl)->traceJitEnabled = false;
     }
 }
 #endif
 
 JS_PUBLIC_API(JSBool)
 JS_SetInterrupt(JSRuntime *rt, JSInterruptHook hook, void *closure)
 {
 #ifdef JS_TRACER