Bug 660438 - Update tracer for changed [[DefaultValue]] semantics to fall back for not-callable, not for not-primitive. r=luke

This commit is contained in:
Jeff Walden 2011-05-31 11:10:19 -07:00
parent 9d216339ba
commit d255c9a807
9 changed files with 53 additions and 38 deletions

View File

@ -42,10 +42,10 @@
dup # any obj obj
dup # any obj obj obj
getprop valueOf # any obj obj valueOf
ifprimtop 1 # any obj obj valueOf
ifcantcalltop 1 # any obj obj valueOf
swap # any obj valueOf obj
call 0 # any obj rval
ifprimtop 3 # any obj rval
ifcantcalltop 3 # any obj rval
pop # any obj
dup # any obj obj
goto 2
@ -64,10 +64,10 @@
dup # any obj obj
dup # any obj obj obj
getprop valueOf # any obj obj valueOf
ifprimtop 1 # any obj obj valueOf
ifcantcalltop 1 # any obj obj valueOf
swap # any obj valueOf obj
call 0 # any obj lval
ifprimtop 3 # any obj lval
ifcantcalltop 3 # any obj lval
pop # any obj
dup # any obj obj
goto 2
@ -91,10 +91,10 @@
dup # any obj obj
dup # any obj obj obj
getprop valueOf # any obj obj valueOf
ifprimtop 1 # any obj obj valueOf
ifcantcalltop 1 # any obj obj valueOf
swap # any obj valueOf obj
call 0 # any obj rval
ifprimtop 3 # any obj rval
ifcantcalltop 3 # any obj rval
pop # any obj
dup # any obj obj
goto 2
@ -113,10 +113,10 @@
dup # any obj obj
dup # any obj obj obj
getprop valueOf # any obj obj valueOf
ifprimtop 1 # any obj obj valueOf
ifcantcalltop 1 # any obj obj valueOf
swap # any obj valueOf obj
call 0 # any obj lval
ifprimtop 3 # any obj lval
ifcantcalltop 3 # any obj lval
pop # any obj
dup # any obj obj
goto 2
@ -136,10 +136,10 @@
dup # obj2 obj1 obj1
dup # obj2 obj1 obj1 obj1
getprop valueOf # obj2 obj1 obj1 valueOf
ifprimtop 1 # obj2 obj1 obj1 valueOf
ifcantcalltop 1 # obj2 obj1 obj1 valueOf
swap # obj2 obj1 valueOf obj1
call 0 # obj2 obj1 lval
ifprimtop 3 # obj2 obj1 lval
ifcantcalltop 3 # obj2 obj1 lval
pop # obj2 obj1
dup # obj2 obj1 obj1
goto 2
@ -153,10 +153,10 @@
dup # lval obj1 obj1
dup # lval obj obj obj
getprop valueOf # lval obj obj valueOf
ifprimtop 4 # lval obj obj valueOf
ifcantcalltop 4 # lval obj obj valueOf
swap # lval obj valueOf obj
call 0 # lval obj rval
ifprimtop 6 # lval obj rval
ifcantcalltop 6 # lval obj rval
pop # lval obj
dup # lval obj obj
goto 5
@ -178,10 +178,10 @@
dup # any obj obj
dup # any obj obj obj
getprop valueOf # any obj obj valueOf
ifprimtop 1 # any obj obj valueOf
ifcantcalltop 1 # any obj obj valueOf
swap # any obj valueOf obj
call 0 # any obj rval
ifprimtop 3 # any obj rval
ifcantcalltop 3 # any obj rval
pop # any obj
dup # any obj obj
goto 2
@ -200,10 +200,10 @@
dup # any obj obj
dup # any obj obj obj
getprop valueOf # any obj obj valueOf
ifprimtop 1 # any obj obj valueOf
ifcantcalltop 1 # any obj obj valueOf
swap # any obj valueOf obj
call 0 # any obj lval
ifprimtop 3 # any obj lval
ifcantcalltop 3 # any obj lval
pop # any obj
dup # any obj obj
goto 2
@ -223,10 +223,10 @@
dup # obj2 obj1 obj1
dup # obj2 obj1 obj1 obj1
getprop valueOf # obj2 obj1 obj1 valueOf
ifprimtop 1 # obj2 obj1 obj1 valueOf
ifcantcalltop 1 # obj2 obj1 obj1 valueOf
swap # obj2 obj1 valueOf obj1
call 0 # obj2 obj1 lval
ifprimtop 3 # obj2 obj1 lval
ifcantcalltop 3 # obj2 obj1 lval
pop # obj2 obj1
dup # obj2 obj1 obj1
goto 2
@ -240,10 +240,10 @@
dup # lval obj obj
dup # lval obj obj obj
getprop valueOf # lval obj obj valueOf
ifprimtop 4 # lval obj obj valueOf
ifcantcalltop 4 # lval obj obj valueOf
swap # lval obj valueOf obj
call 0 # lval obj rval
ifprimtop 6 # lval obj rval
ifcantcalltop 6 # lval obj rval
pop # lval obj
dup # lval obj obj
goto 5
@ -265,10 +265,10 @@
dup # obj obj
dup # obj obj obj
getprop valueOf # obj obj valueOf
ifprimtop 2 # obj obj valueOf
ifcantcalltop 2 # obj obj valueOf
swap # obj valueOf obj
call 0 # obj lval
ifprimtop 1 # obj lval
ifcantcalltop 1 # obj lval
pop # obj
dup # obj obj
goto 3
@ -347,10 +347,10 @@
dup # String this obj obj
dup # String this obj obj obj
getprop toString # String this obj obj toString
ifprimtop 1 # String this obj obj toString
ifcantcalltop 1 # String this obj obj toString
swap # String this obj toString obj
call 0 # String this obj rval
ifprimtop 3 # String this obj rval
ifcantcalltop 3 # String this obj rval
pop # String this obj
dup # String this obj obj
goto 2
@ -372,10 +372,10 @@
dup # String this obj obj
dup # String this obj obj obj
getprop toString # String this obj obj toString
ifprimtop 1 # String this obj obj toString
ifcantcalltop 1 # String this obj obj toString
swap # String this obj toString obj
call 0 # String this obj rval
ifprimtop 3 # String this obj rval
ifcantcalltop 3 # String this obj rval
pop # String this obj
dup # String this obj obj
goto 2

