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