Backed out changeset f3b470fb91a9 (orange) for bug 623297
authorBill McCloskey <wmccloskey@mozilla.com>
Mon, 24 Jan 2011 11:18:53 -0800
changeset 61231 30c2d7eaef7d9e2a3b3c0edd562643daad185c70
parent 61230 f3b470fb91a9741c87994f5d4b4d79dc17c06a8c
child 61232 df4c38d9144eb27d437bd457fdf88b81ab0c6834
push id18277
push usercleary@mozilla.com
push dateTue, 25 Jan 2011 03:52:51 +0000
treeherdermozilla-central@7ee91bd90e7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs623297
milestone2.0b10pre
backs outf3b470fb91a9741c87994f5d4b4d79dc17c06a8c
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
Backed out changeset f3b470fb91a9 (orange) for bug 623297
js/src/jit-test/tests/basic/bug623297.js
js/src/jscntxt.h
js/src/jscompartment.h
js/src/jstracer.cpp
deleted file mode 100644
--- a/js/src/jit-test/tests/basic/bug623297.js
+++ /dev/null
@@ -1,14 +0,0 @@
-gczeal(2);
-
-function foo() {
-        return /foo/;
-}
-
-function test() {
-    var obj = {};
-    for (var i = 0; i < 50; i++) {
-        obj["_" + i] = "J";
-    }
-}
-
-test();
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -810,16 +810,27 @@ public:
 
 private:
     StackSegment *curcs;
     JSStackFrame *curfp;
 };
 
 } /* namespace js */
 
+/*
+ * N.B. JS_ON_TRACE(cx) is true if JIT code is on the stack in the current
+ * thread, regardless of whether cx is the context in which that trace is
+ * executing.  cx must be a context on the current thread.
+ */
+#ifdef JS_TRACER
+# define JS_ON_TRACE(cx)            (cx->compartment && JS_TRACE_MONITOR(cx).ontrace())
+#else
+# define JS_ON_TRACE(cx)            false
+#endif
+
 #ifdef DEBUG
 # define FUNCTION_KIND_METER_LIST(_)                                          \
                         _(allfun), _(heavy), _(nofreeupvar), _(onlyfreevar),  \
                         _(flat), _(badfunarg),                                \
                         _(joinedsetmethod), _(joinedinitmethod),              \
                         _(joinedreplace), _(joinedsort), _(joinedmodulepat),  \
                         _(mreadbarrier), _(mwritebarrier), _(mwslotbarrier),  \
                         _(unjoined), _(indynamicscope)
