llvm.org GIT mirror llvm / f963cd3
Follow-up to r152620: restore JIT event listener tests to unittest/ExecutionEngine/JIT git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152780 91177308-0d34-0410-b5e6-96231b3b80d8 Eli Bendersky 8 years ago
11 changed file(s) with 755 addition(s) and 757 deletion(s). Raw diff Collapse all Expand all
8282 Analysis/ScalarEvolutionTest.cpp
8383 )
8484
85 add_llvm_unittest(ExecutionEngine
86 ExecutionEngine/ExecutionEngineTest.cpp
87 )
88
8589 if( LLVM_USE_INTEL_JITEVENTS )
8690 include_directories( ${LLVM_INTEL_JITEVENTS_INCDIR} )
8791 link_directories( ${LLVM_INTEL_JITEVENTS_LIBDIR} )
8892 set(ProfileTestSources
89 ExecutionEngine/IntelJITEventListenerTest.cpp
93 ExecutionEngine/JIT/IntelJITEventListenerTest.cpp
9094 )
9195 set(LLVM_LINK_COMPONENTS
9296 ${LLVM_LINK_COMPONENTS}
97101 if( LLVM_USE_OPROFILE )
98102 set(ProfileTestSources
99103 ${ProfileTestSources}
100 ExecutionEngine/OProfileJITEventListenerTest.cpp
104 ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp
101105 )
102106 set(LLVM_LINK_COMPONENTS
103107 ${LLVM_LINK_COMPONENTS}
105109 )
106110 endif( LLVM_USE_OPROFILE )
107111
108 add_llvm_unittest(ExecutionEngine
109 ExecutionEngine/ExecutionEngineTest.cpp
110 ExecutionEngine/JITEventListenerTest.cpp
111 ${ProfileTestSources}
112 )
113
114112 set(JITTestsSources
113 ExecutionEngine/JIT/JITEventListenerTest.cpp
115114 ExecutionEngine/JIT/JITMemoryManagerTest.cpp
116115 ExecutionEngine/JIT/JITTest.cpp
117116 ExecutionEngine/JIT/MultiJITTest.cpp
117 ${ProfileTestSources}
118118 )
119119
120120 if(MSVC)
+0
-110
unittests/ExecutionEngine/IntelJITEventListenerTest.cpp less more
None //===- JITEventListenerTest.cpp - Tests for Intel JITEventListener --------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "JITEventListenerTestCommon.h"
10
11 using namespace llvm;
12
13 #include "llvm/ExecutionEngine/IntelJITEventsWrapper.h"
14
15 #include
16 #include
17
18 namespace {
19
20 // map of function ("method") IDs to source locations
21 NativeCodeMap ReportedDebugFuncs;
22
23 } // namespace
24
25 /// Mock implementaion of Intel JIT API jitprofiling library
26 namespace test_jitprofiling {
27
28 int NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) {
29 switch (EventType) {
30 case iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED: {
31 EXPECT_TRUE(0 != EventSpecificData);
32 iJIT_Method_Load* msg = static_cast(EventSpecificData);
33
34 ReportedDebugFuncs[msg->method_id];
35
36 for(unsigned int i = 0; i < msg->line_number_size; ++i) {
37 EXPECT_TRUE(0 != msg->line_number_table);
38 std::pair loc(
39 std::string(msg->source_file_name),
40 msg->line_number_table[i].LineNumber);
41 ReportedDebugFuncs[msg->method_id].push_back(loc);
42 }
43 }
44 break;
45 case iJVM_EVENT_TYPE_METHOD_UNLOAD_START: {
46 EXPECT_TRUE(0 != EventSpecificData);
47 unsigned int UnloadId
48 = *reinterpret_cast(EventSpecificData);
49 EXPECT_TRUE(1 == ReportedDebugFuncs.erase(UnloadId));
50 }
51 default:
52 break;
53 }
54 return 0;
55 }
56
57 iJIT_IsProfilingActiveFlags IsProfilingActive(void) {
58 // for testing, pretend we have an Intel Parallel Amplifier XE 2011
59 // instance attached
60 return iJIT_SAMPLING_ON;
61 }
62
63 unsigned int GetNewMethodID(void) {
64 static unsigned int id = 0;
65 return ++id;
66 }
67
68 } //namespace test_jitprofiling
69
70 class IntelJITEventListenerTest
71 : public JITEventListenerTestBase {
72 public:
73 IntelJITEventListenerTest()
74 : JITEventListenerTestBase(
75 new IntelJITEventsWrapper(test_jitprofiling::NotifyEvent, 0,
76 test_jitprofiling::IsProfilingActive, 0, 0,
77 test_jitprofiling::GetNewMethodID))
78 {
79 EXPECT_TRUE(0 != MockWrapper);
80
81 Listener.reset(JITEventListener::createIntelJITEventListener(
82 MockWrapper.get()));
83 EXPECT_TRUE(0 != Listener);
84 EE->RegisterJITEventListener(Listener.get());
85 }
86 };
87
88 TEST_F(IntelJITEventListenerTest, NoDebugInfo) {
89 TestNoDebugInfo(ReportedDebugFuncs);
90 }
91
92 TEST_F(IntelJITEventListenerTest, SingleLine) {
93 TestSingleLine(ReportedDebugFuncs);
94 }
95
96 TEST_F(IntelJITEventListenerTest, MultipleLines) {
97 TestMultipleLines(ReportedDebugFuncs);
98 }
99
100 // This testcase is disabled because the Intel JIT API does not support a single
101 // JITted function with source lines associated with multiple files
102 /*
103 TEST_F(IntelJITEventListenerTest, MultipleFiles) {
104 TestMultipleFiles(ReportedDebugFuncs);
105 }
106 */
107
108 testing::Environment* const jit_env =
109 testing::AddGlobalTestEnvironment(new JITEnvironment);
0 //===- JITEventListenerTest.cpp - Tests for Intel JITEventListener --------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "JITEventListenerTestCommon.h"
10
11 using namespace llvm;
12
13 #include "llvm/ExecutionEngine/IntelJITEventsWrapper.h"
14
15 #include
16 #include
17
18 namespace {
19
20 // map of function ("method") IDs to source locations
21 NativeCodeMap ReportedDebugFuncs;
22
23 } // namespace
24
25 /// Mock implementaion of Intel JIT API jitprofiling library
26 namespace test_jitprofiling {
27
28 int NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) {
29 switch (EventType) {
30 case iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED: {
31 EXPECT_TRUE(0 != EventSpecificData);
32 iJIT_Method_Load* msg = static_cast(EventSpecificData);
33
34 ReportedDebugFuncs[msg->method_id];
35
36 for(unsigned int i = 0; i < msg->line_number_size; ++i) {
37 EXPECT_TRUE(0 != msg->line_number_table);
38 std::pair loc(
39 std::string(msg->source_file_name),
40 msg->line_number_table[i].LineNumber);
41 ReportedDebugFuncs[msg->method_id].push_back(loc);
42 }
43 }
44 break;
45 case iJVM_EVENT_TYPE_METHOD_UNLOAD_START: {
46 EXPECT_TRUE(0 != EventSpecificData);
47 unsigned int UnloadId
48 = *reinterpret_cast(EventSpecificData);
49 EXPECT_TRUE(1 == ReportedDebugFuncs.erase(UnloadId));
50 }
51 default:
52 break;
53 }
54 return 0;
55 }
56
57 iJIT_IsProfilingActiveFlags IsProfilingActive(void) {
58 // for testing, pretend we have an Intel Parallel Amplifier XE 2011
59 // instance attached
60 return iJIT_SAMPLING_ON;
61 }
62
63 unsigned int GetNewMethodID(void) {
64 static unsigned int id = 0;
65 return ++id;
66 }
67
68 } //namespace test_jitprofiling
69
70 class IntelJITEventListenerTest
71 : public JITEventListenerTestBase {
72 public:
73 IntelJITEventListenerTest()
74 : JITEventListenerTestBase(
75 new IntelJITEventsWrapper(test_jitprofiling::NotifyEvent, 0,
76 test_jitprofiling::IsProfilingActive, 0, 0,
77 test_jitprofiling::GetNewMethodID))
78 {
79 EXPECT_TRUE(0 != MockWrapper);
80
81 Listener.reset(JITEventListener::createIntelJITEventListener(
82 MockWrapper.get()));
83 EXPECT_TRUE(0 != Listener);
84 EE->RegisterJITEventListener(Listener.get());
85 }
86 };
87
88 TEST_F(IntelJITEventListenerTest, NoDebugInfo) {
89 TestNoDebugInfo(ReportedDebugFuncs);
90 }
91
92 TEST_F(IntelJITEventListenerTest, SingleLine) {
93 TestSingleLine(ReportedDebugFuncs);
94 }
95
96 TEST_F(IntelJITEventListenerTest, MultipleLines) {
97 TestMultipleLines(ReportedDebugFuncs);
98 }
99
100 // This testcase is disabled because the Intel JIT API does not support a single
101 // JITted function with source lines associated with multiple files
102 /*
103 TEST_F(IntelJITEventListenerTest, MultipleFiles) {
104 TestMultipleFiles(ReportedDebugFuncs);
105 }
106 */
107
108 testing::Environment* const jit_env =
109 testing::AddGlobalTestEnvironment(new JITEnvironment);
0 //===- JITEventListenerTest.cpp - Unit tests for JITEventListeners --------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/ExecutionEngine/JITEventListener.h"
10
11 #include "llvm/LLVMContext.h"
12 #include "llvm/Instructions.h"
13 #include "llvm/Module.h"
14 #include "llvm/ADT/OwningPtr.h"
15 #include "llvm/CodeGen/MachineCodeInfo.h"
16 #include "llvm/ExecutionEngine/JIT.h"
17 #include "llvm/Support/TypeBuilder.h"
18 #include "llvm/Support/TargetSelect.h"
19 #include "gtest/gtest.h"
20 #include
21
22 using namespace llvm;
23
24 int dummy;
25
26 namespace {
27
28 struct FunctionEmittedEvent {
29 // Indices are local to the RecordingJITEventListener, since the
30 // JITEventListener interface makes no guarantees about the order of
31 // calls between Listeners.
32 unsigned Index;
33 const Function *F;
34 void *Code;
35 size_t Size;
36 JITEvent_EmittedFunctionDetails Details;
37 };
38 struct FunctionFreedEvent {
39 unsigned Index;
40 void *Code;
41 };
42
43 struct RecordingJITEventListener : public JITEventListener {
44 std::vector EmittedEvents;
45 std::vector FreedEvents;
46
47 unsigned NextIndex;
48
49 RecordingJITEventListener() : NextIndex(0) {}
50
51 virtual void NotifyFunctionEmitted(const Function &F,
52 void *Code, size_t Size,
53 const EmittedFunctionDetails &Details) {
54 FunctionEmittedEvent Event = {NextIndex++, &F, Code, Size, Details};
55 EmittedEvents.push_back(Event);
56 }
57
58 virtual void NotifyFreeingMachineCode(void *OldPtr) {
59 FunctionFreedEvent Event = {NextIndex++, OldPtr};
60 FreedEvents.push_back(Event);
61 }
62 };
63
64 class JITEventListenerTest : public testing::Test {
65 protected:
66 JITEventListenerTest()
67 : M(new Module("module", getGlobalContext())),
68 EE(EngineBuilder(M)
69 .setEngineKind(EngineKind::JIT)
70 .create()) {
71 }
72
73 Module *M;
74 const OwningPtr EE;
75 };
76
77 Function *buildFunction(Module *M) {
78 Function *Result = Function::Create(
79 TypeBuilder::get(getGlobalContext()),
80 GlobalValue::ExternalLinkage, "id", M);
81 Value *Arg = Result->arg_begin();
82 BasicBlock *BB = BasicBlock::Create(M->getContext(), "entry", Result);
83 ReturnInst::Create(M->getContext(), Arg, BB);
84 return Result;
85 }
86
87 // Tests that a single JITEventListener follows JIT events accurately.
88 TEST_F(JITEventListenerTest, Simple) {
89 RecordingJITEventListener Listener;
90 EE->RegisterJITEventListener(&Listener);
91 Function *F1 = buildFunction(M);
92 Function *F2 = buildFunction(M);
93
94 void *F1_addr = EE->getPointerToFunction(F1);
95 void *F2_addr = EE->getPointerToFunction(F2);
96 EE->getPointerToFunction(F1); // Should do nothing.
97 EE->freeMachineCodeForFunction(F1);
98 EE->freeMachineCodeForFunction(F2);
99
100 ASSERT_EQ(2U, Listener.EmittedEvents.size());
101 ASSERT_EQ(2U, Listener.FreedEvents.size());
102
103 EXPECT_EQ(0U, Listener.EmittedEvents[0].Index);
104 EXPECT_EQ(F1, Listener.EmittedEvents[0].F);
105 EXPECT_EQ(F1_addr, Listener.EmittedEvents[0].Code);
106 EXPECT_LT(0U, Listener.EmittedEvents[0].Size)
107 << "We don't know how big the function will be, but it had better"
108 << " contain some bytes.";
109
110 EXPECT_EQ(1U, Listener.EmittedEvents[1].Index);
111 EXPECT_EQ(F2, Listener.EmittedEvents[1].F);
112 EXPECT_EQ(F2_addr, Listener.EmittedEvents[1].Code);
113 EXPECT_LT(0U, Listener.EmittedEvents[1].Size)
114 << "We don't know how big the function will be, but it had better"
115 << " contain some bytes.";
116
117 EXPECT_EQ(2U, Listener.FreedEvents[0].Index);
118 EXPECT_EQ(F1_addr, Listener.FreedEvents[0].Code);
119
120 EXPECT_EQ(3U, Listener.FreedEvents[1].Index);
121 EXPECT_EQ(F2_addr, Listener.FreedEvents[1].Code);
122
123 F1->eraseFromParent();
124 F2->eraseFromParent();
125 }
126
127 // Tests that a single JITEventListener follows JIT events accurately.
128 TEST_F(JITEventListenerTest, MultipleListenersDontInterfere) {
129 RecordingJITEventListener Listener1;
130 RecordingJITEventListener Listener2;
131 RecordingJITEventListener Listener3;
132 Function *F1 = buildFunction(M);
133 Function *F2 = buildFunction(M);
134
135 EE->RegisterJITEventListener(&Listener1);
136 EE->RegisterJITEventListener(&Listener2);
137 void *F1_addr = EE->getPointerToFunction(F1);
138 EE->RegisterJITEventListener(&Listener3);
139 EE->UnregisterJITEventListener(&Listener1);
140 void *F2_addr = EE->getPointerToFunction(F2);
141 EE->UnregisterJITEventListener(&Listener2);
142 EE->UnregisterJITEventListener(&Listener3);
143 EE->freeMachineCodeForFunction(F1);
144 EE->RegisterJITEventListener(&Listener2);
145 EE->RegisterJITEventListener(&Listener3);
146 EE->RegisterJITEventListener(&Listener1);
147 EE->freeMachineCodeForFunction(F2);
148 EE->UnregisterJITEventListener(&Listener1);
149 EE->UnregisterJITEventListener(&Listener2);
150 EE->UnregisterJITEventListener(&Listener3);
151
152 // Listener 1.
153 ASSERT_EQ(1U, Listener1.EmittedEvents.size());
154 ASSERT_EQ(1U, Listener1.FreedEvents.size());
155
156 EXPECT_EQ(0U, Listener1.EmittedEvents[0].Index);
157 EXPECT_EQ(F1, Listener1.EmittedEvents[0].F);
158 EXPECT_EQ(F1_addr, Listener1.EmittedEvents[0].Code);
159 EXPECT_LT(0U, Listener1.EmittedEvents[0].Size)
160 << "We don't know how big the function will be, but it had better"
161 << " contain some bytes.";
162
163 EXPECT_EQ(1U, Listener1.FreedEvents[0].Index);
164 EXPECT_EQ(F2_addr, Listener1.FreedEvents[0].Code);
165
166 // Listener 2.
167 ASSERT_EQ(2U, Listener2.EmittedEvents.size());
168 ASSERT_EQ(1U, Listener2.FreedEvents.size());
169
170 EXPECT_EQ(0U, Listener2.EmittedEvents[0].Index);
171 EXPECT_EQ(F1, Listener2.EmittedEvents[0].F);
172 EXPECT_EQ(F1_addr, Listener2.EmittedEvents[0].Code);
173 EXPECT_LT(0U, Listener2.EmittedEvents[0].Size)
174 << "We don't know how big the function will be, but it had better"
175 << " contain some bytes.";
176
177 EXPECT_EQ(1U, Listener2.EmittedEvents[1].Index);
178 EXPECT_EQ(F2, Listener2.EmittedEvents[1].F);
179 EXPECT_EQ(F2_addr, Listener2.EmittedEvents[1].Code);
180 EXPECT_LT(0U, Listener2.EmittedEvents[1].Size)
181 << "We don't know how big the function will be, but it had better"
182 << " contain some bytes.";
183
184 EXPECT_EQ(2U, Listener2.FreedEvents[0].Index);
185 EXPECT_EQ(F2_addr, Listener2.FreedEvents[0].Code);
186
187 // Listener 3.
188 ASSERT_EQ(1U, Listener3.EmittedEvents.size());
189 ASSERT_EQ(1U, Listener3.FreedEvents.size());
190
191 EXPECT_EQ(0U, Listener3.EmittedEvents[0].Index);
192 EXPECT_EQ(F2, Listener3.EmittedEvents[0].F);
193 EXPECT_EQ(F2_addr, Listener3.EmittedEvents[0].Code);
194 EXPECT_LT(0U, Listener3.EmittedEvents[0].Size)
195 << "We don't know how big the function will be, but it had better"
196 << " contain some bytes.";
197
198 EXPECT_EQ(1U, Listener3.FreedEvents[0].Index);
199 EXPECT_EQ(F2_addr, Listener3.FreedEvents[0].Code);
200
201 F1->eraseFromParent();
202 F2->eraseFromParent();
203 }
204
205 TEST_F(JITEventListenerTest, MatchesMachineCodeInfo) {
206 RecordingJITEventListener Listener;
207 MachineCodeInfo MCI;
208 Function *F = buildFunction(M);
209
210 EE->RegisterJITEventListener(&Listener);
211 EE->runJITOnFunction(F, &MCI);
212 void *F_addr = EE->getPointerToFunction(F);
213 EE->freeMachineCodeForFunction(F);
214
215 ASSERT_EQ(1U, Listener.EmittedEvents.size());
216 ASSERT_EQ(1U, Listener.FreedEvents.size());
217
218 EXPECT_EQ(0U, Listener.EmittedEvents[0].Index);
219 EXPECT_EQ(F, Listener.EmittedEvents[0].F);
220 EXPECT_EQ(F_addr, Listener.EmittedEvents[0].Code);
221 EXPECT_EQ(MCI.address(), Listener.EmittedEvents[0].Code);
222 EXPECT_EQ(MCI.size(), Listener.EmittedEvents[0].Size);
223
224 EXPECT_EQ(1U, Listener.FreedEvents[0].Index);
225 EXPECT_EQ(F_addr, Listener.FreedEvents[0].Code);
226 }
227
228 class JITEnvironment : public testing::Environment {
229 virtual void SetUp() {
230 // Required to create a JIT.
231 InitializeNativeTarget();
232 }
233 };
234 testing::Environment* const jit_env =
235 testing::AddGlobalTestEnvironment(new JITEnvironment);
236
237 } // anonymous namespace
0 //===- JITEventListenerTestCommon.h - Helper for JITEventListener tests ------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===-------------------------------------------------------------------------------===//
8
9 #ifndef JIT_EVENT_LISTENER_TEST_COMMON_H
10 #define JIT_EVENT_LISTENER_TEST_COMMON_H
11
12 #include "llvm/Analysis/DIBuilder.h"
13 #include "llvm/Analysis/DebugInfo.h"
14 #include "llvm/CodeGen/MachineCodeInfo.h"
15 #include "llvm/Config/config.h"
16 #include "llvm/ExecutionEngine/JIT.h"
17 #include "llvm/ExecutionEngine/JITEventListener.h"
18 #include "llvm/Instructions.h"
19 #include "llvm/Module.h"
20 #include "llvm/Support/IRBuilder.h"
21 #include "llvm/Support/Dwarf.h"
22 #include "llvm/Support/TypeBuilder.h"
23 #include "llvm/Support/TargetSelect.h"
24
25 #include "gtest/gtest.h"
26
27 #include
28 #include
29 #include
30
31 typedef std::vector > SourceLocations;
32 typedef std::map NativeCodeMap;
33
34 class JITEnvironment : public testing::Environment {
35 virtual void SetUp() {
36 // Required to create a JIT.
37 llvm::InitializeNativeTarget();
38 }
39 };
40
41 inline unsigned int getLine() {
42 return 12;
43 }
44
45 inline unsigned int getCol() {
46 return 0;
47 }
48
49 inline const char* getFilename() {
50 return "mock_source_file.cpp";
51 }
52
53 // Test fixture shared by tests for listener implementations
54 template
55 class JITEventListenerTestBase : public testing::Test {
56 protected:
57 llvm::OwningPtr MockWrapper;
58 llvm::OwningPtr Listener;
59
60 public:
61 llvm::Module* M;
62 llvm::MDNode* Scope;
63 llvm::ExecutionEngine* EE;
64 llvm::DIBuilder* DebugBuilder;
65 llvm::IRBuilder<> Builder;
66
67 JITEventListenerTestBase(WrapperT* w)
68 : MockWrapper(w)
69 , M(new llvm::Module("module", llvm::getGlobalContext()))
70 , EE(llvm::EngineBuilder(M)
71 .setEngineKind(llvm::EngineKind::JIT)
72 .setOptLevel(llvm::CodeGenOpt::None)
73 .create())
74 , DebugBuilder(new llvm::DIBuilder(*M))
75 , Builder(llvm::getGlobalContext())
76 {
77 DebugBuilder->createCompileUnit(llvm::dwarf::DW_LANG_C_plus_plus,
78 "JIT",
79 "JIT",
80 "JIT",
81 true,
82 "",
83 1);
84
85 Scope = DebugBuilder->createFile(getFilename(), ".");
86 }
87
88 llvm::Function *buildFunction(const SourceLocations& DebugLocations) {
89 using namespace llvm;
90
91 LLVMContext& GlobalContext = getGlobalContext();
92
93 SourceLocations::const_iterator CurrentDebugLocation
94 = DebugLocations.begin();
95
96 if (CurrentDebugLocation != DebugLocations.end()) {
97 DebugLoc DebugLocation = DebugLoc::get(getLine(), getCol(),
98 DebugBuilder->createFile(CurrentDebugLocation->first, "."));
99 Builder.SetCurrentDebugLocation(DebugLocation);
100 CurrentDebugLocation++;
101 }
102
103 Function *Result = Function::Create(
104 TypeBuilder::get(GlobalContext),
105 GlobalValue::ExternalLinkage, "id", M);
106 Value *Arg = Result->arg_begin();
107 BasicBlock *BB = BasicBlock::Create(M->getContext(), "entry", Result);
108 Builder.SetInsertPoint(BB);
109 Value* one = ConstantInt::get(GlobalContext, APInt(32, 1));
110 for(; CurrentDebugLocation != DebugLocations.end();
111 ++CurrentDebugLocation) {
112 Arg = Builder.CreateMul(Arg, Builder.CreateAdd(Arg, one));
113 Builder.SetCurrentDebugLocation(
114 DebugLoc::get(CurrentDebugLocation->second, 0,
115 DebugBuilder->createFile(CurrentDebugLocation->first, ".")));
116 }
117 Builder.CreateRet(Arg);
118 return Result;
119 }
120
121 void TestNoDebugInfo(NativeCodeMap& ReportedDebugFuncs) {
122 SourceLocations DebugLocations;
123 llvm::Function* f = buildFunction(DebugLocations);
124 EXPECT_TRUE(0 != f);
125
126 //Cause JITting and callbacks to our listener
127 EXPECT_TRUE(0 != EE->getPointerToFunction(f));
128 EXPECT_TRUE(1 == ReportedDebugFuncs.size());
129
130 EE->freeMachineCodeForFunction(f);
131 EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
132 }
133
134 void TestSingleLine(NativeCodeMap& ReportedDebugFuncs) {
135 SourceLocations DebugLocations;
136 DebugLocations.push_back(std::make_pair(std::string(getFilename()),
137 getLine()));
138 llvm::Function* f = buildFunction(DebugLocations);
139 EXPECT_TRUE(0 != f);
140
141 EXPECT_TRUE(0 != EE->getPointerToFunction(f));
142 EXPECT_TRUE(1 == ReportedDebugFuncs.size());
143 EXPECT_STREQ(ReportedDebugFuncs.begin()->second.begin()->first.c_str(),
144 getFilename());
145 EXPECT_EQ(ReportedDebugFuncs.begin()->second.begin()->second, getLine());
146
147 EE->freeMachineCodeForFunction(f);
148 EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
149 }
150
151 void TestMultipleLines(NativeCodeMap& ReportedDebugFuncs) {
152 using namespace std;
153
154 SourceLocations DebugLocations;
155 unsigned int c = 5;
156 for(unsigned int i = 0; i < c; ++i) {
157 DebugLocations.push_back(make_pair(string(getFilename()), getLine() + i));
158 }
159
160 llvm::Function* f = buildFunction(DebugLocations);
161 EXPECT_TRUE(0 != f);
162
163 EXPECT_TRUE(0 != EE->getPointerToFunction(f));
164 EXPECT_TRUE(1 == ReportedDebugFuncs.size());
165 SourceLocations& FunctionInfo = ReportedDebugFuncs.begin()->second;
166 EXPECT_EQ(c, FunctionInfo.size());
167
168 int VerifyCount = 0;
169 for(SourceLocations::iterator i = FunctionInfo.begin();
170 i != FunctionInfo.end();
171 ++i) {
172 EXPECT_STREQ(i->first.c_str(), getFilename());
173 EXPECT_EQ(i->second, getLine() + VerifyCount);
174 VerifyCount++;
175 }
176
177 EE->freeMachineCodeForFunction(f);
178 EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
179 }
180
181 void TestMultipleFiles(NativeCodeMap& ReportedDebugFuncs) {
182
183 std::string secondFilename("another_file.cpp");
184
185 SourceLocations DebugLocations;
186 DebugLocations.push_back(std::make_pair(std::string(getFilename()),
187 getLine()));
188 DebugLocations.push_back(std::make_pair(secondFilename, getLine()));
189 llvm::Function* f = buildFunction(DebugLocations);
190 EXPECT_TRUE(0 != f);
191
192 EXPECT_TRUE(0 != EE->getPointerToFunction(f));
193 EXPECT_TRUE(1 == ReportedDebugFuncs.size());
194 SourceLocations& FunctionInfo = ReportedDebugFuncs.begin()->second;
195 EXPECT_TRUE(2 == FunctionInfo.size());
196
197 EXPECT_STREQ(FunctionInfo.at(0).first.c_str(), getFilename());
198 EXPECT_STREQ(FunctionInfo.at(1).first.c_str(), secondFilename.c_str());
199
200 EXPECT_EQ(FunctionInfo.at(0).second, getLine());
201 EXPECT_EQ(FunctionInfo.at(1).second, getLine());
202
203 EE->freeMachineCodeForFunction(f);
204 EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
205 }
206 };
207
208 #endif //JIT_EVENT_LISTENER_TEST_COMMON_H
1111 LINK_COMPONENTS := asmparser bitreader bitwriter core jit native support
1212
1313 include $(LEVEL)/Makefile.config
14
15 SOURCES := JITEventListenerTest.cpp
16
17 ifeq ($(USE_INTEL_JITEVENTS), 1)
18 # Build the Intel JIT Events interface tests
19 SOURCES += IntelJITEventListenerTest.cpp
20
21 # Add the Intel JIT Events include directory
22 CPPFLAGS += -I$(INTEL_JITEVENTS_INCDIR)
23
24 # Link against the LLVM Intel JIT Evens interface library
25 LINK_COMPONENTS += inteljitevents
26 endif
27
28 ifeq ($(USE_OPROFILE), 1)
29 # Build the OProfile JIT interface tests
30 SOURCES += OProfileJITEventListenerTest.cpp
31
32 # Link against the LLVM oprofile interface library
33 LINK_COMPONENTS += oprofilejit
34 endif
35
36
1437 include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
1538
1639 # Permit these tests to use the JIT's symbolic lookup.
0 //===- OProfileJITEventListenerTest.cpp - Unit tests for OProfileJITEventsListener --------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===--------------------------------------------------------------------------------------===//
8
9 #include "llvm/ExecutionEngine/JITEventListener.h"
10 #include "llvm/ExecutionEngine/OProfileWrapper.h"
11 #include "JITEventListenerTestCommon.h"
12
13 #include
14 #include
15
16 using namespace llvm;
17
18 namespace {
19
20 struct OprofileNativeFunction {
21 const char* Name;
22 uint64_t Addr;
23 const void* CodePtr;
24 unsigned int CodeSize;
25
26 OprofileNativeFunction(const char* name,
27 uint64_t addr,
28 const void* code,
29 unsigned int size)
30 : Name(name)
31 , Addr(addr)
32 , CodePtr(code)
33 , CodeSize(size) {
34 }
35 };
36
37 typedef std::list NativeFunctionList;
38 typedef std::list NativeDebugList;
39 NativeFunctionList NativeFunctions;
40
41 NativeCodeMap ReportedDebugFuncs;
42
43 } // namespace
44
45 /// Mock implementaion of opagent library
46 namespace test_opagent {
47
48 op_agent_t globalAgent = reinterpret_cast(42);
49
50 op_agent_t open_agent()
51 {
52 // return non-null op_agent_t
53 return globalAgent;
54 }
55
56 int close_agent(op_agent_t agent)
57 {
58 EXPECT_EQ(globalAgent, agent);
59 return 0;
60 }
61
62 int write_native_code(op_agent_t agent,
63 const char* name,
64 uint64_t addr,
65 void const* code,
66 unsigned int size)
67 {
68 EXPECT_EQ(globalAgent, agent);
69 OprofileNativeFunction func(name, addr, code, size);
70 NativeFunctions.push_back(func);
71
72 // Verify no other registration has take place for the same address
73 EXPECT_TRUE(ReportedDebugFuncs.find(addr) == ReportedDebugFuncs.end());
74
75 ReportedDebugFuncs[addr];
76 return 0;
77 }
78
79 int write_debug_line_info(op_agent_t agent,
80 void const* code,
81 size_t num_entries,
82 struct debug_line_info const* info)
83 {
84 EXPECT_EQ(globalAgent, agent);
85
86 //verify code has been loaded first
87 uint64_t addr = reinterpret_cast(code);
88 NativeCodeMap::iterator i = ReportedDebugFuncs.find(addr);
89 EXPECT_TRUE(i != ReportedDebugFuncs.end());
90
91 NativeDebugList NativeInfo(info, info + num_entries);
92
93 SourceLocations locs;
94 for(NativeDebugList::iterator i = NativeInfo.begin();
95 i != NativeInfo.end();
96 ++i) {
97 locs.push_back(std::make_pair(std::string(i->filename), i->lineno));
98 }
99 ReportedDebugFuncs[addr] = locs;
100
101 return 0;
102 }
103
104 int unload_native_code(op_agent_t agent, uint64_t addr) {
105 EXPECT_EQ(globalAgent, agent);
106
107 //verify that something for the given JIT addr has been loaded first
108 NativeCodeMap::iterator i = ReportedDebugFuncs.find(addr);
109 EXPECT_TRUE(i != ReportedDebugFuncs.end());
110 ReportedDebugFuncs.erase(i);
111 return 0;
112 }
113
114 int version() {
115 return 1;
116 }
117
118 bool is_oprofile_running() {
119 return true;
120 }
121
122 } //namespace test_opagent
123
124 class OProfileJITEventListenerTest
125 : public JITEventListenerTestBase
126 {
127 public:
128 OProfileJITEventListenerTest()
129 : JITEventListenerTestBase(
130 new OProfileWrapper(test_opagent::open_agent,
131 test_opagent::close_agent,
132 test_opagent::write_native_code,
133 test_opagent::write_debug_line_info,
134 test_opagent::unload_native_code,
135 test_opagent::version,
136 test_opagent::version,
137 test_opagent::is_oprofile_running))
138 {
139 EXPECT_TRUE(0 != MockWrapper);
140
141 Listener.reset(JITEventListener::createOProfileJITEventListener(
142 MockWrapper.get()));
143 EXPECT_TRUE(0 != Listener);
144 EE->RegisterJITEventListener(Listener.get());
145 }
146 };
147
148 TEST_F(OProfileJITEventListenerTest, NoDebugInfo) {
149 TestNoDebugInfo(ReportedDebugFuncs);
150 }
151
152 TEST_F(OProfileJITEventListenerTest, SingleLine) {
153 TestSingleLine(ReportedDebugFuncs);
154 }
155
156 TEST_F(OProfileJITEventListenerTest, MultipleLines) {
157 TestMultipleLines(ReportedDebugFuncs);
158 }
159
160 TEST_F(OProfileJITEventListenerTest, MultipleFiles) {
161 TestMultipleFiles(ReportedDebugFuncs);
162 }
163
164 testing::Environment* const jit_env =
165 testing::AddGlobalTestEnvironment(new JITEnvironment);
+0
-238
unittests/ExecutionEngine/JITEventListenerTest.cpp less more
None //===- JITEventListenerTest.cpp - Unit tests for JITEventListeners --------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/ExecutionEngine/JITEventListener.h"
10
11 #include "llvm/LLVMContext.h"
12 #include "llvm/Instructions.h"
13 #include "llvm/Module.h"
14 #include "llvm/ADT/OwningPtr.h"
15 #include "llvm/CodeGen/MachineCodeInfo.h"
16 #include "llvm/ExecutionEngine/JIT.h"
17 #include "llvm/Support/TypeBuilder.h"
18 #include "llvm/Support/TargetSelect.h"
19 #include "gtest/gtest.h"
20 #include
21
22 using namespace llvm;
23
24 int dummy;
25
26 namespace {
27
28 struct FunctionEmittedEvent {
29 // Indices are local to the RecordingJITEventListener, since the
30 // JITEventListener interface makes no guarantees about the order of
31 // calls between Listeners.
32 unsigned Index;
33 const Function *F;
34 void *Code;
35 size_t Size;
36 JITEvent_EmittedFunctionDetails Details;
37 };
38 struct FunctionFreedEvent {
39 unsigned Index;
40 void *Code;
41 };
42
43 struct RecordingJITEventListener : public JITEventListener {
44 std::vector EmittedEvents;
45 std::vector FreedEvents;
46
47 unsigned NextIndex;
48
49 RecordingJITEventListener() : NextIndex(0) {}
50
51 virtual void NotifyFunctionEmitted(const Function &F,
52 void *Code, size_t Size,
53 const EmittedFunctionDetails &Details) {
54 FunctionEmittedEvent Event = {NextIndex++, &F, Code, Size, Details};
55 EmittedEvents.push_back(Event);
56 }
57
58 virtual void NotifyFreeingMachineCode(void *OldPtr) {
59 FunctionFreedEvent Event = {NextIndex++, OldPtr};
60 FreedEvents.push_back(Event);
61 }
62 };
63
64 class JITEventListenerTest : public testing::Test {
65 protected:
66 JITEventListenerTest()
67 : M(new Module("module", getGlobalContext())),
68 EE(EngineBuilder(M)
69 .setEngineKind(EngineKind::JIT)
70 .create()) {
71 }
72
73 Module *M;
74 const OwningPtr EE;
75 };
76
77 Function *buildFunction(Module *M) {
78 Function *Result = Function::Create(
79 TypeBuilder::get(getGlobalContext()),
80 GlobalValue::ExternalLinkage, "id", M);
81 Value *Arg = Result->arg_begin();
82 BasicBlock *BB = BasicBlock::Create(M->getContext(), "entry", Result);
83 ReturnInst::Create(M->getContext(), Arg, BB);
84 return Result;
85 }
86
87 // Tests that a single JITEventListener follows JIT events accurately.
88 TEST_F(JITEventListenerTest, Simple) {
89 RecordingJITEventListener Listener;
90 EE->RegisterJITEventListener(&Listener);
91 Function *F1 = buildFunction(M);
92 Function *F2 = buildFunction(M);
93
94 void *F1_addr = EE->getPointerToFunction(F1);
95 void *F2_addr = EE->getPointerToFunction(F2);
96 EE->getPointerToFunction(F1); // Should do nothing.
97 EE->freeMachineCodeForFunction(F1);
98 EE->freeMachineCodeForFunction(F2);
99
100 ASSERT_EQ(2U, Listener.EmittedEvents.size());
101 ASSERT_EQ(2U, Listener.FreedEvents.size());
102
103 EXPECT_EQ(0U, Listener.EmittedEvents[0].Index);
104 EXPECT_EQ(F1, Listener.EmittedEvents[0].F);
105 EXPECT_EQ(F1_addr, Listener.EmittedEvents[0].Code);
106 EXPECT_LT(0U, Listener.EmittedEvents[0].Size)
107 << "We don't know how big the function will be, but it had better"
108 << " contain some bytes.";
109
110 EXPECT_EQ(1U, Listener.EmittedEvents[1].Index);
111 EXPECT_EQ(F2, Listener.EmittedEvents[1].F);
112 EXPECT_EQ(F2_addr, Listener.EmittedEvents[1].Code);
113 EXPECT_LT(0U, Listener.EmittedEvents[1].Size)
114 << "We don't know how big the function will be, but it had better"
115 << " contain some bytes.";
116
117 EXPECT_EQ(2U, Listener.FreedEvents[0].Index);
118 EXPECT_EQ(F1_addr, Listener.FreedEvents[0].Code);
119
120 EXPECT_EQ(3U, Listener.FreedEvents[1].Index);
121 EXPECT_EQ(F2_addr, Listener.FreedEvents[1].Code);
122
123 F1->eraseFromParent();
124 F2->eraseFromParent();
125 }
126
127 // Tests that a single JITEventListener follows JIT events accurately.
128 TEST_F(JITEventListenerTest, MultipleListenersDontInterfere) {
129 RecordingJITEventListener Listener1;
130 RecordingJITEventListener Listener2;
131 RecordingJITEventListener Listener3;
132 Function *F1 = buildFunction(M);
133 Function *F2 = buildFunction(M);
134
135 EE->RegisterJITEventListener(&Listener1);
136 EE->RegisterJITEventListener(&Listener2);
137 void *F1_addr = EE->getPointerToFunction(F1);
138 EE->RegisterJITEventListener(&Listener3);
139 EE->UnregisterJITEventListener(&Listener1);
140 void *F2_addr = EE->getPointerToFunction(F2);
141 EE->UnregisterJITEventListener(&Listener2);
142 EE->UnregisterJITEventListener(&Listener3);
143 EE->freeMachineCodeForFunction(F1);
144 EE->RegisterJITEventListener(&Listener2);
145 EE->RegisterJITEventListener(&Listener3);
146 EE->RegisterJITEventListener(&Listener1);
147 EE->freeMachineCodeForFunction(F2);
148 EE->UnregisterJITEventListener(&Listener1);
149 EE->UnregisterJITEventListener(&Listener2);
150 EE->UnregisterJITEventListener(&Listener3);
151
152 // Listener 1.
153 ASSERT_EQ(1U, Listener1.EmittedEvents.size());
154 ASSERT_EQ(1U, Listener1.FreedEvents.size());
155
156 EXPECT_EQ(0U, Listener1.EmittedEvents[0].Index);
157 EXPECT_EQ(F1, Listener1.EmittedEvents[0].F);
158 EXPECT_EQ(F1_addr, Listener1.EmittedEvents[0].Code);
159 EXPECT_LT(0U, Listener1.EmittedEvents[0].Size)
160 << "We don't know how big the function will be, but it had better"
161 << " contain some bytes.";
162
163 EXPECT_EQ(1U, Listener1.FreedEvents[0].Index);
164 EXPECT_EQ(F2_addr, Listener1.FreedEvents[0].Code);
165
166 // Listener 2.
167 ASSERT_EQ(2U, Listener2.EmittedEvents.size());
168 ASSERT_EQ(1U, Listener2.FreedEvents.size());
169
170 EXPECT_EQ(0U, Listener2.EmittedEvents[0].Index);
171 EXPECT_EQ(F1, Listener2.EmittedEvents[0].F);
172 EXPECT_EQ(F1_addr, Listener2.EmittedEvents[0].Code);
173 EXPECT_LT(0U, Listener2.EmittedEvents[0].Size)
174 << "We don't know how big the function will be, but it had better"
175 << " contain some bytes.";
176
177 EXPECT_EQ(1U, Listener2.EmittedEvents[1].Index);
178 EXPECT_EQ(F2, Listener2.EmittedEvents[1].F);
179 EXPECT_EQ(F2_addr, Listener2.EmittedEvents[1].Code);
180 EXPECT_LT(0U, Listener2.EmittedEvents[1].Size)
181 << "We don't know how big the function will be, but it had better"
182 << " contain some bytes.";
183
184 EXPECT_EQ(2U, Listener2.FreedEvents[0].Index);
185 EXPECT_EQ(F2_addr, Listener2.FreedEvents[0].Code);
186
187 // Listener 3.
188 ASSERT_EQ(1U, Listener3.EmittedEvents.size());
189 ASSERT_EQ(1U, Listener3.FreedEvents.size());
190
191 EXPECT_EQ(0U, Listener3.EmittedEvents[0].Index);
192 EXPECT_EQ(F2, Listener3.EmittedEvents[0].F);
193 EXPECT_EQ(F2_addr, Listener3.EmittedEvents[0].Code);
194 EXPECT_LT(0U, Listener3.EmittedEvents[0].Size)
195 << "We don't know how big the function will be, but it had better"
196 << " contain some bytes.";
197
198 EXPECT_EQ(1U, Listener3.FreedEvents[0].Index);
199 EXPECT_EQ(F2_addr, Listener3.FreedEvents[0].Code);
200
201 F1->eraseFromParent();
202 F2->eraseFromParent();
203 }
204
205 TEST_F(JITEventListenerTest, MatchesMachineCodeInfo) {
206 RecordingJITEventListener Listener;
207 MachineCodeInfo MCI;
208 Function *F = buildFunction(M);
209
210 EE->RegisterJITEventListener(&Listener);
211 EE->runJITOnFunction(F, &MCI);
212 void *F_addr = EE->getPointerToFunction(F);
213 EE->freeMachineCodeForFunction(F);
214
215 ASSERT_EQ(1U, Listener.EmittedEvents.size());
216 ASSERT_EQ(1U, Listener.FreedEvents.size());
217
218 EXPECT_EQ(0U, Listener.EmittedEvents[0].Index);
219 EXPECT_EQ(F, Listener.EmittedEvents[0].F);
220 EXPECT_EQ(F_addr, Listener.EmittedEvents[0].Code);
221 EXPECT_EQ(MCI.address(), Listener.EmittedEvents[0].Code);
222 EXPECT_EQ(MCI.size(), Listener.EmittedEvents[0].Size);
223
224 EXPECT_EQ(1U, Listener.FreedEvents[0].Index);
225 EXPECT_EQ(F_addr, Listener.FreedEvents[0].Code);
226 }
227
228 class JITEnvironment : public testing::Environment {
229 virtual void SetUp() {
230 // Required to create a JIT.
231 InitializeNativeTarget();
232 }
233 };
234 testing::Environment* const jit_env =
235 testing::AddGlobalTestEnvironment(new JITEnvironment);
236
237 } // anonymous namespace
+0
-209
unittests/ExecutionEngine/JITEventListenerTestCommon.h less more
None //===- JITEventListenerTestCommon.h - Helper for JITEventListener tests ------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===-------------------------------------------------------------------------------===//
8
9 #ifndef JIT_EVENT_LISTENER_TEST_COMMON_H
10 #define JIT_EVENT_LISTENER_TEST_COMMON_H
11
12 #include "llvm/Analysis/DIBuilder.h"
13 #include "llvm/Analysis/DebugInfo.h"
14 #include "llvm/CodeGen/MachineCodeInfo.h"
15 #include "llvm/Config/config.h"
16 #include "llvm/ExecutionEngine/JIT.h"
17 #include "llvm/ExecutionEngine/JITEventListener.h"
18 #include "llvm/Instructions.h"
19 #include "llvm/Module.h"
20 #include "llvm/Support/IRBuilder.h"
21 #include "llvm/Support/Dwarf.h"
22 #include "llvm/Support/TypeBuilder.h"
23 #include "llvm/Support/TargetSelect.h"
24
25 #include "gtest/gtest.h"
26
27 #include
28 #include
29 #include
30
31 typedef std::vector > SourceLocations;
32 typedef std::map NativeCodeMap;
33
34 class JITEnvironment : public testing::Environment {
35 virtual void SetUp() {
36 // Required to create a JIT.
37 llvm::InitializeNativeTarget();
38 }
39 };
40
41 inline unsigned int getLine() {
42 return 12;
43 }
44
45 inline unsigned int getCol() {
46 return 0;
47 }
48
49 inline const char* getFilename() {
50 return "mock_source_file.cpp";
51 }
52
53 // Test fixture shared by tests for listener implementations
54 template
55 class JITEventListenerTestBase : public testing::Test {
56 protected:
57 llvm::OwningPtr MockWrapper;
58 llvm::OwningPtr Listener;
59
60 public:
61 llvm::Module* M;
62 llvm::MDNode* Scope;
63 llvm::ExecutionEngine* EE;
64 llvm::DIBuilder* DebugBuilder;
65 llvm::IRBuilder<> Builder;
66
67 JITEventListenerTestBase(WrapperT* w)
68 : MockWrapper(w)
69 , M(new llvm::Module("module", llvm::getGlobalContext()))
70 , EE(llvm::EngineBuilder(M)
71 .setEngineKind(llvm::EngineKind::JIT)
72 .setOptLevel(llvm::CodeGenOpt::None)
73 .create())
74 , DebugBuilder(new llvm::DIBuilder(*M))
75 , Builder(llvm::getGlobalContext())
76 {
77 DebugBuilder->createCompileUnit(llvm::dwarf::DW_LANG_C_plus_plus,
78 "JIT",
79 "JIT",
80 "JIT",
81 true,
82 "",
83 1);
84
85 Scope = DebugBuilder->createFile(getFilename(), ".");
86 }
87
88 llvm::Function *buildFunction(const SourceLocations& DebugLocations) {
89 using namespace llvm;
90
91 LLVMContext& GlobalContext = getGlobalContext();
92
93 SourceLocations::const_iterator CurrentDebugLocation
94 = DebugLocations.begin();
95
96 if (CurrentDebugLocation != DebugLocations.end()) {
97 DebugLoc DebugLocation = DebugLoc::get(getLine(), getCol(),
98 DebugBuilder->createFile(CurrentDebugLocation->first, "."));
99 Builder.SetCurrentDebugLocation(DebugLocation);
100 CurrentDebugLocation++;
101 }
102
103 Function *Result = Function::Create(
104 TypeBuilder::get(GlobalContext),
105 GlobalValue::ExternalLinkage, "id", M);
106 Value *Arg = Result->arg_begin();
107 BasicBlock *BB = BasicBlock::Create(M->getContext(), "entry", Result);
108 Builder.SetInsertPoint(BB);
109 Value* one = ConstantInt::get(GlobalContext, APInt(32, 1));
110 for(; CurrentDebugLocation != DebugLocations.end();
111 ++CurrentDebugLocation) {
112 Arg = Builder.CreateMul(Arg, Builder.CreateAdd(Arg, one));
113 Builder.SetCurrentDebugLocation(
114 DebugLoc::get(CurrentDebugLocation->second, 0,
115 DebugBuilder->createFile(CurrentDebugLocation->first, ".")));
116 }
117 Builder.CreateRet(Arg);
118 return Result;
119 }
120
121 void TestNoDebugInfo(NativeCodeMap& ReportedDebugFuncs) {
122 SourceLocations DebugLocations;
123 llvm::Function* f = buildFunction(DebugLocations);
124 EXPECT_TRUE(0 != f);
125
126 //Cause JITting and callbacks to our listener
127 EXPECT_TRUE(0 != EE->getPointerToFunction(f));
128 EXPECT_TRUE(1 == ReportedDebugFuncs.size());
129
130 EE->freeMachineCodeForFunction(f);
131 EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
132 }
133
134 void TestSingleLine(NativeCodeMap& ReportedDebugFuncs) {
135 SourceLocations DebugLocations;
136 DebugLocations.push_back(std::make_pair(std::string(getFilename()),
137 getLine()));
138 llvm::Function* f = buildFunction(DebugLocations);
139 EXPECT_TRUE(0 != f);
140
141 EXPECT_TRUE(0 != EE->getPointerToFunction(f));
142 EXPECT_TRUE(1 == ReportedDebugFuncs.size());
143 EXPECT_STREQ(ReportedDebugFuncs.begin()->second.begin()->first.c_str(),
144 getFilename());
145 EXPECT_EQ(ReportedDebugFuncs.begin()->second.begin()->second, getLine());
146
147 EE->freeMachineCodeForFunction(f);
148 EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
149 }
150
151 void TestMultipleLines(NativeCodeMap& ReportedDebugFuncs) {
152 using namespace std;
153
154 SourceLocations DebugLocations;
155 unsigned int c = 5;
156 for(unsigned int i = 0; i < c; ++i) {
157 DebugLocations.push_back(make_pair(string(getFilename()), getLine() + i));
158 }
159
160 llvm::Function* f = buildFunction(DebugLocations);
161 EXPECT_TRUE(0 != f);
162
163 EXPECT_TRUE(0 != EE->getPointerToFunction(f));
164 EXPECT_TRUE(1 == ReportedDebugFuncs.size());
165 SourceLocations& FunctionInfo = ReportedDebugFuncs.begin()->second;
166 EXPECT_EQ(c, FunctionInfo.size());
167
168 int VerifyCount = 0;
169 for(SourceLocations::iterator i = FunctionInfo.begin();
170 i != FunctionInfo.end();
171 ++i) {
172 EXPECT_STREQ(i->first.c_str(), getFilename());
173 EXPECT_EQ(i->second, getLine() + VerifyCount);
174 VerifyCount++;
175 }
176
177 EE->freeMachineCodeForFunction(f);
178 EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
179 }
180
181 void TestMultipleFiles(NativeCodeMap& ReportedDebugFuncs) {
182
183 std::string secondFilename("another_file.cpp");
184
185 SourceLocations DebugLocations;
186 DebugLocations.push_back(std::make_pair(std::string(getFilename()),
187 getLine()));
188 DebugLocations.push_back(std::make_pair(secondFilename, getLine()));
189 llvm::Function* f = buildFunction(DebugLocations);
190 EXPECT_TRUE(0 != f);
191
192 EXPECT_TRUE(0 != EE->getPointerToFunction(f));
193 EXPECT_TRUE(1 == ReportedDebugFuncs.size());
194 SourceLocations& FunctionInfo = ReportedDebugFuncs.begin()->second;
195 EXPECT_TRUE(2 == FunctionInfo.size());
196
197 EXPECT_STREQ(FunctionInfo.at(0).first.c_str(), getFilename());
198 EXPECT_STREQ(FunctionInfo.at(1).first.c_str(), secondFilename.c_str());
199
200 EXPECT_EQ(FunctionInfo.at(0).second, getLine());
201 EXPECT_EQ(FunctionInfo.at(1).second, getLine());
202
203 EE->freeMachineCodeForFunction(f);
204 EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
205 }
206 };
207
208 #endif //JIT_EVENT_LISTENER_TEST_COMMON_H
99 LEVEL = ../..
1010 TESTNAME = ExecutionEngine
1111 LINK_COMPONENTS := engine interpreter
12 PARALLEL_DIRS = JIT
1213
1314 include $(LEVEL)/Makefile.config
14
15 SOURCES := ExecutionEngineTest.cpp \
16 JITEventListenerTest.cpp
17
18 ifeq ($(USE_INTEL_JITEVENTS), 1)
19 # Build the Intel JIT Events interface tests
20 SOURCES += IntelJITEventListenerTest.cpp
21
22 # Add the Intel JIT Events include directory
23 CPPFLAGS += -I$(INTEL_JITEVENTS_INCDIR)
24
25 # Link against the LLVM Intel JIT Evens interface library
26 LINK_COMPONENTS += inteljitevents
27 endif
28
29 ifeq ($(USE_OPROFILE), 1)
30 # Build the OProfile JIT interface tests
31 SOURCES += OProfileJITEventListenerTest.cpp
32
33 # Link against the LLVM oprofile interface library
34 LINK_COMPONENTS += oprofilejit
35 endif
36
37
38 PARALLEL_DIRS = JIT
39
4015 include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
+0
-166
unittests/ExecutionEngine/OProfileJITEventListenerTest.cpp less more
None //===- OProfileJITEventListenerTest.cpp - Unit tests for OProfileJITEventsListener --------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===--------------------------------------------------------------------------------------===//
8
9 #include "llvm/ExecutionEngine/JITEventListener.h"
10 #include "llvm/ExecutionEngine/OProfileWrapper.h"
11 #include "JITEventListenerTestCommon.h"
12
13 #include
14 #include
15
16 using namespace llvm;
17
18 namespace {
19
20 struct OprofileNativeFunction {
21 const char* Name;
22 uint64_t Addr;
23 const void* CodePtr;
24 unsigned int CodeSize;
25
26 OprofileNativeFunction(const char* name,
27 uint64_t addr,
28 const void* code,
29 unsigned int size)
30 : Name(name)
31 , Addr(addr)
32 , CodePtr(code)
33 , CodeSize(size) {
34 }
35 };
36
37 typedef std::list NativeFunctionList;
38 typedef std::list NativeDebugList;
39 NativeFunctionList NativeFunctions;
40
41 NativeCodeMap ReportedDebugFuncs;
42
43 } // namespace
44
45 /// Mock implementaion of opagent library
46 namespace test_opagent {
47
48 op_agent_t globalAgent = reinterpret_cast(42);
49
50 op_agent_t open_agent()
51 {
52 // return non-null op_agent_t
53 return globalAgent;
54 }
55
56 int close_agent(op_agent_t agent)
57 {
58 EXPECT_EQ(globalAgent, agent);
59 return 0;
60 }
61
62 int write_native_code(op_agent_t agent,
63 const char* name,
64 uint64_t addr,
65 void const* code,
66 unsigned int size)
67 {
68 EXPECT_EQ(globalAgent, agent);
69 OprofileNativeFunction func(name, addr, code, size);
70 NativeFunctions.push_back(func);
71
72 // Verify no other registration has take place for the same address
73 EXPECT_TRUE(ReportedDebugFuncs.find(addr) == ReportedDebugFuncs.end());
74
75 ReportedDebugFuncs[addr];
76 return 0;
77 }
78
79 int write_debug_line_info(op_agent_t agent,
80 void const* code,
81 size_t num_entries,
82 struct debug_line_info const* info)
83 {
84 EXPECT_EQ(globalAgent, agent);
85
86 //verify code has been loaded first
87 uint64_t addr = reinterpret_cast(code);
88 NativeCodeMap::iterator i = ReportedDebugFuncs.find(addr);
89 EXPECT_TRUE(i != ReportedDebugFuncs.end());
90
91 NativeDebugList NativeInfo(info, info + num_entries);
92
93 SourceLocations locs;
94 for(NativeDebugList::iterator i = NativeInfo.begin();
95 i != NativeInfo.end();
96 ++i) {
97 locs.push_back(std::make_pair(std::string(i->filename), i->lineno));
98 }
99 ReportedDebugFuncs[addr] = locs;
100
101 return 0;
102 }
103
104 int unload_native_code(op_agent_t agent, uint64_t addr) {
105 EXPECT_EQ(globalAgent, agent);
106
107 //verify that something for the given JIT addr has been loaded first
108 NativeCodeMap::iterator i = ReportedDebugFuncs.find(addr);
109 EXPECT_TRUE(i != ReportedDebugFuncs.end());
110 ReportedDebugFuncs.erase(i);
111 return 0;
112 }
113
114 int version() {
115 return 1;
116 }
117
118 bool is_oprofile_running() {
119 return true;
120 }
121
122 } //namespace test_opagent
123
124 class OProfileJITEventListenerTest
125 : public JITEventListenerTestBase
126 {
127 public:
128 OProfileJITEventListenerTest()
129 : JITEventListenerTestBase(
130 new OProfileWrapper(test_opagent::open_agent,
131 test_opagent::close_agent,
132 test_opagent::write_native_code,
133 test_opagent::write_debug_line_info,
134 test_opagent::unload_native_code,
135 test_opagent::version,
136 test_opagent::version,
137 test_opagent::is_oprofile_running))
138 {
139 EXPECT_TRUE(0 != MockWrapper);
140
141 Listener.reset(JITEventListener::createOProfileJITEventListener(
142 MockWrapper.get()));
143 EXPECT_TRUE(0 != Listener);
144 EE->RegisterJITEventListener(Listener.get());
145 }
146 };
147
148 TEST_F(OProfileJITEventListenerTest, NoDebugInfo) {
149 TestNoDebugInfo(ReportedDebugFuncs);
150 }
151
152 TEST_F(OProfileJITEventListenerTest, SingleLine) {
153 TestSingleLine(ReportedDebugFuncs);
154 }
155
156 TEST_F(OProfileJITEventListenerTest, MultipleLines) {
157 TestMultipleLines(ReportedDebugFuncs);
158 }
159
160 TEST_F(OProfileJITEventListenerTest, MultipleFiles) {
161 TestMultipleFiles(ReportedDebugFuncs);
162 }
163
164 testing::Environment* const jit_env =
165 testing::AddGlobalTestEnvironment(new JITEnvironment);