mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge tracemonkey to mozilla-central.
This commit is contained in:
commit
f3cf0427b7
@ -211,6 +211,7 @@ struct JSTraceableNative {
|
||||
#define _JS_CTYPE_INTERPSTATE _JS_CTYPE(InterpState *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_FRAGMENT _JS_CTYPE(nanojit::Fragment *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_CLASS _JS_CTYPE(JSClass *, _JS_PTR, --, --, INFALLIBLE)
|
||||
#define _JS_CTYPE_DOUBLEPTR _JS_CTYPE(double *, _JS_PTR, --, --, INFALLIBLE)
|
||||
|
||||
#define _JS_EXPAND(tokens) tokens
|
||||
|
||||
|
@ -2024,7 +2024,7 @@ js_DoIncDec(JSContext *cx, const JSCodeSpec *cs, jsval *vp, jsval *vp2)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
jsval
|
||||
jsval&
|
||||
js_GetUpvar(JSContext *cx, uintN level, uintN cookie)
|
||||
{
|
||||
level -= UPVAR_FRAME_SKIP(cookie);
|
||||
|
@ -555,7 +555,7 @@ js_InternNonIntElementId(JSContext *cx, JSObject *obj, jsval idval, jsid *idp);
|
||||
* Given an active context, a static scope level, and an upvar cookie, return
|
||||
* the value of the upvar.
|
||||
*/
|
||||
extern jsval
|
||||
extern jsval&
|
||||
js_GetUpvar(JSContext *cx, uintN level, uintN cookie);
|
||||
|
||||
/*
|
||||
|
@ -367,7 +367,7 @@ Tracker::set(const void* v, LIns* i)
|
||||
p->map[(jsuword(v) & PAGEMASK) >> 2] = i;
|
||||
}
|
||||
|
||||
static inline jsint argSlots(JSStackFrame* fp)
|
||||
static inline jsuint argSlots(JSStackFrame* fp)
|
||||
{
|
||||
return JS_MAX(fp->argc, fp->fun->nargs);
|
||||
}
|
||||
@ -1238,7 +1238,7 @@ TypeMap::captureTypes(JSContext* cx, SlotList& slots, unsigned callDepth)
|
||||
if ((type == JSVAL_INT) && oracle.isStackSlotUndemotable(cx, unsigned(m - map)))
|
||||
type = JSVAL_DOUBLE;
|
||||
JS_ASSERT(type != JSVAL_BOXED);
|
||||
debug_only_v(printf("capture stack type %s%d: %d=%c vp=%p v=%x\n", vpname, vpnum, type, typeChar[type], vp, (uint32) *vp);)
|
||||
debug_only_v(printf("capture stack type %s%d: %d=%c\n", vpname, vpnum, type, typeChar[type]);)
|
||||
JS_ASSERT(uintptr_t(m - map) < length());
|
||||
*m++ = type;
|
||||
);
|
||||
@ -1838,6 +1838,47 @@ FlushNativeGlobalFrame(JSContext* cx, unsigned ngslots, uint16* gslots, uint8* m
|
||||
return mp - mp_base;
|
||||
}
|
||||
|
||||
/*
|
||||
* Builtin to get an upvar on trace. See js_GetUpvar for the meaning
|
||||
* of the first three arguments. The value of the upvar is stored in
|
||||
* *result as an unboxed native. The return value is the typemap type.
|
||||
*/
|
||||
uint32 JS_FASTCALL
|
||||
js_GetUpvarOnTrace(JSContext *cx, uint32 level, uint32 cookie, double* result)
|
||||
{
|
||||
uintN skip = UPVAR_FRAME_SKIP(cookie);
|
||||
InterpState* state = cx->interpState;
|
||||
uintN callDepth = state->rp - state->callstackBase;
|
||||
|
||||
/*
|
||||
* If we are skipping past all frames that are part of active traces,
|
||||
* then we simply get the value from the interpreter state.
|
||||
*/
|
||||
if (skip > callDepth) {
|
||||
jsval v = js_GetUpvar(cx, level, cookie);
|
||||
uint8 type = getCoercedType(v);
|
||||
ValueToNative(cx, v, type, result);
|
||||
return type;
|
||||
}
|
||||
|
||||
/*
|
||||
* The value we need is logically in a stack frame that is part of
|
||||
* an active trace. We reconstruct the value we need from the tracer
|
||||
* stack records.
|
||||
*/
|
||||
uintN frameIndex = callDepth - skip; // pos of target frame in rp stack
|
||||
uintN nativeStackFramePos = 0; // pos of target stack frame in sp stack
|
||||
for (uintN i = 0; i < frameIndex; ++i)
|
||||
nativeStackFramePos += state->callstackBase[i]->s.spdist;
|
||||
FrameInfo* fi = state->callstackBase[frameIndex];
|
||||
uint8* typemap = (uint8*) (fi+1);
|
||||
|
||||
uintN slot = UPVAR_FRAME_SLOT(cookie);
|
||||
slot = slot == CALLEE_UPVAR_SLOT ? 0 : slot + 2;
|
||||
*result = state->stackBase[nativeStackFramePos + slot];
|
||||
return typemap[slot];
|
||||
}
|
||||
|
||||
/**
|
||||
* Box the given native stack frame into the virtual machine stack. This
|
||||
* is infallible.
|
||||
@ -8282,6 +8323,8 @@ TraceRecorder::record_JSOP_CALLNAME()
|
||||
return JSRS_CONTINUE;
|
||||
}
|
||||
|
||||
JS_DEFINE_CALLINFO_4(extern, UINT32, js_GetUpvarOnTrace, CONTEXT, UINT32, UINT32, DOUBLEPTR, 0, 0)
|
||||
|
||||
JS_REQUIRES_STACK JSRecordingStatus
|
||||
TraceRecorder::record_JSOP_GETUPVAR()
|
||||
{
|
||||
@ -8291,26 +8334,60 @@ TraceRecorder::record_JSOP_GETUPVAR()
|
||||
JSUpvarArray* uva = JS_SCRIPT_UPVARS(script);
|
||||
JS_ASSERT(index < uva->length);
|
||||
|
||||
uintN skip = UPVAR_FRAME_SKIP(uva->vector[index]);
|
||||
if (skip > callDepth)
|
||||
ABORT_TRACE("upvar out of reach");
|
||||
|
||||
JSStackFrame* fp2 = cx->display[script->staticLevel - skip];
|
||||
JS_ASSERT(fp2->script);
|
||||
|
||||
uintN slot = UPVAR_FRAME_SLOT(uva->vector[index]);
|
||||
jsval* vp;
|
||||
if (!fp2->fun) {
|
||||
vp = fp2->slots + fp2->script->nfixed;
|
||||
} else if (slot < fp2->fun->nargs) {
|
||||
vp = fp2->argv;
|
||||
} else {
|
||||
slot -= fp2->fun->nargs;
|
||||
JS_ASSERT(slot < fp2->script->nslots);
|
||||
vp = fp2->slots;
|
||||
/*
|
||||
* Try to find the upvar in the current trace's tracker.
|
||||
*/
|
||||
jsval& v = js_GetUpvar(cx, script->staticLevel, uva->vector[index]);
|
||||
LIns* upvar_ins = get(&v);
|
||||
if (upvar_ins) {
|
||||
stack(0, upvar_ins);
|
||||
return JSRS_CONTINUE;
|
||||
}
|
||||
|
||||
stack(0, get(&vp[slot]));
|
||||
/*
|
||||
* The upvar is not in the current trace, so get the upvar value
|
||||
* exactly as the interpreter does and unbox.
|
||||
*/
|
||||
LIns* outp = lir->insAlloc(sizeof(double));
|
||||
LIns* args[] = {
|
||||
outp,
|
||||
lir->insImm(uva->vector[index]),
|
||||
lir->insImm(script->staticLevel),
|
||||
cx_ins
|
||||
};
|
||||
const CallInfo* ci = &js_GetUpvarOnTrace_ci;
|
||||
LIns* call_ins = lir->insCall(ci, args);
|
||||
uint8 type = getCoercedType(v);
|
||||
guard(true,
|
||||
addName(lir->ins2(LIR_eq, call_ins, lir->insImm(type)),
|
||||
"guard(type-stable upvar)"),
|
||||
BRANCH_EXIT);
|
||||
|
||||
LOpcode loadOp;
|
||||
switch (type) {
|
||||
case JSVAL_DOUBLE:
|
||||
loadOp = LIR_ldq;
|
||||
break;
|
||||
case JSVAL_OBJECT:
|
||||
case JSVAL_STRING:
|
||||
case JSVAL_TFUN:
|
||||
case JSVAL_TNULL:
|
||||
loadOp = LIR_ldp;
|
||||
break;
|
||||
case JSVAL_INT:
|
||||
case JSVAL_BOOLEAN:
|
||||
loadOp = LIR_ld;
|
||||
break;
|
||||
case JSVAL_BOXED:
|
||||
default:
|
||||
JS_NOT_REACHED("found boxed type in an upvar type map entry");
|
||||
return JSRS_STOP;
|
||||
}
|
||||
|
||||
LIns* result = lir->insLoad(loadOp, outp, lir->insImm(0));
|
||||
if (type == JSVAL_INT)
|
||||
result = lir->ins1(LIR_i2f, result);
|
||||
stack(0, result);
|
||||
return JSRS_CONTINUE;
|
||||
}
|
||||
|
||||
@ -10527,13 +10604,20 @@ TraceRecorder::record_JSOP_NEWARRAY()
|
||||
guard(false, lir->ins_eq0(v_ins), OOM_EXIT);
|
||||
|
||||
LIns* dslots_ins = NULL;
|
||||
uint32 count = 0;
|
||||
for (uint32 i = 0; i < len; i++) {
|
||||
jsval& v = stackval(int(i) - int(len));
|
||||
if (v != JSVAL_HOLE)
|
||||
count++;
|
||||
LIns* elt_ins = get(&v);
|
||||
box_jsval(v, elt_ins);
|
||||
stobj_set_dslot(v_ins, i, dslots_ins, elt_ins, "set_array_elt");
|
||||
}
|
||||
|
||||
LIns* dummy = NULL;
|
||||
if (count > 0)
|
||||
stobj_set_slot(v_ins, JSSLOT_ARRAY_COUNT, dummy, INS_CONST(count));
|
||||
|
||||
stack(-int(len), v_ins);
|
||||
return JSRS_CONTINUE;
|
||||
}
|
||||
|
@ -367,7 +367,7 @@ typedef enum JSBuiltinStatus {
|
||||
struct InterpState
|
||||
{
|
||||
double *sp; // native stack pointer, stack[0] is spbase[0]
|
||||
void *rp; // call stack pointer
|
||||
FrameInfo** rp; // call stack pointer
|
||||
JSContext *cx; // current VM context handle
|
||||
double *eos; // first unusable word after the native stack
|
||||
void *eor; // first unusable word after the call stack
|
||||
|
@ -4180,8 +4180,8 @@ function testBug458838() {
|
||||
testBug458838.expected = 10;
|
||||
testBug458838.jitstats = {
|
||||
recorderStarted: 1,
|
||||
recorderAborted: 1,
|
||||
traceCompleted: 0
|
||||
recorderAborted: 0,
|
||||
traceCompleted: 1
|
||||
};
|
||||
test(testBug458838);
|
||||
|
||||
@ -5200,6 +5200,19 @@ function testConstructorBail() {
|
||||
}
|
||||
test(testConstructorBail);
|
||||
|
||||
function testNewArrayCount()
|
||||
{
|
||||
var a = [];
|
||||
for (var i = 0; i < 5; i++)
|
||||
a = [0];
|
||||
assertEq(a.__count__, 1);
|
||||
for (var i = 0; i < 5; i++)
|
||||
a = [0, , 2];
|
||||
assertEq(a.__count__, 2);
|
||||
}
|
||||
test(testNewArrayCount);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* _____ _ _ _____ ______ _____ _______ *
|
||||
|
Loading…
Reference in New Issue
Block a user