Remove LeaveTrace and related structures (bug 698201 part 5, r=luke).

This commit is contained in:
David Anderson 2011-11-22 17:41:43 -05:00
Родитель 66a9ff0dee
Коммит bac3c4eebc
39 изменённых файлов: 16 добавлений и 1010 удалений

Просмотреть файл

@ -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, &ethogram_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, &ethogram_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, &ethogram_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, &ethogram_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, &ethogram_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, &ethogram_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;
}