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