Clean up and document SRFlags

Make it part of abi-x64.h and explain what the flags mean.
Esse commit está contido em:
Jordan DeLong
2013-05-06 18:50:37 -07:00
commit de Sara Golemon
commit 5b7a3e3895
4 arquivos alterados com 86 adições e 43 exclusões
+45
Ver Arquivo
@@ -226,6 +226,51 @@ enum ServiceRequest {
#undef REQ
};
/*
* Various flags that are passed to emitServiceReq. May be or'd
* together.
*/
enum class SRFlags {
None = 0,
/*
* Indicates the service request should be aligned.
*/
Align = 1,
/*
* Indicates the service request is not a one-time use stub, so it's
* ineligable for service request reclamation.
*
* The service request also will not reuse an existing service
* request---i.e. it will be emitted at the current astubs frontier.
*/
Persistent = 2,
/*
* For some service requests (returning from interpreted frames),
* using a ret instruction to get back to enterTCHelper will
* unbalance the return stack buffer---in these cases use a jmp.
*/
JmpInsteadOfRet = 4,
/*
* The service request should be emitted on a instead of astubs.
*
* Overrides whatever the bits for Align and Persistent are and
* implies !Align and !Persistent.
*/
EmitInA = 8,
};
inline bool operator&(SRFlags a, SRFlags b) {
return int(a) & int(b);
}
inline SRFlags operator|(SRFlags a, SRFlags b) {
return SRFlags(int(a) | int(b));
}
//////////////////////////////////////////////////////////////////////
// Set of all the x64 registers.
+5 -5
Ver Arquivo
@@ -2153,7 +2153,7 @@ void CodeGenerator::cgRetCtrl(IRInstruction* inst) {
void CodeGenerator::emitReqBindAddr(const Func* func,
TCA& dest,
Offset offset) {
dest = m_tx64->emitServiceReq(TranslatorX64::SRFlags::SRNone,
dest = m_tx64->emitServiceReq(SRFlags::None,
REQ_BIND_ADDR,
2ull,
&dest,
@@ -2496,7 +2496,7 @@ void CodeGenerator::cgExitTrace(IRInstruction* inst) {
uint64_t notTaken = notTakenPC->getValInt();
m_astubs.setcc(cc, rbyte(serviceReqArgRegs[4]));
m_tx64->emitServiceReq(TranslatorX64::SRFlags::SRInline,
m_tx64->emitServiceReq(SRFlags::Persistent,
REQ_BIND_JMPCC_FIRST,
4ull,
smashAddr,
@@ -2516,7 +2516,7 @@ void CodeGenerator::cgExitTrace(IRInstruction* inst) {
if (smashAddr != kIRDirectJccJmpActive) {
// kIRDirectJccJmpActive only needs NormalCc exit in astubs
m_tx64->emitServiceReq(TranslatorX64::SRFlags::SRInline,
m_tx64->emitServiceReq(SRFlags::Persistent,
REQ_BIND_JMP, 2,
smashAddr,
uint64_t(destSK.offset()));
@@ -2551,7 +2551,7 @@ void CodeGenerator::cgExitTrace(IRInstruction* inst) {
if (RuntimeOption::EvalHHIRDisableTx64) {
// Emit a service request to interpret a single instruction before
// creating a new translation
m_tx64->emitServiceReq(TranslatorX64::SRFlags::SRInline,
m_tx64->emitServiceReq(SRFlags::Persistent,
REQ_INTERPRET,
2ull, uint64_t(destSK.offset()), 1);
} else {
@@ -4834,7 +4834,7 @@ void CodeGenerator::cgInterpOneCF(IRInstruction* inst) {
m_as.loadq(rax[offsetof(VMExecutionContext, m_stack) +
Stack::topOfStackOffset()], rVmSp);
m_tx64->emitServiceReq(TranslatorX64::SRFlags::SREmitInA, REQ_RESUME, 0ull);
m_tx64->emitServiceReq(SRFlags::EmitInA, REQ_RESUME, 0ull);
}
void CodeGenerator::cgDefFunc(IRInstruction* inst) {
+35 -30
Ver Arquivo
@@ -1389,7 +1389,7 @@ TranslatorX64::createTranslation(SrcKey sk, bool align,
TCA astart = a.code.frontier;
TCA stubstart = astubs.code.frontier;
TCA req = emitServiceReq(SRFlags::SRNone, REQ_RETRANSLATE,
TCA req = emitServiceReq(SRFlags::None, REQ_RETRANSLATE,
1, uint64_t(sk.offset()));
SKTRACE(1, sk, "inserting anchor translation for (%p,%d) at %p\n",
curUnit(), sk.offset(), req);
@@ -2499,7 +2499,7 @@ TranslatorX64::emitBindCallHelper(SrcKey srcKey,
astubs. mov_reg64_reg64(rStashedAR, serviceReqArgRegs[1]);
emitPopRetIntoActRec(astubs);
emitServiceReq(SRFlags::SRInline, REQ_BIND_CALL, 1ull, req);
emitServiceReq(SRFlags::Persistent, REQ_BIND_CALL, 1ull, req);
TRACE(1, "will bind static call: tca %p, this %p, funcd %p, astubs %p\n",
toSmash, this, funcd, astubs.code.frontier);
@@ -2531,7 +2531,7 @@ TranslatorX64::emitCondJmp(SrcKey skTaken, SrcKey skNotTaken,
// emitServiceReq because that only supports constants/immediates, so
// compute the last argument via setcc.
astubs.setcc(cc, rbyte(serviceReqArgRegs[4]));
emitServiceReq(SRFlags::SRInline, REQ_BIND_JMPCC_FIRST, 4ull,
emitServiceReq(SRFlags::Persistent, REQ_BIND_JMPCC_FIRST, 4ull,
old,
uint64_t(skTaken.offset()),
uint64_t(skNotTaken.offset()),
@@ -2609,7 +2609,7 @@ TranslatorX64::bindJmpccFirst(TCA toSmash,
// yet.
if (taken) cc = ccNegate(cc);
TCA stub =
emitServiceReq(SRFlags::SRNone, REQ_BIND_JMPCC_SECOND, 3,
emitServiceReq(SRFlags::None, REQ_BIND_JMPCC_SECOND, 3,
toSmash, uint64_t(offWillDefer), uint64_t(cc));
Asm& as = getAsmFor(toSmash);
@@ -2688,7 +2688,7 @@ TranslatorX64::emitBindJ(X64Assembler& _a, ConditionCode cc,
emitJmpOrJcc(_a, cc, toSmash);
}
TCA sr = emitServiceReq(SRFlags::SRNone, req, 2,
TCA sr = emitServiceReq(SRFlags::None, req, 2,
toSmash, uint64_t(dest.offset()));
if (&_a == &astubs) {
@@ -2996,7 +2996,7 @@ TranslatorX64::emitRetFromInterpretedFrame() {
// Marshall our own args by hand here.
astubs. lea (rVmSp[-arBase], serviceReqArgRegs[0]);
astubs. movq (rVmFp, serviceReqArgRegs[1]);
(void) emitServiceReq(SRFlags(SRInline | SRJmpInsteadOfRet),
(void) emitServiceReq(SRFlags::Persistent | SRFlags::JmpInsteadOfRet,
REQ_POST_INTERP_RET, 0ull);
return stub;
}
@@ -3016,7 +3016,7 @@ TranslatorX64::emitRetFromInterpretedGeneratorFrame() {
astubs. loadq (rVmFp[AROFF(m_this)], rContAR);
astubs. loadq (rContAR[CONTOFF(m_arPtr)], rContAR);
astubs. movq (rVmFp, serviceReqArgRegs[1]);
(void) emitServiceReq(SRFlags(SRInline | SRJmpInsteadOfRet),
(void) emitServiceReq(SRFlags::Persistent | SRFlags::JmpInsteadOfRet,
REQ_POST_INTERP_RET, 0ull);
return stub;
}
@@ -3417,11 +3417,7 @@ TranslatorX64::freeRequestStub(TCA stub) {
return true;
}
TCA
TranslatorX64::getFreeStub(bool inLine) {
if (inLine) {
return astubs.code.frontier;
}
TCA TranslatorX64::getFreeStub() {
TCA ret = m_freeStubs.maybePop();
if (ret) {
Stats::inc(Stats::Astubs_Reused);
@@ -3474,11 +3470,13 @@ class ConditionalCodeCursor {
TCA
TranslatorX64::emitServiceReqVA(SRFlags flags, ServiceRequest req, int numArgs,
va_list args) {
bool emitInA = bool(flags & SRFlags::SREmitInA);
bool align = bool(flags & SRFlags::SRAlign) && !emitInA;
bool inLine = bool(flags & SRFlags::SRInline);
bool emitInA = flags & SRFlags::EmitInA;
bool align = (flags & SRFlags::Align) && !emitInA;
bool notReusable = flags & SRFlags::Persistent;
Asm& as = emitInA ? a : astubs;
TCA start = emitInA ? a.code.frontier : getFreeStub(inLine);
TCA start = emitInA ? a.code.frontier :
notReusable ? astubs.code.frontier :
getFreeStub();
ConditionalCodeCursor cg(as, start);
/* max space for moving to align, saving VM regs plus emitting args */
static const int kVMRegSpace = 0x14;
@@ -3501,18 +3499,21 @@ TranslatorX64::emitServiceReqVA(SRFlags flags, ServiceRequest req, int numArgs,
TRACE(3, "%p,", (void*)argVal);
emitImmReg(as, argVal, serviceReqArgRegs[i]);
}
if (!inLine) {
/* make sure that the stub has enough space that it can be
* reused for other service requests, with different number of
* arguments, alignment, etc.
if (notReusable) {
emitImmReg(as, 0, rScratch);
} else {
/*
* Make sure that the stub has enough space so it can be reused
* for other service requests, with different number of arguments,
* alignment, etc.
*/
as.emitNop(start + kMaxStubSpace - as.code.frontier);
emitImmReg(as, (uint64_t)start, rScratch);
} else {
emitImmReg(as, 0, rScratch);
}
TRACE(3, ")\n");
emitImmReg(as, req, rdi);
/*
* Weird hand-shaking with enterTC: reverse-call a service routine.
*
@@ -3521,7 +3522,7 @@ TranslatorX64::emitServiceReqVA(SRFlags flags, ServiceRequest req, int numArgs,
* something other than enterTCHelper. In that case
* SRJmpInsteadOfRet indicates to fake the return.
*/
if (flags & SRFlags::SRJmpInsteadOfRet) {
if (flags & SRFlags::JmpInsteadOfRet) {
as.pop(rax);
as.jmp(rax);
} else {
@@ -3536,7 +3537,7 @@ TCA
TranslatorX64::emitServiceReq(ServiceRequest req, int numArgs, ...) {
va_list args;
va_start(args, numArgs);
TCA retval = emitServiceReqVA(SRFlags::SRAlign, req, numArgs, args);
TCA retval = emitServiceReqVA(SRFlags::Align, req, numArgs, args);
va_end(args);
return retval;
}
@@ -6349,7 +6350,7 @@ TranslatorX64::translateSwitch(const Tracelet& t,
for (int idx = 0; idx < jmptabSize; ++idx) {
SrcKey sk(curFunc(), i.offset() + iv.vec32()[idx]);
jmptab[idx] = emitServiceReq(SRFlags::SRNone, REQ_BIND_ADDR, 2ull,
jmptab[idx] = emitServiceReq(SRFlags::None, REQ_BIND_ADDR, 2ull,
&jmptab[idx], uint64_t(sk.offset()));
}
}
@@ -6411,7 +6412,7 @@ TranslatorX64::translateSSwitch(const Tracelet& t,
auto bindAddr = [&](TCA& dest, Offset o) {
SrcKey sk(curFunc(), ni.offset() + o);
dest = emitServiceReq(SRFlags::SRNone, REQ_BIND_ADDR, 2ull,
dest = emitServiceReq(SRFlags::None, REQ_BIND_ADDR, 2ull,
&dest, uint64_t(sk.offset()));
};
if (fastPath) {
@@ -8502,7 +8503,7 @@ TranslatorX64::translateReqLit(const Tracelet& t,
emitCall(a, (TCA)reqLitHelper, true);
args->m_efile = efile;
args->m_pseudoMain = emitServiceReq(SRFlags::SRNone, REQ_BIND_REQUIRE, 3,
args->m_pseudoMain = emitServiceReq(SRFlags::None, REQ_BIND_REQUIRE, 3,
uint64_t(args),
uint64_t(func), uint64_t(func->base()));
args->m_pcOff = after;
@@ -11284,6 +11285,10 @@ TranslatorX64::translateTracelet(SrcKey sk, bool considerHHIR/*=true*/,
hhirTraceStart(sk.offset());
SKTRACE(1, sk, "retrying irTranslateTracelet\n");
result = irTranslateTracelet(t, start, stubStart, &bcMapping);
if (result == Retry) {
assert(a.code.frontier == start);
assert(astubs.code.frontier == stubStart);
}
} while (result == Retry);
m_useHHIR = false;
if (result == Success) {
@@ -11647,7 +11652,7 @@ TranslatorX64::TranslatorX64()
// Call to exit with whatever value the program leaves on
// the return stack.
m_callToExit = emitServiceReq(SRFlags(SRAlign | SRJmpInsteadOfRet),
m_callToExit = emitServiceReq(SRFlags::Align | SRFlags::JmpInsteadOfRet,
REQ_EXIT, 0ull);
/*
@@ -11674,7 +11679,7 @@ TranslatorX64::TranslatorX64()
rVmFp);
astubs. load_reg64_disp_reg64(rax, offsetof(VMExecutionContext, m_stack) +
Stack::topOfStackOffset(), rVmSp);
emitServiceReq(SRFlags::SRInline, REQ_RESUME, 0ull);
emitServiceReq(SRFlags::Persistent, REQ_RESUME, 0ull);
// Helper for DefCls, in astubs.
{
@@ -11743,7 +11748,7 @@ TranslatorX64::TranslatorX64()
astubs. load_reg64_disp_reg32(rax, Func::sharedBaseOffset(), rax);
astubs. add_reg32_reg32(rax, rdi);
emitEagerVMRegSave(astubs, SaveFP | SavePC);
emitServiceReq(SRFlags::SRInline, REQ_STACK_OVERFLOW, 0ull);
emitServiceReq(SRFlags::Persistent, REQ_STACK_OVERFLOW, 0ull);
}
// do gdb specific initialization. This has to happen after
+1 -8
Ver Arquivo
@@ -813,7 +813,7 @@ public:
FreeStubList m_freeStubs;
bool freeRequestStub(TCA stub);
TCA getFreeStub(bool inLine);
TCA getFreeStub();
private:
TCA getInterceptHelper();
void translateInstr(const Tracelet& t, const NormalizedInstruction& i);
@@ -931,13 +931,6 @@ private:
int offset,
SrcRec& fail);
enum SRFlags {
SRNone = 0,
SRAlign = 1,
SRInline = 2,
SRJmpInsteadOfRet = 4,
SREmitInA = 8,
};
TCA emitServiceReq(ServiceRequest, int numArgs, ...);
TCA emitServiceReq(SRFlags flags, ServiceRequest, int numArgs, ...);
TCA emitServiceReqVA(SRFlags flags, ServiceRequest, int numArgs,