161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky//===-- IntelJITEventListener.cpp - Tell Intel profiler about JITed code --===// 261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// 361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// The LLVM Compiler Infrastructure 461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// 561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// This file is distributed under the University of Illinois Open Source 661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// License. See LICENSE.TXT for details. 761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// 861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky//===----------------------------------------------------------------------===// 961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// 1061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// This file defines a JITEventListener object to tell Intel(R) VTune(TM) 1161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// Amplifier XE 2011 about JITted functions. 1261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// 1361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky//===----------------------------------------------------------------------===// 1461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 1561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/Config/config.h" 1661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/ExecutionEngine/JITEventListener.h" 1761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DebugInfo.h" 190b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 200b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Metadata.h" 2161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/ADT/DenseMap.h" 2261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/CodeGen/MachineFunction.h" 23710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor#include "llvm/DebugInfo/DIContext.h" 2434519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor#include "llvm/ExecutionEngine/ObjectImage.h" 25710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor#include "llvm/Object/ObjectFile.h" 2661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/Support/Debug.h" 2761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/Support/raw_ostream.h" 2861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/Support/Errno.h" 2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/ValueHandle.h" 3061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "EventListenerCommon.h" 31770b97b995aace9177a80510b7fd3cdab21dde0eAndrew Kaylor#include "IntelJITEventsWrapper.h" 3261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 3361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskyusing namespace llvm; 3461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskyusing namespace llvm::jitprofiling; 3561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 36dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "amplifier-jit-event-listener" 37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 3861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskynamespace { 3961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 4061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskyclass IntelJITEventListener : public JITEventListener { 4161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky typedef DenseMap<void*, unsigned int> MethodIDMap; 4261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<IntelJITEventsWrapper> Wrapper; 4461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky MethodIDMap MethodIDs; 4561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FilenameCache Filenames; 4661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 4734519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor typedef SmallVector<const void *, 64> MethodAddressVector; 4834519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor typedef DenseMap<const void *, MethodAddressVector> ObjectMap; 4934519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor 5034519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor ObjectMap LoadedObjectMap; 5134519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor 5261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskypublic: 5344aebe85e30e3ecb3d9fef39fe719513743e6024Andrew Kaylor IntelJITEventListener(IntelJITEventsWrapper* libraryWrapper) { 5444aebe85e30e3ecb3d9fef39fe719513743e6024Andrew Kaylor Wrapper.reset(libraryWrapper); 5561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky } 5661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 5761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky ~IntelJITEventListener() { 5861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky } 5961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 6061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky virtual void NotifyFunctionEmitted(const Function &F, 6161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky void *FnStart, size_t FnSize, 6261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky const EmittedFunctionDetails &Details); 6361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 6461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky virtual void NotifyFreeingMachineCode(void *OldPtr); 65776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor 66776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor virtual void NotifyObjectEmitted(const ObjectImage &Obj); 67776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor 68776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor virtual void NotifyFreeingObject(const ObjectImage &Obj); 6961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky}; 7061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 7161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskystatic LineNumberInfo LineStartToIntelJITFormat( 7261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky uintptr_t StartAddress, 7361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky uintptr_t Address, 7461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky DebugLoc Loc) { 7561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky LineNumberInfo Result; 7661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 7761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.Offset = Address - StartAddress; 7861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.LineNumber = Loc.getLine(); 7961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 8061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky return Result; 8161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky} 8261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 83710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylorstatic LineNumberInfo DILineInfoToIntelJITFormat(uintptr_t StartAddress, 84710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor uintptr_t Address, 85b8d2c92ac42eca3d4242bd7ce6c6e87a4d887727Andrew Kaylor DILineInfo Line) { 86710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor LineNumberInfo Result; 87710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor 88710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor Result.Offset = Address - StartAddress; 89cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Result.LineNumber = Line.Line; 90710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor 91710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor return Result; 92710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor} 93710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor 9461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskystatic iJIT_Method_Load FunctionDescToIntelJITFormat( 9561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky IntelJITEventsWrapper& Wrapper, 9661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky const char* FnName, 9761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky uintptr_t FnStart, 9861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky size_t FnSize) { 9961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky iJIT_Method_Load Result; 10061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky memset(&Result, 0, sizeof(iJIT_Method_Load)); 10161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 10261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.method_id = Wrapper.iJIT_GetNewMethodID(); 10361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.method_name = const_cast<char*>(FnName); 10461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.method_load_address = reinterpret_cast<void*>(FnStart); 10561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.method_size = FnSize; 10661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 10761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.class_id = 0; 10861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.class_file_name = NULL; 10961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.user_data = NULL; 11061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.user_data_size = 0; 11161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.env = iJDE_JittingAPI; 11261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 11361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky return Result; 11461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky} 11561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 11661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// Adds the just-emitted function to the symbol table. 11761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskyvoid IntelJITEventListener::NotifyFunctionEmitted( 11861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky const Function &F, void *FnStart, size_t FnSize, 11961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky const EmittedFunctionDetails &Details) { 12044aebe85e30e3ecb3d9fef39fe719513743e6024Andrew Kaylor iJIT_Method_Load FunctionMessage = FunctionDescToIntelJITFormat(*Wrapper, 12161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky F.getName().data(), 12261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky reinterpret_cast<uint64_t>(FnStart), 12361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FnSize); 12461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 12561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky std::vector<LineNumberInfo> LineInfo; 12661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 12761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky if (!Details.LineStarts.empty()) { 12861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky // Now convert the line number information from the address/DebugLoc 12961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky // format in Details to the offset/lineno in Intel JIT API format. 13061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 13161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky LineInfo.reserve(Details.LineStarts.size() + 1); 13261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 13361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky DebugLoc FirstLoc = Details.LineStarts[0].Loc; 13461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky assert(!FirstLoc.isUnknown() 13561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky && "LineStarts should not contain unknown DebugLocs"); 13661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 13761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky MDNode *FirstLocScope = FirstLoc.getScope(F.getContext()); 13861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky DISubprogram FunctionDI = getDISubprogram(FirstLocScope); 13961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky if (FunctionDI.Verify()) { 14061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FunctionMessage.source_file_name = const_cast<char*>( 14161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Filenames.getFullPath(FirstLocScope)); 14261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 14361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky LineNumberInfo FirstLine; 14461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FirstLine.Offset = 0; 14561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FirstLine.LineNumber = FunctionDI.getLineNumber(); 14661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky LineInfo.push_back(FirstLine); 14761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky } 14861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 14961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky for (std::vector<EmittedFunctionDetails::LineStart>::const_iterator I = 15061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Details.LineStarts.begin(), E = Details.LineStarts.end(); 15161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky I != E; ++I) { 15261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky // This implementation ignores the DebugLoc filename because the Intel 15361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky // JIT API does not support multiple source files associated with a single 15461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky // JIT function 15561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky LineInfo.push_back(LineStartToIntelJITFormat( 15661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky reinterpret_cast<uintptr_t>(FnStart), 15761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky I->Address, 15861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky I->Loc)); 15961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 16061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky // If we have no file name yet for the function, use the filename from 16161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky // the first instruction that has one 16261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky if (FunctionMessage.source_file_name == 0) { 16361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky MDNode *scope = I->Loc.getScope( 16496cb1128528a512f1ef9c28ae5e1b78a98dcc505Bill Wendling Details.MF->getFunction()->getContext()); 16561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FunctionMessage.source_file_name = const_cast<char*>( 16661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Filenames.getFullPath(scope)); 16761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky } 16861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky } 16961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 17061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FunctionMessage.line_number_size = LineInfo.size(); 17161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FunctionMessage.line_number_table = &*LineInfo.begin(); 17261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky } else { 17361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FunctionMessage.line_number_size = 0; 17461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FunctionMessage.line_number_table = 0; 17561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky } 17661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 17744aebe85e30e3ecb3d9fef39fe719513743e6024Andrew Kaylor Wrapper->iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, 17844aebe85e30e3ecb3d9fef39fe719513743e6024Andrew Kaylor &FunctionMessage); 17961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky MethodIDs[FnStart] = FunctionMessage.method_id; 18061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky} 18161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 18261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskyvoid IntelJITEventListener::NotifyFreeingMachineCode(void *FnStart) { 18361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky MethodIDMap::iterator I = MethodIDs.find(FnStart); 18461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky if (I != MethodIDs.end()) { 18544aebe85e30e3ecb3d9fef39fe719513743e6024Andrew Kaylor Wrapper->iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_UNLOAD_START, &I->second); 18661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky MethodIDs.erase(I); 18761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky } 18861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky} 18961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 190776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylorvoid IntelJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) { 19134519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor // Get the address of the object image for use as a unique identifier 19234519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor const void* ObjData = Obj.getData().data(); 193710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor DIContext* Context = DIContext::getDWARFContext(Obj.getObjectFile()); 19434519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor MethodAddressVector Functions; 19534519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor 19634519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor // Use symbol info to iterate functions in the object. 19734519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor for (object::symbol_iterator I = Obj.begin_symbols(), 19834519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor E = Obj.end_symbols(); 199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines I != E; 200dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ++I) { 201710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor std::vector<LineNumberInfo> LineInfo; 202710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor std::string SourceFileName; 203710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor 20434519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor object::SymbolRef::Type SymType; 20534519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor if (I->getType(SymType)) continue; 20634519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor if (SymType == object::SymbolRef::ST_Function) { 207710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor StringRef Name; 208710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor uint64_t Addr; 209710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor uint64_t Size; 21034519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor if (I->getName(Name)) continue; 21134519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor if (I->getAddress(Addr)) continue; 21234519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor if (I->getSize(Size)) continue; 21334519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor 21434519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor // Record this address in a local vector 21534519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor Functions.push_back((void*)Addr); 21634519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor 21734519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor // Build the function loaded notification message 21834519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor iJIT_Method_Load FunctionMessage = FunctionDescToIntelJITFormat(*Wrapper, 21934519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor Name.data(), 22034519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor Addr, 22134519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor Size); 222710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor if (Context) { 223710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size); 224710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor DILineInfoTable::iterator Begin = Lines.begin(); 225710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor DILineInfoTable::iterator End = Lines.end(); 226710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor for (DILineInfoTable::iterator It = Begin; It != End; ++It) { 227710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor LineInfo.push_back(DILineInfoToIntelJITFormat((uintptr_t)Addr, 228710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor It->first, 229710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor It->second)); 230710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor } 231710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor if (LineInfo.size() == 0) { 232710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor FunctionMessage.source_file_name = 0; 233710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor FunctionMessage.line_number_size = 0; 234710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor FunctionMessage.line_number_table = 0; 235710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor } else { 236cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SourceFileName = Lines.front().second.FileName; 237dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FunctionMessage.source_file_name = const_cast<char *>(SourceFileName.c_str()); 238710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor FunctionMessage.line_number_size = LineInfo.size(); 239710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor FunctionMessage.line_number_table = &*LineInfo.begin(); 240710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor } 241710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor } else { 242710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor FunctionMessage.source_file_name = 0; 243710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor FunctionMessage.line_number_size = 0; 244710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor FunctionMessage.line_number_table = 0; 245710cb0c7826c61b432e19d5899a2f26f76d7aa81Andrew Kaylor } 24634519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor 24734519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor Wrapper->iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, 24834519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor &FunctionMessage); 24934519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor MethodIDs[(void*)Addr] = FunctionMessage.method_id; 25034519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor } 25134519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor } 25234519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor 25334519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor // To support object unload notification, we need to keep a list of 25434519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor // registered function addresses for each loaded object. We will 25534519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor // use the MethodIDs map to get the registered ID for each function. 25634519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor LoadedObjectMap[ObjData] = Functions; 257776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor} 258776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor 259776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylorvoid IntelJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) { 26034519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor // Get the address of the object image for use as a unique identifier 26134519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor const void* ObjData = Obj.getData().data(); 26234519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor 26334519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor // Get the object's function list from LoadedObjectMap 26434519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor ObjectMap::iterator OI = LoadedObjectMap.find(ObjData); 26534519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor if (OI == LoadedObjectMap.end()) 26634519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor return; 26734519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor MethodAddressVector& Functions = OI->second; 26834519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor 26934519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor // Walk the function list, unregistering each function 27034519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor for (MethodAddressVector::iterator FI = Functions.begin(), 27134519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor FE = Functions.end(); 27234519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor FI != FE; 27334519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor ++FI) { 27434519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor void* FnStart = const_cast<void*>(*FI); 27534519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor MethodIDMap::iterator MI = MethodIDs.find(FnStart); 27634519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor if (MI != MethodIDs.end()) { 27734519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor Wrapper->iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_UNLOAD_START, 27834519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor &MI->second); 27934519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor MethodIDs.erase(MI); 28034519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor } 28134519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor } 28234519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor 28334519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor // Erase the object from LoadedObjectMap 28434519fc11df5107cbaab627efe4ea21f811c4430Andrew Kaylor LoadedObjectMap.erase(OI); 285776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor} 286776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor 28761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky} // anonymous namespace. 28861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 28961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskynamespace llvm { 29061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli BenderskyJITEventListener *JITEventListener::createIntelJITEventListener() { 29144aebe85e30e3ecb3d9fef39fe719513743e6024Andrew Kaylor return new IntelJITEventListener(new IntelJITEventsWrapper); 29261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky} 29361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 29461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// for testing 29561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli BenderskyJITEventListener *JITEventListener::createIntelJITEventListener( 29661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky IntelJITEventsWrapper* TestImpl) { 29744aebe85e30e3ecb3d9fef39fe719513743e6024Andrew Kaylor return new IntelJITEventListener(TestImpl); 29861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky} 29961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 30061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky} // namespace llvm 30161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 302