Implement FCallArray in IR

Esse commit está contido em:
aravind
2013-04-29 17:15:46 -07:00
commit de Sara Golemon
commit a5102a5d5e
12 arquivos alterados com 73 adições e 17 exclusões
+8
Ver Arquivo
@@ -881,6 +881,14 @@ InlineReturn S0:FramePtr
Unlinks a frame constructed by DefInlineFP.
D:StkPtr = CallArray S0:StkPtr
Invoke function corresponding to the current FPI with array args.
S0 points to the stack resulting after the ActRec for the function
and the array of its arguments is pushed. CallArray pops the array
off the stack, pushes the elements of the array as arguments, and
invokes the function in the ActRec.
D:StkPtr = Call S0:StkPtr S1:ConstInt S2:Func S3...
Invoke the function S2 with ActRec S0 and variadic arguments S3...
+12
Ver Arquivo
@@ -3238,6 +3238,18 @@ void CodeGenerator::cgInlineCreateCont(IRInstruction* inst) {
}
}
void CodeGenerator::cgCallArray(IRInstruction* inst) {
Offset pc = inst->getExtra<CallArray>()->pc;
Offset after = inst->getExtra<CallArray>()->after;
ArgGroup args;
args.imm(pc).imm(after);
// fCallArrayHelper makes the actual call by smashing its return address.
cgCallHelper(m_as, (TCA)TranslatorX64::fCallArrayHelper,
nullptr, kSyncPoint, args);
}
void CodeGenerator::cgCall(IRInstruction* inst) {
SSATmp* actRec = inst->getSrc(0);
SSATmp* returnBcOffset = inst->getSrc(1);
@@ -1776,8 +1776,10 @@ void HhbcTranslator::emitFPushClsMethodF(int32_t numParams,
}
}
void HhbcTranslator::emitFCallArray() {
PUNT(FCallArray); // can't interpret one because of control flow
void HhbcTranslator::emitFCallArray(const Offset pcOffset,
const Offset after) {
SSATmp* stack = spillStack();
gen(CallArray, CallArrayData(pcOffset, after), stack);
}
void HhbcTranslator::emitFCall(uint32_t numParams,
@@ -240,7 +240,7 @@ struct HhbcTranslator {
void emitFPushCtorD(int32_t numParams, int32_t classNameStrId);
void emitFPushCtor(int32_t numParams);
void emitCreateCl(int32_t numParams, int32_t classNameStrId);
void emitFCallArray();
void emitFCallArray(const Offset pcOffset, const Offset after);
void emitFCall(uint32_t numParams,
Offset returnBcOffset,
const Func* callee);
+15
Ver Arquivo
@@ -333,6 +333,7 @@ O(LdRaw, DParam, SUnk, NF) \
O(FreeActRec, D(FramePtr), S(FramePtr), Mem) \
/* name dstinfo srcinfo flags */ \
O(Call, D(StkPtr), SUnk, E|Mem|CRc|Refs) \
O(CallArray, D(StkPtr), S(StkPtr), E|Mem|N|CRc|Refs) \
O(CallBuiltin, DBuiltin, SUnk, E|Mem|Refs|Er|N|PRc) \
O(NativeImpl, ND, C(Func) S(FramePtr), E|Mem|N|Refs) \
/* XXX: why does RetCtrl sometimes get PtrToGen */ \
@@ -798,6 +799,19 @@ struct BCOffset : IRExtraData {
Offset offset;
};
/*
* FCallArray offsets
*/
struct CallArrayData : IRExtraData {
explicit CallArrayData(Offset pcOffset, Offset aft)
: pc(pcOffset), after(aft) {}
std::string show() const { return folly::to<std::string>(pc, ", ", after); }
Offset pc, after;
};
//////////////////////////////////////////////////////////////////////
#define X(op, data) \
@@ -830,6 +844,7 @@ X(ReDefGeneratorSP, StackOffset);
X(DefSP, StackOffset);
X(DefInlineFP, BCOffset);
X(InlineCreateCont, CreateContData);
X(CallArray, CallArrayData);
#undef X
@@ -1321,7 +1321,11 @@ TranslatorX64::irTranslateFCall(const Tracelet& t,
void
TranslatorX64::irTranslateFCallArray(const Tracelet& t,
const NormalizedInstruction& i) {
HHIR_EMIT(FCallArray);
const Offset pcOffset = i.offset();
SrcKey next = i.next ? i.next->source : t.m_nextSk;
const Offset after = next.offset();
HHIR_EMIT(FCallArray, pcOffset, after);
}
void
@@ -376,6 +376,7 @@ void LinearScan::allocRegToInstruction(InstructionList::iterator it) {
opc == ReDefSP ||
opc == ReDefGeneratorSP ||
opc == Call ||
opc == CallArray ||
opc == SpillStack ||
opc == SpillFrame ||
opc == ExceptionBarrier ||
@@ -69,6 +69,18 @@ SSATmp* getStackValue(SSATmp* sp,
type);
}
case CallArray:
// sp = CallArray(stack)
if (index == 0) {
// return value from call
return nullptr;
}
spansCall = true;
return getStackValue(inst->getSrc(0), // sp == ActRec + array arg
index + kNumActRecCells,
spansCall,
type);
case Call:
// sp = call(actrec, bcoffset, func, args...)
if (index == 0) {
@@ -496,6 +496,15 @@ void TraceBuilder::updateTrackedState(IRInstruction* inst) {
killLocals();
break;
case CallArray:
m_spValue = inst->getDst();
// A CallArray pops the ActRec an array arg and pushes a return value.
m_spOffset -= kNumActRecCells;
assert(m_spOffset >= 0);
killCse();
killLocals();
break;
case ContEnter:
killCse();
killLocals();
@@ -233,15 +233,15 @@ TCA funcBodyHelper(ActRec* fp) {
return tca;
}
void TranslatorX64::fCallArrayHelper(const FCallArrayArgs* args) {
void TranslatorX64::fCallArrayHelper(const Offset pcOff, const Offset pcNext) {
DECLARE_FRAME_POINTER(framePtr);
ActRec* fp = (ActRec*)framePtr->m_savedRbp;
VMExecutionContext *ec = g_vmContext;
ec->m_fp = fp;
ec->m_stack.top() = sp;
ec->m_pc = curUnit()->at(args->m_pcOff);
PC pc = curUnit()->at(args->m_pcNext);
ec->m_pc = curUnit()->at(pcOff);
PC pc = curUnit()->at(pcNext);
tl_regState = REGSTATE_CLEAN;
bool runFunc = ec->doFCallArray(pc);
+2 -5
Ver Arquivo
@@ -9844,13 +9844,10 @@ void TranslatorX64::translateFCallArray(const Tracelet& t,
syncOutputs(i);
FCallArrayArgs* args = m_globalData.alloc<FCallArrayArgs>();
emitImmReg(a, (uint64_t)args, argNumToRegName[0]);
emitImmReg(a, (uint64_t)i.offset(), argNumToRegName[0]);
emitImmReg(a, (uint64_t)after, argNumToRegName[1]);
emitCall(a, (TCA)fCallArrayHelper, true);
args->m_pcOff = i.offset();
args->m_pcNext = after;
if (i.breaksTracelet) {
SrcKey fallThru(curFunc(), after);
emitBindJmp(fallThru);
+1 -5
Ver Arquivo
@@ -999,11 +999,7 @@ private:
bool m_local;
};
static void reqLitHelper(const ReqLitStaticArgs* args);
struct FCallArrayArgs {
Offset m_pcOff;
Offset m_pcNext;
};
static void fCallArrayHelper(const FCallArrayArgs* args);
static void fCallArrayHelper(const Offset pcOff, const Offset pcNext);
TCA getNativeTrampoline(TCA helperAddress);
TCA emitNativeTrampoline(TCA helperAddress);