diff --git a/hphp/runtime/base/runtime_option.h b/hphp/runtime/base/runtime_option.h index cece553dd..750ce1cd8 100644 --- a/hphp/runtime/base/runtime_option.h +++ b/hphp/runtime/base/runtime_option.h @@ -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) \ diff --git a/hphp/runtime/vm/bytecode.cpp b/hphp/runtime/vm/bytecode.cpp index cb4db2e07..e0062ba69 100644 --- a/hphp/runtime/vm/bytecode.cpp +++ b/hphp/runtime/vm/bytecode.cpp @@ -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")); diff --git a/hphp/runtime/vm/translator/hopt/ir.cpp b/hphp/runtime/vm/translator/hopt/ir.cpp index 489cc0c0f..afe723d5b 100644 --- a/hphp/runtime/vm/translator/hopt/ir.cpp +++ b/hphp/runtime/vm/translator/hopt/ir.cpp @@ -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; diff --git a/hphp/runtime/vm/translator/translator-x64.cpp b/hphp/runtime/vm/translator/translator-x64.cpp index 2aeeaf70b..f8a14afc5 100644 --- a/hphp/runtime/vm/translator/translator-x64.cpp +++ b/hphp/runtime/vm/translator/translator-x64.cpp @@ -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), diff --git a/hphp/util/disasm.cpp b/hphp/util/disasm.cpp index 8ba0662aa..5dd5c5dcc 100644 --- a/hphp/util/disasm.cpp +++ b/hphp/util/disasm.cpp @@ -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; } diff --git a/hphp/util/disasm.h b/hphp/util/disasm.h index b52be4bf6..e3bbcac1d 100644 --- a/hphp/util/disasm.h +++ b/hphp/util/disasm.h @@ -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