Run only dtors of the unloaded entities.

This commit is contained in:
Vassil Vassilev 2014-02-27 09:53:42 +01:00 committed by sftnight
parent 1bf7c49086
commit 150231c357
3 changed files with 49 additions and 6 deletions

View File

@ -310,15 +310,25 @@ IncrementalExecutor::runStaticInitializersOnce(llvm::Module* m) {
return kExeSuccess;
}
void
IncrementalExecutor::runStaticDestructorsOnce() {
void IncrementalExecutor::runAndRemoveStaticDestructors(Transaction* T) {
assert(T && "Must be set");
// Collect all the dtors bound to this transaction.
AtExitFunctions boundToT;
for (AtExitFunctions::iterator I = m_AtExitFuncs.begin();
I != m_AtExitFuncs.end();)
if (I->m_FromT == T) {
boundToT.push_back(*I);
I = m_AtExitFuncs.erase(I);
}
else
++I;
// 'Unload' the cxa_atexit entities.
for (AtExitFunctions::reverse_iterator I = m_AtExitFuncs.rbegin(),
E = m_AtExitFuncs.rend(); I != E; ++I) {
for (AtExitFunctions::reverse_iterator I = boundToT.rbegin(),
E = boundToT.rend(); I != E; ++I) {
const CXAAtExitElement& AEE = *I;
(*AEE.m_Func)(AEE.m_Arg);
}
m_AtExitFuncs.clear();
}
void

View File

@ -130,7 +130,12 @@ namespace cling {
}
ExecutionResult runStaticInitializersOnce(llvm::Module* m);
void runStaticDestructorsOnce();
///\brief Runs all destructors bound to the given transaction and removes
/// them from the list.
///\param[in] T - Transaction to which the dtors were bound.
///
void runAndRemoveStaticDestructors(Transaction* T);
ExecutionResult executeFunction(llvm::StringRef function,
StoredValueRef* returnValue = 0);

View File

@ -0,0 +1,28 @@
//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------
// RUN: cat %s | %cling 2>&1 | FileCheck %s
extern "C" int printf(const char* fmt, ...);
.storeState "preUnload"
class ClassWithDtor{
private:
int N;
public:
ClassWithDtor() : N(0){ N++; }
~ClassWithDtor() {
N--;
printf("Dtor called, N=%d\n", N);
}
}; ClassWithDtor m;
.U
//CHECK: Dtor called, N=0
.compareState "preUnload"
//CHECK-NOT: Differences
.q