From bac3c4eebc41f1f685c18569c78aba676adb91a4 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 22 Nov 2011 17:41:43 -0500 Subject: [PATCH] Remove LeaveTrace and related structures (bug 698201 part 5, r=luke). --- js/src/Makefile.in | 2 +- js/src/config/autoconf.mk.in | 2 - js/src/configure.in | 2 - js/src/jit-test/jit_test.py | 6 +- js/src/jsapi.cpp | 12 - js/src/jsapi.h | 2 +- js/src/jsarray.cpp | 1 - js/src/jscntxt.cpp | 13 - js/src/jscntxt.h | 44 +--- js/src/jscntxtinlines.h | 18 -- js/src/jscompartment.h | 250 ------------------ js/src/jsdate.cpp | 1 - js/src/jsdbgapi.cpp | 453 -------------------------------- js/src/jsdbgapi.h | 7 - js/src/jsfun.cpp | 10 - js/src/jsgc.cpp | 16 +- js/src/jsinterp.cpp | 33 +-- js/src/jsiter.cpp | 3 - js/src/jsobj.cpp | 35 +-- js/src/jsobj.h | 11 - js/src/json.cpp | 2 - js/src/jsopcode.cpp | 2 - js/src/jsprvtd.h | 2 - js/src/jsscope.cpp | 1 - js/src/jsscopeinlines.h | 1 - js/src/jsutil.h | 6 - js/src/jswrapper.cpp | 3 - js/src/jsxml.cpp | 2 - js/src/methodjit/MonoIC.cpp | 2 - js/src/shell/js.cpp | 11 +- js/src/tests/browser.js | 8 - js/src/tests/shell.js | 9 - js/src/tests/user.js | 2 - js/src/vm/ArgumentsObject-inl.h | 19 -- js/src/vm/ArgumentsObject.h | 9 +- js/src/vm/RegExpObject-inl.h | 2 +- js/src/vm/Stack-inl.h | 11 - js/src/vm/Stack.cpp | 3 - js/src/vm/String-inl.h | 10 - 39 files changed, 16 insertions(+), 1010 deletions(-) diff --git a/js/src/Makefile.in b/js/src/Makefile.in index 4639ad2cc9e8..253c62fc78e9 100644 --- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -643,7 +643,7 @@ ifneq ($(OS_ARCH),WINNT) # FIXME: this should be made work on Windows too. #check:: check-malloc-function-usage FIXME: disable on JM until closer to merge time. endif -JITFLAGS = ,m,j,mj,mjp,am,amj,amjp,amd,n,mn,jn,mjn,mjpn,amn,amjn,amjpn,amdn +JITFLAGS = ,m,am,amd,n,mn,amn,amdn,mdn check-jit-test:: $(wildcard $(RUN_TEST_PROGRAM)) $(PYTHON) -u $(srcdir)/jit-test/jit_test.py \ --valgrind --no-slow --no-progress --tinderbox --jitflags=$(JITFLAGS) $(DIST)/bin/js$(BIN_SUFFIX) diff --git a/js/src/config/autoconf.mk.in b/js/src/config/autoconf.mk.in index 7c9114cb5868..80a8bc33de3e 100644 --- a/js/src/config/autoconf.mk.in +++ b/js/src/config/autoconf.mk.in @@ -331,9 +331,7 @@ HAVE_DTRACE= @HAVE_DTRACE@ VISIBILITY_FLAGS = @VISIBILITY_FLAGS@ WRAP_SYSTEM_INCLUDES = @WRAP_SYSTEM_INCLUDES@ -ENABLE_TRACEJIT = @ENABLE_TRACEJIT@ ENABLE_METHODJIT = @ENABLE_METHODJIT@ -NANOJIT_ARCH = @NANOJIT_ARCH@ HAVE_ARM_SIMD= @HAVE_ARM_SIMD@ JS_SHARED_LIBRARY = @JS_SHARED_LIBRARY@ diff --git a/js/src/configure.in b/js/src/configure.in index ecff9f88c514..cfefdda9497f 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -2867,8 +2867,6 @@ if test "$ENABLE_METHODJIT_SPEW"; then AC_DEFINE(JS_METHODJIT_SPEW) fi -AC_SUBST(ENABLE_TRACEJIT) - if test -z "$SKIP_COMPILER_CHECKS"; then dnl Checks for typedefs, structures, and compiler characteristics. dnl ======================================================== diff --git a/js/src/jit-test/jit_test.py b/js/src/jit-test/jit_test.py index 5b7c13e0076b..991a8a8d679c 100755 --- a/js/src/jit-test/jit_test.py +++ b/js/src/jit-test/jit_test.py @@ -356,7 +356,7 @@ def parse_jitflags(): for flags in OPTIONS.jitflags.split(',') ] for flags in jitflags: for flag in flags: - if flag not in ('-j', '-m', '-a', '-p', '-d', '-n'): + if flag not in ('-m', '-a', '-p', '-d', '-n'): print('Invalid jit flag: "%s"'%flag) sys.exit(1) return jitflags @@ -420,8 +420,8 @@ def main(argv): help='Enable the |valgrind| flag, if valgrind is in $PATH.') op.add_option('--valgrind-all', dest='valgrind_all', action='store_true', help='Run all tests with valgrind, if valgrind is in $PATH.') - op.add_option('--jitflags', dest='jitflags', default='mjp', - help='Example: --jitflags=j,mj,mjp to run each test with -j, -m -j, -m -j -p [default=%default]') + op.add_option('--jitflags', dest='jitflags', default='m,mn', + help='Example: --jitflags=m,mn to run each test with -m, -m -n [default=%default]') op.add_option('--avoid-stdio', dest='avoid_stdio', action='store_true', help='Use js-shell file indirection instead of piping stdio.') op.add_option('--write-failure-output', dest='write_failure_output', action='store_true', diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 87651785296e..857f5a23538b 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -908,10 +908,6 @@ JS_ShutDown(void) { Probes::shutdown(); -#ifdef MOZ_TRACEVIS - StopTraceVis(); -#endif - #ifdef JS_THREADSAFE js_CleanupLocks(); #endif @@ -974,8 +970,6 @@ StopRequest(JSContext *cx) if (t->data.requestDepth != 1) { t->data.requestDepth--; } else { - LeaveTrace(cx); /* for GC safety */ - t->data.conservativeGC.updateForRequestEnd(t->suspendCount); /* Lock before clearing to interlock with ClaimScope, in jslock.c. */ @@ -2738,8 +2732,6 @@ JS_CompartmentGC(JSContext *cx, JSCompartment *comp) /* We cannot GC the atoms compartment alone; use a full GC instead. */ JS_ASSERT(comp != cx->runtime->atomsCompartment); - LeaveTrace(cx); - js::gc::VerifyBarriers(cx, true); js_GC(cx, comp, GC_NORMAL, gcstats::PUBLIC_API); } @@ -2753,8 +2745,6 @@ JS_GC(JSContext *cx) JS_PUBLIC_API(void) JS_MaybeGC(JSContext *cx) { - LeaveTrace(cx); - MaybeGC(cx); } @@ -5308,7 +5298,6 @@ JS_PUBLIC_API(JSBool) JS_SaveFrameChain(JSContext *cx) { CHECK_REQUEST(cx); - LeaveTrace(cx); return cx->stack.saveFrameChain(); } @@ -5316,7 +5305,6 @@ JS_PUBLIC_API(void) JS_RestoreFrameChain(JSContext *cx) { CHECK_REQUEST(cx); - JS_ASSERT_NOT_ON_TRACE(cx); cx->stack.restoreFrameChain(); } diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 4c0ab2311e40..7694c4a6c78a 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -2157,7 +2157,7 @@ JS_StringToVersion(const char *string); of the input string */ /* JS_BIT(10) is currently unused. */ -#define JSOPTION_JIT JS_BIT(11) /* Enable JIT compilation. */ +#define JSOPTION_JIT JS_BIT(11) /* Deprecated; does nothing */ #define JSOPTION_NO_SCRIPT_RVAL JS_BIT(12) /* A promise to the compiler that a null rval out-param diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp index c54238366bbc..d066fa1cd570 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -1697,7 +1697,6 @@ array_toString(JSContext *cx, uintN argc, Value *vp) return true; } - LeaveTrace(cx); InvokeArgsGuard ag; if (!cx->stack.pushInvokeArgs(cx, 0, &ag)) return false; diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp index 7f188f4792d7..b0504d5c9baf 100644 --- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -1394,7 +1394,6 @@ JSContext::JSContext(JSRuntime *rt) iterValue(MagicValue(JS_NO_ITER_VALUE)), #ifdef JS_METHODJIT methodJitEnabled(false), - profilingEnabled(false), #endif inferenceEnabled(false), #ifdef MOZ_TRACE_JSCALLS @@ -1658,18 +1657,6 @@ JSContext::updateJITEnabled() namespace js { -JS_FORCES_STACK JS_FRIEND_API(void) -LeaveTrace(JSContext *cx) -{ -} - -bool -CanLeaveTrace(JSContext *cx) -{ - JS_ASSERT(JS_ON_TRACE(cx)); - return false; -} - AutoEnumStateRooter::~AutoEnumStateRooter() { if (!stateValue.isNull()) { diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index ae800c621796..d5de926c71cf 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -70,18 +70,6 @@ #pragma warning(disable:4355) /* Silence warning about "this" used in base member initializer list */ #endif -/* Forward declarations of nanojit types. */ -namespace nanojit { - -class Assembler; -class CodeAlloc; -class Fragment; -template struct DefaultHash; -template class HashMap; -template class Seq; - -} /* namespace nanojit */ - JS_BEGIN_EXTERN_C struct DtoaState; JS_END_EXTERN_C @@ -94,35 +82,12 @@ struct JSSharpObjectMap { namespace js { -/* Tracer constants. */ -static const size_t MONITOR_N_GLOBAL_STATES = 4; -static const size_t FRAGMENT_TABLE_SIZE = 512; -static const size_t MAX_GLOBAL_SLOTS = 4096; -static const size_t GLOBAL_SLOTS_BUFFER_SIZE = MAX_GLOBAL_SLOTS + 1; - -/* Forward declarations of tracer types. */ -class VMAllocator; -class FrameInfoCache; -struct FrameInfo; -struct VMSideExit; -struct TreeFragment; -struct TracerState; -template class Queue; -typedef Queue SlotList; -class TypeMap; -class LoopProfile; -class InterpreterFrames; - -#if defined(JS_JIT_SPEW) || defined(DEBUG) -struct FragPI; -typedef nanojit::HashMap > FragStatsMap; -#endif - namespace mjit { class JaegerCompartment; } class WeakMapBase; +class InterpreterFrames; /* * GetSrcNote cache to avoid O(n^2) growth in finding a source note for a @@ -1163,7 +1128,6 @@ struct JSContext #ifdef JS_METHODJIT bool methodJitEnabled; - bool profilingEnabled; inline js::mjit::JaegerCompartment *jaegerCompartment(); #endif @@ -2146,12 +2110,6 @@ js_GetCurrentScript(JSContext* cx); namespace js { -extern JS_FORCES_STACK JS_FRIEND_API(void) -LeaveTrace(JSContext *cx); - -extern bool -CanLeaveTrace(JSContext *cx); - #ifdef JS_METHODJIT namespace mjit { void ExpandInlineFrames(JSCompartment *compartment); diff --git a/js/src/jscntxtinlines.h b/js/src/jscntxtinlines.h index 6de07046cd0b..2e5d6fa539af 100644 --- a/js/src/jscntxtinlines.h +++ b/js/src/jscntxtinlines.h @@ -373,20 +373,6 @@ CallSetter(JSContext *cx, JSObject *obj, jsid id, StrictPropertyOp op, uintN att return CallJSPropertyOpSetter(cx, op, obj, id, strict, vp); } -static JS_INLINE void -LeaveTraceIfGlobalObject(JSContext *cx, JSObject *obj) -{ - if (!obj->getParent()) - LeaveTrace(cx); -} - -static JS_INLINE void -LeaveTraceIfArgumentsObject(JSContext *cx, JSObject *obj) -{ - if (obj->isArguments()) - LeaveTrace(cx); -} - static inline JSAtom ** FrameAtomBase(JSContext *cx, js::StackFrame *fp) { @@ -511,14 +497,10 @@ JSContext::ensureParseMapPool() /* * Get the current frame, first lazily instantiating stack frames if needed. * (Do not access cx->fp() directly except in JS_REQUIRES_STACK code.) - * - * LeaveTrace is defined in jstracer.cpp if JS_TRACER is defined. */ static JS_FORCES_STACK JS_INLINE js::StackFrame * js_GetTopStackFrame(JSContext *cx, FrameExpandKind expand) { - js::LeaveTrace(cx); - #ifdef JS_METHODJIT if (expand) js::mjit::ExpandInlineFrames(cx->compartment); diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index 15805dcce7ec..b5792c9a29cf 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -55,238 +55,11 @@ namespace js { -/* Holds the number of recording attemps for an address. */ -typedef HashMap, - SystemAllocPolicy> RecordAttemptMap; - -/* Holds the profile data for loops. */ -typedef HashMap, - SystemAllocPolicy> LoopProfileMap; - -class Oracle; - -typedef HashSet, - SystemAllocPolicy> TracedScriptSet; - typedef HashMap, SystemAllocPolicy> ToSourceCache; -struct TraceMonitor; - -/* Holds the execution state during trace execution. */ -struct TracerState -{ - JSContext* cx; // current VM context handle - TraceMonitor* traceMonitor; // current TM - double* stackBase; // native stack base - double* sp; // native stack pointer, stack[0] is spbase[0] - double* eos; // first unusable word after the native stack / begin of globals - FrameInfo** callstackBase; // call stack base - void* sor; // start of rp stack - FrameInfo** rp; // call stack pointer - void* eor; // first unusable word after the call stack - VMSideExit* lastTreeExitGuard; // guard we exited on during a tree call - VMSideExit* lastTreeCallGuard; // guard we want to grow from if the tree - // call exit guard mismatched - void* rpAtLastTreeCall; // value of rp at innermost tree call guard - VMSideExit* outermostTreeExitGuard; // the last side exit returned by js_CallTree - TreeFragment* outermostTree; // the outermost tree we initially invoked - VMSideExit** innermostNestedGuardp; - VMSideExit* innermost; - uint64 startTime; - TracerState* prev; - - // Used by _FAIL builtins; see jsbuiltins.h. The builtin sets the - // JSBUILTIN_BAILED bit if it bails off trace and the JSBUILTIN_ERROR bit - // if an error or exception occurred. - uint32 builtinStatus; - - // Used to communicate the location of the return value in case of a deep bail. - double* deepBailSp; - - // Used when calling natives from trace to root the vp vector. - uintN nativeVpLen; - js::Value* nativeVp; - - TracerState(JSContext *cx, TraceMonitor *tm, TreeFragment *ti, - VMSideExit** innermostNestedGuardp); - ~TracerState(); -}; - -/* - * Storage for the execution state and store during trace execution. Generated - * code depends on the fact that the globals begin |MAX_NATIVE_STACK_SLOTS| - * doubles after the stack begins. Thus, on trace, |TracerState::eos| holds a - * pointer to the first global. - */ -struct TraceNativeStorage -{ - /* Max number of stack slots/frame that may need to be restored in LeaveTree. */ - static const size_t MAX_NATIVE_STACK_SLOTS = 4096; - static const size_t MAX_CALL_STACK_ENTRIES = 500; - - double stack_global_buf[MAX_NATIVE_STACK_SLOTS + GLOBAL_SLOTS_BUFFER_SIZE]; - FrameInfo *callstack_buf[MAX_CALL_STACK_ENTRIES]; - - double *stack() { return stack_global_buf; } - double *global() { return stack_global_buf + MAX_NATIVE_STACK_SLOTS; } - FrameInfo **callstack() { return callstack_buf; } -}; - -/* Holds data to track a single globa. */ -struct GlobalState { - JSObject* globalObj; - uint32 globalShape; - SlotList* globalSlots; -}; - -/* - * Trace monitor. Every JSCompartment has an associated trace monitor - * that keeps track of loop frequencies for all JavaScript code loaded - * into that runtime. - */ -struct TraceMonitor { - /* - * The context currently executing JIT-compiled code in this compartment, or - * NULL if none. Among other things, this can in certain cases prevent - * last-ditch GC and suppress calls to JS_ReportOutOfMemory. - * - * !tracecx && !recorder: not on trace - * !tracecx && recorder: recording - * tracecx && !recorder: executing a trace - * tracecx && recorder: executing inner loop, recording outer loop - */ - JSContext *tracecx; - - /* - * State for the current tree execution. bailExit is valid if the tree has - * called back into native code via a _FAIL builtin and has not yet bailed, - * else garbage (NULL in debug builds). - */ - js::TracerState *tracerState; - js::VMSideExit *bailExit; - - /* Counts the number of iterations run by the currently executing trace. */ - unsigned iterationCounter; - - /* - * Cached storage to use when executing on trace. While we may enter nested - * traces, we always reuse the outer trace's storage, so never need more - * than of these. - */ - TraceNativeStorage *storage; - - /* - * There are 4 allocators here. This might seem like overkill, but they - * have different lifecycles, and by keeping them separate we keep the - * amount of retained memory down significantly. They are flushed (ie. - * all the allocated memory is freed) periodically. - * - * - dataAlloc has the lifecycle of the monitor. It's flushed only when - * the monitor is flushed. It's used for fragments. - * - * - traceAlloc has the same flush lifecycle as the dataAlloc, but it is - * also *marked* when a recording starts and rewinds to the mark point - * if recording aborts. So you can put things in it that are only - * reachable on a successful record/compile cycle like GuardRecords and - * SideExits. - * - * - tempAlloc is flushed after each recording, successful or not. It's - * used to store LIR code and for all other elements in the LIR - * pipeline. - * - * - codeAlloc has the same lifetime as dataAlloc, but its API is - * different (CodeAlloc vs. VMAllocator). It's used for native code. - * It's also a good idea to keep code and data separate to avoid I-cache - * vs. D-cache issues. - */ - VMAllocator* dataAlloc; - VMAllocator* traceAlloc; - VMAllocator* tempAlloc; - nanojit::CodeAlloc* codeAlloc; - nanojit::Assembler* assembler; - FrameInfoCache* frameCache; - - /* This gets incremented every time the monitor is flushed. */ - uintN flushEpoch; - - Oracle* oracle; - TraceRecorder* recorder; - - /* If we are profiling a loop, this tracks the current profile. Otherwise NULL. */ - LoopProfile* profile; - - GlobalState globalStates[MONITOR_N_GLOBAL_STATES]; - TreeFragment *vmfragments[FRAGMENT_TABLE_SIZE]; - RecordAttemptMap* recordAttempts; - - /* A hashtable mapping PC values to loop profiles for those loops. */ - LoopProfileMap* loopProfiles; - - /* - * Maximum size of the code cache before we start flushing. 1/16 of this - * size is used as threshold for the regular expression code cache. - */ - uint32 maxCodeCacheBytes; - - /* - * If nonzero, do not flush the JIT cache after a deep bail. That would - * free JITted code pages that we will later return to. Instead, set the - * needFlush flag so that it can be flushed later. - */ - JSBool needFlush; - - // Cached temporary typemap to avoid realloc'ing every time we create one. - // This must be used in only one place at a given time. It must be cleared - // before use. - TypeMap* cachedTempTypeMap; - - /* Scripts with recorded fragments. */ - TracedScriptSet tracedScripts; - -#ifdef DEBUG - /* Fields needed for fragment/guard profiling. */ - nanojit::Seq* branches; - uint32 lastFragID; - VMAllocator* profAlloc; - FragStatsMap* profTab; - - void logFragProfile(); -#endif - - TraceMonitor(); - ~TraceMonitor(); - - bool init(JSRuntime* rt); - - bool ontrace() const { - return !!tracecx; - } - - /* Flush the JIT cache. */ - void flush(); - - /* Sweep any cache entry pointing to dead GC things. */ - void sweep(JSContext *cx); - - /* Mark any tracer stacks that are active. */ - void mark(JSTracer *trc); - - bool outOfMemory() const; - - JS_FRIEND_API(void) getCodeAllocStats(size_t &total, size_t &frag_size, size_t &free_size) const; - JS_FRIEND_API(size_t) getVMAllocatorsMainSize(JSUsableSizeFun usf) const; - JS_FRIEND_API(size_t) getVMAllocatorsReserveSize(JSUsableSizeFun usf) const; - JS_FRIEND_API(size_t) getTraceMonitorSize(JSUsableSizeFun usf) const; -}; - namespace mjit { class JaegerCompartment; } @@ -624,29 +397,6 @@ struct JS_FRIEND_API(JSCompartment) { #define JS_PROPERTY_TREE(cx) ((cx)->compartment->propertyTree) -/* - * 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(const JSContext *cx) -{ - return false; -} - -static inline js::TraceRecorder * -TRACE_RECORDER(JSContext *cx) -{ - return NULL; -} - -static inline js::LoopProfile * -TRACE_PROFILER(JSContext *cx) -{ - return NULL; -} - namespace js { static inline MathCache * GetMathCache(JSContext *cx) diff --git a/js/src/jsdate.cpp b/js/src/jsdate.cpp index a9a7d00aa81f..72ee7474f88b 100644 --- a/js/src/jsdate.cpp +++ b/js/src/jsdate.cpp @@ -2147,7 +2147,6 @@ date_toJSON(JSContext *cx, uintN argc, Value *vp) } /* Step 6. */ - LeaveTrace(cx); InvokeArgsGuard args; if (!cx->stack.pushInvokeArgs(cx, 0, &args)) return false; diff --git a/js/src/jsdbgapi.cpp b/js/src/jsdbgapi.cpp index 632a28561537..4f5515049436 100644 --- a/js/src/jsdbgapi.cpp +++ b/js/src/jsdbgapi.cpp @@ -730,8 +730,6 @@ JS_EvaluateUCInStackFrame(JSContext *cx, JSStackFrame *fpArg, const char *filename, uintN lineno, jsval *rval) { - JS_ASSERT_NOT_ON_TRACE(cx); - if (!CheckDebugMode(cx)) return false; @@ -1089,8 +1087,6 @@ JS_PUBLIC_API(JSDebugHooks *) JS_SetContextDebugHooks(JSContext *cx, const JSDebugHooks *hooks) { JS_ASSERT(hooks); - if (hooks != &cx->runtime->globalDebugHooks && hooks != &js_NullDebugHooks) - LeaveTrace(cx); JSDebugHooks *old = const_cast(cx->debugHooks); cx->debugHooks = hooks; @@ -1611,455 +1607,6 @@ js_ResumeVtune() #endif /* MOZ_VTUNE */ -#ifdef MOZ_TRACEVIS -/* - * Ethogram - Javascript wrapper for TraceVis state - * - * ethology: The scientific study of animal behavior, - * especially as it occurs in a natural environment. - * ethogram: A pictorial catalog of the behavioral patterns of - * an organism or a species. - * - */ -#if defined(XP_WIN) -#include "jswin.h" -#else -#include -#endif - -#define ETHOGRAM_BUF_SIZE 65536 - -static JSBool -ethogram_construct(JSContext *cx, uintN argc, jsval *vp); -static void -ethogram_finalize(JSContext *cx, JSObject *obj); - -static JSClass ethogram_class = { - "Ethogram", - JSCLASS_HAS_PRIVATE, - JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, - JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, ethogram_finalize, - JSCLASS_NO_OPTIONAL_MEMBERS -}; - -struct EthogramEvent { - TraceVisState s; - TraceVisExitReason r; - int ts; - int tus; - JSString *filename; - int lineno; -}; - -static int -compare_strings(const void *k1, const void *k2) -{ - return strcmp((const char *) k1, (const char *) k2) == 0; -} - -class EthogramEventBuffer { -private: - EthogramEvent mBuf[ETHOGRAM_BUF_SIZE]; - int mReadPos; - int mWritePos; - JSObject *mFilenames; - int mStartSecond; - - struct EthogramScriptEntry { - char *filename; - JSString *jsfilename; - - EthogramScriptEntry *next; - }; - EthogramScriptEntry *mScripts; - -public: - friend JSBool - ethogram_construct(JSContext *cx, uintN argc, jsval *vp); - - inline void push(TraceVisState s, TraceVisExitReason r, char *filename, int lineno) { - mBuf[mWritePos].s = s; - mBuf[mWritePos].r = r; -#if defined(XP_WIN) - FILETIME now; - GetSystemTimeAsFileTime(&now); - unsigned long long raw_us = 0.1 * - (((unsigned long long) now.dwHighDateTime << 32ULL) | - (unsigned long long) now.dwLowDateTime); - unsigned int sec = raw_us / 1000000L; - unsigned int usec = raw_us % 1000000L; - mBuf[mWritePos].ts = sec - mStartSecond; - mBuf[mWritePos].tus = usec; -#else - struct timeval tv; - gettimeofday(&tv, NULL); - mBuf[mWritePos].ts = tv.tv_sec - mStartSecond; - mBuf[mWritePos].tus = tv.tv_usec; -#endif - - JSString *jsfilename = findScript(filename); - mBuf[mWritePos].filename = jsfilename; - mBuf[mWritePos].lineno = lineno; - - mWritePos = (mWritePos + 1) % ETHOGRAM_BUF_SIZE; - if (mWritePos == mReadPos) { - mReadPos = (mWritePos + 1) % ETHOGRAM_BUF_SIZE; - } - } - - inline EthogramEvent *pop() { - EthogramEvent *e = &mBuf[mReadPos]; - mReadPos = (mReadPos + 1) % ETHOGRAM_BUF_SIZE; - return e; - } - - bool isEmpty() { - return (mReadPos == mWritePos); - } - - EthogramScriptEntry *addScript(JSContext *cx, JSObject *obj, char *filename, JSString *jsfilename) { - JSHashNumber hash = JS_HashString(filename); - JSHashEntry **hep = JS_HashTableRawLookup(traceVisScriptTable, hash, filename); - if (*hep != NULL) - return NULL; - - JS_HashTableRawAdd(traceVisScriptTable, hep, hash, filename, this); - - EthogramScriptEntry * entry = (EthogramScriptEntry *) JS_malloc(cx, sizeof(EthogramScriptEntry)); - if (entry == NULL) - return NULL; - - entry->next = mScripts; - mScripts = entry; - entry->filename = filename; - entry->jsfilename = jsfilename; - - return mScripts; - } - - void removeScripts(JSContext *cx) { - EthogramScriptEntry *se = mScripts; - while (se != NULL) { - char *filename = se->filename; - - JSHashNumber hash = JS_HashString(filename); - JSHashEntry **hep = JS_HashTableRawLookup(traceVisScriptTable, hash, filename); - JSHashEntry *he = *hep; - if (he) { - /* we hardly knew he */ - JS_HashTableRawRemove(traceVisScriptTable, hep, he); - } - - EthogramScriptEntry *se_head = se; - se = se->next; - JS_free(cx, se_head); - } - } - - JSString *findScript(char *filename) { - EthogramScriptEntry *se = mScripts; - while (se != NULL) { - if (compare_strings(se->filename, filename)) - return (se->jsfilename); - se = se->next; - } - return NULL; - } - - JSObject *filenames() { - return mFilenames; - } - - int length() { - if (mWritePos < mReadPos) - return (mWritePos + ETHOGRAM_BUF_SIZE) - mReadPos; - else - return mWritePos - mReadPos; - } -}; - -static char jstv_empty[] = ""; - -inline char * -jstv_Filename(StackFrame *fp) -{ - while (fp && !fp->isScriptFrame()) - fp = fp->prev(); - return (fp && fp->maybeScript() && fp->script()->filename) - ? (char *)fp->script()->filename - : jstv_empty; -} -inline uintN -jstv_Lineno(JSContext *cx, StackFrame *fp) -{ - while (fp && fp->pcQuadratic(cx->stack) == NULL) - fp = fp->prev(); - jsbytecode *pc = fp->pcQuadratic(cx->stack); - return (fp && pc) ? js_FramePCToLineNumber(cx, fp, pc) : 0; -} - -/* Collect states here and distribute to a matching buffer, if any */ -JS_FRIEND_API(void) -js::StoreTraceVisState(JSContext *cx, TraceVisState s, TraceVisExitReason r) -{ - StackFrame *fp = cx->fp(); - - char *script_file = jstv_Filename(fp); - JSHashNumber hash = JS_HashString(script_file); - - JSHashEntry **hep = JS_HashTableRawLookup(traceVisScriptTable, hash, script_file); - /* update event buffer, flag if overflowed */ - JSHashEntry *he = *hep; - if (he) { - EthogramEventBuffer *p; - p = (EthogramEventBuffer *) he->value; - - p->push(s, r, script_file, jstv_Lineno(cx, fp)); - } -} - -static JSBool -ethogram_construct(JSContext *cx, uintN argc, jsval *vp) -{ - EthogramEventBuffer *p; - - p = (EthogramEventBuffer *) JS_malloc(cx, sizeof(EthogramEventBuffer)); - if (!p) - return JS_FALSE; - - p->mReadPos = p->mWritePos = 0; - p->mScripts = NULL; - p->mFilenames = JS_NewArrayObject(cx, 0, NULL); - -#if defined(XP_WIN) - FILETIME now; - GetSystemTimeAsFileTime(&now); - unsigned long long raw_us = 0.1 * - (((unsigned long long) now.dwHighDateTime << 32ULL) | - (unsigned long long) now.dwLowDateTime); - unsigned int s = raw_us / 1000000L; - p->mStartSecond = s; -#else - struct timeval tv; - gettimeofday(&tv, NULL); - p->mStartSecond = tv.tv_sec; -#endif - JSObject *obj; - if (JS_IsConstructing(cx, vp)) { - obj = JS_NewObject(cx, ðogram_class, NULL, NULL); - if (!obj) - return JS_FALSE; - } else { - obj = JS_THIS_OBJECT(cx, vp); - } - - jsval filenames = OBJECT_TO_JSVAL(p->filenames()); - if (!JS_DefineProperty(cx, obj, "filenames", filenames, - NULL, NULL, JSPROP_READONLY|JSPROP_PERMANENT)) - return JS_FALSE; - - JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj)); - JS_SetPrivate(cx, obj, p); - return JS_TRUE; -} - -static void -ethogram_finalize(JSContext *cx, JSObject *obj) -{ - EthogramEventBuffer *p; - p = (EthogramEventBuffer *) JS_GetInstancePrivate(cx, obj, ðogram_class, NULL); - if (!p) - return; - - p->removeScripts(cx); - - JS_free(cx, p); -} - -static JSBool -ethogram_addScript(JSContext *cx, uintN argc, jsval *vp) -{ - JSString *str; - char *filename = NULL; - jsval *argv = JS_ARGV(cx, vp); - JSObject *obj = JS_THIS_OBJECT(cx, vp); - if (!obj) - return false; - if (argc < 1) { - /* silently ignore no args */ - JS_SET_RVAL(cx, vp, JSVAL_VOID); - return true; - } - if (JSVAL_IS_STRING(argv[0])) { - str = JSVAL_TO_STRING(argv[0]); - filename = DeflateString(cx, str->getChars(cx), str->length()); - if (!filename) - return false; - } - - EthogramEventBuffer *p = (EthogramEventBuffer *) JS_GetInstancePrivate(cx, obj, ðogram_class, argv); - - p->addScript(cx, obj, filename, str); - JS_SET_RVAL(cx, vp, JSVAL_VOID); - jsval dummy; - JS_CallFunctionName(cx, p->filenames(), "push", 1, argv, &dummy); - return true; -} - -static JSBool -ethogram_getAllEvents(JSContext *cx, uintN argc, jsval *vp) -{ - EthogramEventBuffer *p; - jsval *argv = JS_ARGV(cx, vp); - - JSObject *obj = JS_THIS_OBJECT(cx, vp); - if (!obj) - return JS_FALSE; - - p = (EthogramEventBuffer *) JS_GetInstancePrivate(cx, obj, ðogram_class, argv); - if (!p) - return JS_FALSE; - - if (p->isEmpty()) { - JS_SET_RVAL(cx, vp, JSVAL_NULL); - return JS_TRUE; - } - - JSObject *rarray = JS_NewArrayObject(cx, 0, NULL); - if (rarray == NULL) { - JS_SET_RVAL(cx, vp, JSVAL_NULL); - return JS_TRUE; - } - - JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(rarray)); - - for (uint32 i = 0; !p->isEmpty(); i++) { - - JSObject *x = JS_NewObject(cx, NULL, NULL, NULL); - if (x == NULL) - return JS_FALSE; - - EthogramEvent *e = p->pop(); - - jsval state = INT_TO_JSVAL(e->s); - jsval reason = INT_TO_JSVAL(e->r); - jsval ts = INT_TO_JSVAL(e->ts); - jsval tus = INT_TO_JSVAL(e->tus); - - jsval filename = STRING_TO_JSVAL(e->filename); - jsval lineno = INT_TO_JSVAL(e->lineno); - - if (!JS_SetProperty(cx, x, "state", &state)) - return JS_FALSE; - if (!JS_SetProperty(cx, x, "reason", &reason)) - return JS_FALSE; - if (!JS_SetProperty(cx, x, "ts", &ts)) - return JS_FALSE; - if (!JS_SetProperty(cx, x, "tus", &tus)) - return JS_FALSE; - - if (!JS_SetProperty(cx, x, "filename", &filename)) - return JS_FALSE; - if (!JS_SetProperty(cx, x, "lineno", &lineno)) - return JS_FALSE; - - jsval element = OBJECT_TO_JSVAL(x); - JS_SetElement(cx, rarray, i, &element); - } - - return JS_TRUE; -} - -static JSBool -ethogram_getNextEvent(JSContext *cx, uintN argc, jsval *vp) -{ - EthogramEventBuffer *p; - jsval *argv = JS_ARGV(cx, vp); - - JSObject *obj = JS_THIS_OBJECT(cx, vp); - if (!obj) - return JS_FALSE; - - p = (EthogramEventBuffer *) JS_GetInstancePrivate(cx, obj, ðogram_class, argv); - if (!p) - return JS_FALSE; - - JSObject *x = JS_NewObject(cx, NULL, NULL, NULL); - if (x == NULL) - return JS_FALSE; - - if (p->isEmpty()) { - JS_SET_RVAL(cx, vp, JSVAL_NULL); - return JS_TRUE; - } - - EthogramEvent *e = p->pop(); - jsval state = INT_TO_JSVAL(e->s); - jsval reason = INT_TO_JSVAL(e->r); - jsval ts = INT_TO_JSVAL(e->ts); - jsval tus = INT_TO_JSVAL(e->tus); - - jsval filename = STRING_TO_JSVAL(e->filename); - jsval lineno = INT_TO_JSVAL(e->lineno); - - if (!JS_SetProperty(cx, x, "state", &state)) - return JS_FALSE; - if (!JS_SetProperty(cx, x, "reason", &reason)) - return JS_FALSE; - if (!JS_SetProperty(cx, x, "ts", &ts)) - return JS_FALSE; - if (!JS_SetProperty(cx, x, "tus", &tus)) - return JS_FALSE; - if (!JS_SetProperty(cx, x, "filename", &filename)) - return JS_FALSE; - - if (!JS_SetProperty(cx, x, "lineno", &lineno)) - return JS_FALSE; - - JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(x)); - - return JS_TRUE; -} - -static JSFunctionSpec ethogram_methods[] = { - JS_FN("addScript", ethogram_addScript, 1,0), - JS_FN("getAllEvents", ethogram_getAllEvents, 0,0), - JS_FN("getNextEvent", ethogram_getNextEvent, 0,0), - JS_FS_END -}; - -/* - * An |Ethogram| organizes the output of a collection of files that should be - * monitored together. A single object gets events for the group. - */ -JS_FRIEND_API(JSBool) -js_InitEthogram(JSContext *cx, uintN argc, jsval *vp) -{ - if (!traceVisScriptTable) { - traceVisScriptTable = JS_NewHashTable(8, JS_HashString, compare_strings, - NULL, NULL, NULL); - } - - JS_InitClass(cx, JS_GetGlobalObject(cx), NULL, ðogram_class, - ethogram_construct, 0, NULL, ethogram_methods, - NULL, NULL); - - JS_SET_RVAL(cx, vp, JSVAL_VOID); - return true; -} - -JS_FRIEND_API(JSBool) -js_ShutdownEthogram(JSContext *cx, uintN argc, jsval *vp) -{ - if (traceVisScriptTable) - JS_HashTableDestroy(traceVisScriptTable); - - JS_SET_RVAL(cx, vp, JSVAL_VOID); - return true; -} - -#endif /* MOZ_TRACEVIS */ - #ifdef MOZ_TRACE_JSCALLS JS_PUBLIC_API(void) diff --git a/js/src/jsdbgapi.h b/js/src/jsdbgapi.h index faffc3ea7cd5..f2b6951d2125 100644 --- a/js/src/jsdbgapi.h +++ b/js/src/jsdbgapi.h @@ -577,13 +577,6 @@ js_ResumeVtune(); #endif /* MOZ_VTUNE */ -#ifdef MOZ_TRACEVIS -extern JS_FRIEND_API(JSBool) -js_InitEthogram(JSContext *cx, uintN argc, jsval *vp); -extern JS_FRIEND_API(JSBool) -js_ShutdownEthogram(JSContext *cx, uintN argc, jsval *vp); -#endif /* MOZ_TRACEVIS */ - #ifdef MOZ_TRACE_JSCALLS typedef void (*JSFunctionCallback)(const JSFunction *fun, const JSScript *scr, diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index 69cec2572f10..3b0e74bf12ae 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -262,8 +262,6 @@ args_delProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp) static JSBool ArgGetter(JSContext *cx, JSObject *obj, jsid id, Value *vp) { - LeaveTrace(cx); - if (!obj->isNormalArguments()) return true; @@ -394,8 +392,6 @@ args_enumerate(JSContext *cx, JSObject *obj) static JSBool StrictArgGetter(JSContext *cx, JSObject *obj, jsid id, Value *vp) { - LeaveTrace(cx); - if (!obj->isStrictArguments()) return true; @@ -548,11 +544,6 @@ static void args_trace(JSTracer *trc, JSObject *obj) { ArgumentsObject *argsobj = obj->asArguments(); - if (argsobj->onTrace()) { - JS_ASSERT(!argsobj->isStrictArguments()); - return; - } - ArgumentsData *data = argsobj->data(); MarkValue(trc, data->callee, js_callee_str); MarkValueRange(trc, argsobj->initialLength(), data->slots, js_arguments_str); @@ -2436,7 +2427,6 @@ js_ReportIsNotFunction(JSContext *cx, const Value *vp, uintN flags) const char *name = NULL, *source = NULL; AutoValueRooter tvr(cx); uintN error = (flags & JSV2F_CONSTRUCT) ? JSMSG_NOT_CONSTRUCTOR : JSMSG_NOT_FUNCTION; - LeaveTrace(cx); /* * We try to the print the code that produced vp if vp is a value in the diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 6492794ebfaf..37b17010212c 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -1632,7 +1632,7 @@ RunLastDitchGC(JSContext *cx) inline bool IsGCAllowed(JSContext *cx) { - return !JS_ON_TRACE(cx) && !JS_THREAD_DATA(cx)->waiveGCQuota; + return !JS_THREAD_DATA(cx)->waiveGCQuota; } /* static */ void * @@ -2956,11 +2956,6 @@ js_GC(JSContext *cx, JSCompartment *comp, JSGCInvocationKind gckind, gcstats::Re if (rt->state != JSRTS_UP && gckind != GC_LAST_CONTEXT) return; - if (JS_ON_TRACE(cx)) { - JS_ASSERT(gckind != GC_LAST_CONTEXT); - return; - } - #ifdef JS_GC_ZEAL struct AutoVerifyBarriers { JSContext *cx; @@ -3032,7 +3027,6 @@ void TraceRuntime(JSTracer *trc) { JS_ASSERT(!IS_GC_MARKING_TRACER(trc)); - LeaveTrace(trc->context); #ifdef JS_THREADSAFE { @@ -3098,7 +3092,6 @@ IterateCompartmentsArenasCells(JSContext *cx, void *data, IterateCellCallback cellCallback) { CHECK_REQUEST(cx); - LeaveTrace(cx); JSRuntime *rt = cx->runtime; JS_ASSERT(!rt->gcRunning); @@ -3129,7 +3122,6 @@ IterateChunks(JSContext *cx, void *data, IterateChunkCallback chunkCallback) { /* :XXX: Any way to common this preamble with IterateCompartmentsArenasCells? */ CHECK_REQUEST(cx); - LeaveTrace(cx); JSRuntime *rt = cx->runtime; JS_ASSERT(!rt->gcRunning); @@ -3152,8 +3144,6 @@ IterateCells(JSContext *cx, JSCompartment *compartment, AllocKind thingKind, /* :XXX: Any way to common this preamble with IterateCompartmentsArenasCells? */ CHECK_REQUEST(cx); - LeaveTrace(cx); - JSRuntime *rt = cx->runtime; JS_ASSERT(!rt->gcRunning); @@ -3371,8 +3361,6 @@ StartVerifyBarriers(JSContext *cx) if (rt->gcVerifyData) return; - LeaveTrace(cx); - AutoLockGC lock(rt); AutoGCSession gcsession(cx); @@ -3498,8 +3486,6 @@ CheckEdge(JSTracer *jstrc, void *thing, JSGCTraceKind kind) static void EndVerifyBarriers(JSContext *cx) { - LeaveTrace(cx); - JSRuntime *rt = cx->runtime; AutoLockGC lock(rt); diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index 48ab1ba46e4f..9b5dfbb747e7 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -271,9 +271,6 @@ GetScopeChainFull(JSContext *cx, StackFrame *fp, JSObject *blockChain) return &fp->scopeChain(); } - /* We don't handle cloning blocks on trace. */ - LeaveTrace(cx); - /* * We have one or more lexical scopes to reflect into fp->scopeChain, so * make sure there's a call object at the current head of the scope chain, @@ -704,8 +701,6 @@ bool js::InvokeGetterOrSetter(JSContext *cx, JSObject *obj, const Value &fval, uintN argc, Value *argv, Value *rval) { - LeaveTrace(cx); - /* * Invoke could result in another try to get or set the same id again, see * bug 355497. @@ -755,8 +750,6 @@ js::ExecuteKernel(JSContext *cx, JSScript *script, JSObject &scopeChain, const V return true; } - LeaveTrace(cx); - ExecuteFrameGuard efg; if (!cx->stack.pushExecuteFrame(cx, script, thisv, scopeChain, type, evalInFrame, &efg)) return false; @@ -1516,8 +1509,6 @@ JS_STATIC_ASSERT(JSOP_INCNAME_LENGTH == JSOP_DECNAME_LENGTH); JS_STATIC_ASSERT(JSOP_INCNAME_LENGTH == JSOP_NAMEINC_LENGTH); JS_STATIC_ASSERT(JSOP_INCNAME_LENGTH == JSOP_NAMEDEC_LENGTH); -# define ABORT_RECORDING(cx, reason) ((void) 0) - /* * Inline fast paths for iteration. js_IteratorMore and js_IteratorNext handle * all cases, but we inline the most frequently taken paths here. @@ -1576,9 +1567,6 @@ TypeCheckNextBytecode(JSContext *cx, JSScript *script, unsigned n, const FrameRe JS_NEVER_INLINE bool js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode) { -#ifdef MOZ_TRACEVIS - TraceVisStateObj tvso(cx, S_INTERP); -#endif JSAutoResolveFlags rf(cx, RESOLVE_INFER); gc::VerifyBarriers(cx, true); @@ -1614,10 +1602,7 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode) typedef GenericInterruptEnabler InterruptEnabler; InterruptEnabler interruptEnabler(&jumpTable, interruptJumpTable); -# define CHECK_RECORDER() ((void)0) - # define DO_OP() JS_BEGIN_MACRO \ - CHECK_RECORDER(); \ CHECK_PCCOUNT_INTERRUPTS(); \ js::gc::VerifyBarriers(cx); \ JS_EXTENSION_(goto *jumpTable[op]); \ @@ -1628,7 +1613,7 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode) DO_OP(); \ JS_END_MACRO -# define BEGIN_CASE(OP) L_##OP: CHECK_RECORDER(); +# define BEGIN_CASE(OP) L_##OP: # define END_CASE(OP) DO_NEXT_OP(OP##_LENGTH); # define END_VARLEN_CASE DO_NEXT_OP(len); # define ADD_EMPTY_CASE(OP) BEGIN_CASE(OP) \ @@ -1645,15 +1630,13 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode) typedef GenericInterruptEnabler InterruptEnabler; InterruptEnabler interruptEnabler(&switchMask, -1); -# define CHECK_RECORDER() ((void)0) - # define DO_OP() goto do_op # define DO_NEXT_OP(n) JS_BEGIN_MACRO \ JS_ASSERT((n) == len); \ goto advance_pc; \ JS_END_MACRO -# define BEGIN_CASE(OP) case OP: CHECK_RECORDER(); +# define BEGIN_CASE(OP) case OP: # define END_CASE(OP) END_CASE_LEN(OP##_LENGTH) # define END_CASE_LEN(n) END_CASE_LENX(n) # define END_CASE_LENX(n) END_CASE_LEN##n @@ -1880,7 +1863,6 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode) op = (JSOp) *regs.pc; do_op: - CHECK_RECORDER(); CHECK_PCCOUNT_INTERRUPTS(); js::gc::VerifyBarriers(cx); switchOp = intN(op) | switchMask; @@ -1929,10 +1911,6 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode) } #if JS_THREADED_INTERP -#ifdef MOZ_TRACEVIS - if (!moreInterrupts) - ExitTraceVisState(cx, R_ABORT); -#endif jumpTable = moreInterrupts ? interruptJumpTable : normalJumpTable; JS_EXTENSION_(goto *normalJumpTable[op]); #else @@ -3569,7 +3547,6 @@ BEGIN_CASE(JSOP_SETMETHOD) } else { if (!obj->setGeneric(cx, id, &rval, script->strictModeCode)) goto error; - ABORT_RECORDING(cx, "Non-native set"); } } while (0); } @@ -3807,7 +3784,7 @@ BEGIN_CASE(JSOP_FUNAPPLY) mjit::CompileStatus status = mjit::CanMethodJIT(cx, script, construct, request); if (status == mjit::Compile_Error) goto error; - if (!TRACE_RECORDER(cx) && !TRACE_PROFILER(cx) && status == mjit::Compile_Okay) { + if (status == mjit::Compile_Okay) { mjit::JaegerStatus status = mjit::JaegerShot(cx, true); CHECK_PARTIAL_METHODJIT(status); interpReturnOK = (status == mjit::Jaeger_Returned); @@ -4558,10 +4535,6 @@ BEGIN_CASE(JSOP_LAMBDA) * Optimize var obj = {method: function () { ... }, ...}, * this.method = function () { ... }; and other significant * single-use-of-null-closure bytecode sequences. - * - * WARNING: code in TraceRecorder::record_JSOP_LAMBDA must - * match the optimization cases in the following code that - * break from the outer do-while(0). */ if (op2 == JSOP_INITMETHOD) { #ifdef DEBUG diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp index 1917be5f526a..aea4ac3847d8 100644 --- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -369,7 +369,6 @@ GetCustomIterator(JSContext *cx, JSObject *obj, uintN flags, Value *vp) ++sCustomIteratorCount; /* Otherwise call it and return that object. */ - LeaveTrace(cx); Value arg = BooleanValue((flags & JSITER_FOREACH) == 0); if (!Invoke(cx, ObjectValue(*obj), *vp, 1, &arg, vp)) return false; @@ -1396,8 +1395,6 @@ CloseGenerator(JSContext *cx, JSObject *obj) static JSBool generator_op(JSContext *cx, Native native, JSGeneratorOp op, Value *vp, uintN argc) { - LeaveTrace(cx); - CallArgs args = CallArgsFromVp(argc, vp); bool ok; diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 0b7b9409769f..9137a2c11090 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -3126,8 +3126,6 @@ Detecting(JSContext *cx, jsbytecode *pc) uintN js_InferFlags(JSContext *cx, uintN defaultFlags) { - JS_ASSERT_NOT_ON_TRACE(cx); - const JSCodeSpec *cs; uint32 format; uintN flags = 0; @@ -4428,8 +4426,7 @@ JSObject::allocSlots(JSContext *cx, size_t newcap) } if (newcap > NSLOTS_LIMIT) { - if (!JS_ON_TRACE(cx)) - js_ReportAllocationOverflow(cx); + js_ReportAllocationOverflow(cx); return false; } @@ -4937,15 +4934,6 @@ PurgeProtoChain(JSContext *cx, JSObject *obj, jsid id) if (shape) { PCMETER(JS_PROPERTY_CACHE(cx).pcpurges++); obj->shadowingShapeChange(cx, *shape); - - if (!obj->getParent()) { - /* - * All scope chains end in a global object, so this will change - * the global shape. jstracer.cpp assumes that the global shape - * never changes on trace, so we must deep-bail here. - */ - LeaveTrace(cx); - } return JS_TRUE; } obj = obj->getProto(); @@ -5075,7 +5063,6 @@ DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &value, { JS_ASSERT((defineHow & ~(DNP_CACHE_RESULT | DNP_DONT_PURGE | DNP_SET_METHOD | DNP_SKIP_TYPE)) == 0); - LeaveTraceIfGlobalObject(cx, obj); /* Convert string indices to integers if appropriate. */ id = js_CheckForStringIndex(id); @@ -5240,7 +5227,6 @@ DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &value, } if (defineHow & DNP_CACHE_RESULT) { - JS_ASSERT_NOT_ON_TRACE(cx); if (adding) JS_PROPERTY_CACHE(cx).fill(cx, obj, 0, obj, shape, true); } @@ -5440,7 +5426,6 @@ js_FindPropertyHelper(JSContext *cx, jsid id, bool cacheResult, bool global, int scopeIndex; JSProperty *prop; - JS_ASSERT_IF(cacheResult, !JS_ON_TRACE(cx)); scopeChain = cx->stack.currentScriptedScopeChain(); if (global) { @@ -5555,7 +5540,6 @@ js_FindIdentifierBase(JSContext *cx, JSObject *scopeChain, jsid id) * trace and should have a valid cache entry for native scopeChain. */ JS_ASSERT(scopeChain->getParent()); - JS_ASSERT(!JS_ON_TRACE(cx)); JSObject *obj = scopeChain; @@ -5619,8 +5603,6 @@ static JS_ALWAYS_INLINE JSBool js_NativeGetInline(JSContext *cx, JSObject *receiver, JSObject *obj, JSObject *pobj, const Shape *shape, uintN getHow, Value *vp) { - LeaveTraceIfGlobalObject(cx, pobj); - uint32 slot; int32 sample; @@ -5676,8 +5658,6 @@ js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj, const Shape *shape, u JSBool js_NativeSet(JSContext *cx, JSObject *obj, const Shape *shape, bool added, bool strict, Value *vp) { - LeaveTraceIfGlobalObject(cx, obj); - AddTypePropertyId(cx, obj, shape->propid, *vp); uint32 slot; @@ -5738,8 +5718,6 @@ js_GetPropertyHelperInline(JSContext *cx, JSObject *obj, JSObject *receiver, jsi JSProperty *prop; const Shape *shape; - JS_ASSERT_IF(getHow & JSGET_CACHE_RESULT, !JS_ON_TRACE(cx)); - /* Convert string indices to integers if appropriate. */ id = js_CheckForStringIndex(id); @@ -5770,10 +5748,8 @@ js_GetPropertyHelperInline(JSContext *cx, JSObject *obj, JSObject *receiver, jsi uintN flags; op = (JSOp) *pc; - if (op == JSOP_TRAP) { - JS_ASSERT_NOT_ON_TRACE(cx); + if (op == JSOP_TRAP) op = JS_GetTrapOpcode(cx, cx->fp()->script(), pc); - } if (op == JSOP_GETXPROP) { flags = JSREPORT_ERROR; } else { @@ -5792,7 +5768,6 @@ js_GetPropertyHelperInline(JSContext *cx, JSObject *obj, JSObject *receiver, jsi /* Do not warn about tests like (obj[prop] == undefined). */ if (cx->resolveFlags == RESOLVE_INFER) { - LeaveTrace(cx); pc += js_CodeSpec[op].length; if (Detecting(cx, pc)) return JS_TRUE; @@ -5822,10 +5797,8 @@ js_GetPropertyHelperInline(JSContext *cx, JSObject *obj, JSObject *receiver, jsi shape = (Shape *) prop; - if (getHow & JSGET_CACHE_RESULT) { - JS_ASSERT_NOT_ON_TRACE(cx); + if (getHow & JSGET_CACHE_RESULT) JS_PROPERTY_CACHE(cx).fill(cx, aobj, 0, obj2, shape); - } /* This call site is hot -- use the always-inlined variant of js_NativeGet(). */ if (!js_NativeGetInline(cx, receiver, obj, obj2, shape, getHow, vp)) @@ -5982,8 +5955,6 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow, bool added; JS_ASSERT((defineHow & ~(DNP_CACHE_RESULT | DNP_SET_METHOD | DNP_UNQUALIFIED)) == 0); - if (defineHow & DNP_CACHE_RESULT) - JS_ASSERT_NOT_ON_TRACE(cx); /* Convert string indices to integers if appropriate. */ id = js_CheckForStringIndex(id); diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 2236e0ff6cfe..cb37a435790b 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -62,8 +62,6 @@ #include "gc/Barrier.h" #include "vm/String.h" -namespace nanojit { class ValidateWriter; } - namespace js { class AutoPropDescArrayRooter; @@ -412,15 +410,6 @@ class RegExpObject; * guaranteed to have the same number of fixed slots. */ struct JSObject : js::gc::Cell { - /* - * TraceRecorder must be a friend because it generates code that - * manipulates JSObjects, which requires peeking under any encapsulation. - * ValidateWriter must be a friend because it works in tandem with - * TraceRecorder. - */ - friend class js::TraceRecorder; - friend class nanojit::ValidateWriter; - /* * Private pointer to the last added property and methods to manipulate the * list it links among properties in this scope. diff --git a/js/src/json.cpp b/js/src/json.cpp index c18712858c77..8def9d439f6d 100644 --- a/js/src/json.cpp +++ b/js/src/json.cpp @@ -344,7 +344,6 @@ PreprocessValue(JSContext *cx, JSObject *holder, KeyType key, Value *vp, Stringi return false; } - LeaveTrace(cx); InvokeArgsGuard args; if (!cx->stack.pushInvokeArgs(cx, 2, &args)) return false; @@ -861,7 +860,6 @@ Walk(JSContext *cx, JSObject *holder, jsid name, const Value &reviver, Value *vp if (!key) return false; - LeaveTrace(cx); InvokeArgsGuard args; if (!cx->stack.pushInvokeArgs(cx, 2, &args)) return false; diff --git a/js/src/jsopcode.cpp b/js/src/jsopcode.cpp index c77de81daf96..d13698dae147 100644 --- a/js/src/jsopcode.cpp +++ b/js/src/jsopcode.cpp @@ -5154,8 +5154,6 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v, spindex == JSDVG_IGNORE_STACK || spindex == JSDVG_SEARCH_STACK); - LeaveTrace(cx); - if (!cx->hasfp() || !cx->fp()->isScriptFrame()) goto do_fallback; diff --git a/js/src/jsprvtd.h b/js/src/jsprvtd.h index d2248ac9b3b6..3a5747b17073 100644 --- a/js/src/jsprvtd.h +++ b/js/src/jsprvtd.h @@ -155,8 +155,6 @@ class ExecuteArgsGuard; class InvokeFrameGuard; class InvokeArgsGuard; class StringBuffer; -class TraceRecorder; -struct TraceMonitor; class FrameRegs; class StackFrame; diff --git a/js/src/jsscope.cpp b/js/src/jsscope.cpp index ac6e992dc14a..0fed411ca8df 100644 --- a/js/src/jsscope.cpp +++ b/js/src/jsscope.cpp @@ -1147,7 +1147,6 @@ JSObject::clear(JSContext *cx) clearOwnShape(); setMap(shape); - LeaveTraceIfGlobalObject(cx, this); JS_ATOMIC_INCREMENT(&cx->runtime->propertyRemovals); CHECK_SHAPE_CONSISTENCY(this); } diff --git a/js/src/jsscopeinlines.h b/js/src/jsscopeinlines.h index 9dc089f56851..3545b0f46ea9 100644 --- a/js/src/jsscopeinlines.h +++ b/js/src/jsscopeinlines.h @@ -122,7 +122,6 @@ inline void JSObject::updateShape(JSContext *cx) { JS_ASSERT(isNative()); - js::LeaveTraceIfGlobalObject(cx, this); if (hasOwnShape()) setOwnShape(js_GenerateShape(cx)); else diff --git a/js/src/jsutil.h b/js/src/jsutil.h index 856e37cd0b63..eb8c3d3116b8 100644 --- a/js/src/jsutil.h +++ b/js/src/jsutil.h @@ -380,16 +380,10 @@ inline __attribute__ ((unused)) void MUST_FLOW_THROUGH(const char *label) {} inline JS_FORCES_STACK void VOUCH_DOES_NOT_REQUIRE_STACK() {} -inline JS_FORCES_STACK void -JS_ASSERT_NOT_ON_TRACE(JSContext *cx) -{ - JS_ASSERT(!JS_ON_TRACE(cx)); -} #else # define MUST_FLOW_THROUGH(label) ((void) 0) # define MUST_FLOW_LABEL(label) # define VOUCH_DOES_NOT_REQUIRE_STACK() ((void) 0) -# define JS_ASSERT_NOT_ON_TRACE(cx) JS_ASSERT(!JS_ON_TRACE(cx)) #endif /* Crash diagnostics */ diff --git a/js/src/jswrapper.cpp b/js/src/jswrapper.cpp index 8d1bbc107813..4cbd6b1782e7 100644 --- a/js/src/jswrapper.cpp +++ b/js/src/jswrapper.cpp @@ -420,7 +420,6 @@ ForceFrame::enter() frame = context->new_(); if (!frame) return false; - LeaveTrace(context); JS_ASSERT(context->compartment == target->compartment()); JSCompartment *destination = context->compartment; @@ -451,8 +450,6 @@ AutoCompartment::enter() { JS_ASSERT(!entered); if (origin != destination) { - LeaveTrace(context); - JSObject *scopeChain = target->getGlobal(); JS_ASSERT(scopeChain->isNative()); diff --git a/js/src/jsxml.cpp b/js/src/jsxml.cpp index 975e886d2b5c..8bc3dedcbb13 100644 --- a/js/src/jsxml.cpp +++ b/js/src/jsxml.cpp @@ -1792,7 +1792,6 @@ ParseXMLSource(JSContext *cx, JSString *src) InflateStringToBuffer(cx, suffix, constrlen(suffix), chars + offset, &dstlen); chars [offset + dstlen] = 0; - LeaveTrace(cx); xml = NULL; filename = NULL; lineno = 1; @@ -7960,7 +7959,6 @@ js_StepXMLListFilter(JSContext *cx, JSBool initialized) JSXML *xml, *list; JSXMLFilter *filter; - LeaveTrace(cx); sp = cx->regs().sp; if (!initialized) { /* diff --git a/js/src/methodjit/MonoIC.cpp b/js/src/methodjit/MonoIC.cpp index 02ffe7550c1e..cb188289eb11 100644 --- a/js/src/methodjit/MonoIC.cpp +++ b/js/src/methodjit/MonoIC.cpp @@ -1298,8 +1298,6 @@ ic::SplatApplyArgs(VMFrame &f) if (!js_GetLengthProperty(cx, aobj, &length)) THROWV(false); - JS_ASSERT(!JS_ON_TRACE(cx)); - /* Step 6. */ if (length > StackSpace::ARGS_LENGTH_MAX) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index a30092b37797..9f3703020ba2 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -155,7 +155,6 @@ static jsdouble MAX_TIMEOUT_INTERVAL = 1800.0; static jsdouble gTimeoutInterval = -1.0; static volatile bool gCanceled = false; -static bool enableTraceJit = false; static bool enableMethodJit = false; static bool enableProfiling = false; static bool enableTypeInference = false; @@ -4947,8 +4946,6 @@ NewContext(JSRuntime *rt) JS_SetErrorReporter(cx, my_ErrorReporter); JS_SetVersion(cx, JSVERSION_LATEST); SetContextOptions(cx); - if (enableTraceJit) - JS_ToggleOptions(cx, JSOPTION_JIT); if (enableMethodJit) JS_ToggleOptions(cx, JSOPTION_METHODJIT); if (enableTypeInference) @@ -5065,11 +5062,6 @@ ProcessArgs(JSContext *cx, JSObject *obj, OptionParser *op) ParseZealArg(cx, zeal); #endif - if (op->getBoolOption('j')) { - enableTraceJit = true; - JS_ToggleOptions(cx, JSOPTION_JIT); - } - if (op->getBoolOption('p')) { enableProfiling = true; JS_ToggleOptions(cx, JSOPTION_PROFILING); @@ -5254,7 +5246,6 @@ JSBool CheckObjectAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, jsval *vp) { - LeaveTrace(cx); return true; } @@ -5331,7 +5322,7 @@ main(int argc, char **argv, char **envp) || !op.addMultiStringOption('e', "execute", "CODE", "Inline code to run") || !op.addBoolOption('i', "shell", "Enter prompt after running code") || !op.addBoolOption('m', "methodjit", "Enable the JaegerMonkey method JIT") - || !op.addBoolOption('j', "tracejit", "Enable the JaegerMonkey trace JIT") + || !op.addBoolOption('j', "tracejit", "Deprecated; does nothing") || !op.addBoolOption('p', "profiling", "Enable runtime profiling select JIT mode") || !op.addBoolOption('n', "typeinfer", "Enable type inference") || !op.addBoolOption('d', "debugjit", "Enable runtime debug mode for method JIT code") diff --git a/js/src/tests/browser.js b/js/src/tests/browser.js index 77d1a2ca8727..66af768c94d6 100644 --- a/js/src/tests/browser.js +++ b/js/src/tests/browser.js @@ -223,7 +223,6 @@ function optionsInit() { atline: true, xml: true, relimit: true, - tracejit: true, methodjit: true, jitprofiling: true, methodjit_always: true @@ -263,13 +262,6 @@ function gczeal(z) function jit(on) { - // XXX do what shell.js does, namely equate "jit" with "tracejit" - // only - netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); - var tracejitEnabled = Components.utils.tracejit; - if ((on && !tracejitEnabled) || - (!on && tracejitEnabled)) - options('tracejit'); } function jsTestDriverBrowserInit() diff --git a/js/src/tests/shell.js b/js/src/tests/shell.js index f65435fdfd77..2c68d1eb3740 100644 --- a/js/src/tests/shell.js +++ b/js/src/tests/shell.js @@ -649,7 +649,6 @@ function optionsClear() { var optionName = optionNames[i]; if (optionName && optionName != "methodjit" && - optionName != "tracejit" && optionName != "jitprofiling" && optionName != "methodjit_always") { @@ -878,14 +877,6 @@ function jsTestDriverEnd() function jit(on) { - if (on && !options().match(/tracejit/)) - { - options('tracejit'); - } - else if (!on && options().match(/tracejit/)) - { - options('tracejit'); - } } /* diff --git a/js/src/tests/user.js b/js/src/tests/user.js index bed081a443fb..0fb860ccc4db 100755 --- a/js/src/tests/user.js +++ b/js/src/tests/user.js @@ -28,8 +28,6 @@ user_pref("browser.cache.check_doc_frequency", 1); user_pref("extensions.checkCompatibility", false); user_pref("extensions.checkUpdateSecurity", false); user_pref("browser.EULA.override", true); -user_pref("javascript.options.tracejit.chrome", false); -user_pref("javascript.options.tracejit.content", false); user_pref("javascript.options.methodjit.chrome", true); user_pref("javascript.options.methodjit.content", true); user_pref("javascript.options.jitprofiling.chrome", true); diff --git a/js/src/vm/ArgumentsObject-inl.h b/js/src/vm/ArgumentsObject-inl.h index e502afd1828b..c50967d7f583 100644 --- a/js/src/vm/ArgumentsObject-inl.h +++ b/js/src/vm/ArgumentsObject-inl.h @@ -121,25 +121,6 @@ ArgumentsObject::setStackFrame(StackFrame *frame) return setPrivate(frame); } -#define JS_ARGUMENTS_OBJECT_ON_TRACE ((void *)0xa126) -inline bool -ArgumentsObject::onTrace() const -{ - return getPrivate() == JS_ARGUMENTS_OBJECT_ON_TRACE; -} - -inline void -ArgumentsObject::setOnTrace() -{ - return setPrivate(JS_ARGUMENTS_OBJECT_ON_TRACE); -} - -inline void -ArgumentsObject::clearOnTrace() -{ - return setPrivate(NULL); -} - inline const js::Value & NormalArgumentsObject::callee() const { diff --git a/js/src/vm/ArgumentsObject.h b/js/src/vm/ArgumentsObject.h index e9a728fe11e3..ee78feb1bae2 100644 --- a/js/src/vm/ArgumentsObject.h +++ b/js/src/vm/ArgumentsObject.h @@ -202,18 +202,11 @@ class ArgumentsObject : public ::JSObject /* The stack frame for this ArgumentsObject, if the frame is still active. */ inline js::StackFrame *maybeStackFrame() const; inline void setStackFrame(js::StackFrame *frame); - - inline bool onTrace() const; - inline void setOnTrace(); - inline void clearOnTrace(); }; /* * Non-strict arguments have a private: the function's stack frame until the - * function returns, when it is replaced with null. When an arguments object - * is created on-trace its private is JS_ARGUMENTS_OBJECT_ON_TRACE, and when - * the trace exits its private is replaced with the stack frame or null, as - * appropriate. + * function returns, when it is replaced with null. */ class NormalArgumentsObject : public ArgumentsObject { diff --git a/js/src/vm/RegExpObject-inl.h b/js/src/vm/RegExpObject-inl.h index 5be2ad5ca844..8f2eea09c885 100644 --- a/js/src/vm/RegExpObject-inl.h +++ b/js/src/vm/RegExpObject-inl.h @@ -350,7 +350,7 @@ inline bool detail::RegExpPrivateCode::isJITRuntimeEnabled(JSContext *cx) { #if defined(ANDROID) && defined(JS_METHODJIT) - return cx->traceJitEnabled || cx->methodJitEnabled; + return cx->methodJitEnabled; #else return true; #endif diff --git a/js/src/vm/Stack-inl.h b/js/src/vm/Stack-inl.h index 31d8d187ae27..cf965e9b355f 100644 --- a/js/src/vm/Stack-inl.h +++ b/js/src/vm/Stack-inl.h @@ -672,13 +672,6 @@ ArgumentsObject::getElement(uint32 i, Value *vp) if (vp->isMagic(JS_ARGS_HOLE)) return false; - /* - * If this arguments object was created on trace the actual argument value - * could be in a register or something, so we can't optimize. - */ - if (onTrace()) - return false; - /* * If this arguments object has an associated stack frame, that contains * the canonical argument value. Note that strict arguments objects do not @@ -715,10 +708,6 @@ ArgumentsObject::getElements(uint32 start, uint32 count, Value *vp) return true; } - /* If we're on trace, there's no canonical location for elements: fail. */ - if (onTrace()) - return false; - /* Otherwise, element values are on the stack. */ JS_ASSERT(fp->numActualArgs() <= StackSpace::ARGS_LENGTH_MAX); return fp->forEachCanonicalActualArg(detail::CopyNonHoleArgsTo(this, vp), start, count); diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp index 6c3759b48cac..3e5938a3822a 100644 --- a/js/src/vm/Stack.cpp +++ b/js/src/vm/Stack.cpp @@ -644,7 +644,6 @@ ContextStack::popSegment() bool ContextStack::pushInvokeArgs(JSContext *cx, uintN argc, InvokeArgsGuard *iag) { - LeaveTrace(cx); JS_ASSERT(argc <= StackSpace::ARGS_LENGTH_MAX); uintN nvars = 2 + argc; @@ -1096,8 +1095,6 @@ StackIter::StackIter(JSContext *cx, SavedOption savedOption) mjit::ExpandInlineFrames(cx->compartment); #endif - LeaveTrace(cx); - if (StackSegment *seg = cx->stack.seg_) { startOnSegment(seg); settleOnNewState(); diff --git a/js/src/vm/String-inl.h b/js/src/vm/String-inl.h index 5b124c2d4227..6fecbf820140 100644 --- a/js/src/vm/String-inl.h +++ b/js/src/vm/String-inl.h @@ -80,16 +80,6 @@ JS_ALWAYS_INLINE bool JSString::validateLength(JSContext *cx, size_t length) { if (JS_UNLIKELY(length > JSString::MAX_LENGTH)) { - if (JS_ON_TRACE(cx)) { - /* - * If we can't leave the trace, signal OOM condition, otherwise - * exit from trace before throwing. - */ - if (!js::CanLeaveTrace(cx)) - return NULL; - - js::LeaveTrace(cx); - } js_ReportAllocationOverflow(cx); return false; }