Skip to content

Commit 7bd481d

Browse files
committed
[ORC] Add ExecutionSession::removeJITDylibs (plural), use it in endSession.
The ExecutionSession::removeJITDylibs operation will remove all JITDylibs in the given list (i.e. first clear them, then remove them from the session). ExecutionSession::endSession is updated to remove JITDylibs rather than just clearing them. This prevents new code from being added to any JITDylib once endSession has been called.
1 parent d467396 commit 7bd481d

File tree

2 files changed

+54
-41
lines changed
  • llvm

2 files changed

+54
-41
lines changed

llvm/include/llvm/ExecutionEngine/Orc/Core.h

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1465,17 +1465,29 @@ class ExecutionSession {
14651465
/// If no Platform is attached this call is equivalent to createBareJITDylib.
14661466
Expected<JITDylib &> createJITDylib(std::string Name);
14671467

1468-
/// Closes the given JITDylib.
1468+
/// Removes the given JITDylibs from the ExecutionSession.
14691469
///
1470-
/// This method clears all resources held for the JITDylib, puts it in the
1471-
/// closed state, and clears all references held by the ExecutionSession and
1472-
/// other JITDylibs. No further code can be added to the JITDylib, and the
1473-
/// object will be freed once any remaining JITDylibSPs to it are destroyed.
1470+
/// This method clears all resources held for the JITDylibs, puts them in the
1471+
/// closed state, and clears all references to them that are held by the
1472+
/// ExecutionSession or other JITDylibs. No further code can be added to the
1473+
/// removed JITDylibs, and the JITDylib objects will be freed once any
1474+
/// remaining JITDylibSPs pointing to them are destroyed.
14741475
///
1475-
/// This method does *not* run static destructors.
1476+
/// This method does *not* run static destructors for code contained in the
1477+
/// JITDylibs, and each JITDylib can only be removed once.
14761478
///
1477-
/// This method can only be called once for each JITDylib.
1478-
Error removeJITDylib(JITDylib &JD);
1479+
/// JITDylibs will be removed in the order given. Teardown is usually
1480+
/// independent for each JITDylib, but not always. In particular, where the
1481+
/// ORC runtime is used it is expected that teardown off all JITDylibs will
1482+
/// depend on it, so the JITDylib containing the ORC runtime must be removed
1483+
/// last. If the client has introduced any other dependencies they should be
1484+
/// accounted for in the removal order too.
1485+
Error removeJITDylibs(std::vector<JITDylibSP> JDsToRemove);
1486+
1487+
/// Calls removeJTIDylibs on the gives JITDylib.
1488+
Error removeJITDylib(JITDylib &JD) {
1489+
return removeJITDylibs(std::vector<JITDylibSP>({&JD}));
1490+
}
14791491

14801492
/// Set the error reporter function.
14811493
ExecutionSession &setErrorReporter(ErrorReporter ReportError) {

llvm/lib/ExecutionEngine/Orc/Core.cpp

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,16 +1918,14 @@ ExecutionSession::~ExecutionSession() {
19181918
Error ExecutionSession::endSession() {
19191919
LLVM_DEBUG(dbgs() << "Ending ExecutionSession " << this << "\n");
19201920

1921-
std::vector<JITDylibSP> JITDylibsToClose = runSessionLocked([&] {
1921+
auto JDsToRemove = runSessionLocked([&] {
19221922
SessionOpen = false;
1923-
return std::move(JDs);
1923+
return JDs;
19241924
});
19251925

1926-
// TODO: notifiy platform? run static deinits?
1926+
std::reverse(JDsToRemove.begin(), JDsToRemove.end());
19271927

1928-
Error Err = Error::success();
1929-
for (auto &JD : reverse(JITDylibsToClose))
1930-
Err = joinErrors(std::move(Err), JD->clear());
1928+
auto Err = removeJITDylibs(std::move(JDsToRemove));
19311929

19321930
Err = joinErrors(std::move(Err), EPC->disconnect());
19331931

@@ -1977,42 +1975,45 @@ Expected<JITDylib &> ExecutionSession::createJITDylib(std::string Name) {
19771975
return JD;
19781976
}
19791977

1980-
Error ExecutionSession::removeJITDylib(JITDylib &JD) {
1981-
// Keep JD alive throughout this routine, even if all other references
1982-
// have been dropped.
1983-
JITDylibSP JDKeepAlive = &JD;
1978+
Error ExecutionSession::removeJITDylibs(std::vector<JITDylibSP> JDsToRemove) {
19841979

19851980
// Set JD to 'Closing' state and remove JD from the ExecutionSession.
19861981
runSessionLocked([&] {
1987-
assert(JD.State == JITDylib::Open && "JD already closed");
1988-
JD.State = JITDylib::Closing;
1989-
auto I = llvm::find(JDs, &JD);
1990-
assert(I != JDs.end() && "JD does not appear in session JDs");
1991-
JDs.erase(I);
1982+
for (auto &JD : JDsToRemove) {
1983+
assert(JD->State == JITDylib::Open && "JD already closed");
1984+
JD->State = JITDylib::Closing;
1985+
auto I = llvm::find(JDs, JD);
1986+
assert(I != JDs.end() && "JD does not appear in session JDs");
1987+
JDs.erase(I);
1988+
}
19921989
});
19931990

1994-
// Clear the JITDylib. Hold on to any error while we clean up the
1995-
// JITDylib members below.
1996-
auto Err = JD.clear();
1997-
1998-
// Notify the platform of the teardown.
1999-
if (P)
2000-
Err = joinErrors(std::move(Err), P->teardownJITDylib(JD));
1991+
// Clear JITDylibs and notify the platform.
1992+
Error Err = Error::success();
1993+
for (auto JD : JDsToRemove) {
1994+
dbgs() << "---REMOVING--- " << JD->getName() << "\n";
1995+
Err = joinErrors(std::move(Err), JD->clear());
1996+
if (P)
1997+
Err = joinErrors(std::move(Err), P->teardownJITDylib(*JD));
1998+
}
20011999

20022000
// Set JD to closed state. Clear remaining data structures.
20032001
runSessionLocked([&] {
2004-
assert(JD.State == JITDylib::Closing && "JD should be closing");
2005-
JD.State = JITDylib::Closed;
2006-
assert(JD.Symbols.empty() && "JD.Symbols is not empty after clear");
2007-
assert(JD.UnmaterializedInfos.empty() &&
2008-
"JD.UnmaterializedInfos is not empty after clear");
2009-
assert(JD.MaterializingInfos.empty() &&
2010-
"JD.MaterializingInfos is not empty after clear");
2011-
assert(JD.TrackerSymbols.empty() &&
2012-
"TrackerSymbols is not empty after clear");
2013-
JD.DefGenerators.clear();
2014-
JD.LinkOrder.clear();
2002+
for (auto &JD : JDsToRemove) {
2003+
assert(JD->State == JITDylib::Closing && "JD should be closing");
2004+
JD->State = JITDylib::Closed;
2005+
assert(JD->Symbols.empty() && "JD.Symbols is not empty after clear");
2006+
assert(JD->UnmaterializedInfos.empty() &&
2007+
"JD.UnmaterializedInfos is not empty after clear");
2008+
assert(JD->MaterializingInfos.empty() &&
2009+
"JD.MaterializingInfos is not empty after clear");
2010+
assert(JD->TrackerSymbols.empty() &&
2011+
"TrackerSymbols is not empty after clear");
2012+
JD->DefGenerators.clear();
2013+
JD->LinkOrder.clear();
2014+
}
20152015
});
2016+
20162017
return Err;
20172018
}
20182019

0 commit comments

Comments
 (0)