mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +01:00
Implementing basic function-level profiling support in IntelJITEventListener.
Tests to follow in another patch. llvm-svn: 168444
This commit is contained in:
parent
a96a1c8e42
commit
74bde65ee0
@ -22,6 +22,7 @@
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/ExecutionEngine/ObjectImage.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/Errno.h"
|
||||
@ -41,6 +42,11 @@ class IntelJITEventListener : public JITEventListener {
|
||||
MethodIDMap MethodIDs;
|
||||
FilenameCache Filenames;
|
||||
|
||||
typedef SmallVector<const void *, 64> MethodAddressVector;
|
||||
typedef DenseMap<const void *, MethodAddressVector> ObjectMap;
|
||||
|
||||
ObjectMap LoadedObjectMap;
|
||||
|
||||
public:
|
||||
IntelJITEventListener(IntelJITEventsWrapper* libraryWrapper) {
|
||||
Wrapper.reset(libraryWrapper);
|
||||
@ -169,9 +175,78 @@ void IntelJITEventListener::NotifyFreeingMachineCode(void *FnStart) {
|
||||
}
|
||||
|
||||
void IntelJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) {
|
||||
// Get the address of the object image for use as a unique identifier
|
||||
const void* ObjData = Obj.getData().data();
|
||||
MethodAddressVector Functions;
|
||||
|
||||
// Use symbol info to iterate functions in the object.
|
||||
error_code ec;
|
||||
for (object::symbol_iterator I = Obj.begin_symbols(),
|
||||
E = Obj.end_symbols();
|
||||
I != E && !ec;
|
||||
I.increment(ec)) {
|
||||
object::SymbolRef::Type SymType;
|
||||
if (I->getType(SymType)) continue;
|
||||
if (SymType == object::SymbolRef::ST_Function) {
|
||||
StringRef Name;
|
||||
uint64_t Addr;
|
||||
uint64_t Size;
|
||||
if (I->getName(Name)) continue;
|
||||
if (I->getAddress(Addr)) continue;
|
||||
if (I->getSize(Size)) continue;
|
||||
|
||||
// Record this address in a local vector
|
||||
Functions.push_back((void*)Addr);
|
||||
|
||||
// Build the function loaded notification message
|
||||
iJIT_Method_Load FunctionMessage = FunctionDescToIntelJITFormat(*Wrapper,
|
||||
Name.data(),
|
||||
Addr,
|
||||
Size);
|
||||
|
||||
// FIXME: Try to find line info for this function in the DWARF sections.
|
||||
FunctionMessage.source_file_name = 0;
|
||||
FunctionMessage.line_number_size = 0;
|
||||
FunctionMessage.line_number_table = 0;
|
||||
|
||||
Wrapper->iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED,
|
||||
&FunctionMessage);
|
||||
MethodIDs[(void*)Addr] = FunctionMessage.method_id;
|
||||
}
|
||||
}
|
||||
|
||||
// To support object unload notification, we need to keep a list of
|
||||
// registered function addresses for each loaded object. We will
|
||||
// use the MethodIDs map to get the registered ID for each function.
|
||||
LoadedObjectMap[ObjData] = Functions;
|
||||
}
|
||||
|
||||
void IntelJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) {
|
||||
// Get the address of the object image for use as a unique identifier
|
||||
const void* ObjData = Obj.getData().data();
|
||||
|
||||
// Get the object's function list from LoadedObjectMap
|
||||
ObjectMap::iterator OI = LoadedObjectMap.find(ObjData);
|
||||
if (OI == LoadedObjectMap.end())
|
||||
return;
|
||||
MethodAddressVector& Functions = OI->second;
|
||||
|
||||
// Walk the function list, unregistering each function
|
||||
for (MethodAddressVector::iterator FI = Functions.begin(),
|
||||
FE = Functions.end();
|
||||
FI != FE;
|
||||
++FI) {
|
||||
void* FnStart = const_cast<void*>(*FI);
|
||||
MethodIDMap::iterator MI = MethodIDs.find(FnStart);
|
||||
if (MI != MethodIDs.end()) {
|
||||
Wrapper->iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_UNLOAD_START,
|
||||
&MI->second);
|
||||
MethodIDs.erase(MI);
|
||||
}
|
||||
}
|
||||
|
||||
// Erase the object from LoadedObjectMap
|
||||
LoadedObjectMap.erase(OI);
|
||||
}
|
||||
|
||||
} // anonymous namespace.
|
||||
|
Loading…
Reference in New Issue
Block a user