Index: include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h =================================================================== --- include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -172,6 +172,11 @@ return nullptr; } + void removeModulesFromBaseLayer(BaseLayerT &BaseLayer) { + for (auto &BLH : BaseLayerHandles) + BaseLayer.removeModuleSet(BLH); + } + std::unique_ptr ExternalSymbolResolver; std::unique_ptr> MemMgr; std::unique_ptr StubsMgr; @@ -204,6 +209,11 @@ CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)), CloneStubsIntoPartitions(CloneStubsIntoPartitions) {} + ~CompileOnDemandLayer() { + while (!LogicalDylibs.empty()) + removeModuleSet(LogicalDylibs.begin()); + } + /// @brief Add a module to the compile-on-demand layer. template @@ -239,6 +249,7 @@ /// This will remove all modules in the layers below that were derived from /// the module represented by H. void removeModuleSet(ModuleSetHandleT H) { + H->removeModulesFromBaseLayer(BaseLayer); LogicalDylibs.erase(H); } @@ -478,6 +489,8 @@ return 0; } + LD.BaseLayerHandles.push_back(PartH); + return CalledAddr; } Index: include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h =================================================================== --- include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h +++ include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h @@ -144,16 +144,16 @@ void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override { - UnfinalizedEHFrames.push_back( - std::make_pair(LoadAddr, static_cast(Size))); + UnfinalizedEHFrames.push_back({LoadAddr, static_cast(Size)}); } - void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, - size_t Size) override { - auto Err = Client.deregisterEHFrames(LoadAddr, Size); - // FIXME: Add error poll. - assert(!Err && "Failed to register remote EH frames."); - (void)Err; + void deregisterEHFrames() override { + for (auto &Frame : RegisteredEHFrames) { + auto Err = Client.deregisterEHFrames(Frame.Addr, Frame.Size); + // FIXME: Add error poll. + assert(!Err && "Failed to register remote EH frames."); + (void)Err; + } } void notifyObjectLoaded(RuntimeDyld &Dyld, @@ -320,7 +320,7 @@ Unfinalized.clear(); for (auto &EHFrame : UnfinalizedEHFrames) { - if (auto Err = Client.registerEHFrames(EHFrame.first, EHFrame.second)) { + if (auto Err = Client.registerEHFrames(EHFrame.Addr, EHFrame.Size)) { // FIXME: Replace this once finalizeMemory can return an Error. handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) { if (ErrMsg) { @@ -331,7 +331,8 @@ return false; } } - UnfinalizedEHFrames.clear(); + RegisteredEHFrames = std::move(UnfinalizedEHFrames); + UnfinalizedEHFrames = std::vector(); return false; } @@ -387,7 +388,13 @@ ResourceIdMgr::ResourceId Id; std::vector Unmapped; std::vector Unfinalized; - std::vector> UnfinalizedEHFrames; + + struct EHFrame { + JITTargetAddress Addr; + uint32_t Size; + }; + std::vector UnfinalizedEHFrames; + std::vector RegisteredEHFrames; }; /// Remote indirect stubs manager. Index: include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h =================================================================== --- include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h +++ include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h @@ -120,6 +120,10 @@ buildInitialSymbolTable(PFC->Objects); } + ~ConcreteLinkedObjectSet() override { + MemMgr->deregisterEHFrames(); + } + void setHandle(ObjSetHandleT H) { PFC->Handle = H; } Index: include/llvm/ExecutionEngine/RTDyldMemoryManager.h =================================================================== --- include/llvm/ExecutionEngine/RTDyldMemoryManager.h +++ include/llvm/ExecutionEngine/RTDyldMemoryManager.h @@ -69,14 +69,9 @@ /// Deregister EH frames in the current proces. static void deregisterEHFramesInProcess(uint8_t *Addr, size_t Size); - void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override { - registerEHFramesInProcess(Addr, Size); - } + void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override; + void deregisterEHFrames() override; - void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override { - deregisterEHFramesInProcess(Addr, Size); - } - /// This method returns the address of the specified function or variable in /// the current process. static uint64_t getSymbolAddressInProcess(const std::string &Name); @@ -139,6 +134,13 @@ /// MCJIT or RuntimeDyld. Use getSymbolAddress instead. virtual void *getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure = true); + +private: + struct EHFrame { + uint8_t *Addr; + uint64_t Size; + }; + std::vector EHFrames; }; // Create wrappers for C Binding types (see CBindingWrapping.h). Index: include/llvm/ExecutionEngine/RuntimeDyld.h =================================================================== --- include/llvm/ExecutionEngine/RuntimeDyld.h +++ include/llvm/ExecutionEngine/RuntimeDyld.h @@ -150,8 +150,7 @@ /// be the case for local execution) these two values will be the same. virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) = 0; - virtual void deregisterEHFrames(uint8_t *addr, uint64_t LoadAddr, - size_t Size) = 0; + virtual void deregisterEHFrames() = 0; /// This method is called when object loading is complete and section page /// permissions can be applied. It is up to the memory manager implementation Index: lib/ExecutionEngine/Orc/OrcMCJITReplacement.h =================================================================== --- lib/ExecutionEngine/Orc/OrcMCJITReplacement.h +++ lib/ExecutionEngine/Orc/OrcMCJITReplacement.h @@ -94,9 +94,8 @@ return ClientMM->registerEHFrames(Addr, LoadAddr, Size); } - void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, - size_t Size) override { - return ClientMM->deregisterEHFrames(Addr, LoadAddr, Size); + void deregisterEHFrames() override { + return ClientMM->deregisterEHFrames(); } void notifyObjectLoaded(RuntimeDyld &RTDyld, Index: lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp =================================================================== --- lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp +++ lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp @@ -134,6 +134,18 @@ #endif +void RTDyldMemoryManager::registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, + size_t Size) { + registerEHFramesInProcess(Addr, Size); + EHFrames.push_back({Addr, Size}); +} + +void RTDyldMemoryManager::deregisterEHFrames() { + for (auto &Frame : EHFrames) + deregisterEHFramesInProcess(Frame.Addr, Frame.Size); + EHFrames.clear(); +} + static int jit_noop() { return 0; } Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp =================================================================== --- lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -73,7 +73,9 @@ void RuntimeDyldImpl::registerEHFrames() {} -void RuntimeDyldImpl::deregisterEHFrames() {} +void RuntimeDyldImpl::deregisterEHFrames() { + MemMgr.deregisterEHFrames(); +} #ifndef NDEBUG static void dumpSectionMemory(const SectionEntry &S, StringRef State) { Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h =================================================================== --- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -149,7 +149,6 @@ // in a table until we receive a request to register all unregistered // EH frame sections with the memory manager. SmallVector UnregisteredEHFrameSections; - SmallVector RegisteredEHFrameSections; // Map between GOT relocation value and corresponding GOT offset std::map GOTOffsetMap; @@ -177,7 +176,6 @@ StubMap &Stubs) override; bool isCompatibleFile(const object::ObjectFile &Obj) const override; void registerEHFrames() override; - void deregisterEHFrames() override; Error finalizeLoad(const ObjectFile &Obj, ObjSectionToIDMap &SectionMap) override; }; Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp =================================================================== --- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -221,22 +221,10 @@ uint64_t EHFrameLoadAddr = Sections[EHFrameSID].getLoadAddress(); size_t EHFrameSize = Sections[EHFrameSID].getSize(); MemMgr.registerEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize); - RegisteredEHFrameSections.push_back(EHFrameSID); } UnregisteredEHFrameSections.clear(); } -void RuntimeDyldELF::deregisterEHFrames() { - for (int i = 0, e = RegisteredEHFrameSections.size(); i != e; ++i) { - SID EHFrameSID = RegisteredEHFrameSections[i]; - uint8_t *EHFrameAddr = Sections[EHFrameSID].getAddress(); - uint64_t EHFrameLoadAddr = Sections[EHFrameSID].getLoadAddress(); - size_t EHFrameSize = Sections[EHFrameSID].getSize(); - MemMgr.deregisterEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize); - } - RegisteredEHFrameSections.clear(); -} - std::unique_ptr llvm::RuntimeDyldELF::create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr, Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h =================================================================== --- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -515,7 +515,7 @@ virtual void registerEHFrames(); - virtual void deregisterEHFrames(); + void deregisterEHFrames(); virtual Error finalizeLoad(const ObjectFile &ObjImg, ObjSectionToIDMap &SectionMap) { Index: lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h =================================================================== --- lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h +++ lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h @@ -217,7 +217,6 @@ } void registerEHFrames() override {} - void deregisterEHFrames() override {} }; } Index: lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h =================================================================== --- lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h +++ lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h @@ -316,7 +316,6 @@ } void registerEHFrames() override {} - void deregisterEHFrames() override {} }; } Index: lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h =================================================================== --- lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h +++ lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h @@ -194,9 +194,6 @@ } UnregisteredEHFrameSections.clear(); } - void deregisterEHFrames() override { - // Stub - } Error finalizeLoad(const ObjectFile &Obj, ObjSectionToIDMap &SectionMap) override { // Look for and record the EH frame section IDs. Index: tools/lli/RemoteJITUtils.h =================================================================== --- tools/lli/RemoteJITUtils.h +++ tools/lli/RemoteJITUtils.h @@ -118,9 +118,8 @@ MemMgr->registerEHFrames(Addr, LoadAddr, Size); } - void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, - size_t Size) override { - MemMgr->deregisterEHFrames(Addr, LoadAddr, Size); + void deregisterEHFrames() override { + MemMgr->deregisterEHFrames(); } bool finalizeMemory(std::string *ErrMsg = nullptr) override { Index: tools/llvm-rtdyld/llvm-rtdyld.cpp =================================================================== --- tools/llvm-rtdyld/llvm-rtdyld.cpp +++ tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -175,8 +175,7 @@ void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override {} - void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, - size_t Size) override {} + void deregisterEHFrames() override {} void preallocateSlab(uint64_t Size) { std::string Err; Index: unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp =================================================================== --- unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp +++ unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp @@ -304,7 +304,7 @@ return nullptr; } void registerEHFrames(uint8_t *, uint64_t, size_t) override {} - void deregisterEHFrames(uint8_t *, uint64_t, size_t) override {} + void deregisterEHFrames() override {} bool finalizeMemory(std::string *) override { return false; } }; Index: unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp =================================================================== --- unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp +++ unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp @@ -90,7 +90,8 @@ Objs.push_back(OwningObj.getBinary()); bool DebugSectionSeen = false; - SectionMemoryManagerWrapper SMMW(DebugSectionSeen); + auto SMMW = + std::make_shared(DebugSectionSeen); auto Resolver = createLambdaResolver( [](const std::string &Name) { @@ -102,7 +103,7 @@ { // Test with ProcessAllSections = false (the default). - auto H = ObjLayer.addObjectSet(Objs, &SMMW, &*Resolver); + auto H = ObjLayer.addObjectSet(Objs, SMMW, &*Resolver); ObjLayer.emitAndFinalize(H); EXPECT_EQ(DebugSectionSeen, false) << "Unexpected debug info section"; @@ -112,7 +113,7 @@ { // Test with ProcessAllSections = true. ObjLayer.setProcessAllSections(true); - auto H = ObjLayer.addObjectSet(Objs, &SMMW, &*Resolver); + auto H = ObjLayer.addObjectSet(Objs, SMMW, &*Resolver); ObjLayer.emitAndFinalize(H); EXPECT_EQ(DebugSectionSeen, true) << "Expected debug info section not seen"; @@ -178,14 +179,15 @@ return JITSymbol(nullptr); }); - SectionMemoryManagerWrapper SMMW; - ObjLayer.addObjectSet(std::move(Obj1Set), &SMMW, &*Resolver); - auto H = ObjLayer.addObjectSet(std::move(Obj2Set), &SMMW, &*Resolver); + auto SMMW = std::make_shared(); + ObjLayer.addObjectSet(std::move(Obj1Set), SMMW, &*Resolver); + auto H = ObjLayer.addObjectSet(std::move(Obj2Set), SMMW, &*Resolver); ObjLayer.emitAndFinalize(H); - + ObjLayer.removeObjectSet(H); + // Finalization of module 2 should trigger finalization of module 1. // Verify that finalize on SMMW is only called once. - EXPECT_EQ(SMMW.FinalizationCount, 1) + EXPECT_EQ(SMMW->FinalizationCount, 1) << "Extra call to finalize"; } @@ -238,14 +240,15 @@ std::vector Obj2Set; Obj2Set.push_back(Obj2.getBinary()); - SectionMemoryManagerWrapper SMMW; + auto SMMW = std::make_shared(); NullResolver NR; - auto H = ObjLayer.addObjectSet(std::move(Obj1Set), &SMMW, &NR); - ObjLayer.addObjectSet(std::move(Obj2Set), &SMMW, &NR); + auto H = ObjLayer.addObjectSet(std::move(Obj1Set), SMMW, &NR); + ObjLayer.addObjectSet(std::move(Obj2Set), SMMW, &NR); ObjLayer.emitAndFinalize(H); - + ObjLayer.removeObjectSet(H); + // Only one call to needsToReserveAllocationSpace should have been made. - EXPECT_EQ(SMMW.NeedsToReserveAllocationSpaceCount, 1) + EXPECT_EQ(SMMW->NeedsToReserveAllocationSpaceCount, 1) << "More than one call to needsToReserveAllocationSpace " "(multiple unrelated objects loaded prior to finalization)"; }