Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion interpreter/cling/lib/Interpreter/CIFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1622,7 +1622,9 @@ namespace {
for (auto& E : moduleExtensions)
FrontendOpts.ModuleFileExtensions.push_back(E);

FrontendOpts.DisableFree = true;
// The clang driver adds -disable-free to every cc1 line.
// Interpreter::ShutDown() should free the frontend.
FrontendOpts.DisableFree = false;

// Set up compiler language and target
if (!SetupCompiler(CI.get(), COpts, InitLang, InitTarget))
Expand Down
30 changes: 21 additions & 9 deletions interpreter/cling/lib/Interpreter/IncrementalJIT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ namespace {
bool needsToReserveAllocationSpace() override { return true; }
};

/// A JITLinkMemoryManager for Cling that never frees its allocations.
/// A JITLinkMemoryManager for Cling.
class ClingJITLinkMemoryManager : public InProcessMemoryManager {
public:
using InProcessMemoryManager::InProcessMemoryManager;
Expand All @@ -273,16 +273,28 @@ namespace {
// Disabled until CallFunc is informed about unloading, and can
// re-generate the wrapper (if the decl is still available). See
// https://github.com/root-project/root/issues/10898

// We still have to release the allocations which resets their addresses
// to FinalizedAlloc::InvalidAddr, or the assertion in ~FinalizedAlloc
// will be unhappy...
for (auto &Alloc : Allocs) {
Alloc.release();
}
// Pretend we successfully deallocated everything...
//
// Releasing the handles orphans each allocation's vector of JITLink
// dealloc actions. Retain them (required for CallFunc) and let the
// base class free everything when this manager is destroyed at
// interpreter teardown.
std::lock_guard<std::mutex> G(m_RetainedMutex);
for (auto& Alloc : Allocs)
m_Retained.push_back(std::move(Alloc));
OnDeallocated(Error::success());
}

~ClingJITLinkMemoryManager() override {
if (!m_Retained.empty())
InProcessMemoryManager::deallocate(std::move(m_Retained),
[](Error Err) {
consumeError(std::move(Err));
});
}

private:
std::mutex m_RetainedMutex;
std::vector<FinalizedAlloc> m_Retained;
};

/// A DynamicLibrarySearchGenerator that uses ResourceTracker to remember
Expand Down
2 changes: 2 additions & 0 deletions interpreter/cling/lib/Interpreter/IncrementalParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,8 @@ namespace cling {
return Result.getLocWithOffset(m_VirtualFileLocOffset++);
}

void IncrementalParser::destroyParser() { m_Parser.reset(); }

IncrementalParser::~IncrementalParser() {
Transaction* T = const_cast<Transaction*>(getFirstTransaction());
while (T) {
Expand Down
4 changes: 4 additions & 0 deletions interpreter/cling/lib/Interpreter/IncrementalParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ namespace cling {
bool isChildInterpreter);
clang::CompilerInstance* getCI() const { return m_CI.get(); }
clang::Parser* getParser() const { return m_Parser.get(); }

///\brief Destroy the Parser. It writes to Sema in its destructor, so
/// it must go before Interpreter::ShutDown() frees Sema.
void destroyParser();
clang::CodeGenerator* getCodeGenerator() const { return m_CodeGen; }
bool hasCodeGenerator() const { return m_CodeGen; }

Expand Down
11 changes: 7 additions & 4 deletions interpreter/cling/lib/Interpreter/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,11 @@ namespace cling {
CI->resetAndLeakASTContext();
llvm::BuryPointer(CI->takeASTConsumer().get());
} else {
// The Parser writes to Sema in its destructor, so it must go
// first; Sema, the ASTContext and the consumer are freed here,
// while the diagnostic client and the interpreter callbacks are
// still alive -- ~Sema and ~ASTContext reach both.
m_IncrParser->destroyParser();
CI->setSema(nullptr);
CI->setASTContext(nullptr);
CI->setASTConsumer(nullptr);
Expand All @@ -625,11 +630,9 @@ namespace cling {
CI->resetAndLeakPreprocessor();
CI->resetAndLeakSourceManager();
CI->resetAndLeakFileManager();
} else {
CI->setPreprocessor(nullptr);
CI->setSourceManager(nullptr);
CI->setFileManager(nullptr);
}
// ~CompilerInstance destroys the Preprocessor, SourceManager and
// FileManager in the right order.
}

LO.setCompilingModule(clang::LangOptions::CMK_None);
Expand Down