Print relative offsets in Eval.JitCompareHHIR
This diff adds a relativeOffsets option to Disasm, which will print code addresses as relative offsets from the beginning of the tracelet instead of absolute addresses. This format makes it much easier to compare the relative sizes of the instructions selected by the two jits. I also changed the runtime option to be a double instead of a bool, which is used as the cutoff ratio for which tracelets to print. Setting it to 1 will print tracelets where the ir made larger code than tx64, setting it to 2 will print tracelets where the ir's code is at least twice as big as tx64's, etc...
Esse commit está contido em:
@@ -409,7 +409,7 @@ public:
|
||||
F(bool, JitTransCounters, false) \
|
||||
F(bool, JitMGeneric, true) \
|
||||
F(bool, JitUseIR, false) \
|
||||
F(bool, JitCompareHHIR, false) \
|
||||
F(double, JitCompareHHIR, 0) \
|
||||
F(bool, IRPuntDontInterp, false) \
|
||||
F(bool, HHIRGenericDtorHelper, true) \
|
||||
F(bool, HHIRCse, true) \
|
||||
|
||||
@@ -1910,6 +1910,10 @@ static int exception_handler() {
|
||||
} catch (Exception &e) {
|
||||
pushFault(Fault::CppException, e.clone());
|
||||
longJmpType = g_vmContext->hhvmPrepareThrow();
|
||||
} catch (std::exception& e) {
|
||||
pushFault(Fault::CppException,
|
||||
new Exception("unexpected %s: %s", typeid(e).name(), e.what()));
|
||||
longJmpType = g_vmContext->hhvmPrepareThrow();
|
||||
} catch (...) {
|
||||
pushFault(Fault::CppException,
|
||||
new Exception("unknown exception"));
|
||||
|
||||
@@ -1067,7 +1067,8 @@ void Trace::print() const {
|
||||
|
||||
void Trace::print(std::ostream& os, const AsmInfo* asmInfo) const {
|
||||
static const int kIndent = 4;
|
||||
Disasm disasm(kIndent + 4, RuntimeOption::EvalDumpIR > 5);
|
||||
Disasm disasm(Disasm::Options().indent(kIndent + 4)
|
||||
.printEncoding(RuntimeOption::EvalDumpIR > 5));
|
||||
|
||||
// Print unlikely blocks at the end
|
||||
BlockList blocks, unlikely;
|
||||
|
||||
@@ -11475,7 +11475,7 @@ TranslatorX64::translateTracelet(SrcKey sk, bool considerHHIR/*=true*/,
|
||||
|
||||
if (transKind == TransNormalIR && RuntimeOption::EvalJitCompareHHIR) {
|
||||
m_useHHIR = false;
|
||||
Disasm disasm;
|
||||
Disasm disasm(Disasm::Options().relativeOffset(true));
|
||||
TCA irEnd = a.code.frontier;
|
||||
TCA irStubsEnd = astubs.code.frontier;
|
||||
TCA tx64Start = a.code.frontier;
|
||||
@@ -11484,15 +11484,16 @@ TranslatorX64::translateTracelet(SrcKey sk, bool considerHHIR/*=true*/,
|
||||
size_t irSize = irEnd - start;
|
||||
size_t tx64Size = tx64End - tx64Start;
|
||||
|
||||
if (irSize > tx64Size) {
|
||||
double ratio = (double)irSize / tx64Size;
|
||||
if (ratio > RuntimeOption::EvalJitCompareHHIR) {
|
||||
std::ostringstream irOut, tx64Out, out;
|
||||
out << folly::format("{:-^140}\n",
|
||||
folly::format(" New translation - hhir/tx64 = {}% ",
|
||||
100 * irSize / tx64Size));
|
||||
int(100 * ratio)));
|
||||
t.print(out);
|
||||
out << '\n';
|
||||
# define IRCOL "{:<90}"
|
||||
# define TXCOL "{:<55}"
|
||||
# define TXCOL "{:<50}"
|
||||
out << folly::format(TXCOL " " TXCOL "\n",
|
||||
folly::format("Translation from tx64 ({} bytes)",
|
||||
tx64Size),
|
||||
|
||||
+25
-9
@@ -123,9 +123,8 @@ static int addressToSymbol(xed_uint64_t address,
|
||||
}
|
||||
#endif /* HAVE_LIBXED */
|
||||
|
||||
Disasm::Disasm(int indentLevel /* = 0 */, bool printEncoding /* = false */)
|
||||
: m_indent(indentLevel)
|
||||
, m_printEncoding(printEncoding)
|
||||
Disasm::Disasm(const Disasm::Options& opts)
|
||||
: m_opts(opts)
|
||||
{
|
||||
#ifdef HAVE_LIBXED
|
||||
xed_state_init(&m_xedState, XED_MACHINE_MODE_LONG_64,
|
||||
@@ -153,6 +152,7 @@ void Disasm::disasm(std::ostream& out, uint8_t* codeStartAddr,
|
||||
char codeStr[MAX_INSTR_ASM_LEN];
|
||||
xed_uint8_t *frontier;
|
||||
xed_decoded_inst_t xedd;
|
||||
uint64_t codeBase = uint64_t(codeStartAddr);
|
||||
uint64_t ip;
|
||||
|
||||
// Decode and print each instruction
|
||||
@@ -168,14 +168,30 @@ void Disasm::disasm(std::ostream& out, uint8_t* codeStartAddr,
|
||||
MAX_INSTR_ASM_LEN, ip, nullptr)) {
|
||||
error("disasm error: xed_format_context failed");
|
||||
}
|
||||
uint32_t instrLen = xed_decoded_inst_get_length(&xedd);
|
||||
|
||||
for (int i = 0; i < m_indent; ++i) {
|
||||
// If it's a jump, we're printing relative offsets, and the dest
|
||||
// is within the range we're printing, add the dest as a relative
|
||||
// offset.
|
||||
std::string jmpComment;
|
||||
auto const cat = xed_decoded_inst_get_category(&xedd);
|
||||
if (cat == XED_CATEGORY_COND_BR || cat == XED_CATEGORY_UNCOND_BR) {
|
||||
if (m_opts.m_relativeOffset) {
|
||||
auto disp = uint64_t(frontier + instrLen +
|
||||
xed_decoded_inst_get_branch_displacement(&xedd) -
|
||||
codeBase);
|
||||
if (disp < uint64_t(codeEndAddr - codeStartAddr)) {
|
||||
jmpComment = folly::format(" # {:#x}", disp).str();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_opts.m_indentLevel; ++i) {
|
||||
out << ' ';
|
||||
}
|
||||
out << folly::format("{:#10x}: ", ip);
|
||||
|
||||
uint32_t instrLen = xed_decoded_inst_get_length(&xedd);
|
||||
if (m_printEncoding) {
|
||||
const char* fmt = m_opts.m_relativeOffset ? "{:3x}: " : "{:#10x}: ";
|
||||
out << folly::format(fmt, ip - (m_opts.m_relativeOffset ? codeBase : 0));
|
||||
if (m_opts.m_printEncoding) {
|
||||
// print encoding, like in objdump
|
||||
unsigned posi = 0;
|
||||
for (; posi < instrLen; ++posi) {
|
||||
@@ -185,7 +201,7 @@ void Disasm::disasm(std::ostream& out, uint8_t* codeStartAddr,
|
||||
out << " ";
|
||||
}
|
||||
}
|
||||
out << codeStr << std::endl;
|
||||
out << codeStr << jmpComment << std::endl;
|
||||
frontier += instrLen;
|
||||
ip += instrLen;
|
||||
}
|
||||
|
||||
+27
-3
@@ -30,10 +30,35 @@ namespace HPHP {
|
||||
|
||||
class Disasm : private boost::noncopyable {
|
||||
public:
|
||||
struct Options {
|
||||
Options()
|
||||
: m_indentLevel(0)
|
||||
, m_printEncoding(false)
|
||||
, m_relativeOffset(false)
|
||||
{}
|
||||
|
||||
Options& indent(int i) {
|
||||
m_indentLevel = i;
|
||||
return *this;
|
||||
}
|
||||
Options& printEncoding(bool pe) {
|
||||
m_printEncoding = pe;
|
||||
return *this;
|
||||
}
|
||||
Options& relativeOffset(bool re) {
|
||||
m_relativeOffset = re;
|
||||
return *this;
|
||||
}
|
||||
|
||||
int m_indentLevel;
|
||||
bool m_printEncoding;
|
||||
bool m_relativeOffset;
|
||||
};
|
||||
|
||||
/* Create a Disasm object. indentLevel spaces will be put at the beginning of
|
||||
* each line of disassembly. If printEncoding is true, the raw hex bytes of
|
||||
* the instructions will also be in the output. */
|
||||
explicit Disasm(int indentLevel = 0, bool printEncoding = false);
|
||||
explicit Disasm(const Options& opts = Options());
|
||||
|
||||
/* Disassemble instructions. start should be the first byte of the region to
|
||||
* disassemble and end should be the first byte past the region to
|
||||
@@ -44,8 +69,7 @@ class Disasm : private boost::noncopyable {
|
||||
#ifdef HAVE_LIBXED
|
||||
xed_state_t m_xedState;
|
||||
#endif // HAVE_LIBXED
|
||||
const int m_indent;
|
||||
const bool m_printEncoding;
|
||||
const Options m_opts;
|
||||
};
|
||||
|
||||
} // namespace HPHP
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário