2015-02-03 21:32:09 +01:00
//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author: Axel Naumann <axel@cern.ch>
//
// 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.
//------------------------------------------------------------------------------
# ifndef CLING_INCREMENTAL_JIT_H
# define CLING_INCREMENTAL_JIT_H
# include <map>
# include <memory>
# include <set>
# include <string>
# include <vector>
# include "llvm/IR/Mangler.h"
# include "llvm/IR/GlobalValue.h"
2015-02-25 11:25:50 +01:00
# include "llvm/ExecutionEngine/JITEventListener.h"
2015-02-03 21:32:09 +01:00
# include "llvm/ExecutionEngine/Orc/CompileUtils.h"
# include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
# include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
# include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
2015-02-25 11:25:50 +01:00
# include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
2015-02-03 21:32:09 +01:00
# include "llvm/Target/TargetMachine.h"
namespace llvm {
class Module ;
class RTDyldMemoryManager ;
}
namespace cling {
class Azog ;
class IncrementalExecutor ;
class IncrementalJIT {
friend class Azog ;
///\brief The IncrementalExecutor who owns us.
IncrementalExecutor & m_Parent ;
2015-03-19 16:17:58 +01:00
llvm : : JITEventListener * m_GDBListener ; // owned by llvm::ManagedStaticBase
2015-02-03 21:32:09 +01:00
class NotifyObjectLoadedT {
public :
2016-04-22 15:13:51 +02:00
typedef std : : vector < std : : unique_ptr < llvm : : object : : OwningBinary < llvm : : object : : ObjectFile > > > ObjListT ;
2015-02-03 21:32:09 +01:00
typedef std : : vector < std : : unique_ptr < llvm : : RuntimeDyld : : LoadedObjectInfo > >
LoadedObjInfoListT ;
NotifyObjectLoadedT ( IncrementalJIT & jit ) : m_JIT ( jit ) { }
2016-04-22 15:13:51 +02:00
void operator ( ) ( llvm : : orc : : ObjectLinkingLayerBase : : ObjSetHandleT H ,
2015-02-03 21:32:09 +01:00
const ObjListT & Objects ,
const LoadedObjInfoListT & Infos ) const {
m_JIT . m_UnfinalizedSections [ H ]
= std : : move ( m_JIT . m_SectionsAllocatedSinceLastLoad ) ;
m_JIT . m_SectionsAllocatedSinceLastLoad = SectionAddrSet ( ) ;
assert ( Objects . size ( ) = = Infos . size ( ) & &
" Incorrect number of Infos for Objects. " ) ;
2015-02-25 11:25:50 +01:00
for ( size_t I = 0 , N = Objects . size ( ) ; I < N ; + + I )
2016-04-22 15:13:51 +02:00
m_JIT . m_GDBListener - > NotifyObjectEmitted ( * Objects [ I ] - > getBinary ( ) ,
* Infos [ I ] ) ;
2015-02-03 21:32:09 +01:00
} ;
private :
IncrementalJIT & m_JIT ;
} ;
class NotifyFinalizedT {
public :
NotifyFinalizedT ( IncrementalJIT & jit ) : m_JIT ( jit ) { }
2016-04-22 15:13:51 +02:00
void operator ( ) ( llvm : : orc : : ObjectLinkingLayerBase : : ObjSetHandleT H ) {
2015-02-03 21:32:09 +01:00
m_JIT . m_UnfinalizedSections . erase ( H ) ;
}
private :
IncrementalJIT & m_JIT ;
} ;
2016-04-22 15:13:51 +02:00
typedef llvm : : orc : : ObjectLinkingLayer < NotifyObjectLoadedT > ObjectLayerT ;
typedef llvm : : orc : : IRCompileLayer < ObjectLayerT > CompileLayerT ;
typedef llvm : : orc : : LazyEmittingLayer < CompileLayerT > LazyEmitLayerT ;
2015-02-03 21:32:09 +01:00
typedef LazyEmitLayerT : : ModuleSetHandleT ModuleSetHandleT ;
std : : unique_ptr < llvm : : TargetMachine > m_TM ;
2016-04-22 15:13:51 +02:00
llvm : : DataLayout m_TMDataLayout ;
2015-02-03 21:32:09 +01:00
///\brief The RTDyldMemoryManager used to communicate with the
/// IncrementalExecutor to handle missing or special symbols.
std : : unique_ptr < llvm : : RTDyldMemoryManager > m_ExeMM ;
NotifyObjectLoadedT m_NotifyObjectLoaded ;
NotifyFinalizedT m_NotifyFinalized ;
ObjectLayerT m_ObjectLayer ;
CompileLayerT m_CompileLayer ;
LazyEmitLayerT m_LazyEmitLayer ;
// We need to store ObjLayerT::ObjSetHandles for each of the object sets
// that have been emitted but not yet finalized so that we can forward the
// mapSectionAddress calls appropriately.
typedef std : : set < const void * > SectionAddrSet ;
struct ObjSetHandleCompare {
bool operator ( ) ( ObjectLayerT : : ObjSetHandleT H1 ,
ObjectLayerT : : ObjSetHandleT H2 ) const {
return & * H1 < & * H2 ;
}
} ;
SectionAddrSet m_SectionsAllocatedSinceLastLoad ;
std : : map < ObjectLayerT : : ObjSetHandleT , SectionAddrSet , ObjSetHandleCompare >
m_UnfinalizedSections ;
///\brief Vector of ModuleSetHandleT. UnloadHandles index into that
/// vector.
std : : vector < ModuleSetHandleT > m_UnloadPoints ;
std : : string Mangle ( llvm : : StringRef Name ) {
std : : string MangledName ;
{
llvm : : raw_string_ostream MangledNameStream ( MangledName ) ;
2016-04-22 15:13:51 +02:00
llvm : : Mangler : : getNameWithPrefix ( MangledNameStream , Name ,
m_TMDataLayout ) ;
2015-02-03 21:32:09 +01:00
}
return MangledName ;
}
public :
IncrementalJIT ( IncrementalExecutor & exe ,
std : : unique_ptr < llvm : : TargetMachine > TM ) ;
///\brief Get the address of a symbol from the JIT or the memory manager,
/// mangling the name as needed. Use this to resolve symbols as coming
/// from clang's mangler.
2015-12-04 12:25:14 +01:00
/// \param Name - name to look for. This name might still get mangled
/// (prefixed by '_') to make IR versus symbol names.
/// \param AlsoInProcess - Sometimes you only care about JITed symbols. If so,
/// pass `false` here to not resolve the symbol through dlsym().
uint64_t getSymbolAddress ( llvm : : StringRef Name , bool AlsoInProcess ) {
2016-04-22 15:13:51 +02:00
return getSymbolAddressWithoutMangling ( Mangle ( Name ) , AlsoInProcess )
. getAddress ( ) ;
2015-02-03 21:32:09 +01:00
}
///\brief Get the address of a symbol from the JIT or the memory manager.
/// Use this to resolve symbols of known, target-specific names.
2016-04-22 15:13:51 +02:00
llvm : : orc : : JITSymbol getSymbolAddressWithoutMangling ( llvm : : StringRef Name ,
bool AlsoInProcess ) ;
2015-02-03 21:32:09 +01:00
size_t addModules ( std : : vector < llvm : : Module * > & & modules ) ;
void removeModules ( size_t handle ) ;
IncrementalExecutor & getParent ( ) const { return m_Parent ; }
//void finalizeMemory();
} ;
} // end cling
# endif // CLING_INCREMENTAL_EXECUTOR_H