@@ -843,28 +854,16 @@ struct JSPendingProxyOperation {
 };
 
 struct JSThreadData {
 #ifdef JS_THREADSAFE
     /* The request depth for this thread. */
     unsigned            requestDepth;
 #endif
 
-#ifdef JS_TRACER
-    /*
-     * During trace execution (or during trace recording or
-     * profiling), this field points to the compartment doing the
-     * execution on this thread. At other times, it is NULL.  If a
-     * thread tries to execute/record/profile one trace while another
-     * is still running, the initial one will abort. Therefore, we
-     * only need to track one tracerCompartment at a time.
-     */
-    JSCompartment       *tracerCompartment;
-#endif
-    
     /*
      * If non-zero, we were been asked to call the operation callback as soon
      * as possible.  If the thread has an active request, this contributes
      * towards rt->interruptCounter.
      */
     volatile int32      interruptFlags;
 
     /* Keeper of the contiguous stack used by all contexts in this thread. */
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -407,44 +407,19 @@ struct JS_FRIEND_API(JSCompartment) {
     js::MathCache *allocMathCache(JSContext *cx);
 
   public:
     js::MathCache *getMathCache(JSContext *cx) {
         return mathCache ? mathCache : allocMathCache(cx);
     }
 };
 
+#define JS_TRACE_MONITOR(cx)    (cx->compartment->traceMonitor)
 #define JS_SCRIPTS_TO_GC(cx)    (cx->compartment->scriptsToGC)
 
-#ifdef JS_TRACER
-static inline js::TraceMonitor &
-JS_TRACE_MONITOR(JSContext *cx)
-{
-    JSCompartment *c = JS_THREAD_DATA(cx)->tracerCompartment;
-    if (c == NULL)
-        c = cx->compartment;
-    return c->traceMonitor;
-}
-#endif
-
-/*
- * N.B. JS_ON_TRACE(cx) is true if JIT code is on the stack in the current
- * thread, regardless of whether cx is the context in which that trace is
- * executing.  cx must be a context on the current thread.
- */
-static inline bool
-JS_ON_TRACE(JSContext *cx)
-{
-#ifdef JS_TRACER
-    if (cx->compartment || JS_THREAD_DATA(cx)->tracerCompartment)
-        return JS_TRACE_MONITOR(cx).ontrace();
-#endif
-    return false;
-}
-
 namespace js {
 static inline MathCache *
 GetMathCache(JSContext *cx)
 {
     return cx->compartment->getMathCache(cx);
 }
 }
 
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -2306,18 +2306,16 @@ TraceRecorder::TraceRecorder(JSContext* 
     generatedSpecializedNative(),
     tempTypeMap(cx),
     w(&tempAlloc(), lirbuf)
 {
     JS_ASSERT(globalObj == cx->fp()->scopeChain().getGlobal());
     JS_ASSERT(globalObj->hasOwnShape());
     JS_ASSERT(cx->regs->pc == (jsbytecode*)fragment->ip);
 
-    JS_THREAD_DATA(cx)->tracerCompartment = cx->compartment;
-
 #ifdef DEBUG
     lirbuf->printer = new (tempAlloc()) LInsPrinter(tempAlloc(), TM_NUM_USED_ACCS);
 #endif
 
     /*
      * Reset the fragment state we care about in case we got a recycled
      * fragment.  This includes resetting any profiling data we might have
      * accumulated.
@@ -2457,18 +2455,16 @@ TraceRecorder::TraceRecorder(JSContext* 
     w.comment("end-setup");
 }
 
 TraceRecorder::~TraceRecorder()
 {
     /* Should already have been adjusted by callers before calling delete. */
     JS_ASSERT(traceMonitor->recorder != this);
 
-    JS_THREAD_DATA(cx)->tracerCompartment = NULL;
-    
     if (trashSelf)
         TrashTree(fragment->root);
 
     for (unsigned int i = 0; i < whichTreesToTrash.length(); i++)
         TrashTree(whichTreesToTrash[i]);
 
     /* Purge the tempAlloc used during recording. */
     tempAlloc().reset();
@@ -6321,16 +6317,19 @@ public:
     bool isOk() {
         return mOk;
     }
 };
 
 JS_REQUIRES_STACK TreeFragment*
 TraceRecorder::findNestedCompatiblePeer(TreeFragment* f)
 {
+    TraceMonitor* tm;
+
+    tm = &JS_TRACE_MONITOR(cx);
     unsigned int ngslots = tree->globalSlots->length();
 
     for (; f != NULL; f = f->peer) {
         if (!f->code())
             continue;
 
         debug_only_printf(LC_TMTracer, "checking nested types %p: ", (void*)f);
 
@@ -6485,18 +6484,16 @@ TracerState::TracerState(JSContext* cx, 
     nativeVp(NULL)
 {
     JS_ASSERT(tm == &JS_TRACE_MONITOR(cx));
     JS_ASSERT(!tm->tracecx);
     tm->tracecx = cx;
     prev = tm->tracerState;
     tm->tracerState = this;
 
-    JS_THREAD_DATA(cx)->tracerCompartment = cx->compartment;
-
     JS_ASSERT(eos == stackBase + MAX_NATIVE_STACK_SLOTS);
     JS_ASSERT(sp < eos);
 
     /*
      * inlineCallCount has already been incremented, if being invoked from
      * EnterFrame. It is okay to have a 0-frame restriction since the JIT
      * might not need any frames.
      */
@@ -6515,18 +6512,16 @@ TracerState::TracerState(JSContext* cx, 
 JS_ALWAYS_INLINE
 TracerState::~TracerState()
 {
     JS_ASSERT(!nativeVp);
 
     TraceMonitor *tm = &JS_TRACE_MONITOR(cx);
     tm->tracerState = prev;
     tm->tracecx = NULL;
-
-    JS_THREAD_DATA(cx)->tracerCompartment = NULL;
 }
 
 /* Call |f|, return the exit taken. */
 static JS_ALWAYS_INLINE VMSideExit*
 ExecuteTrace(JSContext* cx, Fragment* f, TracerState& state)
 {
     JS_ASSERT(!JS_TRACE_MONITOR(cx).bailExit);
 #ifdef JS_METHODJIT
@@ -16902,24 +16897,16 @@ LookupLoopProfile(JSContext *cx, jsbytec
     LoopProfileMap &table = *tm->loopProfiles;
     if (LoopProfileMap::Ptr p = table.lookup(pc)) {
         JS_ASSERT(p->value->top == pc);
         return p->value;
     } else
         return NULL;
 }
 
-static void
-StopProfiling(JSContext *cx)
-{
-    TraceMonitor* tm = &JS_TRACE_MONITOR(cx);
-    tm->profile = NULL;
-    JS_THREAD_DATA(cx)->tracerCompartment = NULL;
-}
-
 JS_REQUIRES_STACK TracePointAction
 MonitorTracePoint(JSContext *cx, uintN& inlineCallCount, bool* blacklist,
                   void** traceData, uintN *traceEpoch, uint32 *loopCounter, uint32 hits)
 {
     if (!cx->profilingEnabled)
         return RecordTracePoint(cx, inlineCallCount, blacklist, true);
 
     *blacklist = false;
@@ -16953,18 +16940,16 @@ MonitorTracePoint(JSContext *cx, uintN& 
         }
     }
 
     debug_only_printf(LC_TMProfiler, "Profiling at line %d\n",
                       js_FramePCToLineNumber(cx, cx->fp()));
 
     tm->profile = prof;
 
-    JS_THREAD_DATA(cx)->tracerCompartment = cx->compartment;
-
     if (!Interpret(cx, cx->fp(), inlineCallCount, JSINTERP_PROFILE))
         return TPA_Error;
 
     JS_ASSERT(!cx->isExceptionPending());
 
     /* Look it up again since a reset may have happened during Interpret. */
     prof = LookupLoopProfile(cx, pc);
     if (prof && prof->undecided) {
@@ -16989,43 +16974,43 @@ PCWithinLoop(JSStackFrame *fp, jsbytecod
 }
 
 LoopProfile::ProfileAction
 LoopProfile::profileOperation(JSContext* cx, JSOp op)
 {
     TraceMonitor* tm = &JS_TRACE_MONITOR(cx);
 
     if (profiled) {
-        StopProfiling(cx);
+        tm->profile = NULL;
         return ProfComplete;
     }
 
     jsbytecode *pc = cx->regs->pc;
     JSStackFrame *fp = cx->fp();
     JSScript *script = fp->script();
 
     if (!PCWithinLoop(fp, pc, *this)) {
         debug_only_printf(LC_TMProfiler, "Profiling complete (loop exit) at line %u\n",
                           js_FramePCToLineNumber(cx, cx->fp()));
         tm->profile->decide(cx);
-        StopProfiling(cx);
+        tm->profile = NULL;
         return ProfComplete;
     }
 
     while (loopStackDepth > 0 && !PCWithinLoop(fp, pc, loopStack[loopStackDepth-1])) {
         debug_only_print0(LC_TMProfiler, "Profiler: Exiting inner loop\n");
         loopStackDepth--;
     }
 
     if (op == JSOP_TRACE || op == JSOP_NOTRACE) {
         if (pc != top && (loopStackDepth == 0 || pc != loopStack[loopStackDepth-1].top)) {
             if (loopStackDepth == PROFILE_MAX_INNER_LOOPS) {
                 debug_only_print0(LC_TMProfiler, "Profiling complete (maxnest)\n");
                 tm->profile->decide(cx);
-                StopProfiling(cx);
+                tm->profile = NULL;
                 return ProfComplete;
             }
 
             debug_only_printf(LC_TMProfiler, "Profiler: Entering inner loop at line %d\n",
                               js_FramePCToLineNumber(cx, cx->fp()));
             loopStack[loopStackDepth++] = InnerLoop(fp, pc, GetLoopBottom(cx));
         }
     }
@@ -17099,17 +17084,17 @@ LoopProfile::profileOperation(JSContext*
     }
 
     if (op == JSOP_LOOKUPSWITCH)
         branchMultiplier *= GET_UINT16(pc + JUMP_OFFSET_LEN);
     
     if (numAllOps >= MAX_PROFILE_OPS) {
         debug_only_print0(LC_TMProfiler, "Profiling complete (maxops)\n");
         tm->profile->decide(cx);
-        StopProfiling(cx);
+        tm->profile = NULL;
         return ProfComplete;
     }
 
     /* These are the places where the interpreter skips over branches. */
     jsbytecode *testPC = cx->regs->pc;
     if (op == JSOP_EQ || op == JSOP_NE || op == JSOP_LT || op == JSOP_GT
         || op == JSOP_LE || op == JSOP_GE || op == JSOP_IN || op == JSOP_MOREITER)
     {
@@ -17361,17 +17346,17 @@ MonitorLoopEdge(JSContext* cx, uintN& in
 void
 AbortProfiling(JSContext *cx)
 {
     debug_only_print0(LC_TMProfiler, "Profiling complete (aborted)\n");
     TraceMonitor *tm = &JS_TRACE_MONITOR(cx);
     tm->profile->profiled = true;
     tm->profile->traceOK = false;
     tm->profile->execOK = false;
-    StopProfiling(cx);
+    tm->profile = NULL;
 }
 
 #else /* JS_METHODJIT */
 
 JS_REQUIRES_STACK MonitorResult
 MonitorLoopEdge(JSContext* cx, uintN& inlineCallCount)
 {
     return RecordLoopEdge(cx, inlineCallCount);