Tweaks to AllocObjFast relating to allocating extension classes
When there's an instance ctor, it's not necessary to do the memcpy for properties or other ObjectData-initialization duties (the instance ctor does this). Also, use extra data for the compile-time constant Class*.
Esse commit está contido em:
@@ -953,11 +953,16 @@ D:Obj = AllocObj S1:Cls
|
||||
|
||||
Allocates a new object of class S1.
|
||||
|
||||
D:Obj = AllocObjFast S1:ConstCls
|
||||
D:Obj = AllocObjFast<class>
|
||||
|
||||
Allocate a new object of class S1 where S1 is persistent and able to
|
||||
be instantiated (i.e., S1 is not an abstract class, interface, or
|
||||
trait).
|
||||
Allocate a new object of the specified class, which must be
|
||||
persistent and able to be instantiated (i.e., S1 is not an abstract
|
||||
class, interface, or trait). The class' constructor is also assumed
|
||||
to be accessible in the current context.
|
||||
|
||||
This instruction does not handle adding the object to the global
|
||||
destructor list, so currently is not used when
|
||||
RuntimeOption::EnableObjDestructCall is true.
|
||||
|
||||
D:Arr = NewArray S0:ConstInt
|
||||
|
||||
|
||||
@@ -3582,8 +3582,21 @@ ObjectData* createClHelper(Class* cls, int numArgs, ActRec* ar,
|
||||
}
|
||||
|
||||
void CodeGenerator::cgAllocObjFast(IRInstruction* inst) {
|
||||
const Class* cls = inst->src(0)->getValClass();
|
||||
auto dstReg = m_regs[inst->dst()].reg();
|
||||
auto const cls = inst->extra<AllocObjFast>()->cls;
|
||||
auto const dstReg = m_regs[inst->dst()].reg();
|
||||
|
||||
// If it's an extension class with a custom instance initializer,
|
||||
// that init function does all the work.
|
||||
if (cls->instanceCtor()) {
|
||||
cgCallHelper(m_as,
|
||||
(TCA)cls->instanceCtor(),
|
||||
dstReg,
|
||||
SyncOptions::kSyncPoint,
|
||||
ArgGroup(m_regs)
|
||||
.immPtr(cls)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// First, make sure our property init vectors are all set up
|
||||
bool props = cls->pinitVec().size() > 0;
|
||||
@@ -3615,22 +3628,14 @@ void CodeGenerator::cgAllocObjFast(IRInstruction* inst) {
|
||||
}
|
||||
|
||||
// Next, allocate the object
|
||||
if (cls->instanceCtor()) {
|
||||
cgCallHelper(m_as,
|
||||
(TCA)cls->instanceCtor(),
|
||||
dstReg,
|
||||
SyncOptions::kSyncPoint,
|
||||
ArgGroup(m_regs).imm((uint64_t)cls));
|
||||
} else {
|
||||
size_t size = ObjectData::sizeForNProps(cls->numDeclProperties());
|
||||
int allocator = object_alloc_size_to_index(size);
|
||||
assert(allocator != -1);
|
||||
cgCallHelper(m_as,
|
||||
(TCA)getMethodPtr(&ObjectData::newInstanceRaw),
|
||||
dstReg,
|
||||
SyncOptions::kSyncPoint,
|
||||
ArgGroup(m_regs).imm((uint64_t)cls).imm(allocator));
|
||||
}
|
||||
size_t size = ObjectData::sizeForNProps(cls->numDeclProperties());
|
||||
int allocator = object_alloc_size_to_index(size);
|
||||
assert(allocator != -1);
|
||||
cgCallHelper(m_as,
|
||||
(TCA)getMethodPtr(&ObjectData::newInstanceRaw),
|
||||
dstReg,
|
||||
SyncOptions::kSyncPoint,
|
||||
ArgGroup(m_regs).imm((uint64_t)cls).imm(allocator));
|
||||
|
||||
// Set the attributes, if any
|
||||
int odAttrs = cls->getODAttrs();
|
||||
|
||||
@@ -132,6 +132,14 @@ struct IterId : IRExtraData {
|
||||
uint32_t iterId;
|
||||
};
|
||||
|
||||
struct ClassData : IRExtraData {
|
||||
explicit ClassData(const Class* cls) : cls(cls) {}
|
||||
std::string show() const {
|
||||
return folly::to<std::string>(cls->name()->data());
|
||||
}
|
||||
const Class* cls;
|
||||
};
|
||||
|
||||
struct FPushCufData : IRExtraData {
|
||||
FPushCufData(uint32_t a, int32_t id)
|
||||
: args(a), iterId(id)
|
||||
@@ -359,6 +367,7 @@ X(IterFree, IterId);
|
||||
X(MIterFree, IterId);
|
||||
X(CIterFree, IterId);
|
||||
X(DecodeCufIter, IterId);
|
||||
X(AllocObjFast, ClassData);
|
||||
X(CufIterSpillFrame, FPushCufData);
|
||||
X(DefConst, ConstData);
|
||||
X(LdConst, ConstData);
|
||||
|
||||
@@ -1917,21 +1917,13 @@ void HhbcTranslator::emitFPushCtorD(int32_t numParams, int32_t classNameStrId) {
|
||||
}
|
||||
}
|
||||
|
||||
SSATmp* clss = nullptr;
|
||||
if (persistentCls) {
|
||||
clss = cns(cls);
|
||||
} else {
|
||||
clss = gen(LdClsCached, catchTrace1, cns(className));
|
||||
}
|
||||
|
||||
SSATmp* obj = nullptr;
|
||||
if (fastAlloc) {
|
||||
obj = gen(IncRef, gen(AllocObjFast, clss));
|
||||
} else {
|
||||
obj = gen(IncRef, gen(AllocObj, clss));
|
||||
}
|
||||
|
||||
emitFPushCtorCommon(clss, obj, func, numParams, catchTrace2);
|
||||
auto const ssaCls =
|
||||
persistentCls ? cns(cls)
|
||||
: gen(LdClsCached, catchTrace1, cns(className));
|
||||
auto const obj =
|
||||
fastAlloc ? gen(IncRef, gen(AllocObjFast, ClassData(cls)))
|
||||
: gen(IncRef, gen(AllocObj, ssaCls));
|
||||
emitFPushCtorCommon(ssaCls, obj, func, numParams, catchTrace2);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -373,7 +373,7 @@ 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(AllocObj, D(Obj), S(Cls), N) \
|
||||
O(AllocObjFast, D(Obj), C(Cls), N) \
|
||||
O(AllocObjFast, D(Obj), NA, N) \
|
||||
O(LdClsCtor, D(Func), S(Cls), C|Er|N) \
|
||||
O(CreateCl, D(Obj), C(Cls) \
|
||||
C(Int) \
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário