Inline FPushCtor
Similar to FPushCtorD
Esse commit está contido em:
@@ -817,18 +817,9 @@ D:BoxedCell = LdStaticLocCached S0:ConstCacheHandle -> L
|
||||
|
||||
8. Allocation
|
||||
|
||||
D:StkPtr = NewObj S0:ConstInt S1:Cls S2:StkPtr S3:FramePtr
|
||||
|
||||
Allocate a new object. Push a Cell pointing to the object and an
|
||||
ActRec for the constructor onto the stack and return the new SP.
|
||||
S0 is the number of parameters for the constructor
|
||||
S1 is the class of the object
|
||||
S2 is the current stack pointer
|
||||
S3 is the frame pointer of the current ActRec
|
||||
|
||||
D:Obj = AllocObj S1:Cls
|
||||
|
||||
Allocate a new object of class S1.
|
||||
Allocates a new object of class S1.
|
||||
|
||||
NewArray
|
||||
NewTuple
|
||||
|
||||
@@ -144,6 +144,7 @@ void annotate(NormalizedInstruction* i) {
|
||||
case OpFPushClsMethodD:
|
||||
case OpFPushClsMethodF:
|
||||
case OpFPushCtorD:
|
||||
case OpFPushCtor:
|
||||
case OpFPushFuncD: {
|
||||
// When we push predictable action records, we can use a simpler
|
||||
// translation for their corresponding FCall.
|
||||
@@ -170,12 +171,16 @@ void annotate(NormalizedInstruction* i) {
|
||||
} else if (i->op() == OpFPushClsMethodD) {
|
||||
funcName = curUnit()->lookupLitstrId(i->imm[1].u_SA);
|
||||
className = curUnit()->lookupLitstrId(i->imm[2].u_SA);
|
||||
} else {
|
||||
assert(i->op() == OpFPushCtorD);
|
||||
} else if (i->op() == OpFPushCtorD) {
|
||||
className = curUnit()->lookupLitstrId(i->imm[1].u_SA);
|
||||
const Class* cls = Unit::lookupUniqueClass(className);
|
||||
if (!cls) break;
|
||||
funcName = cls->getCtor()->name();
|
||||
} else {
|
||||
assert(i->op() == OpFPushCtor);
|
||||
const Class* cls = i->inputs[0]->rtt.valueClass();
|
||||
if (!cls) break;
|
||||
funcName = cls->getCtor()->name();
|
||||
}
|
||||
assert(funcName->isStatic());
|
||||
recordActRecPush(*i, curUnit(), funcName, className,
|
||||
|
||||
@@ -351,7 +351,7 @@ CALL_OPCODE(CreateCont)
|
||||
CALL_OPCODE(FillContLocals)
|
||||
CALL_OPCODE(NewArray)
|
||||
CALL_OPCODE(NewTuple)
|
||||
CALL_OPCODE(NewObj)
|
||||
CALL_OPCODE(AllocObj)
|
||||
CALL_OPCODE(LdClsCtor);
|
||||
CALL_OPCODE(CreateCl)
|
||||
CALL_OPCODE(PrintStr)
|
||||
@@ -3253,53 +3253,12 @@ const Func* loadClassCtor(Class* cls) {
|
||||
return f;
|
||||
}
|
||||
|
||||
HOT_FUNC_VM ActRec*
|
||||
irNewInstanceHelper(Class* cls,
|
||||
int numArgs,
|
||||
Cell* sp,
|
||||
ActRec* prevAr) {
|
||||
Cell* obj = sp - 1; // this is where the newly allocated object will go
|
||||
ActRec* ar = (ActRec*)(uintptr_t(obj) - sizeof(ActRec));
|
||||
|
||||
Instance* newObj = newInstanceHelper(cls, numArgs, ar, prevAr);
|
||||
// store obj into the stack
|
||||
obj->m_data.pobj = newObj;
|
||||
obj->m_type = KindOfObject;
|
||||
return ar;
|
||||
}
|
||||
|
||||
static inline ALWAYS_INLINE Class* getKnownClass(Class** classCache,
|
||||
const StringData* clsName) {
|
||||
Class* cls = *classCache;
|
||||
if (UNLIKELY(cls == nullptr)) {
|
||||
// lookupKnownClass does its own VMRegAnchor'ing.
|
||||
cls = TargetCache::lookupKnownClass<false>(classCache, clsName, true);
|
||||
assert(*classCache && *classCache == cls);
|
||||
}
|
||||
assert(cls);
|
||||
return cls;
|
||||
}
|
||||
|
||||
Instance* createClHelper(Class* cls, int numArgs, ActRec* ar, TypedValue* sp) {
|
||||
Instance* newObj = newInstance(cls);
|
||||
newObj->incRefCount();
|
||||
return static_cast<c_Closure*>(newObj)->init(numArgs, ar, sp);
|
||||
}
|
||||
|
||||
void CodeGenerator::cgAllocObj(IRInstruction* inst) {
|
||||
SSATmp* dst = inst->getDst();
|
||||
SSATmp* cls = inst->getSrc(0);
|
||||
|
||||
Instance* (*helper)(Class*) = newInstance;
|
||||
ArgGroup args;
|
||||
args.ssa(cls);
|
||||
cgCallHelper(m_as,
|
||||
(TCA)helper,
|
||||
dst,
|
||||
kSyncPoint,
|
||||
args);
|
||||
}
|
||||
|
||||
void CodeGenerator::cgInlineCreateCont(IRInstruction* inst) {
|
||||
auto const& data = *inst->getExtra<InlineCreateCont>();
|
||||
auto const helper = data.origFunc->isMethod()
|
||||
|
||||
@@ -528,11 +528,6 @@ private:
|
||||
|
||||
const Func* loadClassCtor(Class* cls);
|
||||
|
||||
ActRec* irNewInstanceHelper(Class* cls,
|
||||
int numArgs,
|
||||
Cell* sp,
|
||||
ActRec* prevAr);
|
||||
|
||||
Instance* createClHelper(Class*, int, ActRec*, TypedValue*);
|
||||
|
||||
void genCodeForTrace(Trace* trace,
|
||||
|
||||
@@ -1487,11 +1487,27 @@ void HhbcTranslator::emitFPushActRec(SSATmp* func,
|
||||
assert(m_stackDeficit == 0);
|
||||
}
|
||||
|
||||
void HhbcTranslator::emitFPushCtorCommon(SSATmp* cls,
|
||||
const Func* func,
|
||||
int32_t numParams) {
|
||||
SSATmp* obj = gen(IncRef, gen(AllocObj, cls));
|
||||
push(obj);
|
||||
|
||||
SSATmp* fn = nullptr;
|
||||
if (func) {
|
||||
fn = cns(func);
|
||||
} else {
|
||||
fn = gen(LdClsCtor, cls);
|
||||
}
|
||||
SSATmp* obj2 = gen(IncRef, obj);
|
||||
int32_t numArgsAndCtorFlag = numParams | (1 << 31);
|
||||
emitFPushActRec(fn, obj2, numArgsAndCtorFlag, nullptr);
|
||||
}
|
||||
|
||||
void HhbcTranslator::emitFPushCtor(int32_t numParams) {
|
||||
SSATmp* cls = popA();
|
||||
exceptionBarrier();
|
||||
gen(NewObj, cls, cns(numParams), m_tb->getSp(), m_tb->getFp());
|
||||
m_fpiStack.emplace(nullptr, 0);
|
||||
emitFPushCtorCommon(cls, nullptr, numParams);
|
||||
}
|
||||
|
||||
void HhbcTranslator::emitFPushCtorD(int32_t numParams, int32_t classNameStrId) {
|
||||
@@ -1521,19 +1537,7 @@ void HhbcTranslator::emitFPushCtorD(int32_t numParams, int32_t classNameStrId) {
|
||||
} else {
|
||||
clss = gen(LdClsCached, cns(className));
|
||||
}
|
||||
SSATmp* obj = gen(IncRef, gen(AllocObj, clss));
|
||||
push(obj);
|
||||
|
||||
SSATmp* fn = nullptr;
|
||||
if (func) {
|
||||
fn = cns(func);
|
||||
} else {
|
||||
fn = gen(LdClsCtor, clss);
|
||||
}
|
||||
|
||||
SSATmp* obj2 = gen(IncRef, obj);
|
||||
int32_t numArgsAndCtorFlag = numParams | (1 << 31);
|
||||
emitFPushActRec(fn, obj2, numArgsAndCtorFlag, nullptr);
|
||||
emitFPushCtorCommon(clss, func, numParams);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -239,6 +239,7 @@ struct HhbcTranslator {
|
||||
const StringData* methName);
|
||||
void emitFPushCtorD(int32_t numParams, int32_t classNameStrId);
|
||||
void emitFPushCtor(int32_t numParams);
|
||||
void emitFPushCtorCommon(SSATmp* cls, const Func* func, int32_t numParams);
|
||||
void emitCreateCl(int32_t numParams, int32_t classNameStrId);
|
||||
void emitFCallArray(const Offset pcOffset, const Offset after);
|
||||
void emitFCall(uint32_t numParams,
|
||||
|
||||
@@ -311,10 +311,6 @@ O(LdSwitchDblIndex, D(Int), S(Dbl) S(Int) S(Int), N) \
|
||||
O(LdSwitchStrIndex, D(Int), S(Str) S(Int) S(Int), CRc|N) \
|
||||
O(LdSwitchObjIndex, D(Int), S(Obj) S(Int) S(Int), CRc|N|Er) \
|
||||
O(JmpSwitchDest, ND, S(Int), T|E) \
|
||||
O(NewObj, D(StkPtr), S(Cls) \
|
||||
C(Int) \
|
||||
S(StkPtr) \
|
||||
S(FramePtr), E|Mem|N|Refs|PRc|Er) \
|
||||
O(AllocObj, D(Obj), S(Cls), N) \
|
||||
O(LdClsCtor, D(Func), S(Cls), C|Er|N) \
|
||||
O(CreateCl, D(Obj), C(Cls) \
|
||||
|
||||
@@ -376,7 +376,6 @@ void LinearScan::allocRegToInstruction(InstructionList::iterator it) {
|
||||
opc == SpillFrame ||
|
||||
opc == ExceptionBarrier ||
|
||||
opc == RetAdjustStack ||
|
||||
opc == NewObj ||
|
||||
opc == InterpOne ||
|
||||
opc == GenericRetDecRefs ||
|
||||
opc == GuardStk ||
|
||||
|
||||
@@ -133,8 +133,8 @@ static CallMap s_callMap({
|
||||
{NewArray, (TCA)new_array, DSSA, SNone, {{SSA, 0}}},
|
||||
{NewTuple, (TCA)new_tuple, DSSA, SNone,
|
||||
{{SSA, 0}, {SSA, 1}}},
|
||||
{NewObj, (TCA)irNewInstanceHelper, DSSA, SSync,
|
||||
{{SSA, 0}, {SSA, 1}, {SSA, 2}, {SSA, 3}}},
|
||||
{AllocObj, (TCA)newInstance, DSSA, SSync,
|
||||
{{SSA, 0}}},
|
||||
{LdClsCtor, (TCA)loadClassCtor, DSSA, SSync,
|
||||
{{SSA, 0}}},
|
||||
{PrintStr, (TCA)print_string, DNone, SNone, {{SSA, 0}}},
|
||||
|
||||
@@ -130,17 +130,6 @@ StackValueInfo getStackValue(SSATmp* sp, uint32_t index) {
|
||||
// pushes an ActRec
|
||||
index - kNumActRecCells);
|
||||
|
||||
case NewObj:
|
||||
if (index == kNumActRecCells) {
|
||||
// newly allocated object, which we unfortunately don't have any
|
||||
// kind of handle to :-(
|
||||
return StackValueInfo { Type::Obj };
|
||||
}
|
||||
|
||||
return getStackValue(sp->inst()->getSrc(2),
|
||||
// NewObj pushes an object and an ActRec
|
||||
index - (1 + kNumActRecCells));
|
||||
|
||||
default:
|
||||
{
|
||||
// Assume it's a vector instruction. This will assert in
|
||||
|
||||
@@ -289,12 +289,6 @@ void TraceBuilder::updateTrackedState(IRInstruction* inst) {
|
||||
m_spOffset += kNumActRecCells;
|
||||
break;
|
||||
|
||||
case NewObj:
|
||||
m_spValue = inst->getDst();
|
||||
// new obj leaves the new object and an actrec on the stack
|
||||
m_spOffset += kNumActRecCells + 1;
|
||||
break;
|
||||
|
||||
case InterpOne: {
|
||||
m_spValue = inst->getDst();
|
||||
int64_t stackAdjustment = inst->getSrc(3)->getValInt();
|
||||
|
||||
@@ -3004,7 +3004,7 @@ static bool shouldAnalyzeCallee(const NormalizedInstruction* fcall) {
|
||||
// methods, which will need to be updated when we support
|
||||
// OpFPushClsMethod here.
|
||||
if (pushOp != OpFPushFuncD && pushOp != OpFPushObjMethodD
|
||||
&& pushOp != OpFPushCtorD) {
|
||||
&& pushOp != OpFPushCtorD && pushOp != OpFPushCtor) {
|
||||
FTRACE(1, "analyzeCallee: push op ({}) was not supported\n",
|
||||
opcodeToName(pushOp));
|
||||
return false;
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário