Merge.
Merge.
--- a/js/src/js.cpp
+++ b/js/src/js.cpp
@@ -1,10 +1,10 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sw=4 et tw=78:
+ * vim: set ts=8 sw=4 et tw=99:
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
@@ -264,22 +264,22 @@ Process(JSContext *cx, JSObject *obj, ch
while((ch = fgetc(file)) != EOF) {
if (ch == '\n' || ch == '\r')
break;
}
}
ungetc(ch, file);
oldopts = JS_GetOptions(cx);
- JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO);
+ JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
script = JS_CompileFileHandle(cx, obj, filename, file);
JS_SetOptions(cx, oldopts);
if (script) {
if (!compileOnly)
- (void)JS_ExecuteScript(cx, obj, script, &result);
+ (void)JS_ExecuteScript(cx, obj, script, NULL);
JS_DestroyScript(cx, script);
}
if (file != stdin)
fclose(file);
return;
}
@@ -648,24 +648,24 @@ Load(JSContext *cx, JSObject *obj, uintN
for (i = 0; i < argc; i++) {
str = JS_ValueToString(cx, argv[i]);
if (!str)
return JS_FALSE;
argv[i] = STRING_TO_JSVAL(str);
filename = JS_GetStringBytes(str);
errno = 0;
oldopts = JS_GetOptions(cx);
- JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO);
+ JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
script = JS_CompileFile(cx, obj, filename);
JS_SetOptions(cx, oldopts);
if (!script) {
ok = JS_FALSE;
} else {
ok = !compileOnly
- ? JS_ExecuteScript(cx, obj, script, &result)
+ ? JS_ExecuteScript(cx, obj, script, NULL)
: JS_TRUE;
JS_DestroyScript(cx, script);
}
if (!ok)
return JS_FALSE;
}
return JS_TRUE;
@@ -1432,17 +1432,17 @@ DisassFile(JSContext *cx, JSObject *obj,
str = JS_ValueToString(cx, argv[0]);
if (!str)
return JS_FALSE;
argv[0] = STRING_TO_JSVAL(str);
filename = JS_GetStringBytes(str);
oldopts = JS_GetOptions(cx);
- JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO);
+ JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
script = JS_CompileFile(cx, obj, filename);
JS_SetOptions(cx, oldopts);
if (!script)
return JS_FALSE;
obj = JS_NewScriptObject(cx, script);
if (!obj)
return JS_FALSE;
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4580,27 +4580,31 @@ JS_CompileUCScript(JSContext *cx, JSObje
#define LAST_FRAME_CHECKS(cx,result) \
JS_BEGIN_MACRO \
if (!(cx)->fp) { \
(cx)->weakRoots.lastInternalResult = JSVAL_NULL; \
LAST_FRAME_EXCEPTION_CHECK(cx, result); \
} \
JS_END_MACRO
+#define JS_OPTIONS_TO_TCFLAGS(cx) \
+ ((((cx)->options & JSOPTION_COMPILE_N_GO) ? TCF_COMPILE_N_GO : 0) | \
+ (((cx)->options & JSOPTION_NO_SCRIPT_RVAL) ? TCF_NO_SCRIPT_RVAL : 0))
+
JS_PUBLIC_API(JSScript *)
JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj,
JSPrincipals *principals,
const jschar *chars, size_t length,
const char *filename, uintN lineno)
{
uint32 tcflags;
JSScript *script;
CHECK_REQUEST(cx);
- tcflags = JS_HAS_COMPILE_N_GO_OPTION(cx) ? TCF_COMPILE_N_GO : 0;
+ tcflags = JS_OPTIONS_TO_TCFLAGS(cx);
script = js_CompileScript(cx, obj, principals, tcflags,
chars, length, NULL, filename, lineno);
LAST_FRAME_CHECKS(cx, script);
return script;
}
JS_PUBLIC_API(JSBool)
JS_BufferIsCompilableUnit(JSContext *cx, JSObject *obj,
@@ -4656,17 +4660,17 @@ JS_CompileFile(JSContext *cx, JSObject *
fp = fopen(filename, "r");
if (!fp) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_OPEN,
filename, "No such file or directory");
return NULL;
}
}
- tcflags = JS_HAS_COMPILE_N_GO_OPTION(cx) ? TCF_COMPILE_N_GO : 0;
+ tcflags = JS_OPTIONS_TO_TCFLAGS(cx);
script = js_CompileScript(cx, obj, NULL, tcflags,
NULL, 0, fp, filename, 1);
if (fp != stdin)
fclose(fp);
LAST_FRAME_CHECKS(cx, script);
return script;
}
@@ -4681,17 +4685,17 @@ JS_PUBLIC_API(JSScript *)
JS_CompileFileHandleForPrincipals(JSContext *cx, JSObject *obj,
const char *filename, FILE *file,
JSPrincipals *principals)
{
uint32 tcflags;
JSScript *script;
CHECK_REQUEST(cx);
- tcflags = JS_HAS_COMPILE_N_GO_OPTION(cx) ? TCF_COMPILE_N_GO : 0;
+ tcflags = JS_OPTIONS_TO_TCFLAGS(cx);
script = js_CompileScript(cx, obj, principals, tcflags,
NULL, 0, file, filename, 1);
LAST_FRAME_CHECKS(cx, script);
return script;
}
JS_PUBLIC_API(JSObject *)
JS_NewScriptObject(JSContext *cx, JSScript *script)
@@ -5017,17 +5021,20 @@ JS_EvaluateUCScriptForPrincipals(JSConte
const jschar *chars, uintN length,
const char *filename, uintN lineno,
jsval *rval)
{
JSScript *script;
JSBool ok;
CHECK_REQUEST(cx);
- script = js_CompileScript(cx, obj, principals, TCF_COMPILE_N_GO,
+ script = js_CompileScript(cx, obj, principals,
+ !rval
+ ? TCF_COMPILE_N_GO | TCF_NO_SCRIPT_RVAL
+ : TCF_COMPILE_N_GO,
chars, length, NULL, filename, lineno);
if (!script)
return JS_FALSE;
ok = js_Execute(cx, obj, script, NULL, 0, rval);
LAST_FRAME_CHECKS(cx, ok);
JS_DestroyScript(cx, script);
return ok;
}
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -583,16 +583,21 @@ JS_StringToVersion(const char *string);
times, where n is length
of the input string */
#define JSOPTION_ANONFUNFIX JS_BIT(10) /* Disallow function () {} in
statement context per
ECMA-262 Edition 3. */
#define JSOPTION_JIT JS_BIT(11) /* Enable JIT compilation. */
+#define JSOPTION_NO_SCRIPT_RVAL JS_BIT(12) /* A promise to the compiler
+ that a null rval out-param
+ will be passed to each call
+ to JS_ExecuteScript. */
+
extern JS_PUBLIC_API(uint32)
JS_GetOptions(JSContext *cx);
extern JS_PUBLIC_API(uint32)
JS_SetOptions(JSContext *cx, uint32 options);
extern JS_PUBLIC_API(uint32)
JS_ToggleOptions(JSContext *cx, uint32 options);
--- a/js/src/jsemit.cpp
+++ b/js/src/jsemit.cpp
@@ -5220,18 +5220,22 @@ js_EmitTree(JSContext *cx, JSCodeGenerat
case TOK_SEMI:
pn2 = pn->pn_kid;
if (pn2) {
/*
* Top-level or called-from-a-native JS_Execute/EvaluateScript,
* debugger, and eval frames may need the value of the ultimate
* expression statement as the script's result, despite the fact
* that it appears useless to the compiler.
+ *
+ * API users may also set the JSOPTION_NO_SCRIPT_RVAL option when
+ * calling JS_Compile* suppress JSOP_POPV.
*/
- useful = wantval = !(cg->treeContext.flags & TCF_IN_FUNCTION);
+ useful = wantval =
+ !(cg->treeContext.flags & (TCF_IN_FUNCTION | TCF_NO_SCRIPT_RVAL));
if (!useful) {
if (!CheckSideEffects(cx, cg, pn2, &useful))
return JS_FALSE;
}
/*
* Don't eliminate apparently useless expressions if they are
* labeled expression statements. The tc->topStmt->update test
--- a/js/src/jsemit.h
+++ b/js/src/jsemit.h
@@ -188,16 +188,18 @@ struct JSTreeContext { /* t
#define TCF_FUN_HEAVYWEIGHT 0x40 /* function needs Call object per call */
#define TCF_FUN_IS_GENERATOR 0x80 /* parsed yield statement in function */
#define TCF_HAS_DEFXMLNS 0x100 /* default xml namespace = ...; parsed */
#define TCF_HAS_FUNCTION_STMT 0x200 /* block contains a function statement */
#define TCF_GENEXP_LAMBDA 0x400 /* flag lambda from generator expression */
#define TCF_COMPILE_N_GO 0x800 /* compiler-and-go mode of script, can
optimize name references based on scope
chain */
+#define TCF_NO_SCRIPT_RVAL 0x1000 /* API caller does not want result value
+ from global script */
/*
* Flags to propagate out of the blocks.
*/
#define TCF_RETURN_FLAGS (TCF_RETURN_EXPR | TCF_RETURN_VOID)
/*
* Flags to propagate from FunctionBody.
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1549,17 +1549,18 @@ js_Execute(JSContext *cx, JSObject *chai
}
if (hook) {
hookData = hook(cx, &frame, JS_TRUE, 0,
cx->debugHooks->executeHookData);
}
ok = js_Interpret(cx);
- *result = frame.rval;
+ if (result)
+ *result = frame.rval;
if (hookData) {
hook = cx->debugHooks->executeHook;
if (hook)
hook(cx, &frame, JS_FALSE, &ok, hookData);
}
out2:
--- a/js/src/jsparse.cpp
+++ b/js/src/jsparse.cpp
@@ -561,17 +561,17 @@ js_CompileScript(JSContext *cx, JSObject
JSTokenType tt;
JSParseNode *pn;
uint32 scriptGlobals;
JSScript *script;
#ifdef METER_PARSENODES
void *sbrk(ptrdiff_t), *before = sbrk(0);
#endif
- JS_ASSERT(!(tcflags & ~TCF_COMPILE_N_GO));
+ JS_ASSERT(!(tcflags & ~(TCF_COMPILE_N_GO | TCF_NO_SCRIPT_RVAL)));
if (!js_InitParseContext(cx, &pc, principals, chars, length, file,
filename, lineno)) {
return NULL;
}
/*
* From this point the control must flow through the label out.
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -64,17 +64,17 @@
#include "jsautooplen.h" // generated headers last
/* Number of iterations of a loop before we start tracing. */
#define HOTLOOP 2
/* Number of times we wait to exit on a side exit before we try to extend the tree. */
#define HOTEXIT 0
-/* Maximum number of guards after which we no longer try to demote loop variables.
+/* Maximum number of guards after which we no longer try to demote loop variables.
0=off */
#define DEMOTE_THRESHOLD 32
#ifdef DEBUG
#define ABORT_TRACE(msg) do { fprintf(stdout, "abort: %d: %s\n", __LINE__, msg); return false; } while(0)
#else
#define ABORT_TRACE(msg) return false
#endif
@@ -306,30 +306,30 @@ public:
v = (LOpcode)((int)v & ~LIR64);
LIns* d0;
LIns* d1;
LIns* result = out->ins2(v, d0 = demote(out, s0), d1 = demote(out, s1));
if (!overflowSafe(d0) || !overflowSafe(d1))
out->insGuard(LIR_xt, out->ins1(LIR_ov, result), recorder.snapshot());
return out->ins1(LIR_i2f, result);
}
- } else if (v == LIR_or &&
+ } else if (v == LIR_or &&
s0->isop(LIR_lsh) && isconst(s0->oprnd2(), 16) &&
s1->isop(LIR_and) && isconst(s1->oprnd2(), 0xffff)) {
LIns* msw = s0->oprnd1();
LIns* lsw = s1->oprnd1();
LIns* x;
LIns* y;
if (lsw->isop(LIR_add) &&
- lsw->oprnd1()->isop(LIR_and) &&
+ lsw->oprnd1()->isop(LIR_and) &&
lsw->oprnd2()->isop(LIR_and) &&
- isconst(lsw->oprnd1()->oprnd2(), 0xffff) &&
+ isconst(lsw->oprnd1()->oprnd2(), 0xffff) &&
isconst(lsw->oprnd2()->oprnd2(), 0xffff) &&
- msw->isop(LIR_add) &&
- msw->oprnd1()->isop(LIR_add) &&
+ msw->isop(LIR_add) &&
+ msw->oprnd1()->isop(LIR_add) &&
msw->oprnd2()->isop(LIR_rsh) &&
msw->oprnd1()->oprnd1()->isop(LIR_rsh) &&
msw->oprnd1()->oprnd2()->isop(LIR_rsh) &&
isconst(msw->oprnd2()->oprnd2(), 16) &&
isconst(msw->oprnd1()->oprnd1()->oprnd2(), 16) &&
isconst(msw->oprnd1()->oprnd2()->oprnd2(), 16) &&
(x = lsw->oprnd1()->oprnd1()) == msw->oprnd1()->oprnd1()->oprnd1() &&
(y = lsw->oprnd2()->oprnd1()) == msw->oprnd1()->oprnd2()->oprnd1() &&
@@ -403,17 +403,17 @@ public:
for (n = 0; n < ngslots; ++n) { \
vp = &STOBJ_GET_SLOT(globalObj, gslots[n]); \
{ code; } \
INC_VPNUM(); \
} \
JS_END_MACRO
/* This macro can be used to iterate over all slots in currently pending
- frames that make up the native frame, consisting of rval, args, vars,
+ frames that make up the native frame, consisting of rval, args, vars,
and stack (except for the top-level frame which does not have args or vars. */
#define FORALL_SLOTS_IN_PENDING_FRAMES(cx, callDepth, code) \
JS_BEGIN_MACRO \
DEF_VPNAME; \
unsigned n; \
jsval* vp; \
JSStackFrame* currentFrame = cx->fp; \
JSStackFrame* entryFrame; \
@@ -499,22 +499,22 @@ TraceRecorder::TraceRecorder(JSContext*
mark = JS_ARENA_MARK(&cx->tempPool);
localNames = js_GetLocalNameArray(cx, cx->fp->fun, &cx->tempPool);
}
#else
localNames = NULL;
#endif
ptrdiff_t offset = 0;
FORALL_GLOBAL_SLOTS(cx, treeInfo->ngslots, treeInfo->gslots,
- import(gp_ins, offset, vp, *m, vpname, vpnum, localNames);
+ import(gp_ins, offset, vp, *m, vpname, vpnum, localNames);
m++; offset += sizeof(double);
);
offset = -treeInfo->nativeStackBase + 8;
FORALL_SLOTS_IN_PENDING_FRAMES(cx, callDepth,
- import(lirbuf->sp, offset, vp, *m, vpname, vpnum, localNames);
+ import(lirbuf->sp, offset, vp, *m, vpname, vpnum, localNames);
m++; offset += sizeof(double);
);
#ifdef DEBUG
JS_ARENA_RELEASE(&cx->tempPool, mark);
#endif
recompileFlag = false;
}
@@ -591,17 +591,17 @@ findInternableGlobals(JSContext* cx, JSS
}
JS_UNLOCK_OBJ(cx, pobj);
}
return count;
}
/* Calculate the total number of native frame slots we need from this frame
all the way back to the entry frame, including the current stack usage. */
-static unsigned nativeStackSlots(unsigned callDepth,
+static unsigned nativeStackSlots(unsigned callDepth,
JSStackFrame* fp, JSFrameRegs& regs)
{
unsigned slots = 0;
for (;;) {
slots += 1/*rval*/ + (regs.sp - StackBase(fp));
if (fp->callee)
slots += 1/*this*/ + fp->fun->nargs + fp->script->nfixed;
if (callDepth-- == 0)
@@ -613,37 +613,37 @@ static unsigned nativeStackSlots(unsigne
/* Determine the offset in the native global frame for a jsval we track */
ptrdiff_t
TraceRecorder::nativeGlobalOffset(jsval* p) const
{
size_t offset = 0;
unsigned ngslots = treeInfo->ngslots;
uint16* gslots = treeInfo->gslots;
- for (unsigned n = 0; n < ngslots; ++n, offset += sizeof(double))
- if (p == &STOBJ_GET_SLOT(globalObj, gslots[n]))
+ for (unsigned n = 0; n < ngslots; ++n, offset += sizeof(double))
+ if (p == &STOBJ_GET_SLOT(globalObj, gslots[n]))
return offset;
return -1; /* not a global */
}
-
+
/* Determine the offset in the native stack for a jsval we track */
ptrdiff_t
TraceRecorder::nativeStackOffset(jsval* p) const
{
-#ifdef DEBUG
+#ifdef DEBUG
size_t slow_offset = 0;
FORALL_SLOTS_IN_PENDING_FRAMES(cx, callDepth,
if (vp == p) goto done;
slow_offset += sizeof(double)
);
/* if its not in a pending frame, it must be on the stack of the current frame above
sp but below script->depth */
JS_ASSERT(size_t(p - StackBase(cx->fp)) < StackDepth(cx->fp->script));
slow_offset += size_t(p - cx->fp->regs->sp) * sizeof(double);
-done:
+done:
#define RETURN(offset) { JS_ASSERT((offset) == slow_offset); return offset; }
#else
#define RETURN(offset) { return offset; }
#endif
size_t offset = 0;
JSStackFrame* currentFrame = cx->fp;
JSStackFrame* entryFrame;
JSStackFrame* fp = currentFrame;
@@ -652,17 +652,17 @@ done:
unsigned frames = callDepth+1;
JSStackFrame** fstack = (JSStackFrame **)alloca(frames * sizeof (JSStackFrame *));
JSStackFrame** fspstop = &fstack[frames];
JSStackFrame** fsp = fspstop-1;
fp = currentFrame;
for (;; fp = fp->down) { *fsp-- = fp; if (fp == entryFrame) break; }
for (fsp = fstack; fsp < fspstop; ++fsp) {
JSStackFrame* f = *fsp;
- if (p == &f->rval)
+ if (p == &f->rval)
RETURN(offset);
offset += sizeof(double);
if (f->callee) {
if (size_t(p - &f->argv[-1]) < (unsigned)f->fun->nargs+1)
RETURN(offset + size_t(p - &f->argv[-1]) * sizeof(double));
offset += (f->fun->nargs+1) * sizeof(double);
if (size_t(p - &f->slots[0]) < f->script->nfixed)
RETURN(offset + size_t(p - &f->slots[0]) * sizeof(double));
@@ -672,17 +672,17 @@ done:
RETURN(offset + size_t(p - StackBase(f)) * sizeof(double));
offset += size_t(f->regs->sp - StackBase(f)) * sizeof(double);
}
/* if its not in a pending frame, it must be on the stack of the current frame above
sp but below script->depth */
JS_ASSERT(size_t(p - StackBase(currentFrame)) < StackDepth(currentFrame->script));
offset += size_t(p - currentFrame->regs->sp) * sizeof(double);
RETURN(offset);
-#undef RETURN
+#undef RETURN
}
/* Track the maximum number of native frame slots we need during
execution. */
void
TraceRecorder::trackNativeStackUse(unsigned slots)
{
if (slots > treeInfo->maxNativeStackSlots)
@@ -865,17 +865,17 @@ box(JSContext* cx, unsigned ngslots, uin
++mp; ++np
);
debug_only(printf("\n");)
return true;
}
/* Emit load instructions onto the trace that read the initial stack state. */
void
-TraceRecorder::import(LIns* base, ptrdiff_t offset, jsval* p, uint8& t,
+TraceRecorder::import(LIns* base, ptrdiff_t offset, jsval* p, uint8& t,
const char *prefix, int index, jsuword *localNames)
{
JS_ASSERT(TYPEMAP_GET_TYPE(t) != TYPEMAP_TYPE_ANY);
LIns* ins;
if (TYPEMAP_GET_TYPE(t) == JSVAL_INT) { /* demoted */
JS_ASSERT(isInt32(*p));
/* Ok, we have a valid demotion attempt pending, so insert an integer
read and promote it to double since all arithmetic operations expect
@@ -926,17 +926,17 @@ TraceRecorder::set(jsval* p, LIns* i, bo
i = ::demote(lir, i);
/* If we are writing to this location for the first time, calculate the offset into the
native frame manually, otherwise just look up the last load or store associated with
the same source address (p) and use the same offset/base. */
LIns* x;
if ((x = nativeFrameTracker.get(p)) == NULL) {
ptrdiff_t offset = nativeGlobalOffset(p);
nativeFrameTracker.set(p, (offset == -1) /* not a global */
- ? lir->insStorei(i, lirbuf->sp,
+ ? lir->insStorei(i, lirbuf->sp,
-treeInfo->nativeStackBase + nativeStackOffset(p) + 8)
: lir->insStorei(i, gp_ins,
offset));
} else {
#define ASSERT_VALID_CACHE_HIT(base, offset) \
JS_ASSERT(base == lirbuf->sp || base == gp_ins); \
JS_ASSERT(offset == ((base == lirbuf->sp) \
? -treeInfo->nativeStackBase + nativeStackOffset(p) + 8 \
@@ -949,17 +949,17 @@ TraceRecorder::set(jsval* p, LIns* i, bo
ASSERT_VALID_CACHE_HIT(x->oprnd2(), x->oprnd3()->constval());
lir->insStorei(i, x->oprnd2(), x->oprnd3()->constval());
} else {
JS_ASSERT(x->isop(LIR_sti) || x->isop(LIR_stqi));
ASSERT_VALID_CACHE_HIT(x->oprnd2(), x->immdisp());
lir->insStorei(i, x->oprnd2(), x->immdisp());
}
}
-#undef ASSERT_VALID_CACHE_HIT
+#undef ASSERT_VALID_CACHE_HIT
}
LIns*
TraceRecorder::get(jsval* p)
{
return tracker.get(p);
}
@@ -1073,17 +1073,17 @@ TraceRecorder::checkType(jsval& v, uint8
JS_ASSERT(TYPEMAP_GET_TYPE(t) == JSVAL_INT &&
TYPEMAP_GET_FLAG(t, TYPEMAP_FLAG_DEMOTE) &&
!TYPEMAP_GET_FLAG(t, TYPEMAP_FLAG_DONT_DEMOTE));
if (!i->isop(LIR_i2f)) {
AUDIT(slotPromoted);
#ifdef DEBUG
ptrdiff_t offset;
printf("demoting type of a slot #%d failed, locking it and re-compiling\n",
- ((offset = nativeGlobalOffset(&v)) == -1)
+ ((offset = nativeGlobalOffset(&v)) == -1)
? nativeStackOffset(&v)
: offset);
#endif
TYPEMAP_SET_FLAG(t, TYPEMAP_FLAG_DONT_DEMOTE);
TYPEMAP_SET_TYPE(t, JSVAL_DOUBLE);
recompileFlag = true;
return true; /* keep going, recompileFlag will trigger error when we are done with
all the slots */
@@ -1231,17 +1231,17 @@ js_ExecuteTree(JSContext* cx, Fragment*
f->releaseCode(JS_TRACE_MONITOR(cx).fragmento);
return NULL;
}
double* global = (double *)alloca((ti->ngslots+1) * sizeof(double));
debug_only(*(uint64*)&global[ti->ngslots] = 0xdeadbeefdeadbeefLL;)
double* stack = (double *)alloca((ti->maxNativeStackSlots+1) * sizeof(double));
debug_only(*(uint64*)&stack[ti->maxNativeStackSlots] = 0xdeadbeefdeadbeefLL;)
- if (!unbox(cx, ti->ngslots, ti->gslots, 0 /*callDepth*/,
+ if (!unbox(cx, ti->ngslots, ti->gslots, 0 /*callDepth*/,
ti->typeMap, global, stack)) {
AUDIT(typeMapMismatchAtEntry);
debug_only(printf("type-map mismatch, skipping trace.\n");)
return NULL;
}
double* entry_sp = &stack[ti->nativeStackBase/sizeof(double) +
(cx->fp->regs->sp - StackBase(cx->fp) - 1)];
JSObject** callstack = (JSObject**)alloca(ti->maxCallDepth * sizeof(JSObject*));
@@ -1266,23 +1266,23 @@ js_ExecuteTree(JSContext* cx, Fragment*
cx->fp->regs->pc += lr->exit->ip_adj;
#if defined(DEBUG) && defined(NANOJIT_IA32)
printf("leaving trace at %s:%u@%u, sp=%p, ip=%p, cycles=%llu\n",
cx->fp->script->filename, js_PCToLineNumber(cx, cx->fp->script, cx->fp->regs->pc),
cx->fp->regs->pc - cx->fp->script->code,
state.sp, lr->jmp,
(rdtsc() - start));
#endif
- box(cx, ti->ngslots, ti->gslots, lr->calldepth,
+ box(cx, ti->ngslots, ti->gslots, lr->calldepth,
lr->exit->typeMap, global, stack);
JS_ASSERT(*(uint64*)&stack[ti->maxNativeStackSlots] == 0xdeadbeefdeadbeefLL);
JS_ASSERT(*(uint64*)&global[ti->ngslots] == 0xdeadbeefdeadbeefLL);
AUDIT(sideExitIntoInterpreter);
-
+
return lr;
}
static bool
js_AttemptToExtendTree(JSContext* cx, GuardRecord* lr, Fragment* f)
{
debug_only(printf("trying to attach another branch to the tree\n");)
@@ -1389,20 +1389,20 @@ js_LoopEdge(JSContext* cx, jsbytecode* o
}
/* recording primary trace */
return js_StartRecorder(cx, NULL, f, ti->typeMap);
}
return false;
}
GuardRecord* lr = js_ExecuteTree(cx, f);
-
+
if (!lr) /* did the tree actually execute? */
return false;
-
+
/* if the side exit terminates the loop, don't try to attach a trace here */
if (lr->exit->loopExit)
return false;
return js_AttemptToExtendTree(cx, lr, f);
}
void
@@ -1544,17 +1544,17 @@ TraceRecorder::inc(jsval& v, jsint incr,
{
LIns* v_ins = get(&v);
if (!inc(v, v_ins, incr, pre))
return false;
set(&v, v_ins);
return true;
}
-/*
+/*
* On exit, v_ins is the incremented unboxed value, and the appropriate
* value (pre- or post-increment as described by pre) is stacked.
*/
bool
TraceRecorder::inc(jsval& v, LIns*& v_ins, jsint incr, bool pre)
{
if (!isNumber(v))
ABORT_TRACE("can only inc numbers");
@@ -1996,17 +1996,17 @@ TraceRecorder::record_EnterFrame()
LIns* void_ins = lir->insImm(JSVAL_TO_BOOLEAN(JSVAL_VOID));
set(&fp->rval, void_ins, true);
unsigned n;
for (n = 0; n < fp->script->nfixed; ++n)
set(&fp->slots[n], void_ins, true);
return true;
}
-bool
+bool
TraceRecorder::record_LeaveFrame()
{
if (callDepth-- <= 0)
return false;
atoms = cx->fp->script->atomMap.vector;
stack(-1, rval_ins); // LeaveFrame gets called after the interpreter stored rval so -1, not 0
return true;
}