Bug 913978 - Fix over-tight assertions after enabling Baseline getter/setter calls for GETELEM/SETELEM ops. r=efaust

This commit is contained in:
Kannan Vijayan 2013-09-10 12:26:47 -04:00
parent 11c7d05ca8
commit 78fdcfa160
5 changed files with 34 additions and 17 deletions

View File

@ -379,9 +379,9 @@ IsInlinableFallback(ICFallbackStub *icEntry)
static inline void*
GetStubReturnAddress(JSContext *cx, jsbytecode *pc)
{
if (IsGetterPC(pc))
if (IsGetPropPC(pc))
return cx->compartment()->ionCompartment()->baselineGetPropReturnAddr();
if (IsSetterPC(pc))
if (IsSetPropPC(pc))
return cx->compartment()->ionCompartment()->baselineSetPropReturnAddr();
// This should be a call op of some kind, now.
JS_ASSERT(IsCallPC(pc));
@ -661,7 +661,7 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC,
// On the caller side this must represent like the function wasn't inlined.
uint32_t pushedSlots = 0;
AutoValueVector savedCallerArgs(cx);
bool needToSaveArgs = op == JSOP_FUNAPPLY || IsGetterPC(pc) || IsSetterPC(pc);
bool needToSaveArgs = op == JSOP_FUNAPPLY || IsGetPropPC(pc) || IsSetPropPC(pc);
if (iter.moreFrames() && (op == JSOP_FUNCALL || needToSaveArgs))
{
uint32_t inlined_args = 0;
@ -670,7 +670,7 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC,
else if (op == JSOP_FUNAPPLY)
inlined_args = 2 + blFrame->numActualArgs();
else
inlined_args = 2 + IsSetterPC(pc);
inlined_args = 2 + IsSetPropPC(pc);
JS_ASSERT(exprStackSlots >= inlined_args);
pushedSlots = exprStackSlots - inlined_args;
@ -725,7 +725,7 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC,
for (uint32_t i = 0; i < inlined_args; i++)
savedCallerArgs[i] = iter.read();
if (IsSetterPC(pc)) {
if (IsSetPropPC(pc)) {
// We would love to just save all the arguments and leave them
// in the stub frame pushed below, but we will lose the inital
// argument which the function was called with, which we must
@ -793,7 +793,7 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC,
// include the this. When inlining that is not included.
// So the exprStackSlots will be one less.
JS_ASSERT(expectedDepth - exprStackSlots <= 1);
} else if (iter.moreFrames() && (IsGetterPC(pc) || IsSetterPC(pc))) {
} else if (iter.moreFrames() && (IsGetPropPC(pc) || IsSetPropPC(pc))) {
// Accessors coming out of ion are inlined via a complete
// lie perpetrated by the compiler internally. Ion just rearranges
// the stack, and pretends that it looked like a call all along.
@ -1028,7 +1028,7 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC,
if (op == JSOP_FUNAPPLY)
actualArgc = blFrame->numActualArgs();
else
actualArgc = IsSetterPC(pc);
actualArgc = IsSetPropPC(pc);
JS_ASSERT(actualArgc + 2 <= exprStackSlots);
JS_ASSERT(savedCallerArgs.length() == actualArgc + 2);

View File

@ -374,7 +374,7 @@ IsIonInlinablePC(jsbytecode *pc) {
// CALL, FUNCALL, FUNAPPLY, EVAL, NEW (Normal Callsites)
// GETPROP, CALLPROP, and LENGTH. (Inlined Getters)
// SETPROP, SETNAME, SETGNAME (Inlined Setters)
return IsCallPC(pc) || IsGetterPC(pc) || IsSetterPC(pc);
return IsCallPC(pc) || IsGetPropPC(pc) || IsSetPropPC(pc);
}
void ForbidCompilation(JSContext *cx, JSScript *script);

View File

@ -1374,9 +1374,9 @@ InlineFrameIteratorMaybeGC<allowGC>::findNextFrame()
if (JSOp(*pc_) == JSOP_FUNCALL) {
JS_ASSERT(GET_ARGC(pc_) > 0);
numActualArgs_ = GET_ARGC(pc_) - 1;
} else if (IsGetterPC(pc_)) {
} else if (IsGetPropPC(pc_)) {
numActualArgs_ = 0;
} else if (IsSetterPC(pc_)) {
} else if (IsSetPropPC(pc_)) {
numActualArgs_ = 1;
}
@ -1443,7 +1443,7 @@ InlineFrameIteratorMaybeGC<allowGC>::isConstructing() const
++parent;
// Inlined Getters and Setters are never constructing.
if (IsGetterPC(parent.pc()) || IsSetterPC(parent.pc()))
if (IsGetPropPC(parent.pc()) || IsSetPropPC(parent.pc()))
return false;
// In the case of a JS frame, look up the pc from the snapshot.
@ -1472,7 +1472,7 @@ IonFrameIterator::isConstructing() const
InlineFrameIterator inlinedParent(GetIonContext()->cx, &parent);
//Inlined Getters and Setters are never constructing.
if (IsGetterPC(inlinedParent.pc()) || IsSetterPC(inlinedParent.pc()))
if (IsGetPropPC(inlinedParent.pc()) || IsSetPropPC(inlinedParent.pc()))
return false;
JS_ASSERT(IsCallPC(inlinedParent.pc()));
@ -1484,8 +1484,9 @@ IonFrameIterator::isConstructing() const
jsbytecode *pc;
parent.baselineScriptAndPc(NULL, &pc);
//Inlined Getters and Setters are never constructing.
if (IsGetterPC(pc) || IsSetterPC(pc))
// Inlined Getters and Setters are never constructing.
// Baseline may call getters from [GET|SET]PROP or [GET|SET]ELEM ops.
if (IsGetPropPC(pc) || IsSetPropPC(pc) || IsGetElemPC(pc) || IsSetElemPC(pc))
return false;
JS_ASSERT(IsCallPC(pc));

View File

@ -284,7 +284,9 @@ CodeGeneratorShared::encode(LSnapshot *snapshot)
// include the this. When inlining that is not included.
// So the exprStackSlots will be one less.
JS_ASSERT(stackDepth - exprStack <= 1);
} else if (JSOp(*bailPC) != JSOP_FUNAPPLY && !IsGetterPC(bailPC) && !IsSetterPC(bailPC)) {
} else if (JSOp(*bailPC) != JSOP_FUNAPPLY &&
!IsGetPropPC(bailPC) && !IsSetPropPC(bailPC))
{
// For fun.apply({}, arguments) the reconstructStackDepth will
// have stackdepth 4, but it could be that we inlined the
// funapply. In that case exprStackSlots, will have the real

View File

@ -591,19 +591,33 @@ IsEqualityOp(JSOp op)
}
inline bool
IsGetterPC(jsbytecode *pc)
IsGetPropPC(jsbytecode *pc)
{
JSOp op = JSOp(*pc);
return op == JSOP_LENGTH || op == JSOP_GETPROP || op == JSOP_CALLPROP;
}
inline bool
IsSetterPC(jsbytecode *pc)
IsSetPropPC(jsbytecode *pc)
{
JSOp op = JSOp(*pc);
return op == JSOP_SETPROP || op == JSOP_SETNAME || op == JSOP_SETGNAME;
}
inline bool
IsGetElemPC(jsbytecode *pc)
{
JSOp op = JSOp(*pc);
return op == JSOP_GETELEM || op == JSOP_CALLELEM;
}
inline bool
IsSetElemPC(jsbytecode *pc)
{
JSOp op = JSOp(*pc);
return op == JSOP_SETELEM;
}
inline bool
IsCallPC(jsbytecode *pc)
{