convert enums to enum classes, part 1

C++11 cleanup (clean up easy enums)

Since sandcastle is failing:
Esse commit está contido em:
Sean Cannella
2013-06-24 20:19:43 -07:00
commit de Sara Golemon
commit 4872a71b36
23 arquivos alterados com 224 adições e 214 exclusões
+2 -2
Ver Arquivo
@@ -1614,7 +1614,7 @@ resume:
return;
} catch (...) {
always_assert(Transl::tl_regState == Transl::REGSTATE_CLEAN);
always_assert(Transl::tl_regState == Transl::VMRegState::CLEAN);
auto const action = exception_handler();
if (action == UnwindAction::ResumeVM) {
goto resume;
@@ -7048,7 +7048,7 @@ VMExecutionContext::prettyStack(const string& prefix) const {
}
void VMExecutionContext::checkRegStateWork() const {
assert(Transl::tl_regState == Transl::REGSTATE_CLEAN);
assert(Transl::tl_regState == Transl::VMRegState::CLEAN);
}
void VMExecutionContext::DumpStack() {
+6 -6
Ver Arquivo
@@ -28,7 +28,7 @@ TRACE_SET_MOD(trans);
* A mapping from FCall instructions to the statically-known StringData*
* that they're calling. Used to accelerate our FCall translations.
*/
enum CallRecordType {
enum class CallRecordType {
EncodedNameAndArgs,
Function
};
@@ -67,7 +67,7 @@ static void recordNameAndArgs(const SrcKey& sk,
const StringData* name,
int numArgs) {
CallRecord cr;
cr.m_type = EncodedNameAndArgs;
cr.m_type = CallRecordType::EncodedNameAndArgs;
cr.m_encodedName = encodeCallAndArgs(name, numArgs);
s_callDB.insert(std::make_pair(sk, cr));
}
@@ -81,7 +81,7 @@ static void recordFunc(NormalizedInstruction& i,
func->fullName()->data());
CallRecord cr;
cr.m_type = Function;
cr.m_type = CallRecordType::Function;
cr.m_func = func;
s_callDB.insert(std::make_pair(sk, cr));
}
@@ -184,10 +184,10 @@ void annotate(NormalizedInstruction* i) {
case OpFCallArray: {
CallRecord callRec;
if (mapGet(s_callDB, i->source, &callRec)) {
if (callRec.m_type == Function) {
if (callRec.m_type == CallRecordType::Function) {
i->funcd = callRec.m_func;
} else {
assert(callRec.m_type == EncodedNameAndArgs);
assert(callRec.m_type == CallRecordType::EncodedNameAndArgs);
i->funcName = callRec.m_encodedName;
}
} else {
@@ -202,7 +202,7 @@ const StringData*
fcallToFuncName(const NormalizedInstruction* i) {
CallRecord callRec;
if (mapGet(s_callDB, i->source, &callRec)) {
if (callRec.m_type == Function) {
if (callRec.m_type == CallRecordType::Function) {
return callRec.m_func->name();
}
string name;
+2 -2
Ver Arquivo
@@ -39,14 +39,14 @@ struct Block : boost::noncopyable {
typedef InstructionList::const_iterator const_iterator;
// Execution frequency hint; codegen will put Unlikely blocks in astubs.
enum Hint { Neither, Likely, Unlikely };
enum class Hint { Neither, Likely, Unlikely };
Block(unsigned id, const Func* func)
: m_trace(nullptr)
, m_func(func)
, m_next(this, nullptr)
, m_id(id)
, m_hint(Neither)
, m_hint(Hint::Neither)
{}
const IRInstruction* beginCatch() const {
+92 -84
Ver Arquivo
@@ -103,7 +103,7 @@ struct CycleInfo {
};
struct MoveInfo {
enum Kind { Move, Xchg };
enum class Kind { Move, Xchg };
MoveInfo(Kind kind, int reg1, int reg2):
m_kind(kind), m_reg1(reg1), m_reg2(reg2) {}
@@ -188,7 +188,7 @@ pathloop:
int node = q[i];
if (moves[node] >= 0) {
int nextNode = moves[node];
howTo.push_back(MoveInfo(MoveInfo::Move, nextNode, node));
howTo.push_back(MoveInfo(MoveInfo::Kind::Move, nextNode, node));
--outDegree[nextNode];
if (outDegree[nextNode] == 0) {
q[qBack] = nextNode;
@@ -204,24 +204,24 @@ pathloop:
if (cycles[i].length == 2 && !hasXMMReg) {
int v = cycles[i].node;
int w = moves[v];
howTo.push_back(MoveInfo(MoveInfo::Xchg, w, v));
howTo.push_back(MoveInfo(MoveInfo::Kind::Xchg, w, v));
} else if (cycles[i].length == 3 && !hasXMMReg) {
int v = cycles[i].node;
int w = moves[v];
howTo.push_back(MoveInfo(MoveInfo::Xchg, w, v));
howTo.push_back(MoveInfo(MoveInfo::Kind::Xchg, w, v));
int x = moves[w];
howTo.push_back(MoveInfo(MoveInfo::Xchg, x, w));
howTo.push_back(MoveInfo(MoveInfo::Kind::Xchg, x, w));
} else {
int v = cycles[i].node;
howTo.push_back(MoveInfo(MoveInfo::Move, v, rTmp));
howTo.push_back(MoveInfo(MoveInfo::Kind::Move, v, rTmp));
int w = v;
int x = moves[w];
while (x != v) {
howTo.push_back(MoveInfo(MoveInfo::Move, x, w));
howTo.push_back(MoveInfo(MoveInfo::Kind::Move, x, w));
w = x;
x = moves[w];
}
howTo.push_back(MoveInfo(MoveInfo::Move, rTmp, w));
howTo.push_back(MoveInfo(MoveInfo::Kind::Move, rTmp, w));
}
}
}
@@ -238,7 +238,7 @@ ArgDesc::ArgDesc(SSATmp* tmp, const RegisterInfo& info, bool val)
: m_imm(-1), m_zeroExtend(false), m_done(false) {
if (tmp->type() == Type::None) {
assert(val);
m_kind = None;
m_kind = Kind::None;
return;
}
if (tmp->inst()->op() == DefConst) {
@@ -248,7 +248,7 @@ ArgDesc::ArgDesc(SSATmp* tmp, const RegisterInfo& info, bool val)
} else {
m_imm = toDataTypeForCall(tmp->type());
}
m_kind = Imm;
m_kind = Kind::Imm;
return;
}
if (tmp->type().isNull()) {
@@ -258,7 +258,7 @@ ArgDesc::ArgDesc(SSATmp* tmp, const RegisterInfo& info, bool val)
} else {
m_imm = toDataTypeForCall(tmp->type());
}
m_kind = Imm;
m_kind = Kind::Imm;
return;
}
if (val || tmp->numNeededRegs() > 1) {
@@ -269,7 +269,7 @@ ArgDesc::ArgDesc(SSATmp* tmp, const RegisterInfo& info, bool val)
// If val is false then we're passing tmp's type. TypeReg lets
// CodeGenerator know that the value might require some massaging
// to be in the right format for the call.
m_kind = val ? Reg : TypeReg;
m_kind = val ? Kind::Reg : Kind::TypeReg;
// zero extend any boolean value that we pass to the helper in case
// the helper expects it (e.g., as TypedValue)
if (val && tmp->isA(Type::Bool)) m_zeroExtend = true;
@@ -278,7 +278,7 @@ ArgDesc::ArgDesc(SSATmp* tmp, const RegisterInfo& info, bool val)
}
m_srcReg = InvalidReg;
m_imm = toDataTypeForCall(tmp->type());
m_kind = Imm;
m_kind = Kind::Imm;
}
const Func* CodeGenerator::curFunc() const {
@@ -774,7 +774,7 @@ void CodeGenerator::emitReqBindJcc(ConditionCode cc,
assert(&m_as != &m_astubs &&
"ReqBindJcc only makes sense outside of astubs");
prepareForTestAndSmash(a, 0, kAlignJccAndJmp);
prepareForTestAndSmash(a, 0, TestAndSmashFlags::kAlignJccAndJmp);
auto const patchAddr = a.code.frontier;
auto const jccStub = m_astubs.code.frontier;
@@ -901,9 +901,9 @@ static int64_t shuffleArgs(Asm& a, ArgGroup& args) {
memset(argDescs, 0, sizeof argDescs);
for (size_t i = 0; i < args.numRegArgs(); ++i) {
auto kind = args[i].kind();
if (!(kind == ArgDesc::Reg ||
kind == ArgDesc::Addr ||
kind == ArgDesc::TypeReg)) {
if (!(kind == ArgDesc::Kind::Reg ||
kind == ArgDesc::Kind::Addr ||
kind == ArgDesc::Kind::TypeReg)) {
continue;
}
auto dstReg = args[i].dstReg();
@@ -918,13 +918,13 @@ static int64_t shuffleArgs(Asm& a, ArgGroup& args) {
// Execute the plan
for (size_t i = 0; i < howTo.size(); ++i) {
if (howTo[i].m_kind == MoveInfo::Move) {
if (howTo[i].m_kind == MoveInfo::Kind::Move) {
if (howTo[i].m_reg2 == rCgGP) {
emitMovRegReg(a, howTo[i].m_reg1, howTo[i].m_reg2);
} else {
ArgDesc* argDesc = argDescs[int(howTo[i].m_reg2)];
ArgDesc::Kind kind = argDesc->kind();
if (kind == ArgDesc::Reg || kind == ArgDesc::TypeReg) {
if (kind == ArgDesc::Kind::Reg || kind == ArgDesc::Kind::TypeReg) {
if (argDesc->isZeroExtend()) {
assert(howTo[i].m_reg1.isGP());
assert(howTo[i].m_reg2.isGP());
@@ -933,13 +933,13 @@ static int64_t shuffleArgs(Asm& a, ArgGroup& args) {
emitMovRegReg(a, howTo[i].m_reg1, howTo[i].m_reg2);
}
} else {
assert(kind == ArgDesc::Addr);
assert(kind == ArgDesc::Kind::Addr);
assert(howTo[i].m_reg1.isGP());
assert(howTo[i].m_reg2.isGP());
a. lea (howTo[i].m_reg1[argDesc->imm().q()],
howTo[i].m_reg2);
}
if (kind != ArgDesc::TypeReg) {
if (kind != ArgDesc::Kind::TypeReg) {
argDesc->markDone();
}
}
@@ -958,16 +958,16 @@ static int64_t shuffleArgs(Asm& a, ArgGroup& args) {
ArgDesc::Kind kind = args[i].kind();
PhysReg dst = args[i].dstReg();
assert(dst.isGP());
if (kind == ArgDesc::Imm) {
if (kind == ArgDesc::Kind::Imm) {
a.emitImmReg(args[i].imm().q(), dst);
} else if (kind == ArgDesc::TypeReg) {
} else if (kind == ArgDesc::Kind::TypeReg) {
a. shlq (kTypeShiftBits, dst);
} else if (kind == ArgDesc::Addr) {
} else if (kind == ArgDesc::Kind::Addr) {
a. addq (args[i].imm(), dst);
} else if (args[i].isZeroExtend()) {
a. movzbl (rbyte(dst), r32(dst));
} else if (RuntimeOption::EvalHHIRGenerateAsserts &&
kind == ArgDesc::None) {
kind == ArgDesc::Kind::None) {
a.emitImmReg(0xbadbadbadbadbad, dst);
}
}
@@ -979,7 +979,7 @@ static int64_t shuffleArgs(Asm& a, ArgGroup& args) {
auto srcReg = arg.srcReg();
assert(arg.dstReg() == InvalidReg);
switch (arg.kind()) {
case ArgDesc::Reg:
case ArgDesc::Kind::Reg:
if (arg.isZeroExtend()) {
a. movzbl(rbyte(srcReg), r32(rCgGP));
a. push(rCgGP);
@@ -993,7 +993,7 @@ static int64_t shuffleArgs(Asm& a, ArgGroup& args) {
}
break;
case ArgDesc::TypeReg:
case ArgDesc::Kind::TypeReg:
static_assert(kTypeWordOffset == 4 || kTypeWordOffset == 1,
"kTypeWordOffset value not supported");
assert(srcReg.isGP());
@@ -1012,15 +1012,15 @@ static int64_t shuffleArgs(Asm& a, ArgGroup& args) {
}
break;
case ArgDesc::Imm:
case ArgDesc::Kind::Imm:
a. emitImmReg(arg.imm(), rCgGP);
a. push(rCgGP);
break;
case ArgDesc::Addr:
case ArgDesc::Kind::Addr:
not_implemented();
case ArgDesc::None:
case ArgDesc::Kind::None:
a. push(rax);
if (RuntimeOption::EvalHHIRGenerateAsserts) {
a. storeq(0xbadbadbadbadbad, *rsp);
@@ -1146,7 +1146,7 @@ void CodeGenerator::cgCallHelper(Asm& a,
// do the call; may use a trampoline
m_tx64->emitCall(a, call);
if (sync != kNoSyncPoint) {
if (sync != SyncOptions::kNoSyncPoint) {
recordSyncPoint(a, sync);
}
@@ -1598,7 +1598,7 @@ void CodeGenerator::cgOpCmpHelper(
if (type1.isString() && type2.isString()) {
ArgGroup args(m_regs);
args.ssa(src1).ssa(src2);
cgCallHelper(m_as, (TCA)str_cmp_str, dst, kSyncPoint, args);
cgCallHelper(m_as, (TCA)str_cmp_str, dst, SyncOptions::kSyncPoint, args);
}
/////////////////////////////////////////////////////////////////////////////
@@ -1649,11 +1649,13 @@ void CodeGenerator::cgOpCmpHelper(
if (type2 == Type::Int) {
ArgGroup args(m_regs);
args.ssa(src1).ssa(src2);
cgCallHelper(m_as, (TCA)str_cmp_int, dst, kSyncPoint, args);
cgCallHelper(m_as, (TCA)str_cmp_int, dst,
SyncOptions::kSyncPoint, args);
} else if (type2 == Type::Obj) {
ArgGroup args(m_regs);
args.ssa(src1).ssa(src2);
cgCallHelper(m_as, (TCA)str_cmp_obj, dst, kSyncPoint, args);
cgCallHelper(m_as, (TCA)str_cmp_obj, dst,
SyncOptions::kSyncPoint, args);
} else {
CG_PUNT(cgOpCmpHelper_sx);
}
@@ -1666,11 +1668,13 @@ void CodeGenerator::cgOpCmpHelper(
if (type2 == Type::Obj) {
ArgGroup args(m_regs);
args.ssa(src1).ssa(src2);
cgCallHelper(m_as, (TCA)obj_cmp_obj, dst, kSyncPoint, args);
cgCallHelper(m_as, (TCA)obj_cmp_obj, dst,
SyncOptions::kSyncPoint, args);
} else if (type2 == Type::Int) {
ArgGroup args(m_regs);
args.ssa(src1).ssa(src2);
cgCallHelper(m_as, (TCA)obj_cmp_int, dst, kSyncPoint, args);
cgCallHelper(m_as, (TCA)obj_cmp_int, dst,
SyncOptions::kSyncPoint, args);
} else {
CG_PUNT(cgOpCmpHelper_ox);
}
@@ -1684,7 +1688,7 @@ void CodeGenerator::cgOpCmpHelper(
else if (type1.isArray() && type2.isArray()) {
ArgGroup args(m_regs);
args.ssa(src1).ssa(src2);
cgCallHelper(m_as, (TCA)arr_cmp_arr, dst, kSyncPoint, args);
cgCallHelper(m_as, (TCA)arr_cmp_arr, dst, SyncOptions::kSyncPoint, args);
}
/////////////////////////////////////////////////////////////////////////////
@@ -1930,7 +1934,7 @@ void CodeGenerator::cgInstanceOf(IRInstruction* inst) {
cgCallHelper(m_as,
TCA(instanceOfHelper),
inst->dst(),
kNoSyncPoint,
SyncOptions::kNoSyncPoint,
ArgGroup(m_regs)
.ssa(inst->src(0))
.ssa(inst->src(1)));
@@ -2243,7 +2247,8 @@ void CodeGenerator::cgLdFunc(IRInstruction* inst) {
TargetCache::CacheHandle ch = TargetCache::FuncCache::alloc();
// raises an error if function not found
cgCallHelper(m_as, (TCA)FuncCache::lookup, m_regs[dst].reg(), kSyncPoint,
cgCallHelper(m_as, (TCA)FuncCache::lookup, m_regs[dst].reg(),
SyncOptions::kSyncPoint,
ArgGroup(m_regs).imm(ch).ssa(methodName));
}
@@ -2287,7 +2292,7 @@ void CodeGenerator::cgLdObjMethod(IRInstruction *inst) {
},
[&] { // else call slow path helper
cgCallHelper(m_as, (TCA)methodCacheSlowPath, InvalidReg,
kSyncPoint,
SyncOptions::kSyncPoint,
ArgGroup(m_regs).addr(rVmTl, handle)
.ssa(actRec)
.ssa(name)
@@ -2451,7 +2456,7 @@ void CodeGenerator::cgLdSSwitchDestFast(IRInstruction* inst) {
cgCallHelper(m_as,
TCA(sswitchHelperFast),
inst->dst(),
kNoSyncPoint,
SyncOptions::kNoSyncPoint,
ArgGroup(m_regs)
.ssa(inst->src(0))
.immPtr(table)
@@ -2484,7 +2489,7 @@ void CodeGenerator::cgLdSSwitchDestSlow(IRInstruction* inst) {
cgCallHelper(m_as,
TCA(sswitchHelperSlow),
inst->dst(),
kSyncPoint,
SyncOptions::kSyncPoint,
ArgGroup(m_regs)
.typedValue(inst->src(0))
.immPtr(strtab)
@@ -3046,7 +3051,7 @@ void CodeGenerator::cgDecRefStaticType(Type type,
unlikelyIfBlock(CC_Z, [&] (Asm& a) {
// Emit the call to release in m_astubs
cgCallHelper(a, m_tx64->getDtorCall(type.toDataType()),
InvalidReg, InvalidReg, kSyncPoint,
InvalidReg, InvalidReg, SyncOptions::kSyncPoint,
ArgGroup(m_regs).reg(dataReg));
});
}
@@ -3079,7 +3084,7 @@ void CodeGenerator::cgDecRefDynamicType(PhysReg typeReg,
// Emit jump to m_astubs (to call release) if count got down to zero
unlikelyIfBlock(CC_Z, [&] (Asm& a) {
// Emit call to release in m_astubs
cgCallHelper(a, getDtorTyped(), InvalidReg, kSyncPoint,
cgCallHelper(a, getDtorTyped(), InvalidReg, SyncOptions::kSyncPoint,
ArgGroup(m_regs).reg(dataReg).reg(typeReg));
});
}
@@ -3150,7 +3155,7 @@ void CodeGenerator::cgDecRefDynamicTypeMem(PhysReg baseReg,
unlikelyIfBlock(CC_Z, [&] (Asm& a) {
// Emit call to release in m_astubs
a.lea(baseReg[offset], scratchReg);
cgCallHelper(a, getDtorGeneric(), InvalidReg, kSyncPoint,
cgCallHelper(a, getDtorGeneric(), InvalidReg, SyncOptions::kSyncPoint,
ArgGroup(m_regs).reg(scratchReg));
});
}
@@ -3394,7 +3399,7 @@ void CodeGenerator::cgAllocObjFast(IRInstruction* inst) {
cgCallHelper(a,
(TCA)getMethodPtr(&Class::initProps),
InvalidReg,
kSyncPoint,
SyncOptions::kSyncPoint,
ArgGroup(m_regs).imm((uint64_t)cls));
});
}
@@ -3405,7 +3410,7 @@ void CodeGenerator::cgAllocObjFast(IRInstruction* inst) {
cgCallHelper(a,
(TCA)getMethodPtr(&Class::initSProps),
InvalidReg,
kSyncPoint,
SyncOptions::kSyncPoint,
ArgGroup(m_regs).imm((uint64_t)cls));
});
}
@@ -3416,7 +3421,7 @@ void CodeGenerator::cgAllocObjFast(IRInstruction* inst) {
cgCallHelper(m_as,
(TCA)cls->instanceCtor(),
dstReg,
kSyncPoint,
SyncOptions::kSyncPoint,
ArgGroup(m_regs).imm((uint64_t)cls));
} else {
size_t size = Instance::sizeForNProps(cls->numDeclProperties());
@@ -3425,7 +3430,7 @@ void CodeGenerator::cgAllocObjFast(IRInstruction* inst) {
cgCallHelper(m_as,
(TCA)getMethodPtr(&Instance::newInstanceRaw),
dstReg,
kSyncPoint,
SyncOptions::kSyncPoint,
ArgGroup(m_regs).imm((uint64_t)cls).imm(allocator));
}
@@ -3451,7 +3456,7 @@ void CodeGenerator::cgAllocObjFast(IRInstruction* inst) {
cgCallHelper(m_as,
(TCA)memcpy,
InvalidReg,
kNoSyncPoint,
SyncOptions::kNoSyncPoint,
args);
} else {
// Slower case: we have to load the src address from the targetcache
@@ -3468,7 +3473,7 @@ void CodeGenerator::cgAllocObjFast(IRInstruction* inst) {
cgCallHelper(m_as,
(TCA)memcpy,
InvalidReg,
kNoSyncPoint,
SyncOptions::kNoSyncPoint,
args);
} else {
ArgGroup args = ArgGroup(m_regs)
@@ -3478,7 +3483,7 @@ void CodeGenerator::cgAllocObjFast(IRInstruction* inst) {
cgCallHelper(m_as,
(TCA)deepInitHelper,
InvalidReg,
kNoSyncPoint,
SyncOptions::kNoSyncPoint,
args);
}
}
@@ -3490,7 +3495,7 @@ void CodeGenerator::cgAllocObjFast(IRInstruction* inst) {
cgCallHelper(m_as,
(TCA)getMethodPtr(&Instance::callCustomInstanceInit),
dstReg,
kSyncPoint,
SyncOptions::kSyncPoint,
ArgGroup(m_regs).reg(dstReg));
}
}
@@ -3504,7 +3509,7 @@ void CodeGenerator::cgCallArray(IRInstruction* inst) {
// fCallArrayHelper makes the actual call by smashing its return address.
cgCallHelper(m_as, (TCA)TranslatorX64::fCallArrayHelper,
nullptr, kSyncPoint, args);
nullptr, SyncOptions::kSyncPoint, args);
}
void CodeGenerator::cgCall(IRInstruction* inst) {
@@ -3570,7 +3575,7 @@ void CodeGenerator::cgCastStk(IRInstruction *inst) {
not_reached();
}
cgCallHelper(m_as, tvCastHelper, nullptr,
kSyncPoint, args, DestType::None);
SyncOptions::kSyncPoint, args, DestType::None);
}
void CodeGenerator::cgCoerceStk(IRInstruction *inst) {
@@ -3662,7 +3667,7 @@ void CodeGenerator::cgCallBuiltin(IRInstruction* inst) {
// return value from this call since we know where the value is.
cgCallHelper(m_as, Transl::CppCall((TCA)func->nativeFuncPtr()),
isCppByRef(funcReturnType) ? InvalidReg : dstReg,
kSyncPoint, callArgs);
SyncOptions::kSyncPoint, callArgs);
// load return value from builtin
// for primitive return types (int, bool), the return value
@@ -4095,12 +4100,12 @@ void CodeGenerator::recordSyncPoint(Asm& as,
Offset stackOff = m_state.lastMarker->stackOff;
switch (sync) {
case kSyncPointAdjustOne:
case SyncOptions::kSyncPointAdjustOne:
stackOff -= 1;
break;
case kSyncPoint:
case SyncOptions::kSyncPoint:
break;
case kNoSyncPoint:
case SyncOptions::kNoSyncPoint:
assert(0);
}
@@ -4454,7 +4459,7 @@ void CodeGenerator::cgLdClsMethodCache(IRInstruction* inst) {
cgCallHelper(a,
(TCA)StaticMethodCache::lookupIR,
funcDestReg,
kSyncPoint,
SyncOptions::kSyncPoint,
ArgGroup(m_regs).imm(ch) // Handle ch
.immPtr(ne) // NamedEntity* np.second
.immPtr(cls) // className
@@ -4568,7 +4573,7 @@ void CodeGenerator::cgLdClsMethodFCache(IRInstruction* inst) {
RegSet toSave = m_state.liveRegs[inst] | RegSet(destCtxReg);
cgCallHelper(a, Transl::CppCall((TCA)lookup),
funcDestReg, InvalidReg,
kSyncPoint,
SyncOptions::kSyncPoint,
ArgGroup(m_regs).imm(ch)
.immPtr(cls)
.immPtr(methName)
@@ -4637,7 +4642,7 @@ void CodeGenerator::cgLdClsPropAddrCached(IRInstruction* inst) {
target ? (TCA)SPropCache::lookupIR<false>
: (TCA)SPropCache::lookupIR<true>, // raise on error
tmpReg,
kSyncPoint, // could re-enter to initialize properties
SyncOptions::kSyncPoint, // could re-enter to init properties
ArgGroup(m_regs).imm(ch).ssa(cls).ssa(propName).ssa(cxt));
if (target) {
a.testq(tmpReg, tmpReg);
@@ -4669,7 +4674,7 @@ void CodeGenerator::cgLdClsPropAddr(IRInstruction* inst) {
target ? (TCA)SPropCache::lookupSProp<false>
: (TCA)SPropCache::lookupSProp<true>, // raise on error
dstReg,
kSyncPoint, // could re-enter to initialize properties
SyncOptions::kSyncPoint, // could re-enter to init properties
ArgGroup(m_regs).ssa(cls).ssa(prop).ssa(ctx));
if (target) {
m_as.testq(dstReg, dstReg);
@@ -4701,7 +4706,7 @@ void CodeGenerator::cgLdClsCached(IRInstruction* inst) {
cgCallHelper(a,
(TCA)TargetCache::lookupKnownClass<false>,
inst->dst(),
kSyncPoint,
SyncOptions::kSyncPoint,
ArgGroup(m_regs).addr(rVmTl, intptr_t(ch)).ssas(inst, 0));
});
}
@@ -4718,7 +4723,7 @@ void CodeGenerator::cgLdCls(IRInstruction* inst) {
SSATmp* className = inst->src(0);
CacheHandle ch = ClassCache::alloc();
cgCallHelper(m_as, (TCA)ClassCache::lookup, dst, kSyncPoint,
cgCallHelper(m_as, (TCA)ClassCache::lookup, dst, SyncOptions::kSyncPoint,
ArgGroup(m_regs).imm(ch).ssa(className));
}
@@ -4744,7 +4749,7 @@ void CodeGenerator::cgLookupClsCns(IRInstruction* inst) {
m_as,
TCA(TargetCache::lookupClassConstantTv),
inst->dst(),
kSyncPoint,
SyncOptions::kSyncPoint,
ArgGroup(m_regs)
.addr(rVmTl, ch)
.immPtr(Unit::GetNamedEntity(extra->clsName))
@@ -4804,7 +4809,7 @@ void CodeGenerator::cgLookupCns(IRInstruction* inst) {
.immPtr(cnsName);
cgCallHelper(m_as, TCA(lookupCnsHelper),
inst->dst(), kSyncPoint, args, DestType::TV);
inst->dst(), SyncOptions::kSyncPoint, args, DestType::TV);
}
HOT_FUNC_VM
@@ -4857,7 +4862,7 @@ void CodeGenerator::cgAKExists(IRInstruction* inst) {
cgCallHelper(m_as,
(TCA)ak_exist_string,
inst->dst(),
kNoSyncPoint,
SyncOptions::kNoSyncPoint,
ArgGroup(m_regs).immPtr(empty_string.get()).ssa(arr));
} else {
m_as.mov_imm64_reg(0, m_regs[inst->dst()].reg());
@@ -4873,7 +4878,7 @@ void CodeGenerator::cgAKExists(IRInstruction* inst) {
cgCallHelper(m_as,
helper_func,
inst->dst(),
kNoSyncPoint,
SyncOptions::kNoSyncPoint,
ArgGroup(m_regs).ssa(key).ssa(arr));
}
@@ -4889,14 +4894,16 @@ HOT_FUNC_VM static TypedValue* ldGblAddrDefHelper(StringData* name) {
void CodeGenerator::cgLdGblAddr(IRInstruction* inst) {
auto dstReg = m_regs[inst->dst()].reg();
cgCallHelper(m_as, (TCA)ldGblAddrHelper, dstReg, kNoSyncPoint,
cgCallHelper(m_as, (TCA)ldGblAddrHelper, dstReg,
SyncOptions::kNoSyncPoint,
ArgGroup(m_regs).ssa(inst->src(0)));
m_as.testq(dstReg, dstReg);
emitFwdJcc(CC_Z, inst->taken());
}
void CodeGenerator::cgLdGblAddrDef(IRInstruction* inst) {
cgCallHelper(m_as, (TCA)ldGblAddrDefHelper, inst->dst(), kNoSyncPoint,
cgCallHelper(m_as, (TCA)ldGblAddrDefHelper, inst->dst(),
SyncOptions::kNoSyncPoint,
ArgGroup(m_regs).ssa(inst->src(0)));
}
@@ -5047,7 +5054,7 @@ void CodeGenerator::cgReleaseVVOrExit(IRInstruction* inst) {
a,
TCA(static_cast<void (*)(ActRec*)>(ExtraArgs::deallocate)),
nullptr,
kSyncPoint,
SyncOptions::kSyncPoint,
ArgGroup(m_regs).reg(rFp),
DestType::None
);
@@ -5064,7 +5071,7 @@ void CodeGenerator::cgBoxPtr(IRInstruction* inst) {
base[TVOFF(m_data)],
[&](ConditionCode cc) {
ifThen(m_as, ccNegate(cc), [&] {
cgCallHelper(m_as, (TCA)tvBox, dstReg, kNoSyncPoint,
cgCallHelper(m_as, (TCA)tvBox, dstReg, SyncOptions::kNoSyncPoint,
ArgGroup(m_regs).ssa(addr));
});
});
@@ -5093,14 +5100,14 @@ void CodeGenerator::cgConcat(IRInstruction* inst) {
fptr = (void*)concat_is;
}
if (fptr) {
cgCallHelper(m_as, (TCA)fptr, dst, kNoSyncPoint,
cgCallHelper(m_as, (TCA)fptr, dst, SyncOptions::kNoSyncPoint,
ArgGroup(m_regs).ssa(tl).ssa(tr));
} else {
if (lType.subtypeOf(Type::Obj) || lType.needsReg() ||
rType.subtypeOf(Type::Obj) || rType.needsReg()) {
CG_PUNT(cgConcat);
}
cgCallHelper(m_as, (TCA)concat_value, dst, kNoSyncPoint,
cgCallHelper(m_as, (TCA)concat_value, dst, SyncOptions::kNoSyncPoint,
ArgGroup(m_regs).typedValue(tl).typedValue(tr));
}
}
@@ -5116,7 +5123,7 @@ void CodeGenerator::cgInterpOne(IRInstruction* inst) {
void* interpOneHelper = interpOneEntryPoints[opc];
auto dstReg = InvalidReg;
cgCallHelper(m_as, (TCA)interpOneHelper, dstReg, kSyncPoint,
cgCallHelper(m_as, (TCA)interpOneHelper, dstReg, SyncOptions::kSyncPoint,
ArgGroup(m_regs).ssa(fp).ssa(sp).imm(pcOff));
auto newSpReg = m_regs[inst->dst()].reg();
@@ -5137,7 +5144,7 @@ void CodeGenerator::cgInterpOneCF(IRInstruction* inst) {
void* interpOneHelper = interpOneEntryPoints[opc];
auto dstReg = InvalidReg;
cgCallHelper(m_as, (TCA)interpOneHelper, dstReg, kSyncPoint,
cgCallHelper(m_as, (TCA)interpOneHelper, dstReg, SyncOptions::kSyncPoint,
ArgGroup(m_regs).ssa(fp).ssa(sp).imm(pcOff));
// The interpOne method returns a pointer to the current ExecutionContext
@@ -5170,7 +5177,7 @@ void CodeGenerator::emitContVarEnvHelperCall(SSATmp* fp, TCA helper) {
m_as. loadq (m_regs[fp].reg()[AROFF(m_varEnv)], scratch);
m_as. testq (scratch, scratch);
unlikelyIfBlock(CC_NZ, [&] (Asm& a) {
cgCallHelper(a, helper, InvalidReg, kNoSyncPoint,
cgCallHelper(a, helper, InvalidReg, SyncOptions::kNoSyncPoint,
ArgGroup(m_regs).ssa(fp));
});
}
@@ -5244,7 +5251,7 @@ void CodeGenerator::cgIterInitCommon(IRInstruction* inst) {
}
TCA helperAddr = isWInit ? (TCA)new_iter_array_key<true> :
isInitK ? (TCA)new_iter_array_key<false> : (TCA)new_iter_array;
cgCallHelper(m_as, helperAddr, inst->dst(), kSyncPoint, args);
cgCallHelper(m_as, helperAddr, inst->dst(), SyncOptions::kSyncPoint, args);
} else {
assert(src->type() == Type::Obj);
args.imm(uintptr_t(curClass())).addr(fpReg, valLocalOffset);
@@ -5258,7 +5265,7 @@ void CodeGenerator::cgIterInitCommon(IRInstruction* inst) {
// stack pointer by 1 stack element on an unwind, skipping over
// the src object.
cgCallHelper(m_as, (TCA)new_iter_object, inst->dst(),
kSyncPointAdjustOne, args);
SyncOptions::kSyncPointAdjustOne, args);
}
}
@@ -5292,7 +5299,7 @@ void CodeGenerator::cgIterNextCommon(IRInstruction* inst) {
}
TCA helperAddr = isWNext ? (TCA)iter_next_key<true> :
isNextK ? (TCA)iter_next_key<false> : (TCA)iter_next;
cgCallHelper(m_as, helperAddr, inst->dst(), kSyncPoint, args);
cgCallHelper(m_as, helperAddr, inst->dst(), SyncOptions::kSyncPoint, args);
}
void iterFreeHelper(Iter* iter) {
@@ -5306,21 +5313,22 @@ void citerFreeHelper(Iter* iter) {
void CodeGenerator::cgIterFree(IRInstruction* inst) {
PhysReg fpReg = m_regs[inst->src(0)].reg();
int64_t offset = iterOffset(inst->extra<IterFree>()->iterId);
cgCallHelper(m_as, (TCA)iterFreeHelper, InvalidReg, kSyncPoint,
cgCallHelper(m_as, (TCA)iterFreeHelper, InvalidReg, SyncOptions::kSyncPoint,
ArgGroup(m_regs).addr(fpReg, offset));
}
void CodeGenerator::cgDecodeCufIter(IRInstruction* inst) {
PhysReg fpReg = m_regs[inst->src(1)].reg();
int64_t offset = iterOffset(inst->extra<DecodeCufIter>()->iterId);
cgCallHelper(m_as, (TCA)decodeCufIterHelper, inst->dst(), kSyncPoint,
cgCallHelper(m_as, (TCA)decodeCufIterHelper, inst->dst(),
SyncOptions::kSyncPoint,
ArgGroup(m_regs).addr(fpReg, offset).typedValue(inst->src(0)));
}
void CodeGenerator::cgCIterFree(IRInstruction* inst) {
PhysReg fpReg = m_regs[inst->src(0)].reg();
int64_t offset = iterOffset(inst->extra<CIterFree>()->iterId);
cgCallHelper(m_as, (TCA)citerFreeHelper, InvalidReg, kSyncPoint,
cgCallHelper(m_as, (TCA)citerFreeHelper, InvalidReg, SyncOptions::kSyncPoint,
ArgGroup(m_regs).addr(fpReg, offset));
}
+7 -7
Ver Arquivo
@@ -49,7 +49,7 @@ enum class DestType : unsigned {
TV // return a TypedValue packed in two registers
};
enum SyncOptions {
enum class SyncOptions {
kNoSyncPoint,
kSyncPoint,
kSyncPointAdjustOne,
@@ -329,7 +329,7 @@ private:
void emitContVarEnvHelperCall(SSATmp* fp, TCA helper);
const Func* curFunc() const;
Class* curClass() const { return curFunc()->cls(); }
void recordSyncPoint(Asm& as, SyncOptions sync = kSyncPoint);
void recordSyncPoint(Asm& as, SyncOptions sync = SyncOptions::kSyncPoint);
Address getDtorGeneric();
Address getDtorTyped();
int iterOffset(SSATmp* tmp);
@@ -393,7 +393,7 @@ private:
class ArgDesc {
public:
enum Kind {
enum class Kind {
Reg, // Normal register
TypeReg, // TypedValue's m_type field. Might need arch-specific
// mangling before call depending on TypedValue's layout.
@@ -469,7 +469,7 @@ struct ArgGroup {
}
ArgGroup& imm(uintptr_t imm) {
push_arg(ArgDesc(ArgDesc::Imm, InvalidReg, imm));
push_arg(ArgDesc(ArgDesc::Kind::Imm, InvalidReg, imm));
return *this;
}
@@ -480,12 +480,12 @@ struct ArgGroup {
ArgGroup& immPtr(std::nullptr_t) { return imm(0); }
ArgGroup& reg(PhysReg reg) {
push_arg(ArgDesc(ArgDesc::Reg, PhysReg(reg), -1));
push_arg(ArgDesc(ArgDesc::Kind::Reg, PhysReg(reg), -1));
return *this;
}
ArgGroup& addr(PhysReg base, intptr_t off) {
push_arg(ArgDesc(ArgDesc::Addr, base, off));
push_arg(ArgDesc(ArgDesc::Kind::Addr, base, off));
return *this;
}
@@ -544,7 +544,7 @@ private:
}
ArgGroup& none() {
push_arg(ArgDesc(ArgDesc::None, InvalidReg, -1));
push_arg(ArgDesc(ArgDesc::Kind::None, InvalidReg, -1));
return *this;
}
+3 -3
Ver Arquivo
@@ -548,7 +548,7 @@ void HhbcTranslator::emitCns(uint32_t id) {
return c1;
},
[&] { // Taken: miss in TC, do lookup & init
m_tb->hint(Block::Unlikely);
m_tb->hint(Block::Hint::Unlikely);
return gen(LookupCns, getCatchTrace(), cnsType, cnsNameTmp);
}
);
@@ -824,7 +824,7 @@ void HhbcTranslator::emitStaticLocInit(uint32_t locId, uint32_t litStrId) {
return gen(IncRef, cachedBox);
},
[&] { // taken: We missed in the cache
m_tb->hint(Block::Unlikely);
m_tb->hint(Block::Hint::Unlikely);
return gen(StaticLocInitCached,
cns(name), m_tb->fp(), value, ch);
}
@@ -2751,7 +2751,7 @@ void HhbcTranslator::emitVerifyParamType(int32_t paramId) {
gen(JmpZero, taken, isInstance);
},
[&] { // taken: the param type does not match
m_tb->hint(Block::Unlikely);
m_tb->hint(Block::Hint::Unlikely);
gen(VerifyParamFail, getCatchTrace(), cns(paramId));
}
);
+5 -5
Ver Arquivo
@@ -86,13 +86,13 @@ static const bool debug = false;
bool isInferredType(const NormalizedInstruction& i) {
return (i.getOutputUsage(i.outStack) ==
NormalizedInstruction::OutputInferred);
NormalizedInstruction::OutputUse::Inferred);
}
JIT::Type getInferredOrPredictedType(const NormalizedInstruction& i) {
NormalizedInstruction::OutputUse u = i.getOutputUsage(i.outStack);
if (u == NormalizedInstruction::OutputInferred ||
(u == NormalizedInstruction::OutputUsed && i.outputPredicted)) {
if (u == NormalizedInstruction::OutputUse::Inferred ||
(u == NormalizedInstruction::OutputUse::Used && i.outputPredicted)) {
return JIT::Type::fromRuntimeType(i.outStack->rtt);
}
return JIT::Type::None;
@@ -1521,12 +1521,12 @@ Translator::passPredictedAndInferredTypes(const NormalizedInstruction& i) {
NormalizedInstruction::OutputUse u = i.getOutputUsage(i.outStack);
JIT::Type jitType = JIT::Type::fromRuntimeType(i.outStack->rtt);
if (u == NormalizedInstruction::OutputInferred) {
if (u == NormalizedInstruction::OutputUse::Inferred) {
TRACE(1, "irPassPredictedAndInferredTypes: output inferred as %s\n",
jitType.toString().c_str());
m_hhbcTrans->assertTypeStack(0, jitType);
} else if ((u == NormalizedInstruction::OutputUsed && i.outputPredicted)) {
} else if (u == NormalizedInstruction::OutputUse::Used && i.outputPredicted) {
// If the value was predicted statically by the front-end, it
// means that it's either the predicted type or null. In this
// case, if the predicted value is not ref-counted and it's simply
+1 -1
Ver Arquivo
@@ -74,7 +74,7 @@ LayoutInfo layoutBlocks(IRTrace* trace, const IRFactory& irFactory) {
ret.astubsIt = std::stable_partition(
ret.blocks.begin(), ret.blocks.end(),
[&] (Block* b) {
return b->isMain() && b->hint() != Block::Unlikely;
return b->isMain() && b->hint() != Block::Hint::Unlikely;
}
);
+1 -1
Ver Arquivo
@@ -879,7 +879,7 @@ static RegNumber findLabelSrcReg(const RegAllocInfo& regs, IRInstruction* label,
assert(label->op() == DefLabel);
SSATmp* withReg = label->block()->findSrc(dstIdx, [&](SSATmp* src) {
return regs[src].reg(regIndex) != InvalidReg &&
src->inst()->block()->hint() != Block::Unlikely;
src->inst()->block()->hint() != Block::Hint::Unlikely;
});
return withReg ? regs[withReg].reg(regIndex) : reg::noreg;
}
+6 -6
Ver Arquivo
@@ -27,13 +27,13 @@ namespace HPHP { namespace JIT { namespace NativeCalls {
using namespace HPHP::Transl;
using namespace HPHP::Transl::TargetCache;
static const SyncOptions SNone = kNoSyncPoint;
static const SyncOptions SSync = kSyncPoint;
static const SyncOptions SSyncAdj1 = kSyncPointAdjustOne;
const SyncOptions SNone = SyncOptions::kNoSyncPoint;
const SyncOptions SSync = SyncOptions::kSyncPoint;
const SyncOptions SSyncAdj1 = SyncOptions::kSyncPointAdjustOne;
static const DestType DSSA = DestType::SSA;
static const DestType DTV = DestType::TV;
static const DestType DNone = DestType::None;
const DestType DSSA = DestType::SSA;
const DestType DTV = DestType::TV;
const DestType DNone = DestType::None;
/*
* The table passed to s_callMap's constructor describes helpers calls
+3 -3
Ver Arquivo
@@ -119,8 +119,8 @@ void printLabel(std::ostream& os, const Block* block) {
os << color(ANSI_COLOR_MAGENTA);
os << "L" << block->id();
switch (block->hint()) {
case Block::Unlikely: os << "<Unlikely>"; break;
case Block::Likely: os << "<Likely>"; break;
case Block::Hint::Unlikely: os << "<Unlikely>"; break;
case Block::Hint::Likely: os << "<Likely>"; break;
default:
break;
}
@@ -276,7 +276,7 @@ static smart::vector<Block*> blocks(const IRTrace* trace,
if (!asmInfo) {
smart::vector<Block*> unlikely;
for (Block* block : trace->blocks()) {
if (block->hint() == Block::Unlikely) {
if (block->hint() == Block::Hint::Unlikely) {
unlikely.push_back(block);
} else {
blocks.push_back(block);
+4 -4
Ver Arquivo
@@ -66,7 +66,7 @@ void SrcRec::emitFallbackJump(TCA from, int cc /* = -1 */) {
if (cc < 0) {
a.jmp(a.code.frontier);
} else {
assert(incoming.type() == IncomingBranch::JCC);
assert(incoming.type() == IncomingBranch::Tag::JCC);
a.jcc((ConditionCode)cc, a.code.frontier);
}
@@ -181,14 +181,14 @@ void SrcRec::replaceOldTranslations() {
void SrcRec::patch(IncomingBranch branch, TCA dest) {
switch (branch.type()) {
case IncomingBranch::JMP: {
case IncomingBranch::Tag::JMP: {
auto& a = tx64->getAsmFor(branch.toSmash());
CodeCursor cg(a, branch.toSmash());
TranslatorX64::smashJmp(a, branch.toSmash(), dest);
break;
}
case IncomingBranch::JCC: {
case IncomingBranch::Tag::JCC: {
// patch destination, but preserve the condition code
int32_t delta = safe_cast<int32_t>((dest - branch.toSmash()) - kJmpccLen);
int32_t* addr = (int32_t*)(branch.toSmash() + kJmpccLen - 4);
@@ -196,7 +196,7 @@ void SrcRec::patch(IncomingBranch branch, TCA dest) {
break;
}
case IncomingBranch::ADDR:
case IncomingBranch::Tag::ADDR:
// Note that this effectively ignores a
atomic_release_store(reinterpret_cast<TCA*>(branch.toSmash()), dest);
}
+11 -7
Ver Arquivo
@@ -42,28 +42,32 @@ namespace Transl {
* intact.
*/
struct IncomingBranch {
enum BranchType {
enum class Tag {
JMP,
JCC,
ADDR,
};
static IncomingBranch jmpFrom(TCA from) { return IncomingBranch(JMP, from); }
static IncomingBranch jccFrom(TCA from) { return IncomingBranch(JCC, from); }
static IncomingBranch jmpFrom(TCA from) {
return IncomingBranch(Tag::JMP, from);
}
static IncomingBranch jccFrom(TCA from) {
return IncomingBranch(Tag::JCC, from);
}
static IncomingBranch addr(TCA* from) {
return IncomingBranch(ADDR, TCA(from));
return IncomingBranch(Tag::ADDR, TCA(from));
}
BranchType type() const { return m_type; }
Tag type() const { return m_type; }
TCA toSmash() const { return m_toSmash; }
private:
explicit IncomingBranch(BranchType type, TCA toSmash)
explicit IncomingBranch(Tag type, TCA toSmash)
: m_type(type)
, m_toSmash(toSmash)
{}
BranchType m_type;
Tag m_type;
TCA m_toSmash;
};
+4 -4
Ver Arquivo
@@ -93,9 +93,9 @@ struct VMRegAnchor : private boost::noncopyable {
explicit VMRegAnchor(ActRec* ar) {
// Some C++ entry points have an ActRec prepared from after a call
// instruction. This syncs us to right after the call instruction.
assert(tl_regState == REGSTATE_DIRTY);
m_old = REGSTATE_DIRTY;
tl_regState = REGSTATE_CLEAN;
assert(tl_regState == VMRegState::DIRTY);
m_old = VMRegState::DIRTY;
tl_regState = VMRegState::CLEAN;
auto prevAr = g_vmContext->getOuterVMFrame(ar);
const Func* prevF = prevAr->m_func;
@@ -122,7 +122,7 @@ struct EagerVMRegAnchor {
assert(vmfp() == fp && vmsp() == sp && vmpc() == pc);
}
m_old = tl_regState;
tl_regState = REGSTATE_CLEAN;
tl_regState = VMRegState::CLEAN;
}
~EagerVMRegAnchor() {
tl_regState = m_old;
+5 -5
Ver Arquivo
@@ -163,7 +163,7 @@ TCA fcallHelper(ActRec* ar) {
have to tell the unwinder that.
*/
DECLARE_FRAME_POINTER(framePtr);
tl_regState = REGSTATE_CLEAN;
tl_regState = VMRegState::CLEAN;
framePtr->m_savedRip = ar->m_savedRip;
throw;
}
@@ -198,7 +198,7 @@ asm (
*/
TCA funcBodyHelper(ActRec* fp) {
setupAfterProlog(fp);
tl_regState = REGSTATE_CLEAN;
tl_regState = VMRegState::CLEAN;
Func* func = const_cast<Func*>(fp->m_func);
TCA tca = tx64->getCallArrayProlog(func);
@@ -208,7 +208,7 @@ TCA funcBodyHelper(ActRec* fp) {
} else {
tca = Translator::Get()->getResumeHelper();
}
tl_regState = REGSTATE_DIRTY;
tl_regState = VMRegState::DIRTY;
return tca;
}
@@ -222,10 +222,10 @@ void TranslatorX64::fCallArrayHelper(const Offset pcOff, const Offset pcNext) {
ec->m_pc = curUnit()->at(pcOff);
PC pc = curUnit()->at(pcNext);
tl_regState = REGSTATE_CLEAN;
tl_regState = VMRegState::CLEAN;
bool runFunc = ec->doFCallArray(pc);
sp = ec->m_stack.top();
tl_regState = REGSTATE_DIRTY;
tl_regState = VMRegState::DIRTY;
if (!runFunc) return;
ec->m_fp->m_savedRip = framePtr->m_savedRip;
+23 -23
Ver Arquivo
@@ -136,7 +136,7 @@ TranslatorX64* volatile nextTx64;
__thread TranslatorX64* tx64;
// Register dirtiness: thread-private.
__thread VMRegState tl_regState = REGSTATE_CLEAN;
__thread VMRegState tl_regState = VMRegState::CLEAN;
static StaticString s___call(LITSTR_INIT("__call"));
static StaticString s___callStatic(LITSTR_INIT("__callStatic"));
@@ -857,18 +857,18 @@ bool isSmashable(Address frontier, int nBytes, int offset /* = 0 */) {
*/
void prepareForTestAndSmash(Asm& a, int testBytes, TestAndSmashFlags flags) {
switch (flags) {
case kAlignJcc:
case TestAndSmashFlags::kAlignJcc:
prepareForSmash(a, testBytes + kJmpccLen, testBytes);
assert(isSmashable(a.code.frontier + testBytes, kJmpccLen));
break;
case kAlignJccImmediate:
case TestAndSmashFlags::kAlignJccImmediate:
prepareForSmash(a,
testBytes + kJmpccLen,
testBytes + kJmpccLen - kJmpImmBytes);
assert(isSmashable(a.code.frontier + testBytes, kJmpccLen,
kJmpccLen - kJmpImmBytes));
break;
case kAlignJccAndJmp:
case TestAndSmashFlags::kAlignJccAndJmp:
// Ensure that the entire jcc, and the entire jmp are smashable
// (but we dont need them both to be in the same cache line)
prepareForSmash(a, testBytes + kJmpccLen, testBytes);
@@ -1042,14 +1042,14 @@ TranslatorX64::shuffleArgsForMagicCall(ActRec* ar) {
* Geronimo!
*/
static void sync_regstate_to_caller(ActRec* preLive) {
assert(tl_regState == REGSTATE_DIRTY);
assert(tl_regState == VMRegState::DIRTY);
VMExecutionContext* ec = g_vmContext;
ec->m_stack.top() = (TypedValue*)preLive - preLive->numArgs();
ActRec* fp = preLive == ec->m_firstAR ?
ec->m_nestedVMs.back().m_savedState.fp : (ActRec*)preLive->m_savedRbp;
ec->m_fp = fp;
ec->m_pc = fp->m_func->unit()->at(fp->m_func->base() + preLive->m_soff);
tl_regState = REGSTATE_CLEAN;
tl_regState = VMRegState::CLEAN;
}
void
@@ -1083,7 +1083,7 @@ TranslatorX64::trimExtraArgs(ActRec* ar) {
// Only go back to dirty in a non-exception case. (Same reason as
// above.)
tl_regState = REGSTATE_DIRTY;
tl_regState = VMRegState::DIRTY;
}
TCA
@@ -1332,8 +1332,8 @@ TranslatorX64::emitPopRetIntoActRec(Asm& a) {
}
static void interp_set_regs(ActRec* ar, Cell* sp, Offset pcOff) {
assert(tl_regState == REGSTATE_DIRTY);
tl_regState = REGSTATE_CLEAN;
assert(tl_regState == VMRegState::DIRTY);
tl_regState = VMRegState::CLEAN;
vmfp() = (Cell*)ar;
vmsp() = sp;
vmpc() = curUnit()->at(pcOff);
@@ -1365,7 +1365,7 @@ TranslatorX64::funcPrologue(Func* func, int nPassed, ActRec* ar) {
interp_set_regs(ar, (Cell*)ar - func->numSlotsInFrame(), entry);
SrcKey funcBody(func, entry);
TCA tca = getTranslation(TranslArgs(funcBody, false));
tl_regState = REGSTATE_DIRTY;
tl_regState = VMRegState::DIRTY;
if (tca) {
// racy, but ok...
func->setPrologue(paramIndex, tca);
@@ -1828,7 +1828,7 @@ TranslatorX64::emitCondJmp(SrcKey skTaken, SrcKey skNotTaken,
// reserve space for a smashable jnz/jmp pair; both initially point
// to our stub.
prepareForTestAndSmash(a, 0, kAlignJccAndJmp);
prepareForTestAndSmash(a, 0, TestAndSmashFlags::kAlignJccAndJmp);
TCA old = a.code.frontier;
TCA stub = astubs.code.frontier;
@@ -1965,7 +1965,7 @@ TranslatorX64::bindJmpccSecond(TCA toSmash, const Offset off,
const Func* f = curFunc();
SrcKey dest(f, off);
TCA branch = getTranslation(TranslArgs(dest, true).src(toSmash));
LeaseHolder writer(s_writeLease, NO_ACQUIRE);
LeaseHolder writer(s_writeLease, LeaseAcquire::NO_ACQUIRE);
if (branch && writer.acquire()) {
smashed = true;
SrcRec* destRec = getSrcRec(dest);
@@ -2280,7 +2280,7 @@ TranslatorX64::enterTC(TCA start, void* data) {
TRACE(1, "enterTC: %p fp%p(%s) sp%p enter {\n", start,
vmfp(), func->name()->data(), vmsp());
tl_regState = REGSTATE_DIRTY;
tl_regState = VMRegState::DIRTY;
// We have to force C++ to spill anything that might be in a callee-saved
// register (aside from rbp). enterTCHelper does not save them.
@@ -2290,7 +2290,7 @@ TranslatorX64::enterTC(TCA start, void* data) {
CALLEE_SAVED_BARRIER();
assert(g_vmContext->m_stack.isValidAddress((uintptr_t)vmsp()));
tl_regState = REGSTATE_CLEAN; // Careful: pc isn't sync'ed yet.
tl_regState = VMRegState::CLEAN; // Careful: pc isn't sync'ed yet.
TRACE(1, "enterTC: %p fp%p sp%p } return\n", start,
vmfp(), vmsp());
@@ -2361,7 +2361,7 @@ bool TranslatorX64::handleServiceRequest(TReqInfo& info,
TRACE(2, "enterTC: bindCall immutably %s -> %p\n",
func->fullName()->data(), dest);
}
LeaseHolder writer(s_writeLease, NO_ACQUIRE);
LeaseHolder writer(s_writeLease, LeaseAcquire::NO_ACQUIRE);
if (dest && writer.acquire()) {
TRACE(2, "enterTC: bindCall smash %p -> %p\n", toSmash, dest);
smashCall(tx64->getAsmFor(toSmash), toSmash, dest);
@@ -2754,7 +2754,7 @@ interpOne##opcode(ActRec* ar, Cell* sp, Offset pcOff) { \
* is actually still correct, and we don't have information in the
* fixup map for interpOne calls anyway.
*/ \
tl_regState = REGSTATE_DIRTY; \
tl_regState = VMRegState::DIRTY; \
return ec; \
}
@@ -2837,9 +2837,9 @@ TCA TranslatorX64::getTranslatedCaller() const {
void
TranslatorX64::syncWork() {
assert(tl_regState == REGSTATE_DIRTY);
assert(tl_regState == VMRegState::DIRTY);
fixup(g_vmContext);
tl_regState = REGSTATE_CLEAN;
tl_regState = VMRegState::CLEAN;
Stats::inc(Stats::TC_Sync);
}
@@ -2971,17 +2971,17 @@ TranslatorX64::getNativeTrampoline(TCA helperAddr) {
}
static void defClsHelper(PreClass *preClass) {
assert(tl_regState == REGSTATE_DIRTY);
tl_regState = REGSTATE_CLEAN;
assert(tl_regState == VMRegState::DIRTY);
tl_regState = VMRegState::CLEAN;
Unit::defClass(preClass);
/*
* m_defClsHelper sync'd the registers for us already. This means
* if an exception propagates we want to leave things as
* REGSTATE_CLEAN, since we're still in sync. Only set it to dirty
* VMRegState::CLEAN, since we're still in sync. Only set it to dirty
* if we are actually returning to run in the TC again.
*/
tl_regState = REGSTATE_DIRTY;
tl_regState = VMRegState::DIRTY;
}
template <typename T>
@@ -3729,7 +3729,7 @@ TCA TranslatorX64::getCatchTrace(CTCA ip) const {
void
TranslatorX64::requestInit() {
TRACE(1, "in requestInit(%" PRId64 ")\n", g_vmContext->m_currentThreadIdx);
tl_regState = REGSTATE_CLEAN;
tl_regState = VMRegState::CLEAN;
PendQ::drain();
requestResetHighLevelTranslator();
Treadmill::startRequest(g_vmContext->m_currentThreadIdx);
+1 -1
Ver Arquivo
@@ -113,7 +113,7 @@ constexpr int kTestImmRegLen = 5; // only for rax -- special encoding
constexpr size_t kX64CacheLineSize = 64;
constexpr size_t kX64CacheLineMask = kX64CacheLineSize - 1;
enum TestAndSmashFlags {
enum class TestAndSmashFlags {
kAlignJccImmediate,
kAlignJcc,
kAlignJccAndJmp
+15 -16
Ver Arquivo
@@ -2481,13 +2481,12 @@ static bool isPop(const NormalizedInstruction* instr) {
NormalizedInstruction::OutputUse
NormalizedInstruction::getOutputUsage(const DynLocation* output) const {
for (NormalizedInstruction* succ = next;
succ; succ = succ->next) {
for (NormalizedInstruction* succ = next; succ; succ = succ->next) {
if (succ->noOp) continue;
for (size_t i = 0; i < succ->inputs.size(); ++i) {
if (succ->inputs[i] == output) {
if (succ->inputWasInferred(i)) {
return OutputInferred;
return OutputUse::Inferred;
}
if (Translator::Get()->dontGuardAnyInputs(succ->op())) {
/* the consumer doesnt care about its inputs
@@ -2496,22 +2495,22 @@ NormalizedInstruction::getOutputUsage(const DynLocation* output) const {
*/
if (!outputDependsOnInput(succ->op()) ||
!(succ->outStack && !succ->outStack->rtt.isVagueValue() &&
succ->getOutputUsage(succ->outStack) != OutputUsed) ||
succ->getOutputUsage(succ->outStack) != OutputUse::Used) ||
!(succ->outLocal && !succ->outLocal->rtt.isVagueValue() &&
succ->getOutputUsage(succ->outLocal)) != OutputUsed) {
return OutputDoesntCare;
succ->getOutputUsage(succ->outLocal) != OutputUse::Used)) {
return OutputUse::DoesntCare;
}
}
return OutputUsed;
return OutputUse::Used;
}
}
}
return OutputUnused;
return OutputUse::Unused;
}
bool NormalizedInstruction::isOutputUsed(const DynLocation* output) const {
return (output && !output->rtt.isVagueValue() &&
getOutputUsage(output) == OutputUsed);
getOutputUsage(output) == OutputUse::Used);
}
bool NormalizedInstruction::isAnyOutputUsed() const
@@ -3276,7 +3275,7 @@ std::unique_ptr<Tracelet> Translator::analyze(SrcKey sk,
NormalizedInstruction* ni = t.newNormalizedInstruction();
ni->source = sk;
ni->stackOffset = stackFrameOffset;
ni->funcd = (t.m_arState.getCurrentState() == ActRecState::KNOWN) ?
ni->funcd = (t.m_arState.getCurrentState() == ActRecState::State::KNOWN) ?
t.m_arState.getCurrentFunc() : nullptr;
ni->m_unit = unit;
ni->preppedByRef = false;
@@ -4056,7 +4055,7 @@ void
ActRecState::pushFuncD(const Func* func) {
TRACE(2, "ActRecState: pushStatic func %p(%s)\n", func, func->name()->data());
Record r;
r.m_state = KNOWN;
r.m_state = State::KNOWN;
r.m_topFunc = func;
r.m_entryArDelta = InvalidEntryArDelta;
m_arStack.push_back(r);
@@ -4066,7 +4065,7 @@ void
ActRecState::pushDynFunc() {
TRACE(2, "ActRecState: pushDynFunc\n");
Record r;
r.m_state = UNKNOWABLE;
r.m_state = State::UNKNOWABLE;
r.m_topFunc = nullptr;
r.m_entryArDelta = InvalidEntryArDelta;
m_arStack.push_back(r);
@@ -4098,20 +4097,20 @@ ActRecState::getReffiness(int argNum, int entryArDelta, RefDeps* outRefDeps) {
// guards.
const ActRec* ar = arFromSpOffset((ActRec*)vmsp(), entryArDelta);
Record r;
r.m_state = GUESSABLE;
r.m_state = State::GUESSABLE;
r.m_entryArDelta = entryArDelta;
r.m_topFunc = ar->m_func;
m_arStack.push_back(r);
}
Record& r = m_arStack.back();
if (r.m_state == UNKNOWABLE) {
if (r.m_state == State::UNKNOWABLE) {
TRACE(2, "ActRecState: unknowable, throwing in the towel\n");
throwUnknownInput();
not_reached();
}
assert(r.m_topFunc);
bool retval = r.m_topFunc->byRef(argNum);
if (r.m_state == GUESSABLE) {
if (r.m_state == State::GUESSABLE) {
assert(r.m_entryArDelta != InvalidEntryArDelta);
TRACE(2, "ActRecState: guessing arg%d -> %d\n", argNum, retval);
outRefDeps->addDep(r.m_entryArDelta, argNum, retval);
@@ -4127,7 +4126,7 @@ ActRecState::getCurrentFunc() {
ActRecState::State
ActRecState::getCurrentState() {
if (m_arStack.empty()) return GUESSABLE;
if (m_arStack.empty()) return State::GUESSABLE;
return m_arStack.back().m_state;
}
+22 -23
Ver Arquivo
@@ -65,13 +65,12 @@ extern TranslatorX64* volatile nextTx64;
extern __thread TranslatorX64* tx64;
/*
* REGSTATE_DIRTY when the live register state is spread across the
* stack and m_fixup, REGSTATE_CLEAN when it has been sync'ed into
* g_context.
* DIRTY when the live register state is spread across the stack and m_fixup,
* CLEAN when it has been sync'ed into g_context.
*/
enum VMRegState {
REGSTATE_CLEAN,
REGSTATE_DIRTY
enum class VMRegState {
CLEAN,
DIRTY
};
extern __thread VMRegState tl_regState;
@@ -321,11 +320,11 @@ class NormalizedInstruction {
return i < 32 && ((checkedInputs >> i) & 1);
}
enum OutputUse {
OutputUsed,
OutputUnused,
OutputInferred,
OutputDoesntCare
enum class OutputUse {
Used,
Unused,
Inferred,
DoesntCare
};
OutputUse getOutputUsage(const DynLocation* output) const;
bool isOutputUsed(const DynLocation* output) const;
@@ -470,7 +469,7 @@ struct ActRecState {
// instructions that need to do so.
static const int InvalidEntryArDelta = INT_MAX;
enum State {
enum class State {
GUESSABLE, KNOWN, UNKNOWABLE
};
@@ -1058,12 +1057,12 @@ public:
static bool liveFrameIsPseudoMain();
inline void sync() {
if (tl_regState == REGSTATE_CLEAN) return;
if (tl_regState == VMRegState::CLEAN) return;
syncWork();
}
inline bool stateIsDirty() {
return tl_regState == REGSTATE_DIRTY;
return tl_regState == VMRegState::DIRTY;
}
inline bool isTransDBEnabled() const {
@@ -1115,10 +1114,10 @@ public:
int getStackDelta(const NormalizedInstruction& ni);
enum ControlFlowInfo {
ControlFlowNone,
ControlFlowChangesPC,
ControlFlowBreaksBB
enum class ControlFlowInfo {
None,
ChangesPC,
BreaksBB
};
static inline ControlFlowInfo
@@ -1153,7 +1152,7 @@ opcodeControlFlowInfo(const Opcode instr) {
case OpEval:
case OpNativeImpl:
case OpContHandle:
return ControlFlowBreaksBB;
return ControlFlowInfo::BreaksBB;
case OpFCall:
case OpFCallArray:
case OpContEnter:
@@ -1162,9 +1161,9 @@ opcodeControlFlowInfo(const Opcode instr) {
case OpReq:
case OpReqOnce:
case OpReqDoc:
return ControlFlowChangesPC;
return ControlFlowInfo::ChangesPC;
default:
return ControlFlowNone;
return ControlFlowInfo::None;
}
}
@@ -1176,7 +1175,7 @@ opcodeControlFlowInfo(const Opcode instr) {
*/
static inline bool
opcodeChangesPC(const Opcode instr) {
return opcodeControlFlowInfo(instr) >= ControlFlowChangesPC;
return opcodeControlFlowInfo(instr) >= ControlFlowInfo::ChangesPC;
}
/*
@@ -1188,7 +1187,7 @@ opcodeChangesPC(const Opcode instr) {
*/
static inline bool
opcodeBreaksBB(const Opcode instr) {
return opcodeControlFlowInfo(instr) == ControlFlowBreaksBB;
return opcodeControlFlowInfo(instr) == ControlFlowInfo::BreaksBB;
}
bool outputDependsOnInput(const Opcode instr);
+4 -4
Ver Arquivo
@@ -53,7 +53,7 @@ void append_vec(std::vector<char>& v,
}
void sync_regstate(_Unwind_Context* context) {
assert(tl_regState == REGSTATE_DIRTY);
assert(tl_regState == VMRegState::DIRTY);
uintptr_t frameRbp = _Unwind_GetGR(context, Debug::RBP);
uintptr_t frameRip = _Unwind_GetGR(context, Debug::RIP);
@@ -73,7 +73,7 @@ void sync_regstate(_Unwind_Context* context) {
Stats::inc(Stats::TC_SyncUnwind);
tx64->fixupWork(g_vmContext, &fakeAr);
tl_regState = REGSTATE_CLEAN;
tl_regState = VMRegState::CLEAN;
}
bool install_catch_trace(_Unwind_Context* ctx, _Unwind_Exception* exn,
@@ -134,7 +134,7 @@ tc_unwind_personality(int version,
assert(status == 0);
FTRACE(1, "unwind {} exn {}: regState: {} ip: {} type: {}. ",
unwindType, exceptionObj,
tl_regState == REGSTATE_DIRTY ? "dirty" : "clean",
tl_regState == VMRegState::DIRTY ? "dirty" : "clean",
(TCA)_Unwind_GetIP(context), exnType);
}
@@ -160,7 +160,7 @@ tc_unwind_personality(int version,
* which is an exit traces from hhir with a few special instructions.
*/
else if (actions & _UA_CLEANUP_PHASE) {
if (tl_regState == REGSTATE_DIRTY) {
if (tl_regState == VMRegState::DIRTY) {
sync_regstate(context);
}
if (install_catch_trace(context, exceptionObj, ism)) {
+2 -2
Ver Arquivo
@@ -869,7 +869,7 @@ SSATmp* HhbcTranslator::VectorTranslator::checkInitProp(
[&] { // Taken: Property is Uninit. Raise a warning and return
// a pointer to InitNull, either in the object or
// init_null_variant.
m_tb.hint(Block::Unlikely);
m_tb.hint(Block::Hint::Unlikely);
if (doWarn && wantPropSpecializedWarnings()) {
gen(RaiseUndefProp, m_ht.getCatchTrace(), baseAsObj, key);
}
@@ -931,7 +931,7 @@ void HhbcTranslator::VectorTranslator::emitPropSpecialized(const MInstrAttr mia,
doDefine);
},
[&] { // Taken: Base is Null. Raise warnings/errors and return InitNull.
m_tb.hint(Block::Unlikely);
m_tb.hint(Block::Hint::Unlikely);
if (doWarn) {
gen(WarnNonObjProp);
}
+2 -2
Ver Arquivo
@@ -121,8 +121,8 @@ void Lease::drop(int64_t hintExpireDelay) {
LeaseHolderBase::LeaseHolderBase(Lease& l, LeaseAcquire acquire,
bool blocking)
: m_lease(l), m_haveLock(false), m_acquired(false) {
assert(IMPLIES(blocking, acquire == ACQUIRE));
if (!m_lease.amOwner() && acquire == ACQUIRE) {
assert(IMPLIES(blocking, acquire == LeaseAcquire::ACQUIRE));
if (!m_lease.amOwner() && acquire == LeaseAcquire::ACQUIRE) {
m_acquired = m_lease.acquire(blocking);
}
m_haveLock = m_lease.amOwner();
+3 -3
Ver Arquivo
@@ -71,7 +71,7 @@ private:
void gremlinUnlockImpl();
};
enum LeaseAcquire {
enum class LeaseAcquire {
ACQUIRE,
NO_ACQUIRE,
};
@@ -91,12 +91,12 @@ struct LeaseHolderBase {
bool m_acquired;
};
struct LeaseHolder : public LeaseHolderBase {
explicit LeaseHolder(Lease& l, LeaseAcquire acquire = ACQUIRE)
explicit LeaseHolder(Lease& l, LeaseAcquire acquire = LeaseAcquire::ACQUIRE)
: LeaseHolderBase(l, acquire, false) {}
};
struct BlockingLeaseHolder : public LeaseHolderBase {
explicit BlockingLeaseHolder(Lease& l)
: LeaseHolderBase(l, ACQUIRE, true) {}
: LeaseHolderBase(l, LeaseAcquire::ACQUIRE, true) {}
};
}} // HPHP::Transl