JITEventListenerTest.cpp revision 8dd0ab074a86ea5eaadfb970323ce133328a2860
1//===- JITEventListenerTest.cpp - Unit tests for JITEventListeners --------===//
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
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"
22#include <vector>
23
24using namespace llvm;
25
26int dummy;
27
28#if 0
29namespace {
30
31struct FunctionEmittedEvent {
32  // Indices are local to the RecordingJITEventListener, since the
33  // JITEventListener interface makes no guarantees about the order of
34  // calls between Listeners.
35  unsigned Index;
36  const Function *F;
37  void *Code;
38  size_t Size;
39  JITEvent_EmittedFunctionDetails Details;
40};
41struct FunctionFreedEvent {
42  unsigned Index;
43  void *Code;
44};
45
46struct RecordingJITEventListener : public JITEventListener {
47  std::vector<FunctionEmittedEvent> EmittedEvents;
48  std::vector<FunctionFreedEvent> FreedEvents;
49
50  int NextIndex;
51
52  RecordingJITEventListener() : NextIndex(0) {}
53
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);
59  }
60
61  virtual void NotifyFreeingMachineCode(void *OldPtr) {
62    FunctionFreedEvent Event = {NextIndex++, OldPtr};
63    FreedEvents.push_back(Event);
64  }
65};
66
67class JITEventListenerTest : public testing::Test {
68 protected:
69  JITEventListenerTest()
70      : M(new Module("module", getGlobalContext())),
71        EE(EngineBuilder(M)
72           .setEngineKind(EngineKind::JIT)
73           .create()) {
74  }
75
76  Module *M;
77  const OwningPtr<ExecutionEngine> EE;
78};
79
80Function *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);
87  return Result;
88}
89
90// Tests that a single JITEventListener follows JIT events accurately.
91TEST_F(JITEventListenerTest, Simple) {
92  RecordingJITEventListener Listener;
93  EE->RegisterJITEventListener(&Listener);
94  Function *F1 = buildFunction(M);
95  Function *F2 = buildFunction(M);
96
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);
102
103  ASSERT_EQ(2U, Listener.EmittedEvents.size());
104  ASSERT_EQ(2U, Listener.FreedEvents.size());
105
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.";
112
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.";
119
120  EXPECT_EQ(2U, Listener.FreedEvents[0].Index);
121  EXPECT_EQ(F1_addr, Listener.FreedEvents[0].Code);
122
123  EXPECT_EQ(3U, Listener.FreedEvents[1].Index);
124  EXPECT_EQ(F2_addr, Listener.FreedEvents[1].Code);
125
126  F1->eraseFromParent();
127  F2->eraseFromParent();
128}
129
130// Tests that a single JITEventListener follows JIT events accurately.
131TEST_F(JITEventListenerTest, MultipleListenersDontInterfere) {
132  RecordingJITEventListener Listener1;
133  RecordingJITEventListener Listener2;
134  RecordingJITEventListener Listener3;
135  Function *F1 = buildFunction(M);
136  Function *F2 = buildFunction(M);
137
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);
154
155  // Listener 1.
156  ASSERT_EQ(1U, Listener1.EmittedEvents.size());
157  ASSERT_EQ(1U, Listener1.FreedEvents.size());
158
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.";
165
166  EXPECT_EQ(1U, Listener1.FreedEvents[0].Index);
167  EXPECT_EQ(F2_addr, Listener1.FreedEvents[0].Code);
168
169  // Listener 2.
170  ASSERT_EQ(2U, Listener2.EmittedEvents.size());
171  ASSERT_EQ(1U, Listener2.FreedEvents.size());
172
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.";
179
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.";
186
187  EXPECT_EQ(2U, Listener2.FreedEvents[0].Index);
188  EXPECT_EQ(F2_addr, Listener2.FreedEvents[0].Code);
189
190  // Listener 3.
191  ASSERT_EQ(1U, Listener3.EmittedEvents.size());
192  ASSERT_EQ(1U, Listener3.FreedEvents.size());
193
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.";
200
201  EXPECT_EQ(1U, Listener3.FreedEvents[0].Index);
202  EXPECT_EQ(F2_addr, Listener3.FreedEvents[0].Code);
203
204  F1->eraseFromParent();
205  F2->eraseFromParent();
206}
207
208TEST_F(JITEventListenerTest, MatchesMachineCodeInfo) {
209  RecordingJITEventListener Listener;
210  MachineCodeInfo MCI;
211  Function *F = buildFunction(M);
212
213  EE->RegisterJITEventListener(&Listener);
214  EE->runJITOnFunction(F, &MCI);
215  void *F_addr = EE->getPointerToFunction(F);
216  EE->freeMachineCodeForFunction(F);
217
218  ASSERT_EQ(1U, Listener.EmittedEvents.size());
219  ASSERT_EQ(1U, Listener.FreedEvents.size());
220
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);
226
227  EXPECT_EQ(1U, Listener.FreedEvents[0].Index);
228  EXPECT_EQ(F_addr, Listener.FreedEvents[0].Code);
229}
230
231class JITEnvironment : public testing::Environment {
232  virtual void SetUp() {
233    // Required to create a JIT.
234    InitializeNativeTarget();
235  }
236};
237testing::Environment* const jit_env =
238  testing::AddGlobalTestEnvironment(new JITEnvironment);
239
240}  // anonymous namespace
241#endif
242