зеркало из https://github.com/mozilla/gecko-dev.git
Remove LeaveTrace and related structures (bug 698201 part 5, r=luke).
This commit is contained in:
Родитель
66a9ff0dee
Коммит
bac3c4eebc
|
@ -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)
|
||||
|
|
|
@ -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@
|
||||
|
|
|
@ -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 ========================================================
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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<typename K> struct DefaultHash;
|
||||
template<typename K, typename V, typename H> class HashMap;
|
||||
template<typename T> 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<typename T> class Queue;
|
||||
typedef Queue<uint16> SlotList;
|
||||
class TypeMap;
|
||||
class LoopProfile;
|
||||
class InterpreterFrames;
|
||||
|
||||
#if defined(JS_JIT_SPEW) || defined(DEBUG)
|
||||
struct FragPI;
|
||||
typedef nanojit::HashMap<uint32, FragPI, nanojit::DefaultHash<uint32> > 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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -55,238 +55,11 @@
|
|||
|
||||
namespace js {
|
||||
|
||||
/* Holds the number of recording attemps for an address. */
|
||||
typedef HashMap<jsbytecode*,
|
||||
size_t,
|
||||
DefaultHasher<jsbytecode*>,
|
||||
SystemAllocPolicy> RecordAttemptMap;
|
||||
|
||||
/* Holds the profile data for loops. */
|
||||
typedef HashMap<jsbytecode*,
|
||||
LoopProfile*,
|
||||
DefaultHasher<jsbytecode*>,
|
||||
SystemAllocPolicy> LoopProfileMap;
|
||||
|
||||
class Oracle;
|
||||
|
||||
typedef HashSet<JSScript *,
|
||||
DefaultHasher<JSScript *>,
|
||||
SystemAllocPolicy> TracedScriptSet;
|
||||
|
||||
typedef HashMap<JSFunction *,
|
||||
JSString *,
|
||||
DefaultHasher<JSFunction *>,
|
||||
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<nanojit::Fragment*>* 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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<JSDebugHooks *>(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 <sys/time.h>
|
||||
#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[] = "<null>";
|
||||
|
||||
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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<void * const *> 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<intN> 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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -155,8 +155,6 @@ class ExecuteArgsGuard;
|
|||
class InvokeFrameGuard;
|
||||
class InvokeArgsGuard;
|
||||
class StringBuffer;
|
||||
class TraceRecorder;
|
||||
struct TraceMonitor;
|
||||
|
||||
class FrameRegs;
|
||||
class StackFrame;
|
||||
|
|
|
@ -1147,7 +1147,6 @@ JSObject::clear(JSContext *cx)
|
|||
clearOwnShape();
|
||||
setMap(shape);
|
||||
|
||||
LeaveTraceIfGlobalObject(cx, this);
|
||||
JS_ATOMIC_INCREMENT(&cx->runtime->propertyRemovals);
|
||||
CHECK_SHAPE_CONSISTENCY(this);
|
||||
}
|
||||
|
|
|
@ -122,7 +122,6 @@ inline void
|
|||
JSObject::updateShape(JSContext *cx)
|
||||
{
|
||||
JS_ASSERT(isNative());
|
||||
js::LeaveTraceIfGlobalObject(cx, this);
|
||||
if (hasOwnShape())
|
||||
setOwnShape(js_GenerateShape(cx));
|
||||
else
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -420,7 +420,6 @@ ForceFrame::enter()
|
|||
frame = context->new_<DummyFrameGuard>();
|
||||
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());
|
||||
|
||||
|
|
|
@ -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) {
|
||||
/*
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче