Add guards for XML objects, and some tracer bits to accommodate them.

This commit is contained in:
shaver@mozilla.org 2008-06-27 23:58:06 -04:00
parent e5d4f398ef
commit 4fc71515e0
5 changed files with 103 additions and 11 deletions

View File

@ -3767,12 +3767,14 @@ JS_INTERPRET(JSContext *cx, JSInterpreterState *state)
*/
#if JS_HAS_XML_SUPPORT
#define XML_EQUALITY_OP(OP) \
if ((ltmp == JSVAL_OBJECT && \
(obj2 = JSVAL_TO_OBJECT(lval)) && \
OBJECT_IS_XML(cx, obj2)) || \
(rtmp == JSVAL_OBJECT && \
(obj2 = JSVAL_TO_OBJECT(rval)) && \
OBJECT_IS_XML(cx, obj2))) { \
if ((JSVAL_IS_OBJECT(lval) && \
!guard_jsval_is_null(cx, regs, lval) && \
(prim_jsval_to_object(cx, lval, obj2), \
guard_obj_is_xml(cx, regs, obj2))) || \
(JSVAL_IS_OBJECT(rval) && \
!guard_jsval_is_null(cx, regs, rval) && \
(prim_jsval_to_object(cx, rval, obj2), \
guard_obj_is_xml(cx, regs, obj2)))) { \
JSXMLObjectOps *ops; \
\
ops = (JSXMLObjectOps *) obj2->map->ops; \

View File

@ -212,6 +212,33 @@ PRIMITIVE(guard_obj_is_null)(JSContext* cx, JSFrameRegs& regs, JSObject*& obj)
return !obj;
}
static inline void
PRIMITIVE(prim_load_map_from_obj)(JSContext *cx, JSFrameRegs& regs,
JSObject*& obj, JSObjectMap*& map)
{
map = obj->map;
}
static inline void
PRIMITIVE(prim_load_ops_from_map)(JSContext *cx, JSFrameRegs& regs,
JSObjectMap*& map, JSObjectOps*& ops)
{
ops = map->ops;
}
static inline bool
PRIMITIVE(prim_ops_are_xml)(JSContext *cx, JSFrameRegs& regs,
JSObjectOps*& ops)
{
return ops == &js_XMLObjectOps.base;
}
static inline bool
PRIMITIVE(guard_obj_is_xml)(JSContext *cx, JSFrameRegs& regs, JSObject*& obj)
{
return OBJECT_IS_XML(cx, obj);
}
static inline void
PRIMITIVE(call_ValueToNonNullObject)(JSContext* cx, jsval& v, JSObject*& obj)
{

View File

@ -247,11 +247,11 @@ TraceRecorder::TraceRecorder(JSContext* cx, JSFrameRegs& regs, Fragmento* fragme
JSStackFrame* fp = cx->fp;
unsigned n;
for (n = 0; n < fp->argc; ++n)
load(&fp->argv[n]);
readstack(&fp->argv[n]);
for (n = 0; n < fp->nvars; ++n)
load(&fp->vars[n]);
readstack(&fp->vars[n]);
for (n = 0; n < (unsigned)(regs.sp - fp->spbase); ++n)
load(&fp->spbase[n]);
readstack(&fp->spbase[n]);
}
TraceRecorder::~TraceRecorder()
@ -265,7 +265,7 @@ TraceRecorder::~TraceRecorder()
}
void
TraceRecorder::load(void* p)
TraceRecorder::readstack(void* p)
{
JS_ASSERT(frameStack.contains(p));
tracker.set(p, lir->insLoadi(tracker.get(&entryState.sp),
@ -402,6 +402,24 @@ TraceRecorder::guard_ov(bool expected, void* a, JSFrameRegs& regs)
#endif
}
void
TraceRecorder::guard_eq(bool expected, void* a, void* b, JSFrameRegs& regs)
{
SideExit exit;
lir->insGuard(expected ? LIR_xf : LIR_xt,
lir->ins2(LIR_eq, get(a), get(b)),
snapshot(exit, regs));
}
void
TraceRecorder::guard_eqi(bool expected, void* a, int i, JSFrameRegs& regs)
{
SideExit exit;
lir->insGuard(expected ? LIR_xf : LIR_xt,
lir->ins2i(LIR_eq, get(a), i),
snapshot(exit, regs));
}
void
TraceRecorder::closeLoop(Fragmento* fragmento)
{
@ -409,6 +427,12 @@ TraceRecorder::closeLoop(Fragmento* fragmento)
compile(fragmento->assm(), fragment);
}
void
TraceRecorder::load(void* a, int32_t i, void* v)
{
set(v, lir->insLoadi(get(a), i));
}
bool
js_StartRecording(JSContext* cx, JSFrameRegs& regs)
{

View File

@ -112,7 +112,7 @@ public:
void set(void* p, nanojit::LIns* l);
nanojit::LIns* get(void* p);
void load(void*);
void readstack(void*);
void copy(void* a, void* v);
void imm(jsint i, void* v);
@ -129,8 +129,12 @@ public:
void guard_0(bool expected, void* a, JSFrameRegs& regs);
void guard_h(bool expected, void* a, JSFrameRegs& regs);
void guard_ov(bool expected, void* a, JSFrameRegs& regs);
void guard_eq(bool expected, void* a, void* b, JSFrameRegs& regs);
void guard_eqi(bool expected, void* a, int i, JSFrameRegs& regs);
void closeLoop(nanojit::Fragmento* fragmento);
void load(void* a, int32_t i, void* v);
};
/*

View File

@ -474,4 +474,39 @@ prim_object_as_boolean(JSContext* cx, JSObject*& obj, JSBool& r)
recorder(cx)->binary0(LIR_eq, &obj, &r);
}
static inline void
prim_load_ops_from_map(JSContext *cx, JSFrameRegs& regs, JSObjectMap*& map,
JSObjectOps*& ops)
{
interp_prim_load_ops_from_map(cx, regs, map, ops);
recorder(cx)->load(&map, offsetof(JSObjectMap, ops), &ops);
}
static inline void
prim_load_map_from_obj(JSContext *cx, JSFrameRegs& regs, JSObject*& obj,
JSObjectMap*& map)
{
interp_prim_load_map_from_obj(cx, regs, obj, map);
recorder(cx)->load(&obj, offsetof(JSObject, map), &map);
}
static inline bool
guard_ops_are_xml(JSContext *cx, JSFrameRegs& regs, JSObjectOps*& ops)
{
bool ok = interp_prim_ops_are_xml(cx, regs, ops);
recorder(cx)->guard_eqi(ok, &ops, (int)&js_XMLObjectOps.base, regs);
return ok;
}
static inline bool
guard_obj_is_xml(JSContext* cx, JSFrameRegs& regs, JSObject*& obj)
{
JSObjectMap *map;
JSObjectOps *ops;
prim_load_map_from_obj(cx, regs, obj, map);
prim_load_ops_from_map(cx, regs, map, ops);
return guard_ops_are_xml(cx, regs, ops);
}
#endif /* jstracerinlines_h___ */