void cgLdClsInitData(IRLS& env, const IRInstruction* inst) { auto const dst = dstLoc(env, inst, 0).reg(); auto const cls = srcLoc(env, inst, 0).reg(); auto const offset = Class::propDataCacheOff() + rds::Link<Class::PropInitVec*>::handleOff(); auto& v = vmain(env); auto const handle = v.makeReg(); auto const vec = v.makeReg(); v << loadzlq{cls[offset], handle}; v << load{Vreg(rvmtl())[handle], vec}; v << load{vec[Class::PropInitVec::dataOff()], dst}; }
void cgInitObjProps(IRLS& env, const IRInstruction* inst) { auto const cls = inst->extra<InitObjProps>()->cls; auto const obj = srcLoc(env, inst, 0).reg(); auto& v = vmain(env); // Set the attributes, if any. auto const odAttrs = cls->getODAttrs(); if (odAttrs) { static_assert(sizeof(ObjectData::Attribute) == 2, "Codegen expects 2-byte ObjectData attributes"); assertx(!(odAttrs & 0xffff0000)); v << orwim{odAttrs, obj[ObjectData::attributeOff()], v.makeReg()}; } // Initialize the properties. auto const nprops = cls->numDeclProperties(); if (nprops > 0) { if (cls->pinitVec().size() == 0) { // If the Class has no 86pinit property-initializer functions, we can // just copy the initial values from a data member on the Class. implInitObjPropsFast(v, env, inst, obj, cls, nprops); } else { // Load the Class's propInitVec from the target cache. We know it's // already been initialized as a pre-condition on this op. auto const propHandle = cls->propHandle(); assertx(rds::isNormalHandle(propHandle)); auto const propInitVec = v.makeReg(); auto const propData = v.makeReg(); v << load{Vreg(rvmtl())[propHandle], propInitVec}; v << load{propInitVec[Class::PropInitVec::dataOff()], propData}; auto const propsOff = sizeof(ObjectData) + cls->builtinODTailSize(); auto args = argGroup(env, inst) .addr(obj, safe_cast<int32_t>(propsOff)) .reg(propData); if (!cls->hasDeepInitProps()) { cgCallHelper(v, env, CallSpec::direct(memcpy), kVoidDest, SyncOptions::None, args.imm(cellsToBytes(nprops))); } else { cgCallHelper(v, env, CallSpec::direct(deepInitHelper), kVoidDest, SyncOptions::None, args.imm(nprops)); } } } }
template<class Fn> void forEach(LiveSet& bits, Fn fn) { for (auto i = bits.find_first(); i != bits.npos; i = bits.find_next(i)) { fn(Vreg(i)); } }