diff --git a/llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/RemoteJITUtils.cpp b/llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/RemoteJITUtils.cpp --- a/llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/RemoteJITUtils.cpp +++ b/llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/RemoteJITUtils.cpp @@ -37,8 +37,8 @@ return createStringError(inconvertibleErrorCode(), "No debug support for given object layer type"); - ObjLinkingLayer->addPlugin( - std::make_unique(ES, std::move(*Registrar))); + ObjLinkingLayer->addPlugin(std::make_unique( + ES, std::move(*Registrar), true, true)); return Error::success(); } diff --git a/llvm/include/llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h b/llvm/include/llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h --- a/llvm/include/llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h @@ -60,9 +60,15 @@ /// names. Note that this may cause significant memory and transport /// overhead for objects built with a release configuration. /// + /// AutoRegisterCode: + /// Notify the debugger for each new debug object. This is a good default + /// mode, but it may cause significant overhead when adding many modules in + /// sequence. When turning this off, the user has to issue the call to + /// __jit_debug_register_code() on the executor side manually. + /// DebugObjectManagerPlugin(ExecutionSession &ES, std::unique_ptr Target, - bool RequireDebugSections); + bool RequireDebugSections, bool AutoRegisterCode); ~DebugObjectManagerPlugin(); void notifyMaterializing(MaterializationResponsibility &MR, @@ -92,6 +98,7 @@ std::unique_ptr Target; bool RequireDebugSections; + bool AutoRegisterCode; }; } // namespace orc diff --git a/llvm/include/llvm/ExecutionEngine/Orc/EPCDebugObjectRegistrar.h b/llvm/include/llvm/ExecutionEngine/Orc/EPCDebugObjectRegistrar.h --- a/llvm/include/llvm/ExecutionEngine/Orc/EPCDebugObjectRegistrar.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/EPCDebugObjectRegistrar.h @@ -31,7 +31,8 @@ /// Abstract interface for registering debug objects in the executor process. class DebugObjectRegistrar { public: - virtual Error registerDebugObject(ExecutorAddrRange TargetMem) = 0; + virtual Error registerDebugObject(ExecutorAddrRange TargetMem, + bool AutoRegisterCode) = 0; virtual ~DebugObjectRegistrar() = default; }; @@ -42,7 +43,8 @@ EPCDebugObjectRegistrar(ExecutionSession &ES, ExecutorAddr RegisterFn) : ES(ES), RegisterFn(RegisterFn) {} - Error registerDebugObject(ExecutorAddrRange TargetMem) override; + Error registerDebugObject(ExecutorAddrRange TargetMem, + bool AutoRegisterCode) override; private: ExecutionSession &ES; diff --git a/llvm/lib/ExecutionEngine/Orc/DebugObjectManagerPlugin.cpp b/llvm/lib/ExecutionEngine/Orc/DebugObjectManagerPlugin.cpp --- a/llvm/lib/ExecutionEngine/Orc/DebugObjectManagerPlugin.cpp +++ b/llvm/lib/ExecutionEngine/Orc/DebugObjectManagerPlugin.cpp @@ -389,13 +389,14 @@ DebugObjectManagerPlugin::DebugObjectManagerPlugin( ExecutionSession &ES, std::unique_ptr Target, - bool RequireDebugSections) + bool RequireDebugSections, bool AutoRegisterCode) : ES(ES), Target(std::move(Target)), - RequireDebugSections(RequireDebugSections) {} + RequireDebugSections(RequireDebugSections), + AutoRegisterCode(AutoRegisterCode) {} DebugObjectManagerPlugin::DebugObjectManagerPlugin( ExecutionSession &ES, std::unique_ptr Target) - : DebugObjectManagerPlugin(ES, std::move(Target), true) {} + : DebugObjectManagerPlugin(ES, std::move(Target), true, true) {} DebugObjectManagerPlugin::~DebugObjectManagerPlugin() = default; @@ -464,7 +465,8 @@ FinalizePromise.set_value(TargetMem.takeError()); return; } - if (Error Err = Target->registerDebugObject(*TargetMem)) { + if (Error Err = + Target->registerDebugObject(*TargetMem, AutoRegisterCode)) { FinalizePromise.set_value(std::move(Err)); return; } diff --git a/llvm/lib/ExecutionEngine/Orc/DebuggerSupportPlugin.cpp b/llvm/lib/ExecutionEngine/Orc/DebuggerSupportPlugin.cpp --- a/llvm/lib/ExecutionEngine/Orc/DebuggerSupportPlugin.cpp +++ b/llvm/lib/ExecutionEngine/Orc/DebuggerSupportPlugin.cpp @@ -348,11 +348,12 @@ Writer.write(SecCmd); } + static constexpr bool AutoRegisterCode = true; SectionRange R(MachOContainerBlock->getSection()); G.allocActions().push_back( {cantFail(shared::WrapperFunctionCall::Create< - shared::SPSArgList>( - RegisterActionAddr, R.getRange())), + shared::SPSArgList>( + RegisterActionAddr, R.getRange(), AutoRegisterCode)), {}}); return Error::success(); } diff --git a/llvm/lib/ExecutionEngine/Orc/EPCDebugObjectRegistrar.cpp b/llvm/lib/ExecutionEngine/Orc/EPCDebugObjectRegistrar.cpp --- a/llvm/lib/ExecutionEngine/Orc/EPCDebugObjectRegistrar.cpp +++ b/llvm/lib/ExecutionEngine/Orc/EPCDebugObjectRegistrar.cpp @@ -48,10 +48,10 @@ return std::make_unique(ES, (*Result)[0][0]); } -Error EPCDebugObjectRegistrar::registerDebugObject( - ExecutorAddrRange TargetMem) { - return ES.callSPSWrapper(RegisterFn, - TargetMem); +Error EPCDebugObjectRegistrar::registerDebugObject(ExecutorAddrRange TargetMem, + bool AutoRegisterCode) { + return ES.callSPSWrapper( + RegisterFn, TargetMem, AutoRegisterCode); } } // namespace orc diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.cpp --- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.cpp +++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.cpp @@ -67,9 +67,9 @@ using namespace llvm::orc; // Register debug object, return error message or null for success. -static void registerJITLoaderGDBImpl(const char *ObjAddr, size_t Size) { +static void appendJITDebugDescriptor(const char *ObjAddr, size_t Size) { LLVM_DEBUG({ - dbgs() << "Registering debug object with GDB JIT interface " + dbgs() << "Adding debug object to GDB JIT interface " << formatv("([{0:x16} -- {1:x16}])", reinterpret_cast(ObjAddr), reinterpret_cast(ObjAddr + Size)) @@ -94,20 +94,20 @@ __jit_debug_descriptor.first_entry = E; __jit_debug_descriptor.relevant_entry = E; - - // Run into the rendezvous breakpoint. __jit_debug_descriptor.action_flag = JIT_REGISTER_FN; - __jit_debug_register_code(); } extern "C" orc::shared::CWrapperFunctionResult llvm_orc_registerJITLoaderGDBAllocAction(const char *Data, size_t Size) { using namespace orc::shared; - return WrapperFunction::handle( + return WrapperFunction::handle( Data, Size, - [](ExecutorAddrRange R) { - registerJITLoaderGDBImpl(R.Start.toPtr(), + [](ExecutorAddrRange R, bool AutoRegisterCode) { + appendJITDebugDescriptor(R.Start.toPtr(), R.size()); + // Run into the rendezvous breakpoint. + if (AutoRegisterCode) + __jit_debug_register_code(); return Error::success(); }) .release(); @@ -116,11 +116,14 @@ extern "C" orc::shared::CWrapperFunctionResult llvm_orc_registerJITLoaderGDBWrapper(const char *Data, uint64_t Size) { using namespace orc::shared; - return WrapperFunction::handle( + return WrapperFunction::handle( Data, Size, - [](ExecutorAddrRange R) { - registerJITLoaderGDBImpl(R.Start.toPtr(), + [](ExecutorAddrRange R, bool AutoRegisterCode) { + appendJITDebugDescriptor(R.Start.toPtr(), R.size()); + // Run into the rendezvous breakpoint. + if (AutoRegisterCode) + __jit_debug_register_code(); return Error::success(); }) .release(); diff --git a/llvm/tools/lli/lli.cpp b/llvm/tools/lli/lli.cpp --- a/llvm/tools/lli/lli.cpp +++ b/llvm/tools/lli/lli.cpp @@ -938,7 +938,7 @@ L->addPlugin(std::make_unique( ES, ExitOnErr(orc::EPCEHFrameRegistrar::Create(ES)))); L->addPlugin(std::make_unique( - ES, ExitOnErr(orc::createJITLoaderGDBRegistrar(ES)))); + ES, ExitOnErr(orc::createJITLoaderGDBRegistrar(ES)), true, true)); } return L; }); diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp --- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp +++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp @@ -1027,7 +1027,7 @@ ES, ExitOnErr(EPCEHFrameRegistrar::Create(this->ES)))); if (DebuggerSupport) ObjLayer.addPlugin(std::make_unique( - ES, ExitOnErr(createJITLoaderGDBRegistrar(this->ES)))); + ES, ExitOnErr(createJITLoaderGDBRegistrar(this->ES)), true, true)); } ObjLayer.addPlugin(std::make_unique(*this));