Propagate error exceptions from TraceRecorder ctor; fiddle/trim space.

This commit is contained in:
Brendan Eich 2008-07-15 10:26:15 -07:00
parent 852092181c
commit d49babfbb7
2 changed files with 57 additions and 49 deletions

View File

@ -37,28 +37,28 @@
*
* ***** END LICENSE BLOCK ***** */
#include <math.h>
#include "nanojit/avmplus.h"
#include "nanojit/nanojit.h"
#include "jsarray.h"
#include "jsbool.h"
#include "jscntxt.h"
#include "jsobj.h"
#include "jsfun.h"
#include "jsinterp.h"
#include "jsprf.h"
#include "jsscript.h"
#include "jsscope.h"
#include "jstracer.h"
#include "jsautooplen.h"
#include "jsstddef.h" // always first
#include "jsprf.h" // low-level (NSPR-based) headers next
#include <math.h> // standard headers next
#ifdef _MSC_VER
#include <malloc.h>
#define alloca _alloca
#endif
#include "nanojit/avmplus.h" // nanojit
#include "nanojit/nanojit.h"
#include "jsarray.h" // higher-level library and API headers
#include "jsbool.h"
#include "jscntxt.h"
#include "jsfun.h"
#include "jsinterp.h"
#include "jsobj.h"
#include "jsscript.h"
#include "jsscope.h"
#include "jstracer.h"
#include "jsautooplen.h" // generated headers last
#ifdef DEBUG
#define ABORT_TRACE(msg) do { fprintf(stderr, "abort: %d: %s\n", __LINE__, msg); return false; } while(0)
#else
@ -122,7 +122,7 @@ Tracker::clear()
}
}
LIns*
LIns*
Tracker::get(const void* v) const
{
struct Tracker::Page* p = findPage(v);
@ -227,7 +227,7 @@ public:
LIns* result = out->ins1(LIR_neg, demote(out, s0));
out->insGuard(LIR_xt, out->ins1(LIR_ov, result), recorder.snapshot());
return out->ins1(LIR_i2f, result);
}
}
break;
default:;
}
@ -372,10 +372,10 @@ class ExitFilter: public LirWriter
Fragment* _fragment;
Tracker* _tracker;
public:
ExitFilter(LirWriter *out, JSContext* cx, JSStackFrame* entryFrame,
ExitFilter(LirWriter *out, JSContext* cx, JSStackFrame* entryFrame,
Fragment* fragment, Tracker* tracker):
LirWriter(out), _cx(cx),
_entryFrame(entryFrame),
LirWriter(out), _cx(cx),
_entryFrame(entryFrame),
_fragment(fragment), _tracker(tracker)
{
}
@ -429,12 +429,12 @@ TraceRecorder::TraceRecorder(JSContext* cx, Fragmento* fragmento, Fragment* _fra
this->atoms = cx->fp->script->atomMap.vector;
#ifdef DEBUG
printf("recording starting from %s:%u\n", cx->fp->script->filename,
printf("recording starting from %s:%u\n", cx->fp->script->filename,
js_PCToLineNumber(cx, cx->fp->script, entryRegs.pc));
#endif
fragment->calldepth = 0;
lirbuf = new (&gc) LirBuffer(fragmento, builtins);
fragment->lirbuf = lirbuf;
lir = lir_buf_writer = new (&gc) LirBufWriter(lirbuf);
@ -444,36 +444,42 @@ TraceRecorder::TraceRecorder(JSContext* cx, Fragmento* fragmento, Fragment* _fra
#endif
lir = cse_filter = new (&gc) CseFilter(lir, &gc);
lir = expr_filter = new (&gc) ExprFilter(lir);
lir = exit_filter = new (&gc) ExitFilter(lir, cx,
lir = exit_filter = new (&gc) ExitFilter(lir, cx,
entryFrame, fragment, &tracker);
lir = func_filter = new (&gc) FuncFilter(lir, *this);
lir->ins0(LIR_trace);
if (fragment->vmprivate == NULL) {
/* calculate the number of globals we want to intern */
unsigned internableGlobals = findInternableGlobals(entryFrame, NULL);
int internableGlobals = findInternableGlobals(entryFrame, NULL);
if (internableGlobals < 0)
return;
/* generate the entry map and store it in the trace */
unsigned entryNativeFrameSlots = nativeFrameSlots(entryFrame, entryRegs);
LIns* data = lir_buf_writer->skip(sizeof(*fragmentInfo) +
internableGlobals * sizeof(uint16) +
entryNativeFrameSlots * sizeof(uint8));
internableGlobals * sizeof(uint16) +
entryNativeFrameSlots * sizeof(uint8));
fragmentInfo = (VMFragmentInfo*)data->payload();
fragmentInfo->typeMap = (uint8*)(fragmentInfo + 1);
fragmentInfo->gslots = (uint16*)(fragmentInfo->typeMap +
entryNativeFrameSlots * sizeof(uint8));
entryNativeFrameSlots * sizeof(uint8));
fragmentInfo->entryNativeFrameSlots = entryNativeFrameSlots;
fragmentInfo->nativeStackBase = (entryNativeFrameSlots -
(entryRegs.sp - entryFrame->spbase)) * sizeof(double);
(entryRegs.sp - entryFrame->spbase)) * sizeof(double);
fragmentInfo->maxNativeFrameSlots = entryNativeFrameSlots;
fragmentInfo->maxCallDepth = 0;
/* setup the list of global properties we want to intern */
findInternableGlobals(entryFrame, fragmentInfo->gslots);
fragmentInfo->ngslots = internableGlobals;
fragmentInfo->globalShape = OBJ_SCOPE(globalObj)->shape;
/* build the entry type map */
uint8* m = fragmentInfo->typeMap;
/* remember the coerced type of each active slot in the type map */
FORALL_SLOTS_IN_PENDING_FRAMES(cx, fragmentInfo->ngslots, fragmentInfo->gslots,
FORALL_SLOTS_IN_PENDING_FRAMES(cx, fragmentInfo->ngslots, fragmentInfo->gslots,
entryFrame, entryFrame,
*m++ = getCoercedType(*vp)
);
@ -482,7 +488,7 @@ TraceRecorder::TraceRecorder(JSContext* cx, Fragmento* fragmento, Fragment* _fra
fragmentInfo = (VMFragmentInfo*)fragment->vmprivate;
}
fragment->vmprivate = fragmentInfo;
fragment->state = lir->insImm8(LIR_param, Assembler::argRegs[0], 0);
fragment->param1 = lir->insImm8(LIR_param, Assembler::argRegs[1], 0);
fragment->sp = lir->insLoadi(fragment->state, offsetof(InterpState, sp));
@ -570,7 +576,7 @@ TraceRecorder::isGlobal(jsval* p) const
size_t(p - globalObj->dslots) < size_t(globalObj->dslots[-1] - JS_INITIAL_NSLOTS);
}
unsigned
int
TraceRecorder::findInternableGlobals(JSStackFrame* fp, uint16* slots) const
{
unsigned count = 0;
@ -586,7 +592,7 @@ TraceRecorder::findInternableGlobals(JSStackFrame* fp, uint16* slots) const
JSProperty *prop;
JSScopeProperty* sprop;
if (!js_LookupProperty(cx, globalObj, id, &pobj, &prop))
continue;
return -1;
if (!prop)
continue; /* property not found -- string constant? */
if (pobj == globalObj) {
@ -783,7 +789,7 @@ box_jsval(JSContext* cx, jsval& v, uint8 t, double* slot)
/* Attempt to unbox the given JS frame into a native frame, checking along the way that the
supplied typemap holds. */
static bool
unbox(JSContext* cx, unsigned ngslots, uint16* gslots,
unbox(JSContext* cx, unsigned ngslots, uint16* gslots,
JSStackFrame* entryFrame, JSStackFrame* currentFrame, uint8* map, double* native)
{
verbose_only(printf("unbox native@%p ", native);)
@ -857,8 +863,8 @@ TraceRecorder::import(jsval* p, uint8& t, char *prefix, int index)
JS_snprintf(name, sizeof name, "$%s%d", prefix, index);
lirbuf->names->addName(ins, name);
static const char* typestr[] = {
"object", "int", "double", "3", "string", "5", "boolean", "any"
};
"object", "int", "double", "3", "string", "5", "boolean", "any"
};
printf("import vp=%p name=%s type=%s flags=%d\n", p, name, typestr[t & 7], t >> 3);
#endif
}
@ -1137,7 +1143,9 @@ js_LoopEdge(JSContext* cx)
if (!f->isBlacklisted() && hits >= HOTLOOP1) {
if (hits == HOTLOOP1 || hits == HOTLOOP2 || hits == HOTLOOP3) {
tm->recorder = new (&gc) TraceRecorder(cx, tm->fragmento, f);
return true; /* start recording */
/* start recording if no exception during construction */
return !cx->throwing;
}
if (hits > HOTLOOP3)
f->blacklist();
@ -1151,7 +1159,7 @@ js_LoopEdge(JSContext* cx)
verbose_only(printf("global shape mismatch, skipping trace.\n");)
return false;
}
double* native = (double *)alloca((fi->maxNativeFrameSlots+1) * sizeof(double));
#ifdef DEBUG
*(uint64*)&native[fi->maxNativeFrameSlots] = 0xdeadbeefdeadbeefLL;
@ -1173,7 +1181,7 @@ js_LoopEdge(JSContext* cx)
union { NIns *code; GuardRecord* (FASTCALL *func)(InterpState*, Fragment*); } u;
u.code = f->code();
#if defined(DEBUG) && defined(AVMPLUS_IA32)
printf("entering trace at %s:%u, sp=%p\n",
printf("entering trace at %s:%u, sp=%p\n",
cx->fp->script->filename, js_PCToLineNumber(cx, cx->fp->script, cx->fp->regs->pc),
state.sp);
uint64 start = rdtsc();
@ -1182,8 +1190,8 @@ js_LoopEdge(JSContext* cx)
cx->fp->regs->sp += (double*)state.sp - entry_sp;
cx->fp->regs->pc = (jsbytecode*)state.ip;
#if defined(DEBUG) && defined(AVMPLUS_IA32)
printf("leaving trace at %s:%u, sp=%p, cycles=%llu\n",
cx->fp->script->filename, js_PCToLineNumber(cx, cx->fp->script, cx->fp->regs->pc),
printf("leaving trace at %s:%u, sp=%p, cycles=%llu\n",
cx->fp->script->filename, js_PCToLineNumber(cx, cx->fp->script, cx->fp->regs->pc),
state.sp,
(rdtsc() - start));
#endif
@ -1572,7 +1580,7 @@ TraceRecorder::unbox_jsval(jsval v, LIns*& v_ins)
lir->ins2(LIR_and, v_ins, lir->insImmPtr((void*)~JSVAL_TRUE)),
JSVAL_OBJECT));
return true;
}
return false;
}
@ -1879,8 +1887,8 @@ bool TraceRecorder::record_JSOP_GETELEM()
return false;
jsval v = obj->dslots[idx];
/* load the value, check the type (need to check JSVAL_HOLE only for booleans) */
LIns* v_ins = lir->insLoad(LIR_ld,
lir->ins2(LIR_add, dslots_ins,
LIns* v_ins = lir->insLoad(LIR_ld,
lir->ins2(LIR_add, dslots_ins,
lir->ins2i(LIR_lsh, idx_ins, sizeof(jsval) == 4 ? 2 : 3)), 0);
if (!unbox_jsval(v, v_ins))
return false;
@ -1977,7 +1985,7 @@ bool TraceRecorder::record_JSOP_CALL()
JSTraceableNative* known = &knownNatives[i];
if ((JSFastNative)fun->u.n.native != known->native)
continue;
LIns* args[5];
LIns** argp = &args[argc-1];
switch (known->argc) {
@ -1999,7 +2007,7 @@ bool TraceRecorder::record_JSOP_CALL()
default:
JS_ASSERT(0 && "illegal number of args to traceable native");
}
set(&fval, lir->insCall(known->builtin, args));
return true;
}

View File

@ -134,7 +134,7 @@ class TraceRecorder {
JSStackFrame* findFrame(jsval* p) const;
bool onFrame(jsval* p) const;
bool isGlobal(jsval* p) const;
unsigned findInternableGlobals(JSStackFrame* fp, uint16* slots) const;
int findInternableGlobals(JSStackFrame* fp, uint16* slots) const;
unsigned nativeFrameSlots(JSStackFrame* fp, JSFrameRegs& regs) const;
size_t nativeFrameOffset(jsval* p) const;
void import(jsval* p, uint8& t, char *prefix, int index);