author | Jason Orendorff <jorendorff@mozilla.com> |
Tue, 23 Aug 2011 15:36:48 -0500 | |
changeset 77085 | dff3ecc0451a911ea5f96c2cd8b8a9cdcc28584b |
parent 77084 | f7697e32bbf5908d821cb528a66835beb5d8e7c6 |
child 77086 | 6e7449c449ba336e49e2167d8edf3c28169c9962 |
push id | 78 |
push user | clegnitto@mozilla.com |
push date | Fri, 16 Dec 2011 17:32:24 +0000 |
treeherder | mozilla-release@79d24e644fdd [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 680428 |
milestone | 9.0a1 |
backs out | 305a3a0e26fdeb31669d76ee901d84073aadeb00 |
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/debug/onEnterFrame-04.js | file | annotate | diff | comparison | revisions | |
js/src/jit-test/tests/debug/onEnterFrame-05.js | file | annotate | diff | comparison | revisions | |
js/src/jit-test/tests/debug/onEnterFrame-06.js | file | annotate | diff | comparison | revisions | |
js/src/jscntxt.cpp | file | annotate | diff | comparison | revisions | |
js/src/jscntxt.h | file | annotate | diff | comparison | revisions | |
js/src/jscompartment.cpp | file | annotate | diff | comparison | revisions | |
js/src/jsdbgapi.cpp | file | annotate | diff | comparison | revisions |
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