author | Bill McCloskey <wmccloskey@mozilla.com> |
Mon, 24 Jan 2011 11:18:53 -0800 | |
changeset 61231 | 30c2d7eaef7d9e2a3b3c0edd562643daad185c70 |
parent 61230 | f3b470fb91a9741c87994f5d4b4d79dc17c06a8c |
child 61232 | df4c38d9144eb27d437bd457fdf88b81ab0c6834 |
push id | 18277 |
push user | cleary@mozilla.com |
push date | Tue, 25 Jan 2011 03:52:51 +0000 |
treeherder | mozilla-central@7ee91bd90e7a [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 623297 |
milestone | 2.0b10pre |
backs out | f3b470fb91a9741c87994f5d4b4d79dc17c06a8c |
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
|
js/src/jit-test/tests/basic/bug623297.js | file | annotate | diff | comparison | revisions | |
js/src/jscntxt.h | file | annotate | diff | comparison | revisions | |
js/src/jscompartment.h | file | annotate | diff | comparison | revisions | |
js/src/jstracer.cpp | file | annotate | diff | comparison | revisions |
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);