1//===- OProfileJITEventListenerTest.cpp - Unit tests for OProfileJITEventsListener --------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===--------------------------------------------------------------------------------------===//
9
10#include "llvm/ExecutionEngine/JITEventListener.h"
11#include "llvm/ExecutionEngine/OProfileWrapper.h"
12#include "JITEventListenerTestCommon.h"
13
14#include <map>
15#include <list>
16
17using namespace llvm;
18
19namespace {
20
21struct OprofileNativeFunction {
22  const char* Name;
23  uint64_t Addr;
24  const void* CodePtr;
25  unsigned int CodeSize;
26
27  OprofileNativeFunction(const char* name,
28                         uint64_t addr,
29                         const void* code,
30                         unsigned int size)
31  : Name(name)
32  , Addr(addr)
33  , CodePtr(code)
34  , CodeSize(size) {
35  }
36};
37
38typedef std::list<OprofileNativeFunction> NativeFunctionList;
39typedef std::list<debug_line_info> NativeDebugList;
40NativeFunctionList NativeFunctions;
41
42NativeCodeMap ReportedDebugFuncs;
43
44} // namespace
45
46/// Mock implementaion of opagent library
47namespace test_opagent {
48
49op_agent_t globalAgent = reinterpret_cast<op_agent_t>(42);
50
51op_agent_t open_agent()
52{
53  // return non-null op_agent_t
54  return globalAgent;
55}
56
57int close_agent(op_agent_t agent)
58{
59  EXPECT_EQ(globalAgent, agent);
60  return 0;
61}
62
63int write_native_code(op_agent_t agent,
64                      const char* name,
65                      uint64_t addr,
66                      void const* code,
67                      unsigned int size)
68{
69  EXPECT_EQ(globalAgent, agent);
70  OprofileNativeFunction func(name, addr, code, size);
71  NativeFunctions.push_back(func);
72
73  // Verify no other registration has take place for the same address
74  EXPECT_TRUE(ReportedDebugFuncs.find(addr) == ReportedDebugFuncs.end());
75
76  ReportedDebugFuncs[addr];
77  return 0;
78}
79
80int write_debug_line_info(op_agent_t agent,
81                          void const* code,
82                          size_t num_entries,
83                          struct debug_line_info const* info)
84{
85  EXPECT_EQ(globalAgent, agent);
86
87  //verify code has been loaded first
88  uint64_t addr = reinterpret_cast<uint64_t>(code);
89  NativeCodeMap::iterator i = ReportedDebugFuncs.find(addr);
90  EXPECT_TRUE(i != ReportedDebugFuncs.end());
91
92  NativeDebugList NativeInfo(info, info + num_entries);
93
94  SourceLocations locs;
95  for(NativeDebugList::iterator i = NativeInfo.begin();
96      i != NativeInfo.end();
97      ++i) {
98    locs.push_back(std::make_pair(std::string(i->filename), i->lineno));
99  }
100  ReportedDebugFuncs[addr] = locs;
101
102  return 0;
103}
104
105int unload_native_code(op_agent_t agent, uint64_t addr) {
106  EXPECT_EQ(globalAgent, agent);
107
108  //verify that something for the given JIT addr has been loaded first
109  NativeCodeMap::iterator i = ReportedDebugFuncs.find(addr);
110  EXPECT_TRUE(i != ReportedDebugFuncs.end());
111  ReportedDebugFuncs.erase(i);
112  return 0;
113}
114
115int version() {
116  return 1;
117}
118
119bool is_oprofile_running() {
120  return true;
121}
122
123} //namespace test_opagent
124
125class OProfileJITEventListenerTest
126: public JITEventListenerTestBase<OProfileWrapper>
127{
128public:
129  OProfileJITEventListenerTest()
130  : JITEventListenerTestBase<OProfileWrapper>(
131    new OProfileWrapper(test_opagent::open_agent,
132      test_opagent::close_agent,
133      test_opagent::write_native_code,
134      test_opagent::write_debug_line_info,
135      test_opagent::unload_native_code,
136      test_opagent::version,
137      test_opagent::version,
138      test_opagent::is_oprofile_running))
139  {
140    EXPECT_TRUE(0 != MockWrapper);
141
142    Listener.reset(JITEventListener::createOProfileJITEventListener(
143      MockWrapper.get()));
144    EXPECT_TRUE(0 != Listener);
145    EE->RegisterJITEventListener(Listener.get());
146  }
147};
148
149TEST_F(OProfileJITEventListenerTest, NoDebugInfo) {
150  TestNoDebugInfo(ReportedDebugFuncs);
151}
152
153TEST_F(OProfileJITEventListenerTest, SingleLine) {
154  TestSingleLine(ReportedDebugFuncs);
155}
156
157TEST_F(OProfileJITEventListenerTest, MultipleLines) {
158  TestMultipleLines(ReportedDebugFuncs);
159}
160
161TEST_F(OProfileJITEventListenerTest, MultipleFiles) {
162  TestMultipleFiles(ReportedDebugFuncs);
163}
164
165testing::Environment* const jit_env =
166  testing::AddGlobalTestEnvironment(new JITEnvironment);
167