View File

@ -0,0 +1,4 @@
var arr = ["foo", "bar"];
var obj = { toString: {}, valueOf: function() { return 1; } };
for (var i = 0; i < 25; i++)
assertEq(arr[obj], "bar");

View File

@ -0,0 +1,3 @@
var obj = { toString: {}, valueOf: function() { return "foopy"; } };
for (var i = 0; i < 25; i++)
assertEq(String(obj), "foopy");

View File

@ -0,0 +1,3 @@
var obj = { valueOf: {}, toString: function() { return 0; } };
for (var i = 0; i < 25; i++)
assertEq(obj < 1, true);

View File

@ -464,7 +464,7 @@ Script::analyze(JSContext *cx, JSScript *script)
/* Watch for opcodes the method JIT doesn't compile. */
case JSOP_GOSUB:
case JSOP_GOSUBX:
case JSOP_IFPRIMTOP:
case JSOP_IFCANTCALLTOP:
case JSOP_FILTER:
case JSOP_ENDFILTER:
case JSOP_TABLESWITCHX:

View File

@ -6038,17 +6038,17 @@ BEGIN_CASE(JSOP_SETLOCALPOP)
}
END_CASE(JSOP_SETLOCALPOP)
BEGIN_CASE(JSOP_IFPRIMTOP)
BEGIN_CASE(JSOP_IFCANTCALLTOP)
/*
* If the top of stack is of primitive type, jump to our target. Otherwise
* advance to the next opcode.
*/
JS_ASSERT(regs.sp > regs.fp()->base());
if (regs.sp[-1].isPrimitive()) {
if (!js_IsCallable(regs.sp[-1])) {
len = GET_JUMP_OFFSET(regs.pc);
BRANCH(len);
}
END_CASE(JSOP_IFPRIMTOP)
END_CASE(JSOP_IFCANTCALLTOP)
BEGIN_CASE(JSOP_PRIMTOP)
JS_ASSERT(regs.sp > regs.fp()->base());

View File

@ -505,8 +505,8 @@ OPDEF(JSOP_TYPEOFEXPR, 200,"typeofexpr", NULL, 1, 1, 1, 15, JOF_BYTE|J
OPDEF(JSOP_ENTERBLOCK, 201,"enterblock", NULL, 3, 0, -1, 0, JOF_OBJECT)
OPDEF(JSOP_LEAVEBLOCK, 202,"leaveblock", NULL, 5, -1, 0, 0, JOF_UINT16)
/* Jump to target if top of stack value is of primitive type. */
OPDEF(JSOP_IFPRIMTOP, 203,"ifprimtop", NULL, 3, 1, 1, 0, JOF_JUMP|JOF_DETECTING)
/* Jump to target if top of stack value isn't callable. */
OPDEF(JSOP_IFCANTCALLTOP, 203,"ifcantcalltop",NULL, 3, 1, 1, 0, JOF_JUMP|JOF_DETECTING)
/* Throws a TypeError if the value at the top of the stack is not primitive. */
OPDEF(JSOP_PRIMTOP, 204,"primtop", NULL, 2, 1, 1, 0, JOF_INT8)

View File

@ -15598,13 +15598,18 @@ TraceRecorder::record_JSOP_SETLOCALPOP()
}
JS_REQUIRES_STACK AbortableRecordingStatus
TraceRecorder::record_JSOP_IFPRIMTOP()
TraceRecorder::record_JSOP_IFCANTCALLTOP()
{
Value &top = stackval(-1);
// Traces are type-specialized, including null vs. object, so we need do
// nothing here. The upstream unbox_value called after valueOf or toString
// from an imacro (e.g.) will fork the trace for us, allowing us to just
// follow along mindlessly :-).
return ARECORD_CONTINUE;
// nothing if the trace type will be consistently callable or not callable.
if (top.isPrimitive() || top.toObject().isFunction())
return ARECORD_CONTINUE;
// Callable objects that aren't also functions would require a guard, but
// they're rare, so err on the side of simplicity.
return ARECORD_STOP;
}
JS_REQUIRES_STACK AbortableRecordingStatus

View File

@ -231,7 +231,7 @@ JS_XDRFindClassById(JSXDRState *xdr, uint32 id);
* before deserialization of bytecode. If the saved version does not match
* the current version, abort deserialization and invalidate the file.
*/
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 85)
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 86)
/*
* Library-private functions.