зеркало из https://github.com/mozilla/gecko-dev.git
Trace getting String.length (484332, r=brendan).
This commit is contained in:
Родитель
b0de6bb32f
Коммит
8dfa6db1cb
|
@ -6397,6 +6397,30 @@ TraceRecorder::getThis(LIns*& this_ins)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
LIns*
|
||||
TraceRecorder::getStringLength(LIns* str_ins)
|
||||
{
|
||||
LIns* len_ins = lir->insLoad(LIR_ldp, str_ins, (int)offsetof(JSString, length));
|
||||
|
||||
LIns* masked_len_ins = lir->ins2(LIR_piand,
|
||||
len_ins,
|
||||
INS_CONSTPTR((void *)JSSTRING_LENGTH_MASK));
|
||||
|
||||
return
|
||||
lir->ins_choose(lir->ins_eq0(lir->ins2(LIR_piand,
|
||||
len_ins,
|
||||
INS_CONSTPTR((void*)JSSTRFLAG_DEPENDENT))),
|
||||
masked_len_ins,
|
||||
lir->ins_choose(lir->ins_eq0(lir->ins2(LIR_piand,
|
||||
len_ins,
|
||||
INS_CONSTPTR((void*)JSSTRFLAG_PREFIX))),
|
||||
lir->ins2(LIR_piand,
|
||||
len_ins,
|
||||
INS_CONSTPTR((void*)JSSTRDEP_LENGTH_MASK)),
|
||||
masked_len_ins));
|
||||
}
|
||||
|
||||
JS_REQUIRES_STACK bool
|
||||
TraceRecorder::guardClass(JSObject* obj, LIns* obj_ins, JSClass* clasp, VMSideExit* exit)
|
||||
{
|
||||
|
@ -8375,7 +8399,7 @@ TraceRecorder::prop(JSObject* obj, LIns* obj_ins, uint32& slot, LIns*& v_ins)
|
|||
sprop->getter == js_RegExpClass.getProperty &&
|
||||
sprop->shortid < 0) {
|
||||
if (sprop->shortid == REGEXP_LAST_INDEX)
|
||||
ABORT_TRACE("can't trace regexp.lastIndex yet");
|
||||
ABORT_TRACE("can't trace RegExp.lastIndex yet");
|
||||
LIns* args[] = { INS_CONSTPTR(sprop), obj_ins, cx_ins };
|
||||
v_ins = lir->insCall(&js_CallGetter_ci, args);
|
||||
guard(false, lir->ins2(LIR_eq, v_ins, INS_CONST(JSVAL_ERROR_COOKIE)), OOM_EXIT);
|
||||
|
@ -8388,6 +8412,16 @@ TraceRecorder::prop(JSObject* obj, LIns* obj_ins, uint32& slot, LIns*& v_ins)
|
|||
snapshot(MISMATCH_EXIT));
|
||||
return true;
|
||||
}
|
||||
if (setflags == 0 &&
|
||||
sprop->getter == js_StringClass.getProperty &&
|
||||
sprop->id == ATOM_KEY(cx->runtime->atomState.lengthAtom)) {
|
||||
if (!guardClass(obj, obj_ins, &js_StringClass, snapshot(MISMATCH_EXIT)))
|
||||
ABORT_TRACE("can't trace String.length on non-String objects");
|
||||
LIns* str_ins = stobj_get_fslot(obj_ins, JSSLOT_PRIVATE);
|
||||
str_ins = lir->ins2(LIR_piand, str_ins, INS_CONSTPTR((void*)(~JSVAL_TAGMASK)));
|
||||
v_ins = lir->ins1(LIR_i2f, getStringLength(str_ins));
|
||||
return true;
|
||||
}
|
||||
ABORT_TRACE("non-stub getter");
|
||||
}
|
||||
if (!SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj)))
|
||||
|
@ -10034,27 +10068,7 @@ TraceRecorder::record_JSOP_LENGTH()
|
|||
if (JSVAL_IS_PRIMITIVE(l)) {
|
||||
if (!JSVAL_IS_STRING(l))
|
||||
ABORT_TRACE("non-string primitive JSOP_LENGTH unsupported");
|
||||
LIns* str_ins = get(&l);
|
||||
LIns* len_ins = lir->insLoad(LIR_ldp, str_ins, (int)offsetof(JSString, length));
|
||||
|
||||
LIns* masked_len_ins = lir->ins2(LIR_piand,
|
||||
len_ins,
|
||||
INS_CONSTPTR(reinterpret_cast<void *>(JSSTRING_LENGTH_MASK)));
|
||||
|
||||
LIns* choose_len_ins =
|
||||
lir->ins_choose(lir->ins_eq0(lir->ins2(LIR_piand,
|
||||
len_ins,
|
||||
INS_CONSTPTR(reinterpret_cast<void *>(JSSTRFLAG_DEPENDENT)))),
|
||||
masked_len_ins,
|
||||
lir->ins_choose(lir->ins_eq0(lir->ins2(LIR_piand,
|
||||
len_ins,
|
||||
INS_CONSTPTR(reinterpret_cast<void *>(JSSTRFLAG_PREFIX)))),
|
||||
lir->ins2(LIR_piand,
|
||||
len_ins,
|
||||
INS_CONSTPTR(reinterpret_cast<void *>(JSSTRDEP_LENGTH_MASK))),
|
||||
masked_len_ins));
|
||||
|
||||
set(&l, lir->ins1(LIR_i2f, choose_len_ins));
|
||||
set(&l, lir->ins1(LIR_i2f, getStringLength(get(&l))));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -526,6 +526,8 @@ class TraceRecorder : public avmplus::GCObject {
|
|||
bool native_get(nanojit::LIns* obj_ins, nanojit::LIns* pobj_ins, JSScopeProperty* sprop,
|
||||
nanojit::LIns*& dslots_ins, nanojit::LIns*& v_ins);
|
||||
|
||||
nanojit::LIns* getStringLength(nanojit::LIns* str_ins);
|
||||
|
||||
JS_REQUIRES_STACK bool name(jsval*& vp);
|
||||
JS_REQUIRES_STACK bool prop(JSObject* obj, nanojit::LIns* obj_ins, uint32& slot,
|
||||
nanojit::LIns*& v_ins);
|
||||
|
|
|
@ -5032,6 +5032,14 @@ testFunctionIdentityChange.jitstats = {
|
|||
};
|
||||
test(testFunctionIdentityChange);
|
||||
|
||||
function testStringObjectLength() {
|
||||
var x = new String("foo"), y = 0;
|
||||
for (var i = 0; i < 10; ++i)
|
||||
y = x.length;
|
||||
return y;
|
||||
}
|
||||
testStringObjectLength.expected = 3;
|
||||
test(testStringObjectLength);
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
|
|
Загрузка…
Ссылка в новой задаче