зеркало из https://github.com/mozilla/gecko-dev.git
Bug 492915 - Trace incelem/decelem/eleminc/elemdec for objects other than arrays. r=brendan.
--HG-- extra : rebase_source : 33ab817997096bd4b00c8a36bb0444dcacc58a27
This commit is contained in:
Родитель
7a6a0f9780
Коммит
cb43b0920f
|
@ -256,6 +256,62 @@ static struct {
|
|||
/*40*/ JSOP_STOP,
|
||||
},
|
||||
};
|
||||
static struct {
|
||||
jsbytecode incelem[7];
|
||||
jsbytecode eleminc[15];
|
||||
} incelem_imacros = {
|
||||
{
|
||||
/* 0*/ JSOP_DUP2,
|
||||
/* 1*/ JSOP_GETELEM,
|
||||
/* 2*/ JSOP_POS,
|
||||
/* 3*/ JSOP_ONE,
|
||||
/* 4*/ JSOP_ADD,
|
||||
/* 5*/ JSOP_SETELEM,
|
||||
/* 6*/ JSOP_STOP,
|
||||
},
|
||||
{
|
||||
/* 0*/ JSOP_DUP2,
|
||||
/* 1*/ JSOP_GETELEM,
|
||||
/* 2*/ JSOP_POS,
|
||||
/* 3*/ JSOP_DUP,
|
||||
/* 4*/ JSOP_ONE,
|
||||
/* 5*/ JSOP_ADD,
|
||||
/* 6*/ JSOP_PICK, 3,
|
||||
/* 8*/ JSOP_PICK, 3,
|
||||
/*10*/ JSOP_PICK, 2,
|
||||
/*12*/ JSOP_SETELEM,
|
||||
/*13*/ JSOP_POP,
|
||||
/*14*/ JSOP_STOP,
|
||||
},
|
||||
};
|
||||
static struct {
|
||||
jsbytecode decelem[7];
|
||||
jsbytecode elemdec[15];
|
||||
} decelem_imacros = {
|
||||
{
|
||||
/* 0*/ JSOP_DUP2,
|
||||
/* 1*/ JSOP_GETELEM,
|
||||
/* 2*/ JSOP_POS,
|
||||
/* 3*/ JSOP_ONE,
|
||||
/* 4*/ JSOP_SUB,
|
||||
/* 5*/ JSOP_SETELEM,
|
||||
/* 6*/ JSOP_STOP,
|
||||
},
|
||||
{
|
||||
/* 0*/ JSOP_DUP2,
|
||||
/* 1*/ JSOP_GETELEM,
|
||||
/* 2*/ JSOP_POS,
|
||||
/* 3*/ JSOP_DUP,
|
||||
/* 4*/ JSOP_ONE,
|
||||
/* 5*/ JSOP_SUB,
|
||||
/* 6*/ JSOP_PICK, 3,
|
||||
/* 8*/ JSOP_PICK, 3,
|
||||
/*10*/ JSOP_PICK, 2,
|
||||
/*12*/ JSOP_SETELEM,
|
||||
/*13*/ JSOP_POP,
|
||||
/*14*/ JSOP_STOP,
|
||||
},
|
||||
};
|
||||
static struct {
|
||||
jsbytecode String[38];
|
||||
} call_imacros = {
|
||||
|
@ -744,16 +800,16 @@ uint8 js_opcode2extra[JSOP_LIMIT] = {
|
|||
0, /* JSOP_VOID */
|
||||
0, /* JSOP_INCNAME */
|
||||
0, /* JSOP_INCPROP */
|
||||
0, /* JSOP_INCELEM */
|
||||
3, /* JSOP_INCELEM */
|
||||
0, /* JSOP_DECNAME */
|
||||
0, /* JSOP_DECPROP */
|
||||
0, /* JSOP_DECELEM */
|
||||
3, /* JSOP_DECELEM */
|
||||
0, /* JSOP_NAMEINC */
|
||||
0, /* JSOP_PROPINC */
|
||||
0, /* JSOP_ELEMINC */
|
||||
3, /* JSOP_ELEMINC */
|
||||
0, /* JSOP_NAMEDEC */
|
||||
0, /* JSOP_PROPDEC */
|
||||
0, /* JSOP_ELEMDEC */
|
||||
3, /* JSOP_ELEMDEC */
|
||||
1, /* JSOP_GETPROP */
|
||||
0, /* JSOP_SETPROP */
|
||||
0, /* JSOP_GETELEM */
|
||||
|
@ -963,6 +1019,10 @@ uint8 js_opcode2extra[JSOP_LIMIT] = {
|
|||
|| x == JSOP_MOD \
|
||||
|| x == JSOP_NEG \
|
||||
|| x == JSOP_POS \
|
||||
|| x == JSOP_INCELEM \
|
||||
|| x == JSOP_DECELEM \
|
||||
|| x == JSOP_ELEMINC \
|
||||
|| x == JSOP_ELEMDEC \
|
||||
|| x == JSOP_GETPROP \
|
||||
|| x == JSOP_CALL \
|
||||
|| x == JSOP_ITER \
|
||||
|
@ -986,6 +1046,10 @@ js_GetImacroStart(jsbytecode* pc) {
|
|||
if (size_t(pc - add_imacros.obj_any) < 38) return add_imacros.obj_any;
|
||||
if (size_t(pc - add_imacros.obj_obj) < 72) return add_imacros.obj_obj;
|
||||
if (size_t(pc - unary_imacros.sign) < 41) return unary_imacros.sign;
|
||||
if (size_t(pc - incelem_imacros.incelem) < 7) return incelem_imacros.incelem;
|
||||
if (size_t(pc - incelem_imacros.eleminc) < 15) return incelem_imacros.eleminc;
|
||||
if (size_t(pc - decelem_imacros.decelem) < 7) return decelem_imacros.decelem;
|
||||
if (size_t(pc - decelem_imacros.elemdec) < 15) return decelem_imacros.elemdec;
|
||||
if (size_t(pc - call_imacros.String) < 38) return call_imacros.String;
|
||||
if (size_t(pc - new_imacros.String) < 38) return new_imacros.String;
|
||||
if (size_t(pc - apply_imacros.apply0) < 8) return apply_imacros.apply0;
|
||||
|
|
|
@ -298,6 +298,60 @@
|
|||
|
||||
.end unary
|
||||
|
||||
.igroup incelem JSOP_INCELEM,JSOP_ELEMINC
|
||||
.imacro incelem # obj id
|
||||
dup2 # obj id obj id
|
||||
getelem # obj id val
|
||||
pos # obj id n
|
||||
one # obj id n 1
|
||||
add # obj id m
|
||||
setelem # m
|
||||
stop
|
||||
.end
|
||||
|
||||
.imacro eleminc # obj id
|
||||
dup2 # obj id obj id
|
||||
getelem # obj id val
|
||||
pos # obj id n
|
||||
dup # obj id n n
|
||||
one # obj id n n 1
|
||||
add # obj id n m
|
||||
pick 3 # id n m obj
|
||||
pick 3 # n m obj id
|
||||
pick 2 # n obj id m
|
||||
setelem # n m
|
||||
pop # n
|
||||
stop
|
||||
.end
|
||||
.end incelem
|
||||
|
||||
.igroup decelem JSOP_DECELEM,JSOP_ELEMDEC
|
||||
.imacro decelem # obj id
|
||||
dup2 # obj id obj id
|
||||
getelem # obj id val
|
||||
pos # obj id n
|
||||
one # obj id n 1
|
||||
sub # obj id m
|
||||
setelem # m
|
||||
stop
|
||||
.end
|
||||
|
||||
.imacro elemdec # obj id
|
||||
dup2 # obj id obj id
|
||||
getelem # obj id val
|
||||
pos # obj id n
|
||||
dup # obj id n n
|
||||
one # obj id n n 1
|
||||
sub # obj id n m
|
||||
pick 3 # id n m obj
|
||||
pick 3 # n m obj id
|
||||
pick 2 # n obj id m
|
||||
setelem # n m
|
||||
pop # n
|
||||
stop
|
||||
.end
|
||||
.end decelem
|
||||
|
||||
.igroup call JSOP_CALL
|
||||
|
||||
.imacro String # String this obj
|
||||
|
|
|
@ -8608,17 +8608,19 @@ TraceRecorder::incElem(jsint incr, bool pre)
|
|||
LIns* v_ins;
|
||||
LIns* addr_ins;
|
||||
|
||||
if (JSVAL_IS_PRIMITIVE(l) || !JSVAL_IS_INT(r) ||
|
||||
!guardDenseArray(JSVAL_TO_OBJECT(l), get(&l), MISMATCH_EXIT)) {
|
||||
return RECORD_STOP;
|
||||
if (!JSVAL_IS_PRIMITIVE(l) && JSVAL_TO_OBJECT(l)->isDenseArray() && JSVAL_IS_INT(r)) {
|
||||
JS_ALWAYS_TRUE(guardDenseArray(JSVAL_TO_OBJECT(l), get(&l), MISMATCH_EXIT));
|
||||
CHECK_STATUS(denseArrayElement(l, r, vp, v_ins, addr_ins));
|
||||
if (!addr_ins) // if we read a hole, abort
|
||||
return RECORD_STOP;
|
||||
CHECK_STATUS(inc(*vp, v_ins, incr, pre));
|
||||
lir->insStore(box_jsval(*vp, v_ins), addr_ins, 0, ACC_OTHER);
|
||||
return RECORD_CONTINUE;
|
||||
}
|
||||
|
||||
CHECK_STATUS(denseArrayElement(l, r, vp, v_ins, addr_ins));
|
||||
if (!addr_ins) // if we read a hole, abort
|
||||
return RECORD_STOP;
|
||||
CHECK_STATUS(inc(*vp, v_ins, incr, pre));
|
||||
lir->insStore(box_jsval(*vp, v_ins), addr_ins, 0, ACC_OTHER);
|
||||
return RECORD_CONTINUE;
|
||||
return callImacro((incr == 1)
|
||||
? pre ? incelem_imacros.incelem : incelem_imacros.eleminc
|
||||
: pre ? decelem_imacros.decelem : decelem_imacros.elemdec);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
var obj = {p: 100};
|
||||
var name = "p";
|
||||
var a = [];
|
||||
for (var i = 0; i < 10; i++)
|
||||
a[i] = --obj[name];
|
||||
assertEq(a.join(','), '99,98,97,96,95,94,93,92,91,90');
|
||||
assertEq(obj.p, 90);
|
||||
|
||||
checkStats({recorderStarted: 1, recorderAborted: 0, traceCompleted: 1, traceTriggered: 1});
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
var obj = {s: ""};
|
||||
var name = "s";
|
||||
var a = [];
|
||||
for (var i = 0; i <= RECORDLOOP + 5; i++) {
|
||||
a[i] = 'x';
|
||||
if (i > RECORDLOOP)
|
||||
a[i] = --obj[name]; // first recording changes obj.s from string to number
|
||||
}
|
||||
assertEq(a.join(','), Array(RECORDLOOP + 2).join('x,') + '-1,-2,-3,-4,-5');
|
||||
assertEq(obj.s, -5);
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
var obj = {p: 100};
|
||||
var name = "p";
|
||||
var a = [];
|
||||
for (var i = 0; i < 10; i++)
|
||||
a[i] = obj[name]--;
|
||||
assertEq(a.join(','), '100,99,98,97,96,95,94,93,92,91');
|
||||
assertEq(obj.p, 90);
|
||||
|
||||
checkStats({recorderStarted: 1, recorderAborted: 0, traceCompleted: 1, traceTriggered: 1});
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
var obj = {s: ""};
|
||||
var name = "s";
|
||||
for (var i = 0; i <= RECORDLOOP + 5; i++)
|
||||
if (i > RECORDLOOP)
|
||||
obj[name]--; // first recording changes obj.s from string to number
|
||||
assertEq(obj.s, -5);
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
var obj = {p: 100};
|
||||
var name = "p";
|
||||
var a = [];
|
||||
for (var i = 0; i < 10; i++)
|
||||
a[i] = obj[name]++;
|
||||
assertEq(a.join(','), '100,101,102,103,104,105,106,107,108,109');
|
||||
assertEq(obj.p, 110);
|
||||
|
||||
checkStats({recorderStarted: 1, recorderAborted: 0, traceCompleted: 1, traceTriggered: 1});
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
var obj = {s: ""};
|
||||
var name = "s";
|
||||
for (var i = 0; i <= RECORDLOOP + 5; i++)
|
||||
if (i > RECORDLOOP)
|
||||
obj[name]++; // first recording changes obj.s from string to number
|
||||
assertEq(obj.s, 5);
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
var obj = {p: 100};
|
||||
var name = "p";
|
||||
var a = [];
|
||||
for (var i = 0; i < 10; i++)
|
||||
a[i] = ++obj[name];
|
||||
assertEq(a.join(','), '101,102,103,104,105,106,107,108,109,110');
|
||||
assertEq(obj.p, 110);
|
||||
|
||||
checkStats({recorderStarted: 1, recorderAborted: 0, traceCompleted: 1, traceTriggered: 1});
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
var obj = {s: ""};
|
||||
var name = "s";
|
||||
var a = [];
|
||||
for (var i = 0; i <= RECORDLOOP + 5; i++) {
|
||||
a[i] = 'x';
|
||||
if (i > RECORDLOOP)
|
||||
a[i] = ++obj[name]; // first recording changes obj.s from string to number
|
||||
}
|
||||
assertEq(a.join(','), Array(RECORDLOOP + 2).join('x,') + '1,2,3,4,5');
|
||||
assertEq(obj.s, 5);
|
||||
|
Загрузка…
Ссылка в новой задаче