Backed out changesets fabe232e8be9 and c84b0156ae03 (bug 793860) for Linux mochitest-2 timeouts.

This commit is contained in:
Ryan VanderMeulen 2013-12-09 16:40:03 -05:00
Родитель bd668d0af6
Коммит 28a5b72edd
7 изменённых файлов: 158 добавлений и 76 удалений

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

@ -1978,6 +1978,22 @@ EmitNameOp(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool callC
return true;
}
static inline bool
EmitElemOpBase(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op)
{
if (Emit1(cx, bce, op) < 0)
return false;
CheckTypeSet(cx, bce, op);
if (op == JSOP_CALLELEM) {
if (Emit1(cx, bce, JSOP_SWAP) < 0)
return false;
if (Emit1(cx, bce, JSOP_NOTEARG) < 0)
return false;
}
return true;
}
static bool
EmitPropLHS(ExclusiveContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
{
@ -2125,39 +2141,45 @@ EmitNameIncDec(ExclusiveContext *cx, ParseNode *pn, BytecodeEmitter *bce)
return true;
}
/*
* Emit bytecode to put operands for a JSOP_GETELEM/CALLELEM/SETELEM/DELELEM
* opcode onto the stack in the right order. In the case of SETELEM, the
* value to be assigned must already be pushed.
*/
static bool
EmitElemOperands(ExclusiveContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
{
JS_ASSERT(pn->isArity(PN_BINARY));
if (!EmitTree(cx, bce, pn->pn_left))
ParseNode *left, *right;
if (pn->isArity(PN_NAME)) {
/*
* Set left and right so pn appears to be a PNK_ELEM node, instead of
* a PNK_DOT node. See the PNK_FOR/IN case in EmitTree, and
* EmitDestructuringOps nearer below. In the destructuring case, the
* base expression (pn_expr) of the name may be null, which means we
* have to emit a JSOP_BINDNAME.
*/
left = pn->maybeExpr();
if (!left) {
left = bce->parser->handler.new_<NullaryNode>(
PNK_STRING, JSOP_BINDNAME, pn->pn_pos, pn->pn_atom);
if (!left)
return false;
}
right = bce->parser->handler.new_<NullaryNode>(
PNK_STRING, JSOP_STRING, pn->pn_pos, pn->pn_atom);
if (!right)
return false;
} else {
JS_ASSERT(pn->isArity(PN_BINARY));
left = pn->pn_left;
right = pn->pn_right;
}
if (!EmitTree(cx, bce, left))
return false;
if (op == JSOP_CALLELEM && Emit1(cx, bce, JSOP_DUP) < 0)
return false;
if (!EmitTree(cx, bce, pn->pn_right))
return false;
if (op == JSOP_SETELEM && Emit2(cx, bce, JSOP_PICK, (jsbytecode)2) < 0)
return false;
return true;
}
static inline bool
EmitElemOpBase(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op)
{
if (Emit1(cx, bce, op) < 0)
if (!EmitTree(cx, bce, right))
return false;
CheckTypeSet(cx, bce, op);
if (op == JSOP_CALLELEM) {
if (Emit1(cx, bce, JSOP_SWAP) < 0)
return false;
if (Emit1(cx, bce, JSOP_NOTEARG) < 0)
return false;
}
return true;
}
@ -2831,16 +2853,20 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
{
JS_ASSERT(emitOption != DefineVars);
// Now emit the lvalue opcode sequence. If the lvalue is a nested
// destructuring initialiser-form, call ourselves to handle it, then pop
// the matched value. Otherwise emit an lvalue bytecode sequence followed
// by an assignment op.
/*
* Now emit the lvalue opcode sequence. If the lvalue is a nested
* destructuring initialiser-form, call ourselves to handle it, then
* pop the matched value. Otherwise emit an lvalue bytecode sequence
* ending with a JSOP_ENUMELEM or equivalent op.
*/
if (pn->isKind(PNK_ARRAY) || pn->isKind(PNK_OBJECT)) {
if (!EmitDestructuringOpsHelper(cx, bce, pn, emitOption))
return false;
if (emitOption == InitializeVars) {
// Per its post-condition, EmitDestructuringOpsHelper has left the
// to-be-destructured value on top of the stack.
/*
* Per its post-condition, EmitDestructuringOpsHelper has left the
* to-be-destructured value on top of the stack.
*/
if (Emit1(cx, bce, JSOP_POP) < 0)
return false;
}
@ -2850,6 +2876,8 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
JS_ASSERT(pn->getOp() == JSOP_GETLOCAL);
JS_ASSERT(pn->pn_dflags & PND_BOUND);
} else {
// All paths below must pop after assigning to the lhs.
switch (pn->getKind()) {
case PNK_NAME:
if (!BindNameToSlot(cx, bce, pn))
@ -2862,7 +2890,6 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
switch (pn->getOp()) {
case JSOP_SETNAME:
case JSOP_SETGNAME:
case JSOP_SETCONST: {
// This is like ordinary assignment, but with one difference.
//
// In `a = b`, we first determine a binding for `a` (using
@ -2872,28 +2899,27 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
// In `[a] = [b]`, per spec, `b` is evaluated first, then we
// determine a binding for `a`. Then we need to do assignment--
// but the operands are on the stack in the wrong order for
// JSOP_SETPROP, so we have to add a JSOP_SWAP.
jsatomid atomIndex;
if (!bce->makeAtomIndex(pn->pn_atom, &atomIndex))
return false;
if (!pn->isOp(JSOP_SETCONST)) {
JSOp bindOp = pn->isOp(JSOP_SETNAME) ? JSOP_BINDNAME : JSOP_BINDGNAME;
if (!EmitIndex32(cx, bindOp, atomIndex, bce))
return false;
if (Emit1(cx, bce, JSOP_SWAP) < 0)
return false;
}
if (!EmitIndexOp(cx, pn->getOp(), atomIndex, bce))
// JSOP_SETPROP, so we use JSOP_ENUMELEM instead.
//
// EmitElemOp ordinarily works with PNK_ELEM nodes, naturally,
// but it has special code to handle PNK_NAME nodes in this one
// case.
if (!EmitElemOp(cx, pn, JSOP_ENUMELEM, bce))
return false;
break;
case JSOP_SETCONST:
// As above.
if (!EmitElemOp(cx, pn, JSOP_ENUMCONSTELEM, bce))
return false;
break;
}
case JSOP_SETLOCAL:
case JSOP_SETARG:
if (!EmitVarOp(cx, pn, pn->getOp(), bce))
return false;
if (Emit1(cx, bce, JSOP_POP) < 0)
return false;
break;
default:
@ -2902,6 +2928,7 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
break;
case PNK_DOT:
case PNK_ELEM:
// See the (PNK_NAME, JSOP_SETNAME) case above.
//
// In `a.x = b`, `a` is evaluated first, then `b`, then a
@ -2909,20 +2936,11 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
//
// In `[a.x] = [b]`, per spec, `b` is evaluated before `a`. Then we
// need a property set -- but the operands are on the stack in the
// wrong order for JSOP_SETPROP, so we have to add a JSOP_SWAP.
if (!EmitTree(cx, bce, pn->pn_expr))
return false;
if (Emit1(cx, bce, JSOP_SWAP) < 0)
return false;
if (!EmitAtomOp(cx, pn, JSOP_SETPROP, bce))
return false;
break;
case PNK_ELEM:
// See the comment at `case PNK_DOT:` above. This case,
// `[a[x]] = [b]`, is handled much the same way. The JSOP_SWAP
// is emitted by EmitElemOperands.
if (!EmitElemOp(cx, pn, JSOP_SETELEM, bce))
// wrong order for JSOP_SETPROP, so we use JSOP_ENUMELEM instead.
//
// EmitElemOp has special code to handle PNK_DOT nodes in this one
// case.
if (!EmitElemOp(cx, pn, JSOP_ENUMELEM, bce))
return false;
break;
@ -2931,11 +2949,13 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
if (!EmitTree(cx, bce, pn))
return false;
// Pop the call return value. Below, we pop the RHS too, balancing
// the stack --- presumably for the benefit of bytecode
// analysis. (The interpreter will never reach these instructions
// since we just emitted JSOP_SETCALL, which always throws. It's
// possible no analyses actually depend on this either.)
// Pop the call return value and the RHS, presumably for the
// benefit of bytecode analysis. (The interpreter will never reach
// these instructions since we just emitted JSOP_SETCALL, which
// always throws. It's possible no analyses actually depend on this
// either.)
if (Emit1(cx, bce, JSOP_POP) < 0)
return false;
if (Emit1(cx, bce, JSOP_POP) < 0)
return false;
break;
@ -2943,10 +2963,6 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
default:
MOZ_ASSUME_UNREACHABLE("EmitDestructuringLHS: bad lhs kind");
}
// Pop the assigned value.
if (Emit1(cx, bce, JSOP_POP) < 0)
return false;
}
return true;

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

@ -1717,6 +1717,25 @@ BaselineCompiler::emit_JSOP_SETELEM()
return true;
}
bool
BaselineCompiler::emit_JSOP_ENUMELEM()
{
// ENUMELEM is a SETELEM with a different stack arrangement.
// Instead of: OBJ ID RHS
// The stack is: RHS OBJ ID
// Keep object and index in R0 and R1, and keep RHS on the stack.
frame.popRegsAndSync(2);
// Call IC.
ICSetElem_Fallback::Compiler stubCompiler(cx);
if (!emitOpIC(stubCompiler.getStub(&stubSpace_)))
return false;
frame.pop();
return true;
}
typedef bool (*DeleteElementFn)(JSContext *, HandleValue, HandleValue, bool *);
static const VMFunction DeleteElementStrictInfo = FunctionInfo<DeleteElementFn>(DeleteElement<true>);
static const VMFunction DeleteElementNonStrictInfo = FunctionInfo<DeleteElementFn>(DeleteElement<false>);

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

@ -97,6 +97,7 @@ namespace jit {
_(JSOP_GETELEM) \
_(JSOP_SETELEM) \
_(JSOP_CALLELEM) \
_(JSOP_ENUMELEM) \
_(JSOP_DELELEM) \
_(JSOP_IN) \
_(JSOP_GETGNAME) \

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

@ -4888,6 +4888,7 @@ DoSetElemFallback(JSContext *cx, BaselineFrame *frame, ICSetElem_Fallback *stub,
FallbackICSpew(cx, stub, "SetElem(%s)", js_CodeName[JSOp(*pc)]);
JS_ASSERT(op == JSOP_SETELEM ||
op == JSOP_ENUMELEM ||
op == JSOP_INITELEM ||
op == JSOP_INITELEM_ARRAY);

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

@ -273,7 +273,11 @@ OPDEF(JSOP_DEFAULT, 122,"default", NULL, 5, 1, 0, JOF_JUMP)
*/
OPDEF(JSOP_EVAL, 123,"eval", NULL, 3, -1, 1, JOF_UINT16|JOF_INVOKE|JOF_TYPESET)
OPDEF(JSOP_UNUSED124, 124, "unused124", NULL, 1, 0, 0, JOF_BYTE)
/*
* ECMA-compliant helper for 'for (x[i] in o)' loops.
*/
OPDEF(JSOP_ENUMELEM, 124,"enumelem", NULL, 1, 3, 0, JOF_BYTE |JOF_SET|JOF_TMPSLOT)
OPDEF(JSOP_UNUSED125, 125, "unused125", NULL, 1, 0, 0, JOF_BYTE)
OPDEF(JSOP_UNUSED126, 126, "unused126", NULL, 1, 0, 0, JOF_BYTE)
@ -446,8 +450,15 @@ OPDEF(JSOP_GENERATOR, 202,"generator", NULL, 1, 0, 0, JOF_BYTE)
OPDEF(JSOP_YIELD, 203,"yield", NULL, 1, 1, 1, JOF_BYTE)
OPDEF(JSOP_ARRAYPUSH, 204,"arraypush", NULL, 3, 1, 0, JOF_LOCAL)
OPDEF(JSOP_UNUSED205, 205, "unused205", NULL, 1, 0, 0, JOF_BYTE)
OPDEF(JSOP_UNUSED206, 206, "unused206", NULL, 1, 0, 0, JOF_BYTE)
/*
* Get the built-in function::foo namespace and push it.
*/
OPDEF(JSOP_GETFUNNS, 205,"getfunns", NULL, 1, 0, 1, JOF_BYTE)
/*
* Variant of JSOP_ENUMELEM for destructuring const (const [a, b] = ...).
*/
OPDEF(JSOP_ENUMCONSTELEM, 206,"enumconstelem",NULL, 1, 3, 0, JOF_BYTE|JOF_SET)
/*
* Variant of JSOP_LEAVEBLOCK has a result on the stack above the locals,

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

@ -1489,7 +1489,6 @@ CASE(JSOP_UNUSED102)
CASE(JSOP_UNUSED103)
CASE(JSOP_UNUSED104)
CASE(JSOP_UNUSED107)
CASE(JSOP_UNUSED124)
CASE(JSOP_UNUSED125)
CASE(JSOP_UNUSED126)
CASE(JSOP_UNUSED132)
@ -1536,8 +1535,7 @@ CASE(JSOP_UNUSED194)
CASE(JSOP_UNUSED196)
CASE(JSOP_UNUSED200)
CASE(JSOP_UNUSED201)
CASE(JSOP_UNUSED205)
CASE(JSOP_UNUSED206)
CASE(JSOP_GETFUNNS)
CASE(JSOP_UNUSED208)
CASE(JSOP_UNUSED209)
CASE(JSOP_UNUSED210)
@ -1883,6 +1881,26 @@ CASE(JSOP_SETCONST)
}
END_CASE(JSOP_SETCONST);
#if JS_HAS_DESTRUCTURING
CASE(JSOP_ENUMCONSTELEM)
{
RootedValue &rval = rootValue0;
rval = REGS.sp[-3];
RootedObject &obj = rootObject0;
FETCH_OBJECT(cx, -2, obj);
RootedId &id = rootId0;
FETCH_ELEMENT_ID(-1, id);
if (!JSObject::defineGeneric(cx, obj, id, rval,
JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY)) {
goto error;
}
REGS.sp -= 3;
}
END_CASE(JSOP_ENUMCONSTELEM)
#endif
CASE(JSOP_BINDGNAME)
PUSH_OBJECT(REGS.fp()->global());
END_CASE(JSOP_BINDGNAME)
@ -2347,6 +2365,22 @@ CASE(JSOP_SETELEM)
}
END_CASE(JSOP_SETELEM)
CASE(JSOP_ENUMELEM)
{
RootedObject &obj = rootObject0;
RootedValue &rval = rootValue0;
/* Funky: the value to set is under the [obj, id] pair. */
FETCH_OBJECT(cx, -2, obj);
RootedId &id = rootId0;
FETCH_ELEMENT_ID(-1, id);
rval = REGS.sp[-3];
if (!JSObject::setGeneric(cx, obj, obj, id, &rval, script->strict))
goto error;
REGS.sp -= 3;
}
END_CASE(JSOP_ENUMELEM)
CASE(JSOP_EVAL)
{
CallArgs args = CallArgsFromSp(GET_ARGC(REGS.pc), REGS.sp);

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

@ -22,7 +22,7 @@ namespace js {
* and saved versions. If deserialization fails, the data should be
* invalidated if possible.
*/
static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 157);
static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 156);
class XDRBuffer {
public: