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"
11 #include "llvm/ADT/OwningPtr.h"
12 #include "llvm/CodeGen/MachineCodeInfo.h"
13 #include "llvm/ExecutionEngine/JIT.h"
14 #include "llvm/IR/Instructions.h"
15 #include "llvm/IR/LLVMContext.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/IR/TypeBuilder.h"
18 #include "llvm/Support/TargetSelect.h"
19 #include "gtest/gtest.h"
26 struct FunctionEmittedEvent {
27 // Indices are local to the RecordingJITEventListener, since the
28 // JITEventListener interface makes no guarantees about the order of
29 // calls between Listeners.
34 JITEvent_EmittedFunctionDetails Details;
36 struct FunctionFreedEvent {
41 struct RecordingJITEventListener : public JITEventListener {
42 std::vector<FunctionEmittedEvent> EmittedEvents;
43 std::vector<FunctionFreedEvent> FreedEvents;
47 RecordingJITEventListener() : NextIndex(0) {}
49 virtual void NotifyFunctionEmitted(const Function &F,
50 void *Code, size_t Size,
51 const EmittedFunctionDetails &Details) {
52 FunctionEmittedEvent Event = {NextIndex++, &F, Code, Size, Details};
53 EmittedEvents.push_back(Event);
56 virtual void NotifyFreeingMachineCode(void *OldPtr) {
57 FunctionFreedEvent Event = {NextIndex++, OldPtr};
58 FreedEvents.push_back(Event);
62 class JITEventListenerTest : public testing::Test {
64 JITEventListenerTest()
65 : M(new Module("module", getGlobalContext())),
67 .setEngineKind(EngineKind::JIT)
72 const OwningPtr<ExecutionEngine> EE;
75 // Tests on SystemZ disabled as we're running the old JIT
76 #if !defined(__s390__) && !defined(__aarch64__)
77 Function *buildFunction(Module *M) {
78 Function *Result = Function::Create(
79 TypeBuilder<int32_t(int32_t), false>::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);
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);
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);
100 ASSERT_EQ(2U, Listener.EmittedEvents.size());
101 ASSERT_EQ(2U, Listener.FreedEvents.size());
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.";
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.";
117 EXPECT_EQ(2U, Listener.FreedEvents[0].Index);
118 EXPECT_EQ(F1_addr, Listener.FreedEvents[0].Code);
120 EXPECT_EQ(3U, Listener.FreedEvents[1].Index);
121 EXPECT_EQ(F2_addr, Listener.FreedEvents[1].Code);
123 F1->eraseFromParent();
124 F2->eraseFromParent();
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);
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);
153 ASSERT_EQ(1U, Listener1.EmittedEvents.size());
154 ASSERT_EQ(1U, Listener1.FreedEvents.size());
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.";
163 EXPECT_EQ(1U, Listener1.FreedEvents[0].Index);
164 EXPECT_EQ(F2_addr, Listener1.FreedEvents[0].Code);
167 ASSERT_EQ(2U, Listener2.EmittedEvents.size());
168 ASSERT_EQ(1U, Listener2.FreedEvents.size());
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.";
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.";
184 EXPECT_EQ(2U, Listener2.FreedEvents[0].Index);
185 EXPECT_EQ(F2_addr, Listener2.FreedEvents[0].Code);
188 ASSERT_EQ(1U, Listener3.EmittedEvents.size());
189 ASSERT_EQ(1U, Listener3.FreedEvents.size());
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.";
198 EXPECT_EQ(1U, Listener3.FreedEvents[0].Index);
199 EXPECT_EQ(F2_addr, Listener3.FreedEvents[0].Code);
201 F1->eraseFromParent();
202 F2->eraseFromParent();
205 TEST_F(JITEventListenerTest, MatchesMachineCodeInfo) {
206 RecordingJITEventListener Listener;
208 Function *F = buildFunction(M);
210 EE->RegisterJITEventListener(&Listener);
211 EE->runJITOnFunction(F, &MCI);
212 void *F_addr = EE->getPointerToFunction(F);
213 EE->freeMachineCodeForFunction(F);
215 ASSERT_EQ(1U, Listener.EmittedEvents.size());
216 ASSERT_EQ(1U, Listener.FreedEvents.size());
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);
224 EXPECT_EQ(1U, Listener.FreedEvents[0].Index);
225 EXPECT_EQ(F_addr, Listener.FreedEvents[0].Code);
229 class JITEnvironment : public testing::Environment {
230 virtual void SetUp() {
231 // Required to create a JIT.
232 InitializeNativeTarget();
235 testing::Environment* const jit_env =
236 testing::AddGlobalTestEnvironment(new JITEnvironment);
238 } // anonymous namespace