Incomplete stab at CALLPROP, added ABORT_TRACE for better diagnostics, make math_sin non-static in preparation for specializing call.

This commit is contained in:
shaver@mozilla.org 2008-07-11 20:59:10 -04:00
Родитель 469722c66c
Коммит 131566085f
3 изменённых файлов: 66 добавлений и 24 удалений

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

@ -479,7 +479,7 @@ math_round(JSContext *cx, uintN argc, jsval *vp)
return js_NewNumberInRootedValue(cx, z, vp);
}
static JSBool
JSBool
math_sin(JSContext *cx, uintN argc, jsval *vp)
{
jsdouble x, z;

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

@ -43,12 +43,13 @@
#include "nanojit/nanojit.h"
#include "jsarray.h"
#include "jsbool.h"
#include "jstracer.h"
#include "jscntxt.h"
#include "jsscript.h"
#include "jsprf.h"
#include "jsfun.h"
#include "jsinterp.h"
#include "jsprf.h"
#include "jsscript.h"
#include "jsscope.h"
#include "jstracer.h"
#include "jsautooplen.h"
@ -57,6 +58,12 @@
#define alloca _alloca
#endif
#ifdef DEBUG
#define ABORT_TRACE(msg) do { fprintf(stderr, "abort: %d: %s\n", __LINE__, msg); return false; } while(0)
#else
#define ABORT_TRACE(msg) return false
#endif
using namespace avmplus;
using namespace nanojit;
@ -423,7 +430,7 @@ TraceRecorder::TraceRecorder(JSContext* cx, Fragmento* fragmento, Fragment* _fra
#ifdef DEBUG
printf("recording starting from %s:%u\n", cx->fp->script->filename,
js_PCToLineNumber(cx, cx->fp->script, entryRegs.pc));
js_PCToLineNumber(cx, cx->fp->script, entryRegs.pc));
#endif
fragment->calldepth = 0;
@ -1103,18 +1110,18 @@ js_LoopEdge(JSContext* cx)
u.code = f->code();
#if defined(DEBUG) && defined(AVMPLUS_IA32)
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);
cx->fp->script->filename, js_PCToLineNumber(cx, cx->fp->script, cx->fp->regs->pc),
state.sp);
uint64 start = rdtsc();
#endif
GuardRecord* lr = u.func(&state, NULL);
cx->fp->regs->sp += (((double*)state.sp - entry_sp));
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),
state.sp,
(rdtsc() - start));
cx->fp->script->filename, js_PCToLineNumber(cx, cx->fp->script, cx->fp->regs->pc),
state.sp,
(rdtsc() - start));
#endif
box(cx, cx->fp, cx->fp, lr->exit->typeMap, native);
#ifdef DEBUG
@ -1356,7 +1363,7 @@ TraceRecorder::map_is_native(JSObjectMap* map, LIns* map_ins)
guard(true, lir->ins2(LIR_eq, n, lir->insImmPtr(&js_ObjectOps.newObjectMap)));
return true;
}
return false;
ABORT_TRACE("non-native map");
}
bool
@ -1370,13 +1377,13 @@ TraceRecorder::test_property_cache(JSObject* obj, LIns* obj_ins, JSObject*& obj2
JSAtom* atom;
PROPERTY_CACHE_TEST(cx, cx->fp->regs->pc, obj, obj2, entry, atom);
if (atom)
return false;
ABORT_TRACE("PC miss");
if (PCVCAP_TAG(entry->vcap == 1))
return false; // need to look in the prototype, NYI
ABORT_TRACE("PC hit in prototype"); // need to look in the prototype, NYI
if (OBJ_SCOPE(obj)->object != obj)
return false; // need to normalize to the owner of the shared scope, NYI
ABORT_TRACE("obj not scope owner"); // need to normalize to the owner of the shared scope, NYI
LIns* shape_ins = lir->insLoadi(map_ins, offsetof(JSScope, shape));
#ifdef DEBUG
@ -1401,7 +1408,7 @@ TraceRecorder::test_property_cache_direct_slot(JSObject* obj, LIns* obj_ins, uin
/* Handle only gets and sets on the directly addressed object. */
if (obj2 != obj)
return false;
ABORT_TRACE("PC hit on prototype chain");
/* Don't trace setter calls, our caller wants a direct slot. */
if (PCVAL_IS_SPROP(entry->vword)) {
@ -1409,13 +1416,13 @@ TraceRecorder::test_property_cache_direct_slot(JSObject* obj, LIns* obj_ins, uin
JSScopeProperty* sprop = PCVAL_TO_SPROP(entry->vword);
if (!SPROP_HAS_STUB_SETTER(sprop))
return false;
ABORT_TRACE("non-stub setter");
if (!SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj)))
return false;
ABORT_TRACE("no valid slot");
slot = sprop->slot;
} else {
if (!PCVAL_IS_SLOT(entry->vword))
return false;
ABORT_TRACE("PCE is not a slot");
slot = PCVAL_TO_SLOT(entry->vword);
}
@ -1532,21 +1539,34 @@ TraceRecorder::unbox_jsval(jsval v, LIns*& v_ins)
JSVAL_BOOLEAN));
v_ins = lir->ins2i(LIR_ush, v_ins, JSVAL_TAGBITS);
return true;
case JSVAL_OBJECT:
guard(true,
lir->ins2i(LIR_eq,
lir->ins2(LIR_and, v_ins, lir->insImmPtr((void*)~JSVAL_TRUE)),
JSVAL_OBJECT));
return true;
}
return false;
}
bool TraceRecorder::guardThatObjectIsDenseArray(JSObject* obj, LIns* obj_ins, LIns*& dslots_ins)
bool
TraceRecorder::guardThatObjectHasClass(JSObject* obj, LIns* obj_ins,
JSClass* cls, LIns*& dslots_ins)
{
if (!OBJ_IS_DENSE_ARRAY(cx, obj))
if (STOBJ_GET_CLASS(obj) != cls)
return false;
// guard(OBJ_GET_CLASS(obj) == &js_ArrayClass);
LIns* class_ins = stobj_get_slot(obj_ins, JSSLOT_CLASS, dslots_ins);
class_ins = lir->ins2(LIR_and, class_ins, lir->insImmPtr((void*)~3));
guard(true, lir->ins2(LIR_eq, class_ins, lir->insImmPtr(&js_ArrayClass)));
guard(true, lir->ins2(LIR_eq, class_ins, lir->insImmPtr(cls)));
return true;
}
bool TraceRecorder::guardThatObjectIsDenseArray(JSObject* obj, LIns* obj_ins, LIns*& dslots_ins)
{
return guardThatObjectHasClass(obj, obj_ins, &js_ArrayClass, dslots_ins);
}
bool TraceRecorder::guardDenseArrayIndexWithinBounds(JSObject* obj, jsint idx,
LIns* obj_ins, LIns*& dslots_ins, LIns* idx_ins)
{
@ -2497,7 +2517,27 @@ bool TraceRecorder::record_JSOP_XMLPI()
}
bool TraceRecorder::record_JSOP_CALLPROP()
{
return false;
jsval& l = stackval(-1);
if (JSVAL_IS_PRIMITIVE(l))
ABORT_TRACE("CALLPROP on primitive");
JSObject *obj = JSVAL_TO_OBJECT(l);
LIns* obj_ins = get(&l);
uint32 slot;
if (!test_property_cache_direct_slot(obj, obj_ins, slot))
ABORT_TRACE("property_cache_direct_slot");
jsval& fval = STOBJ_GET_SLOT(obj, slot);
LIns* dslots_ins = NULL;
LIns* fval_ins = stobj_get_slot(obj_ins, slot, dslots_ins);
if (!unbox_jsval(fval, fval_ins))
ABORT_TRACE("unbox");
dslots_ins = NULL;
if (!guardThatObjectHasClass(obj, fval_ins, &js_FunctionClass, dslots_ins))
ABORT_TRACE("wrong class");
stack(0, fval_ins);
return true;
}
bool TraceRecorder::record_JSOP_GETFUNNS()
{

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

@ -187,6 +187,8 @@ class TraceRecorder {
bool box_jsval(jsval v, nanojit::LIns*& v_ins);
bool unbox_jsval(jsval v, nanojit::LIns*& v_ins);
bool guardThatObjectHasClass(JSObject* obj, nanojit::LIns* obj_ins,
JSClass* cls, nanojit::LIns*& dslots_ins);
bool guardThatObjectIsDenseArray(JSObject* obj, nanojit::LIns* obj_ins,
nanojit::LIns*& dslots_ins);
bool guardDenseArrayIndexWithinBounds(JSObject* obj, jsint idx, nanojit::LIns* obj_ins,