Translate FPushFuncU

We were punting on this, but it's a pretty easy
translation, and it makes calling functions from inside namespaces
much faster.

Closes #814
Esse commit está contido em:
Eric Caruso
2013-07-11 13:18:30 -07:00
commit de Sara Golemon
commit b94ab7709f
8 arquivos alterados com 82 adições e 19 exclusões
+37
Ver Arquivo
@@ -2248,6 +2248,43 @@ void CodeGenerator::cgLdFuncCached(IRInstruction* inst) {
});
}
void CodeGenerator::cgLdFuncCachedU(IRInstruction* inst) {
SSATmp* dst = inst->dst();
SSATmp* methodName = inst->src(0);
SSATmp* fallbackName = inst->src(1);
// allocate both cache handles
const StringData* name = methodName->getValStr();
CacheHandle ch = TargetCache::allocFixedFunction(name);
size_t funcCacheOff = ch + offsetof(FixedFuncCache, m_func);
const StringData* fallback = fallbackName->getValStr();
CacheHandle fch = TargetCache::allocFixedFunction(fallback);
size_t fallbackCacheOff = fch + offsetof(FixedFuncCache, m_func);
// check the first cache handle, then the fallback
auto dstReg = m_regs[dst].reg();
Label end;
if (dstReg == InvalidReg) {
m_as. cmpq (0, rVmTl[funcCacheOff]);
m_as. jcc8 (CC_NZ, end);
m_as. cmpq (0, rVmTl[fallbackCacheOff]);
} else {
m_as. loadq(rVmTl[funcCacheOff], dstReg);
m_as. testq(dstReg, dstReg);
m_as. jcc8 (CC_NZ, end);
m_as. loadq(rVmTl[fallbackCacheOff], dstReg);
m_as. testq(dstReg, dstReg);
}
// finally, jump to native call in astubs if neither hits
unlikelyIfBlock(CC_Z, [&] (Asm& a) {
// same helper as LdFuncCached
cgCallNative(a, inst);
});
asm_label(m_as, end);
}
void CodeGenerator::cgLdFuncCachedSafe(IRInstruction* inst) {
cgLdFuncCachedCommon(inst);
if (Block* taken = inst->taken()) {
+31 -18
Ver Arquivo
@@ -1965,35 +1965,48 @@ void HhbcTranslator::emitCreateCl(int32_t numParams, int32_t funNameStrId) {
push(closure);
}
void HhbcTranslator::emitFPushFuncD(int32_t numParams, int32_t funcId) {
const NamedEntityPair& nep = lookupNamedEntityPairId(funcId);
const StringData* name = nep.first;
const Func* func = Unit::lookupFunc(nep.second);
if (!func) {
// function lookup failed so just do the same as FPushFunc
emitFPushFunc(numParams, cns(name));
return;
void HhbcTranslator::emitFPushFuncCommon(const Func* func,
const StringData* name,
const StringData* fallback,
int32_t numParams) {
if (func) {
func->validate();
if (func->isNameBindingImmutable(curUnit())) {
emitFPushActRec(cns(func),
m_tb->genDefInitNull(),
numParams,
nullptr);
return;
}
}
func->validate();
const bool immutable = func->isNameBindingImmutable(curUnit());
IRTrace* catchTrace = nullptr;
if (!immutable) {
catchTrace = getCatchTrace(); // LdFuncCached can throw
}
SSATmp* ssaFunc = immutable ? cns(func)
: gen(LdFuncCached, catchTrace, cns(name));
// LdFuncCached can throw
IRTrace* catchTrace = getCatchTrace();
SSATmp* ssaFunc = fallback
? gen(LdFuncCachedU, catchTrace, cns(name), cns(fallback))
: gen(LdFuncCached, catchTrace, cns(name));
emitFPushActRec(ssaFunc,
m_tb->genDefInitNull(),
numParams,
nullptr);
}
void HhbcTranslator::emitFPushFuncD(int32_t numParams, int32_t funcId) {
const NamedEntityPair& nep = lookupNamedEntityPairId(funcId);
const StringData* name = nep.first;
const Func* func = Unit::lookupFunc(nep.second);
emitFPushFuncCommon(func, name, nullptr, numParams);
}
void HhbcTranslator::emitFPushFuncU(int32_t numParams,
int32_t funcId,
int32_t fallbackFuncId) {
PUNT(FPushFuncU);
const NamedEntityPair& nep = lookupNamedEntityPairId(funcId);
const StringData* name = nep.first;
const Func* func = Unit::lookupFunc(nep.second);
const NamedEntityPair& fallbackNep = lookupNamedEntityPairId(fallbackFuncId);
const StringData* fallbackName = fallbackNep.first;
emitFPushFuncCommon(func, name, fallbackName, numParams);
}
void HhbcTranslator::emitFPushFunc(int32_t numParams) {
+4
Ver Arquivo
@@ -255,6 +255,10 @@ struct HhbcTranslator {
const Func* func, int numArgs);
void emitFPushActRec(SSATmp* func, SSATmp* objOrClass, int32_t numArgs,
const StringData* invName = nullptr);
void emitFPushFuncCommon(const Func* func,
const StringData* name,
const StringData* fallback,
int32_t numParams);
void emitFPushFuncD(int32_t numParams, int32_t funcId);
void emitFPushFuncU(int32_t numParams,
int32_t funcId,
+5
Ver Arquivo
@@ -910,6 +910,11 @@ Translator::translateFPushFuncD(const NormalizedInstruction& i) {
HHIR_EMIT(FPushFuncD, (i.imm[0].u_IVA), (i.imm[1].u_SA));
}
void
Translator::translateFPushFuncU(const NormalizedInstruction& i) {
HHIR_EMIT(FPushFuncU, i.imm[0].u_IVA, i.imm[1].u_SA, i.imm[2].u_SA);
}
void
Translator::translateFPassCOp(const NormalizedInstruction& i) {
auto const op = i.op();
+1
Ver Arquivo
@@ -359,6 +359,7 @@ O(LdGblAddr, D(PtrToGen), S(Str), N) \
O(LdObjClass, D(Cls), S(Obj), C) \
O(LdFunc, D(Func), S(Str), E|N|CRc|Er) \
O(LdFuncCached, D(Func), CStr, N|C|E|Er) \
O(LdFuncCachedU, D(Func), CStr CStr, N|C|E|Er) \
O(LdFuncCachedSafe, D(Func), CStr, C) \
O(LdARFuncPtr, D(Func), S(StkPtr,FramePtr) C(Int), C) \
O(LdSSwitchDestFast, D(TCA), S(Gen), N) \
+2
Ver Arquivo
@@ -158,6 +158,8 @@ static CallMap s_callMap({
{{SSA, 0}, {SSA, 1}, {TV, 2}, {SSA, 3}}},
{LdFuncCached, (TCA)FixedFuncCache::lookupUnknownFunc, DSSA, SSync,
{{SSA, 0}}},
{LdFuncCachedU, (TCA)FixedFuncCache::lookupUnknownFunc, DSSA, SSync,
{{SSA, 0}}},
{CreateCl, (TCA)createClHelper, DSSA, SSync,
{{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}}},
{ArrayIdx, {FSSA, 0}, DTV, SSync,
+1
Ver Arquivo
@@ -88,6 +88,7 @@
CASE(UnsetM) \
CASE(BindM) \
CASE(FPushFuncD) \
CASE(FPushFuncU) \
CASE(FPushFunc) \
CASE(FPushClsMethodD) \
CASE(FPushClsMethodF) \
+1 -1
Ver Arquivo
@@ -2036,7 +2036,7 @@ void Translator::getOutputs(/*inout*/ Tracelet& t,
// Pseudo-outputs that affect translator state
case FStack: {
currentStackOffset += kNumActRecCells;
if (op == OpFPushFuncD) {
if (op == OpFPushFuncD || op == OpFPushFuncU) {
const Unit& cu = *ni->unit();
Id funcId = ni->imm[1].u_SA;
const NamedEntityPair &nep = cu.lookupNamedEntityPairId(funcId);