Special case some bytecode ops in getStackValue

Some bytecode ops, such as CGetL3, would munch the
types of the things on the stack above the new cell that was
pushed because getStackValue assumes all stack outputs from
interpOne are on top of the stack. The result is that the top
of the stack would contain the output type, and the two things
below it would not get any type (unknown).

This usually isn't a problem, but if we fail enough in type
prediction we might get around to InterpOneing these ops.
Esse commit está contido em:
Eric Caruso
2013-07-02 13:48:30 -07:00
commit de Sara Golemon
commit 0a6e1587e9
3 arquivos alterados com 31 adições e 5 exclusões
+6 -2
Ver Arquivo
@@ -324,8 +324,8 @@ struct CheckDefinedClsData : IRExtraData {
* Offset and stack deltas for InterpOne.
*/
struct InterpOneData : IRExtraData {
InterpOneData(Offset o, int64_t pop, int64_t push)
: bcOff(o), cellsPopped(pop), cellsPushed(push) {}
InterpOneData(Offset o, int64_t pop, int64_t push, Op op)
: bcOff(o), cellsPopped(pop), cellsPushed(push), opcode(op) {}
// Offset of the instruction to interpret, in the Unit indicated by
// the current Marker.
@@ -335,6 +335,10 @@ struct InterpOneData : IRExtraData {
// instruction, respectively. Includes ActRecs.
int64_t cellsPopped;
int64_t cellsPushed;
// Opcode, in case we need to fix the stack differently. Some byte-
// code instructions modify things below the top of the stack.
Op opcode;
};
//////////////////////////////////////////////////////////////////////
+3 -1
Ver Arquivo
@@ -3539,7 +3539,9 @@ void HhbcTranslator::emitInterpOne(Type outType, int popped) {
void HhbcTranslator::emitInterpOne(Type outType, int popped, int pushed) {
auto sp = spillStack();
gen(InterpOne, outType, InterpOneData(bcOff(), popped, pushed),
Unit *u = curFunc()->unit();
gen(InterpOne, outType, InterpOneData(bcOff(), popped, pushed,
u->getOpcode(bcOff())),
m_tb->fp(), sp);
assert(m_stackDeficit == 0);
}
+22 -2
Ver Arquivo
@@ -22,6 +22,7 @@
#include "hphp/runtime/base/memory/smart_containers.h"
#include "hphp/runtime/base/type_conversions.h"
#include "hphp/runtime/vm/jit/tracebuilder.h"
#include "hphp/runtime/vm/hhbc.h"
#include "hphp/runtime/vm/runtime.h"
namespace HPHP {
@@ -132,8 +133,27 @@ StackValueInfo getStackValue(SSATmp* sp, uint32_t index) {
auto const& extra = *inst->extra<InterpOne>();
int64_t spAdjustment = extra.cellsPopped - extra.cellsPushed;
Type resultType = inst->typeParam();
if (index == 0 && !resultType.equals(Type::None)) {
return StackValueInfo { resultType };
switch (extra.opcode) {
// some instructions are kinda funny and mess with the stack
// in places other than the top
case Op::CGetL2:
if (index == 1) return StackValueInfo { resultType };
if (index == 0) return getStackValue(prevSp, index);
break;
case Op::CGetL3:
if (index == 2) return StackValueInfo { resultType };
if (index < 2) return getStackValue(prevSp, index);
break;
case Op::UnpackCont:
if (index == 0) return StackValueInfo { Type::Cell };
if (index == 1) return StackValueInfo { Type::Int };
break;
default:
if (index == 0 && !resultType.equals(Type::None)) {
return StackValueInfo { resultType };
}
break;
}
// If the index we're looking for is a cell pushed by the InterpOne (other