2012-09-05 13:37:39 +04:00
//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author: Axel Naumann <axel@cern.ch>
2014-01-07 14:08:37 +04:00
//
// 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.
2012-09-05 13:37:39 +04:00
//------------------------------------------------------------------------------
2014-02-19 15:49:24 +04:00
# include "IncrementalExecutor.h"
2012-09-05 13:37:39 +04:00
2014-05-26 18:33:43 +04:00
# include "cling/Interpreter/Value.h"
Provide __cxa_atexit replacement through custom MemoryManager.
On some platforms, global destructors are registered through a call to
__cxa_atexit(dtor, 0/*args*/, __dso_handle). While __cxa_atexit can be resolved
by the regular MemoryManager, __dso_handle (representing the "current shared
library" such that the corresponding atexit function can be called on its
dlclose) can not be resolved by MCJIT. Instead, we provide our own, poining to
the ExecutionEngine, which in turn holds a "current module" that corresponds in
spirit to the shared library handle.
__cxa_atexit, on the other hand, needs to be re-wired: the interpreter needs to
destruct globals upon its destruction, and those globals from a certain module
when that module is unloaded.
Both is done through a custom MemoryManager, significantly reducing the
complexity of the previous ("JIT without MC") implementation.
The custom MemoryManager also forwards in case of a unknown symbols to the LazyFunctionCreators instead of using the generic
ExecutionEngine::InstallLazyFunctionCreator() which has no effect with MCJIT.
2015-01-08 15:54:22 +03:00
# include "cling/Interpreter/Transaction.h"
2014-05-26 18:33:43 +04:00
2014-05-28 15:56:16 +04:00
# include "clang/Basic/Diagnostic.h"
2013-04-24 20:28:08 +04:00
# include "llvm/IR/Constants.h"
2014-03-15 02:11:09 +04:00
# include "llvm/IR/Instructions.h"
2013-11-01 21:31:18 +04:00
# include "llvm/IR/LLVMContext.h"
2013-04-24 20:28:08 +04:00
# include "llvm/IR/Module.h"
2012-09-05 13:37:39 +04:00
# include "llvm/PassManager.h"
2012-11-17 20:28:14 +04:00
# include "llvm/ADT/SmallPtrSet.h"
2013-02-22 19:59:54 +04:00
# include "llvm/ExecutionEngine/GenericValue.h"
Provide __cxa_atexit replacement through custom MemoryManager.
On some platforms, global destructors are registered through a call to
__cxa_atexit(dtor, 0/*args*/, __dso_handle). While __cxa_atexit can be resolved
by the regular MemoryManager, __dso_handle (representing the "current shared
library" such that the corresponding atexit function can be called on its
dlclose) can not be resolved by MCJIT. Instead, we provide our own, poining to
the ExecutionEngine, which in turn holds a "current module" that corresponds in
spirit to the shared library handle.
__cxa_atexit, on the other hand, needs to be re-wired: the interpreter needs to
destruct globals upon its destruction, and those globals from a certain module
when that module is unloaded.
Both is done through a custom MemoryManager, significantly reducing the
complexity of the previous ("JIT without MC") implementation.
The custom MemoryManager also forwards in case of a unknown symbols to the LazyFunctionCreators instead of using the generic
ExecutionEngine::InstallLazyFunctionCreator() which has no effect with MCJIT.
2015-01-08 15:54:22 +03:00
# include "llvm/ExecutionEngine/MCJIT.h"
# include "llvm/ExecutionEngine/SectionMemoryManager.h"
2012-09-05 13:37:39 +04:00
# include "llvm/Support/raw_ostream.h"
# include "llvm/Support/DynamicLibrary.h"
2014-03-07 18:09:02 +04:00
using namespace llvm ;
Provide __cxa_atexit replacement through custom MemoryManager.
On some platforms, global destructors are registered through a call to
__cxa_atexit(dtor, 0/*args*/, __dso_handle). While __cxa_atexit can be resolved
by the regular MemoryManager, __dso_handle (representing the "current shared
library" such that the corresponding atexit function can be called on its
dlclose) can not be resolved by MCJIT. Instead, we provide our own, poining to
the ExecutionEngine, which in turn holds a "current module" that corresponds in
spirit to the shared library handle.
__cxa_atexit, on the other hand, needs to be re-wired: the interpreter needs to
destruct globals upon its destruction, and those globals from a certain module
when that module is unloaded.
Both is done through a custom MemoryManager, significantly reducing the
complexity of the previous ("JIT without MC") implementation.
The custom MemoryManager also forwards in case of a unknown symbols to the LazyFunctionCreators instead of using the generic
ExecutionEngine::InstallLazyFunctionCreator() which has no effect with MCJIT.
2015-01-08 15:54:22 +03:00
namespace {
class ClingMemoryManager : public SectionMemoryManager {
cling : : IncrementalExecutor * m_exe ;
static void local_cxa_atexit ( void ( * func ) ( void * ) , void * arg , void * dso ) {
cling : : IncrementalExecutor * exe = ( cling : : IncrementalExecutor * ) dso ;
exe - > AddAtExitFunc ( func , arg ) ;
}
public :
ClingMemoryManager ( cling : : IncrementalExecutor * Exe ) :
m_exe ( Exe ) { }
///\brief Return the address of a symbol, use callbacks if needed.
uint64_t getSymbolAddress ( const std : : string & Name ) override ;
///\brief Simply wraps the base class's function setting AbortOnFailure
/// to false and instead using the error handling mechanism to report it.
void * getPointerToNamedFunction ( const std : : string & Name ,
bool /*AbortOnFailure*/ = true ) override {
return SectionMemoryManager : : getPointerToNamedFunction ( Name , false ) ;
}
} ;
uint64_t ClingMemoryManager : : getSymbolAddress ( const std : : string & Name ) {
if ( Name = = " __cxa_atexit " ) {
// Rewrire __cxa_atexit to ~Interpreter(), thus also global destruction
// coming from the JIT.
return ( uint64_t ) & local_cxa_atexit ;
} else if ( Name = = " __dso_handle " ) {
// Provide IncrementalExecutor as the third argument to __cxa_atexit.
return ( uint64_t ) m_exe ;
}
if ( uint64_t Addr = SectionMemoryManager : : getSymbolAddress ( Name ) )
return Addr ;
return ( uint64_t ) m_exe - > NotifyLazyFunctionCreators ( Name ) ;
}
}
2014-03-07 18:09:02 +04:00
namespace cling {
2012-09-05 13:37:39 +04:00
2014-02-19 15:49:24 +04:00
std : : set < std : : string > IncrementalExecutor : : m_unresolvedSymbols ;
2014-10-14 16:11:31 +04:00
2014-02-19 15:49:24 +04:00
std : : vector < IncrementalExecutor : : LazyFunctionCreatorFunc_t >
IncrementalExecutor : : m_lazyFuncCreator ;
2012-09-05 13:37:39 +04:00
2015-01-15 17:13:14 +03:00
// Keep in source: ~unique_ptr<ExecutionEngine> needs #include ExecutionEngine
IncrementalExecutor : : ~ IncrementalExecutor ( ) { }
2014-02-28 20:30:56 +04:00
2015-01-15 17:13:14 +03:00
void IncrementalExecutor : : BuildEngine ( std : : unique_ptr < llvm : : Module > m ) {
2014-02-28 20:30:56 +04:00
//
// Create an execution engine to use.
//
assert ( m & & " Module cannot be null " ) ;
// Note: Engine takes ownership of the module.
2015-01-15 17:13:14 +03:00
llvm : : EngineBuilder builder ( std : : move ( m ) ) ;
2014-02-28 20:30:56 +04:00
std : : string errMsg ;
builder . setErrorStr ( & errMsg ) ;
builder . setOptLevel ( llvm : : CodeGenOpt : : Less ) ;
builder . setEngineKind ( llvm : : EngineKind : : JIT ) ;
2015-01-15 17:13:14 +03:00
std : : unique_ptr < llvm : : RTDyldMemoryManager >
MemMan ( new ClingMemoryManager ( this ) ) ;
builder . setMCJITMemoryManager ( std : : move ( MemMan ) ) ;
2014-02-28 20:30:56 +04:00
// EngineBuilder uses default c'ted TargetOptions, too:
llvm : : TargetOptions TargetOpts ;
TargetOpts . NoFramePointerElim = 1 ;
TargetOpts . JITEmitDebugInfo = 1 ;
builder . setTargetOptions ( TargetOpts ) ;
m_engine . reset ( builder . create ( ) ) ;
assert ( m_engine & & " Cannot create module! " ) ;
// install lazy function creators
Provide __cxa_atexit replacement through custom MemoryManager.
On some platforms, global destructors are registered through a call to
__cxa_atexit(dtor, 0/*args*/, __dso_handle). While __cxa_atexit can be resolved
by the regular MemoryManager, __dso_handle (representing the "current shared
library" such that the corresponding atexit function can be called on its
dlclose) can not be resolved by MCJIT. Instead, we provide our own, poining to
the ExecutionEngine, which in turn holds a "current module" that corresponds in
spirit to the shared library handle.
__cxa_atexit, on the other hand, needs to be re-wired: the interpreter needs to
destruct globals upon its destruction, and those globals from a certain module
when that module is unloaded.
Both is done through a custom MemoryManager, significantly reducing the
complexity of the previous ("JIT without MC") implementation.
The custom MemoryManager also forwards in case of a unknown symbols to the LazyFunctionCreators instead of using the generic
ExecutionEngine::InstallLazyFunctionCreator() which has no effect with MCJIT.
2015-01-08 15:54:22 +03:00
//m_engine->InstallLazyFunctionCreator(NotifyLazyFunctionCreators);
2013-06-25 11:21:14 +04:00
}
2012-11-17 16:09:08 +04:00
2014-02-19 15:49:24 +04:00
void IncrementalExecutor : : shuttingDown ( ) {
2013-09-19 13:24:31 +04:00
for ( size_t I = 0 , N = m_AtExitFuncs . size ( ) ; I < N ; + + I ) {
const CXAAtExitElement & AEE = m_AtExitFuncs [ N - I - 1 ] ;
( * AEE . m_Func ) ( AEE . m_Arg ) ;
}
}
2012-09-05 13:37:39 +04:00
2014-04-28 14:32:12 +04:00
void IncrementalExecutor : : remapSymbols ( ) {
// Note: iteration of ++remapI happens in the body due to invalidation
// of the erased iterator!
for ( auto remapI = std : : begin ( m_SymbolsToRemap ) ,
remapE = std : : end ( m_SymbolsToRemap ) ;
remapI ! = remapE ; ) {
// The function for which the symbol address will be replaced
llvm : : Function * origFunc
= m_engine - > FindFunctionNamed ( remapI - > first . c_str ( ) ) ;
if ( ! origFunc ) {
// Go to next element.
+ + remapI ;
continue ;
}
2013-10-31 02:40:00 +04:00
2014-04-28 14:32:12 +04:00
// The new symbol address, which might be NULL to signal a symbol
// lookup is required
void * replaceAddr = remapI - > second . first ;
if ( ! replaceAddr ) {
// A symbol lookup is required to find the replacement address.
llvm : : Function * interpFunc
= m_engine - > FindFunctionNamed ( remapI - > second . second . c_str ( ) ) ;
assert ( interpFunc & & " replacement function must exist. " ) ;
// Generate the symbol and get its address
replaceAddr = m_engine - > getPointerToFunction ( interpFunc ) ;
}
assert ( replaceAddr & & " cannot find replacement symbol " ) ;
// Replace the mapping of function symbol to new address
m_engine - > updateGlobalMapping ( origFunc , replaceAddr ) ;
// Note that the current entry was successfully remapped.
// Save the current so we can erase it *after* the iterator increment
// or we would increment an invalid iterator.
auto remapErase = remapI ;
+ + remapI ;
m_SymbolsToRemap . erase ( remapErase ) ;
}
2013-10-31 02:40:00 +04:00
}
Provide __cxa_atexit replacement through custom MemoryManager.
On some platforms, global destructors are registered through a call to
__cxa_atexit(dtor, 0/*args*/, __dso_handle). While __cxa_atexit can be resolved
by the regular MemoryManager, __dso_handle (representing the "current shared
library" such that the corresponding atexit function can be called on its
dlclose) can not be resolved by MCJIT. Instead, we provide our own, poining to
the ExecutionEngine, which in turn holds a "current module" that corresponds in
spirit to the shared library handle.
__cxa_atexit, on the other hand, needs to be re-wired: the interpreter needs to
destruct globals upon its destruction, and those globals from a certain module
when that module is unloaded.
Both is done through a custom MemoryManager, significantly reducing the
complexity of the previous ("JIT without MC") implementation.
The custom MemoryManager also forwards in case of a unknown symbols to the LazyFunctionCreators instead of using the generic
ExecutionEngine::InstallLazyFunctionCreator() which has no effect with MCJIT.
2015-01-08 15:54:22 +03:00
void IncrementalExecutor : : AddAtExitFunc ( void ( * func ) ( void * ) , void * arg ) {
2013-09-19 13:24:31 +04:00
// Register a CXAAtExit function
Provide __cxa_atexit replacement through custom MemoryManager.
On some platforms, global destructors are registered through a call to
__cxa_atexit(dtor, 0/*args*/, __dso_handle). While __cxa_atexit can be resolved
by the regular MemoryManager, __dso_handle (representing the "current shared
library" such that the corresponding atexit function can be called on its
dlclose) can not be resolved by MCJIT. Instead, we provide our own, poining to
the ExecutionEngine, which in turn holds a "current module" that corresponds in
spirit to the shared library handle.
__cxa_atexit, on the other hand, needs to be re-wired: the interpreter needs to
destruct globals upon its destruction, and those globals from a certain module
when that module is unloaded.
Both is done through a custom MemoryManager, significantly reducing the
complexity of the previous ("JIT without MC") implementation.
The custom MemoryManager also forwards in case of a unknown symbols to the LazyFunctionCreators instead of using the generic
ExecutionEngine::InstallLazyFunctionCreator() which has no effect with MCJIT.
2015-01-08 15:54:22 +03:00
m_AtExitFuncs . push_back ( CXAAtExitElement ( func , arg , m_CurrentAtExitModule ) ) ;
2013-09-19 13:24:31 +04:00
}
2012-09-05 13:37:39 +04:00
void unresolvedSymbol ( )
{
// throw exception?
2014-02-19 15:49:24 +04:00
llvm : : errs ( ) < < " IncrementalExecutor: calling unresolved symbol, "
2012-11-17 20:28:14 +04:00
" see previous error message! \n " ;
2012-09-05 13:37:39 +04:00
}
2014-02-19 15:49:24 +04:00
void * IncrementalExecutor : : HandleMissingFunction ( const std : : string & mangled_name )
2012-09-05 13:37:39 +04:00
{
// Not found in the map, add the symbol in the list of unresolved symbols
2012-10-07 15:53:16 +04:00
if ( m_unresolvedSymbols . insert ( mangled_name ) . second ) {
2014-05-28 15:56:16 +04:00
//llvm::errs() << "IncrementalExecutor: use of undefined symbol '"
// << mangled_name << "'!\n";
2012-10-07 15:53:16 +04:00
}
2012-09-05 13:37:39 +04:00
// Avoid "ISO C++ forbids casting between pointer-to-function and
// pointer-to-object":
return ( void * ) reinterpret_cast < size_t > ( unresolvedSymbol ) ;
}
void *
2014-02-19 15:49:24 +04:00
IncrementalExecutor : : NotifyLazyFunctionCreators ( const std : : string & mangled_name )
2012-09-05 13:37:39 +04:00
{
for ( std : : vector < LazyFunctionCreatorFunc_t > : : iterator it
= m_lazyFuncCreator . begin ( ) , et = m_lazyFuncCreator . end ( ) ;
it ! = et ; + + it ) {
void * ret = ( void * ) ( ( LazyFunctionCreatorFunc_t ) * it ) ( mangled_name ) ;
2014-02-28 20:23:09 +04:00
if ( ret )
2012-10-25 16:58:50 +04:00
return ret ;
2012-09-05 13:37:39 +04:00
}
2012-10-25 16:58:50 +04:00
2012-09-05 13:37:39 +04:00
return HandleMissingFunction ( mangled_name ) ;
}
2012-11-17 20:28:14 +04:00
static void
freeCallersOfUnresolvedSymbols ( llvm : : SmallVectorImpl < llvm : : Function * > &
funcsToFree , llvm : : ExecutionEngine * engine ) {
llvm : : SmallPtrSet < llvm : : Function * , 40 > funcsToFreeUnique ;
for ( size_t i = 0 ; i < funcsToFree . size ( ) ; + + i ) {
llvm : : Function * func = funcsToFree [ i ] ;
2013-10-02 11:24:32 +04:00
assert ( func & & " Cannot free NULL function " ) ;
2015-01-15 17:13:14 +03:00
if ( funcsToFreeUnique . insert ( func ) . second ) {
2012-11-17 20:28:14 +04:00
for ( llvm : : Value : : use_iterator IU = func - > use_begin ( ) ,
EU = func - > use_end ( ) ; IU ! = EU ; + + IU ) {
llvm : : Instruction * instUser = llvm : : dyn_cast < llvm : : Instruction > ( * IU ) ;
if ( ! instUser ) continue ;
if ( ! instUser - > getParent ( ) ) continue ;
if ( llvm : : Function * userFunc = instUser - > getParent ( ) - > getParent ( ) )
funcsToFree . push_back ( userFunc ) ;
}
}
}
for ( llvm : : SmallPtrSet < llvm : : Function * , 40 > : : iterator
I = funcsToFreeUnique . begin ( ) , E = funcsToFreeUnique . end ( ) ;
I ! = E ; + + I ) {
// This should force the JIT to recompile the function. But the stubs stay,
// and the JIT reuses the stubs now pointing nowhere, i.e. without updating
// the machine code address. Fix the JIT, or hope that MCJIT helps.
//engine->freeMachineCodeForFunction(*I);
engine - > updateGlobalMapping ( * I , 0 ) ;
}
}
2014-02-19 15:49:24 +04:00
IncrementalExecutor : : ExecutionResult
IncrementalExecutor : : executeFunction ( llvm : : StringRef funcname ,
2014-02-27 01:37:16 +04:00
Value * returnValue ) {
2012-09-05 13:37:39 +04:00
// Call a function without arguments, or with an SRet argument, see SRet below
// We don't care whether something was unresolved before.
m_unresolvedSymbols . clear ( ) ;
2014-05-26 18:33:43 +04:00
// Set the value to cling::invalid.
if ( returnValue ) {
* returnValue = Value ( ) ;
}
2014-04-28 14:32:12 +04:00
remapSymbols ( ) ;
2014-03-04 21:15:14 +04:00
2012-11-17 20:28:14 +04:00
llvm : : Function * f = m_engine - > FindFunctionNamed ( funcname . str ( ) . c_str ( ) ) ;
2012-09-05 13:37:39 +04:00
if ( ! f ) {
2014-02-19 15:49:24 +04:00
llvm : : errs ( ) < < " IncrementalExecutor::executeFunction: "
2012-11-17 20:28:14 +04:00
" could not find function named " < < funcname < < ' \n ' ;
2012-11-16 00:55:43 +04:00
return kExeFunctionNotCompiled ;
2012-09-05 13:37:39 +04:00
}
2014-03-12 18:18:04 +04:00
assert ( f - > getFunctionType ( ) - > getNumParams ( ) = = 1
& & ( * f - > getFunctionType ( ) - > param_begin ( ) ) - > isPtrOrPtrVectorTy ( ) & &
" Wrong signature " ) ;
2014-02-13 12:52:31 +04:00
typedef void ( * PromptWrapper_t ) ( void * ) ;
2014-02-19 13:03:04 +04:00
union {
PromptWrapper_t wrapperFunction ;
void * address ;
} p2f ;
2015-01-07 12:22:52 +03:00
p2f . address = ( void * ) m_engine - > getFunctionAddress ( funcname ) ;
2014-02-19 13:03:04 +04:00
2012-09-05 13:37:39 +04:00
// check if there is any unresolved symbol in the list
2014-10-16 13:20:04 +04:00
if ( diagnoseUnresolvedSymbols ( funcname , " function " ) )
2012-11-16 00:55:43 +04:00
return kExeUnresolvedSymbols ;
2012-09-05 13:37:39 +04:00
2014-02-19 13:03:04 +04:00
// Run the function
( * p2f . wrapperFunction ) ( returnValue ) ;
2012-09-05 13:37:39 +04:00
2012-11-16 00:55:43 +04:00
return kExeSuccess ;
2012-09-05 13:37:39 +04:00
}
2014-02-19 15:49:24 +04:00
IncrementalExecutor : : ExecutionResult
IncrementalExecutor : : runStaticInitializersOnce ( llvm : : Module * m ) {
2012-09-05 13:37:39 +04:00
assert ( m & & " Module must not be null " ) ;
assert ( m_engine & & " Code generation did not create an engine! " ) ;
Provide __cxa_atexit replacement through custom MemoryManager.
On some platforms, global destructors are registered through a call to
__cxa_atexit(dtor, 0/*args*/, __dso_handle). While __cxa_atexit can be resolved
by the regular MemoryManager, __dso_handle (representing the "current shared
library" such that the corresponding atexit function can be called on its
dlclose) can not be resolved by MCJIT. Instead, we provide our own, poining to
the ExecutionEngine, which in turn holds a "current module" that corresponds in
spirit to the shared library handle.
__cxa_atexit, on the other hand, needs to be re-wired: the interpreter needs to
destruct globals upon its destruction, and those globals from a certain module
when that module is unloaded.
Both is done through a custom MemoryManager, significantly reducing the
complexity of the previous ("JIT without MC") implementation.
The custom MemoryManager also forwards in case of a unknown symbols to the LazyFunctionCreators instead of using the generic
ExecutionEngine::InstallLazyFunctionCreator() which has no effect with MCJIT.
2015-01-08 15:54:22 +03:00
// Set m_CurrentAtExitModule to the Module, unset to 0 once done.
struct AtExitModuleSetterRAII {
llvm : : Module * & m_AEM ;
AtExitModuleSetterRAII ( llvm : : Module * M , llvm : : Module * & AEM ) : m_AEM ( AEM )
{ AEM = M ; }
~ AtExitModuleSetterRAII ( ) { m_AEM = 0 ; }
} DSOHandleSetter ( m , m_CurrentAtExitModule ) ;
2015-01-09 11:40:58 +03:00
// We don't care whether something was unresolved before.
m_unresolvedSymbols . clear ( ) ;
2015-01-07 12:22:52 +03:00
m_engine - > finalizeObject ( ) ;
2015-01-09 11:40:58 +03:00
// check if there is any unresolved symbol in the list
if ( diagnoseUnresolvedSymbols ( " static initializers " ) )
return kExeUnresolvedSymbols ;
2012-11-20 20:24:02 +04:00
llvm : : GlobalVariable * GV
= m - > getGlobalVariable ( " llvm.global_ctors " , true ) ;
// Nothing to do is good, too.
if ( ! GV ) return kExeSuccess ;
// Close similarity to
// m_engine->runStaticConstructorsDestructors(false) aka
// llvm::ExecutionEngine::runStaticConstructorsDestructors()
// is intentional; we do an extra pass to check whether the JIT
// managed to collect all the symbols needed by the niitializers.
// Should be an array of '{ i32, void ()* }' structs. The first value is
// the init priority, which we ignore.
llvm : : ConstantArray * InitList
= llvm : : dyn_cast < llvm : : ConstantArray > ( GV - > getInitializer ( ) ) ;
2014-01-22 18:07:11 +04:00
2014-03-15 02:09:49 +04:00
// We need to delete it here just in case we have recursive inits, otherwise
// it will call inits multiple times.
2014-01-22 18:07:11 +04:00
GV - > eraseFromParent ( ) ;
2012-11-20 20:24:02 +04:00
if ( InitList = = 0 )
return kExeSuccess ;
2012-09-05 13:37:39 +04:00
2014-03-12 20:58:34 +04:00
SmallVector < Function * , 2 > initFuncs ;
2012-11-20 20:24:02 +04:00
for ( unsigned i = 0 , e = InitList - > getNumOperands ( ) ; i ! = e ; + + i ) {
llvm : : ConstantStruct * CS
= llvm : : dyn_cast < llvm : : ConstantStruct > ( InitList - > getOperand ( i ) ) ;
if ( CS = = 0 ) continue ;
llvm : : Constant * FP = CS - > getOperand ( 1 ) ;
if ( FP - > isNullValue ( ) )
continue ; // Found a sentinal value, ignore.
// Strip off constant expression casts.
if ( llvm : : ConstantExpr * CE = llvm : : dyn_cast < llvm : : ConstantExpr > ( FP ) )
if ( CE - > isCast ( ) )
FP = CE - > getOperand ( 0 ) ;
// Execute the ctor/dtor function!
if ( llvm : : Function * F = llvm : : dyn_cast < llvm : : Function > ( FP ) ) {
2014-04-28 14:32:12 +04:00
remapSymbols ( ) ;
2012-11-20 20:24:02 +04:00
m_engine - > getPointerToFunction ( F ) ;
// check if there is any unresolved symbol in the list
2014-10-14 16:11:31 +04:00
if ( diagnoseUnresolvedSymbols ( " static initializers " ) )
2012-11-20 20:24:02 +04:00
return kExeUnresolvedSymbols ;
2014-10-14 16:11:31 +04:00
2014-03-12 02:37:05 +04:00
//executeFunction(F->getName());
m_engine - > runFunction ( F , std : : vector < llvm : : GenericValue > ( ) ) ;
2014-03-12 20:58:34 +04:00
initFuncs . push_back ( F ) ;
2014-07-28 14:27:30 +04:00
if ( F - > getName ( ) . startswith ( " _GLOBAL__sub_I__ " ) ) {
2014-03-15 02:11:09 +04:00
BasicBlock & BB = F - > getEntryBlock ( ) ;
for ( BasicBlock : : iterator I = BB . begin ( ) , E = BB . end ( ) ; I ! = E ; + + I )
if ( CallInst * call = dyn_cast < CallInst > ( I ) )
initFuncs . push_back ( call - > getCalledFunction ( ) ) ;
}
2012-11-20 20:24:02 +04:00
}
2012-09-05 13:37:39 +04:00
}
2012-11-20 20:24:02 +04:00
2014-03-12 20:58:34 +04:00
for ( SmallVector < Function * , 2 > : : iterator I = initFuncs . begin ( ) ,
E = initFuncs . end ( ) ; I ! = E ; + + I ) {
// Cleanup also the dangling init functions. They are in the form:
// define internal void @_GLOBAL__I_aN() section "..."{
// entry:
// call void @__cxx_global_var_init(N-1)()
2014-03-15 02:10:33 +04:00
// call void @__cxx_global_var_initM()
2014-03-12 20:58:34 +04:00
// ret void
// }
//
// define internal void @__cxx_global_var_init(N-1)() section "..." {
// entry:
// call void @_ZN7MyClassC1Ev(%struct.MyClass* @n)
// ret void
// }
// Erase __cxx_global_var_init(N-1)() first.
2014-03-15 02:11:09 +04:00
( * I ) - > removeDeadConstantUsers ( ) ;
2014-03-12 20:58:34 +04:00
( * I ) - > eraseFromParent ( ) ;
}
2012-11-20 20:24:02 +04:00
return kExeSuccess ;
2012-09-05 13:37:39 +04:00
}
2014-02-27 12:53:42 +04:00
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 ( ) ; )
Provide __cxa_atexit replacement through custom MemoryManager.
On some platforms, global destructors are registered through a call to
__cxa_atexit(dtor, 0/*args*/, __dso_handle). While __cxa_atexit can be resolved
by the regular MemoryManager, __dso_handle (representing the "current shared
library" such that the corresponding atexit function can be called on its
dlclose) can not be resolved by MCJIT. Instead, we provide our own, poining to
the ExecutionEngine, which in turn holds a "current module" that corresponds in
spirit to the shared library handle.
__cxa_atexit, on the other hand, needs to be re-wired: the interpreter needs to
destruct globals upon its destruction, and those globals from a certain module
when that module is unloaded.
Both is done through a custom MemoryManager, significantly reducing the
complexity of the previous ("JIT without MC") implementation.
The custom MemoryManager also forwards in case of a unknown symbols to the LazyFunctionCreators instead of using the generic
ExecutionEngine::InstallLazyFunctionCreator() which has no effect with MCJIT.
2015-01-08 15:54:22 +03:00
if ( I - > m_FromM = = T - > getModule ( ) ) {
2014-02-27 12:53:42 +04:00
boundToT . push_back ( * I ) ;
I = m_AtExitFuncs . erase ( I ) ;
}
else
+ + I ;
2013-09-19 13:24:31 +04:00
// 'Unload' the cxa_atexit entities.
2014-02-27 12:53:42 +04:00
for ( AtExitFunctions : : reverse_iterator I = boundToT . rbegin ( ) ,
E = boundToT . rend ( ) ; I ! = E ; + + I ) {
2014-02-26 20:00:13 +04:00
const CXAAtExitElement & AEE = * I ;
2013-09-19 13:24:31 +04:00
( * AEE . m_Func ) ( AEE . m_Arg ) ;
}
2012-09-05 13:37:39 +04:00
}
void
2014-02-19 15:49:24 +04:00
IncrementalExecutor : : installLazyFunctionCreator ( LazyFunctionCreatorFunc_t fp )
2012-09-05 13:37:39 +04:00
{
m_lazyFuncCreator . push_back ( fp ) ;
}
2014-02-19 15:49:24 +04:00
bool
IncrementalExecutor : : addSymbol ( const char * symbolName , void * symbolAddress ) {
2012-09-24 13:57:43 +04:00
void * actualAddress
2012-09-05 13:37:39 +04:00
= llvm : : sys : : DynamicLibrary : : SearchForAddressOfSymbol ( symbolName ) ;
2012-09-24 13:57:43 +04:00
if ( actualAddress )
2012-09-05 13:37:39 +04:00
return false ;
llvm : : sys : : DynamicLibrary : : AddSymbol ( symbolName , symbolAddress ) ;
return true ;
}
2012-09-24 13:57:43 +04:00
2015-01-15 17:13:14 +03:00
void IncrementalExecutor : : addModule ( std : : unique_ptr < Module > module ) {
if ( ! m_engine )
BuildEngine ( std : : move ( module ) ) ;
else
m_engine - > addModule ( std : : move ( module ) ) ;
2015-01-07 12:22:52 +03:00
}
2015-01-12 11:57:30 +03:00
void * IncrementalExecutor : : getAddressOfGlobal ( llvm : : StringRef symbolName ,
2014-03-04 21:15:14 +04:00
bool * fromJIT /*=0*/ ) {
2012-11-19 02:27:00 +04:00
// Return a symbol's address, and whether it was jitted.
void * address
= llvm : : sys : : DynamicLibrary : : SearchForAddressOfSymbol ( symbolName ) ;
2015-01-12 11:23:03 +03:00
// It's not from the JIT if it's in a dylib.
if ( fromJIT )
* fromJIT = ! address ;
if ( ! address )
return ( void * ) m_engine - > getGlobalValueAddress ( symbolName ) ;
2012-11-19 02:27:00 +04:00
return address ;
}
2013-12-05 19:22:34 +04:00
void *
2014-03-04 21:15:14 +04:00
IncrementalExecutor : : getPointerToGlobalFromJIT ( const llvm : : GlobalValue & GV ) {
2014-10-14 16:11:31 +04:00
// Get the function / variable pointer referenced by GV.
// We don't care whether something was unresolved before.
m_unresolvedSymbols . clear ( ) ;
2014-04-28 14:32:12 +04:00
remapSymbols ( ) ;
2013-12-05 19:22:34 +04:00
if ( void * addr = m_engine - > getPointerToGlobalIfAvailable ( & GV ) )
return addr ;
// Function not yet codegened by the JIT, force this to happen now.
2014-10-14 16:11:31 +04:00
void * Ptr = m_engine - > getPointerToGlobal ( & GV ) ;
2014-10-22 21:08:26 +04:00
if ( diagnoseUnresolvedSymbols ( GV . getName ( ) , " symbol " ) )
return 0 ;
2014-10-14 16:11:31 +04:00
return Ptr ;
2013-12-05 19:22:34 +04:00
}
2014-10-14 16:11:31 +04:00
2014-10-16 13:20:04 +04:00
bool IncrementalExecutor : : diagnoseUnresolvedSymbols ( llvm : : StringRef trigger ,
llvm : : StringRef title ) {
2014-10-14 16:11:31 +04:00
if ( m_unresolvedSymbols . empty ( ) )
return false ;
llvm : : SmallVector < llvm : : Function * , 128 > funcsToFree ;
for ( std : : set < std : : string > : : const_iterator i = m_unresolvedSymbols . begin ( ) ,
e = m_unresolvedSymbols . end ( ) ; i ! = e ; + + i ) {
#if 0
// FIXME: This causes a lot of test failures, for some reason it causes
// the call to HandleMissingFunction to be elided.
unsigned diagID = m_Diags . getCustomDiagID ( clang : : DiagnosticsEngine : : Error ,
" %0 unresolved while jitting %1 " ) ;
( void ) diagID ;
//m_Diags.Report(diagID) << *i << funcname; // TODO: demangle the names.
# endif
llvm : : errs ( ) < < " IncrementalExecutor::executeFunction: symbol ' " < < * i
2014-10-16 13:20:04 +04:00
< < " ' unresolved while linking " ;
if ( ! title . empty ( ) )
llvm : : errs ( ) < < title < < " ' " ;
llvm : : errs ( ) < < trigger ;
if ( ! title . empty ( ) )
llvm : : errs ( ) < < " ' " ;
llvm : : errs ( ) < < " ! \n " ;
2014-10-14 16:11:31 +04:00
llvm : : Function * ff = m_engine - > FindFunctionNamed ( i - > c_str ( ) ) ;
// i could also reference a global variable, in which case ff == 0.
if ( ff )
funcsToFree . push_back ( ff ) ;
}
freeCallersOfUnresolvedSymbols ( funcsToFree , m_engine . get ( ) ) ;
m_unresolvedSymbols . clear ( ) ;
return true ;
}
2014-03-07 18:09:02 +04:00
} // end namespace cling