Skip to content

Commit

Permalink
Implementing basic function-level profiling support in IntelJITEventL…
Browse files Browse the repository at this point in the history
…istener.

Tests to follow in another patch.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168444 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Andrew Kaylor committed Nov 21, 2012
1 parent 0ae6124 commit 34519fc
Showing 1 changed file with 75 additions and 0 deletions.
75 changes: 75 additions & 0 deletions lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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);
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 34519fc

Please sign in to comment.