1 //===- JITEventListenerTest.cpp - Unit tests for JITEventListeners --------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ExecutionEngine/JITEventListener.h"
12 #include "llvm/LLVMContext.h"
13 #include "llvm/Instructions.h"
14 #include "llvm/Module.h"
15 #include "llvm/ModuleProvider.h"
16 #include "llvm/ADT/OwningPtr.h"
17 #include "llvm/CodeGen/MachineCodeInfo.h"
18 #include "llvm/ExecutionEngine/JIT.h"
19 #include "llvm/Support/TypeBuilder.h"
20 #include "llvm/Target/TargetSelect.h"
21 #include "gtest/gtest.h"
31 struct FunctionEmittedEvent {
32 // Indices are local to the RecordingJITEventListener, since the
33 // JITEventListener interface makes no guarantees about the order of
34 // calls between Listeners.
39 JITEvent_EmittedFunctionDetails Details;
41 struct FunctionFreedEvent {
46 struct RecordingJITEventListener : public JITEventListener {
47 std::vector<FunctionEmittedEvent> EmittedEvents;
48 std::vector<FunctionFreedEvent> FreedEvents;
52 RecordingJITEventListener() : NextIndex(0) {}
54 virtual void NotifyFunctionEmitted(const Function &F,
55 void *Code, size_t Size,
56 const EmittedFunctionDetails &Details) {
57 FunctionEmittedEvent Event = {NextIndex++, &F, Code, Size, Details};
58 EmittedEvents.push_back(Event);
61 virtual void NotifyFreeingMachineCode(void *OldPtr) {
62 FunctionFreedEvent Event = {NextIndex++, OldPtr};
63 FreedEvents.push_back(Event);
67 class JITEventListenerTest : public testing::Test {
69 JITEventListenerTest()
70 : M(new Module("module", getGlobalContext())),
72 .setEngineKind(EngineKind::JIT)
77 const OwningPtr<ExecutionEngine> EE;
80 Function *buildFunction(Module *M) {
81 Function *Result = Function::Create(
82 TypeBuilder<int32_t(int32_t), false>::get(getGlobalContext()),
83 GlobalValue::ExternalLinkage, "id", M);
84 Value *Arg = Result->arg_begin();
85 BasicBlock *BB = BasicBlock::Create(M->getContext(), "entry", Result);
86 ReturnInst::Create(M->getContext(), Arg, BB);
90 // Tests that a single JITEventListener follows JIT events accurately.
91 TEST_F(JITEventListenerTest, Simple) {
92 RecordingJITEventListener Listener;
93 EE->RegisterJITEventListener(&Listener);
94 Function *F1 = buildFunction(M);
95 Function *F2 = buildFunction(M);
97 void *F1_addr = EE->getPointerToFunction(F1);
98 void *F2_addr = EE->getPointerToFunction(F2);
99 EE->getPointerToFunction(F1); // Should do nothing.
100 EE->freeMachineCodeForFunction(F1);
101 EE->freeMachineCodeForFunction(F2);
103 ASSERT_EQ(2U, Listener.EmittedEvents.size());
104 ASSERT_EQ(2U, Listener.FreedEvents.size());
106 EXPECT_EQ(0U, Listener.EmittedEvents[0].Index);
107 EXPECT_EQ(F1, Listener.EmittedEvents[0].F);
108 EXPECT_EQ(F1_addr, Listener.EmittedEvents[0].Code);
109 EXPECT_LT(0U, Listener.EmittedEvents[0].Size)
110 << "We don't know how big the function will be, but it had better"
111 << " contain some bytes.";
113 EXPECT_EQ(1U, Listener.EmittedEvents[1].Index);
114 EXPECT_EQ(F2, Listener.EmittedEvents[1].F);
115 EXPECT_EQ(F2_addr, Listener.EmittedEvents[1].Code);
116 EXPECT_LT(0U, Listener.EmittedEvents[1].Size)
117 << "We don't know how big the function will be, but it had better"
118 << " contain some bytes.";
120 EXPECT_EQ(2U, Listener.FreedEvents[0].Index);
121 EXPECT_EQ(F1_addr, Listener.FreedEvents[0].Code);
123 EXPECT_EQ(3U, Listener.FreedEvents[1].Index);
124 EXPECT_EQ(F2_addr, Listener.FreedEvents[1].Code);
126 F1->eraseFromParent();
127 F2->eraseFromParent();
130 // Tests that a single JITEventListener follows JIT events accurately.
131 TEST_F(JITEventListenerTest, MultipleListenersDontInterfere) {
132 RecordingJITEventListener Listener1;
133 RecordingJITEventListener Listener2;
134 RecordingJITEventListener Listener3;
135 Function *F1 = buildFunction(M);
136 Function *F2 = buildFunction(M);
138 EE->RegisterJITEventListener(&Listener1);
139 EE->RegisterJITEventListener(&Listener2);
140 void *F1_addr = EE->getPointerToFunction(F1);
141 EE->RegisterJITEventListener(&Listener3);
142 EE->UnregisterJITEventListener(&Listener1);
143 void *F2_addr = EE->getPointerToFunction(F2);
144 EE->UnregisterJITEventListener(&Listener2);
145 EE->UnregisterJITEventListener(&Listener3);
146 EE->freeMachineCodeForFunction(F1);
147 EE->RegisterJITEventListener(&Listener2);
148 EE->RegisterJITEventListener(&Listener3);
149 EE->RegisterJITEventListener(&Listener1);
150 EE->freeMachineCodeForFunction(F2);
151 EE->UnregisterJITEventListener(&Listener1);
152 EE->UnregisterJITEventListener(&Listener2);
153 EE->UnregisterJITEventListener(&Listener3);
156 ASSERT_EQ(1U, Listener1.EmittedEvents.size());
157 ASSERT_EQ(1U, Listener1.FreedEvents.size());
159 EXPECT_EQ(0U, Listener1.EmittedEvents[0].Index);
160 EXPECT_EQ(F1, Listener1.EmittedEvents[0].F);
161 EXPECT_EQ(F1_addr, Listener1.EmittedEvents[0].Code);
162 EXPECT_LT(0U, Listener1.EmittedEvents[0].Size)
163 << "We don't know how big the function will be, but it had better"
164 << " contain some bytes.";
166 EXPECT_EQ(1U, Listener1.FreedEvents[0].Index);
167 EXPECT_EQ(F2_addr, Listener1.FreedEvents[0].Code);
170 ASSERT_EQ(2U, Listener2.EmittedEvents.size());
171 ASSERT_EQ(1U, Listener2.FreedEvents.size());
173 EXPECT_EQ(0U, Listener2.EmittedEvents[0].Index);
174 EXPECT_EQ(F1, Listener2.EmittedEvents[0].F);
175 EXPECT_EQ(F1_addr, Listener2.EmittedEvents[0].Code);
176 EXPECT_LT(0U, Listener2.EmittedEvents[0].Size)
177 << "We don't know how big the function will be, but it had better"
178 << " contain some bytes.";
180 EXPECT_EQ(1U, Listener2.EmittedEvents[1].Index);
181 EXPECT_EQ(F2, Listener2.EmittedEvents[1].F);
182 EXPECT_EQ(F2_addr, Listener2.EmittedEvents[1].Code);
183 EXPECT_LT(0U, Listener2.EmittedEvents[1].Size)
184 << "We don't know how big the function will be, but it had better"
185 << " contain some bytes.";
187 EXPECT_EQ(2U, Listener2.FreedEvents[0].Index);
188 EXPECT_EQ(F2_addr, Listener2.FreedEvents[0].Code);
191 ASSERT_EQ(1U, Listener3.EmittedEvents.size());
192 ASSERT_EQ(1U, Listener3.FreedEvents.size());
194 EXPECT_EQ(0U, Listener3.EmittedEvents[0].Index);
195 EXPECT_EQ(F2, Listener3.EmittedEvents[0].F);
196 EXPECT_EQ(F2_addr, Listener3.EmittedEvents[0].Code);
197 EXPECT_LT(0U, Listener3.EmittedEvents[0].Size)
198 << "We don't know how big the function will be, but it had better"
199 << " contain some bytes.";
201 EXPECT_EQ(1U, Listener3.FreedEvents[0].Index);
202 EXPECT_EQ(F2_addr, Listener3.FreedEvents[0].Code);
204 F1->eraseFromParent();
205 F2->eraseFromParent();
208 TEST_F(JITEventListenerTest, MatchesMachineCodeInfo) {
209 RecordingJITEventListener Listener;
211 Function *F = buildFunction(M);
213 EE->RegisterJITEventListener(&Listener);
214 EE->runJITOnFunction(F, &MCI);
215 void *F_addr = EE->getPointerToFunction(F);
216 EE->freeMachineCodeForFunction(F);
218 ASSERT_EQ(1U, Listener.EmittedEvents.size());
219 ASSERT_EQ(1U, Listener.FreedEvents.size());
221 EXPECT_EQ(0U, Listener.EmittedEvents[0].Index);
222 EXPECT_EQ(F, Listener.EmittedEvents[0].F);
223 EXPECT_EQ(F_addr, Listener.EmittedEvents[0].Code);
224 EXPECT_EQ(MCI.address(), Listener.EmittedEvents[0].Code);
225 EXPECT_EQ(MCI.size(), Listener.EmittedEvents[0].Size);
227 EXPECT_EQ(1U, Listener.FreedEvents[0].Index);
228 EXPECT_EQ(F_addr, Listener.FreedEvents[0].Code);
231 class JITEnvironment : public testing::Environment {
232 virtual void SetUp() {
233 // Required to create a JIT.
234 InitializeNativeTarget();
237 testing::Environment* const jit_env =
238 testing::AddGlobalTestEnvironment(new JITEnvironment);
240 } // anonymous namespace