Bug 492915 - Trace incelem/decelem/eleminc/elemdec for objects other than arrays. r=brendan.

--HG--
extra : rebase_source : 33ab817997096bd4b00c8a36bb0444dcacc58a27
This commit is contained in:
Jason Orendorff 2010-05-03 16:48:06 -05:00
Родитель 7a6a0f9780
Коммит cb43b0920f
11 изменённых файлов: 209 добавлений и 13 удалений

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

@ -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);