mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
Implementing basic function-level profiling support in IntelJITEventListener.
Tests to follow in another patch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168444 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0ae6124034
commit
34519fc11d
@ -22,6 +22,7 @@
|
|||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/OwningPtr.h"
|
#include "llvm/ADT/OwningPtr.h"
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
|
#include "llvm/ExecutionEngine/ObjectImage.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include "llvm/Support/Errno.h"
|
#include "llvm/Support/Errno.h"
|
||||||
@ -41,6 +42,11 @@ class IntelJITEventListener : public JITEventListener {
|
|||||||
MethodIDMap MethodIDs;
|
MethodIDMap MethodIDs;
|
||||||
FilenameCache Filenames;
|
FilenameCache Filenames;
|
||||||
|
|
||||||
|
typedef SmallVector<const void *, 64> MethodAddressVector;
|
||||||
|
typedef DenseMap<const void *, MethodAddressVector> ObjectMap;
|
||||||
|
|
||||||
|
ObjectMap LoadedObjectMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IntelJITEventListener(IntelJITEventsWrapper* libraryWrapper) {
|
IntelJITEventListener(IntelJITEventsWrapper* libraryWrapper) {
|
||||||
Wrapper.reset(libraryWrapper);
|
Wrapper.reset(libraryWrapper);
|
||||||
@ -169,9 +175,78 @@ void IntelJITEventListener::NotifyFreeingMachineCode(void *FnStart) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IntelJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) {
|
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) {
|
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.
|
} // anonymous namespace.
|
||||||
|
Loading…
Reference in New Issue
Block a user