JITEventListenerTest.cpp revision 4b1511b027ce0b648b3379f2891816c25b46f515
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 26namespace { 27 28struct 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}; 38struct FunctionFreedEvent { 39 unsigned Index; 40 const Function *F; 41 void *Code; 42}; 43 44struct RecordingJITEventListener : public JITEventListener { 45 std::vector<FunctionEmittedEvent> EmittedEvents; 46 std::vector<FunctionFreedEvent> FreedEvents; 47 48 int NextIndex; 49 50 RecordingJITEventListener() : NextIndex(0) {} 51 52 virtual void NotifyFunctionEmitted(const Function &F, 53 void *Code, size_t Size, 54 const EmittedFunctionDetails &Details) { 55 FunctionEmittedEvent Event = {NextIndex++, &F, Code, Size, Details}; 56 EmittedEvents.push_back(Event); 57 } 58 59 virtual void NotifyFreeingMachineCode(const Function &F, void *OldPtr) { 60 FunctionFreedEvent Event = {NextIndex++, &F, OldPtr}; 61 FreedEvents.push_back(Event); 62 } 63}; 64 65class JITEventListenerTest : public testing::Test { 66 protected: 67 JITEventListenerTest() 68 : M(new Module("module", getGlobalContext())), 69 EE(EngineBuilder(M) 70 .setEngineToCreate(EngineBuilder::ENG_JIT) 71 .create()) { 72 } 73 74 Module *M; 75 const OwningPtr<ExecutionEngine> EE; 76}; 77 78Function *buildFunction(Module *M) { 79 Function *Result = Function::Create( 80 TypeBuilder<int32_t(int32_t), false>::get(getGlobalContext()), 81 GlobalValue::ExternalLinkage, "id", M); 82 Value *Arg = Result->arg_begin(); 83 BasicBlock *BB = BasicBlock::Create("entry", Result); 84 ReturnInst::Create(Arg, BB); 85 return Result; 86} 87 88// Tests that a single JITEventListener follows JIT events accurately. 89TEST_F(JITEventListenerTest, Simple) { 90 RecordingJITEventListener Listener; 91 EE->RegisterJITEventListener(&Listener); 92 Function *F1 = buildFunction(M); 93 Function *F2 = buildFunction(M); 94 95 void *F1_addr = EE->getPointerToFunction(F1); 96 void *F2_addr = EE->getPointerToFunction(F2); 97 EE->getPointerToFunction(F1); // Should do nothing. 98 EE->freeMachineCodeForFunction(F1); 99 EE->freeMachineCodeForFunction(F2); 100 101 ASSERT_EQ(2U, Listener.EmittedEvents.size()); 102 ASSERT_EQ(2U, Listener.FreedEvents.size()); 103 104 EXPECT_EQ(0U, Listener.EmittedEvents[0].Index); 105 EXPECT_EQ(F1, Listener.EmittedEvents[0].F); 106 EXPECT_EQ(F1_addr, Listener.EmittedEvents[0].Code); 107 EXPECT_LT(0U, Listener.EmittedEvents[0].Size) 108 << "We don't know how big the function will be, but it had better" 109 << " contain some bytes."; 110 111 EXPECT_EQ(1U, Listener.EmittedEvents[1].Index); 112 EXPECT_EQ(F2, Listener.EmittedEvents[1].F); 113 EXPECT_EQ(F2_addr, Listener.EmittedEvents[1].Code); 114 EXPECT_LT(0U, Listener.EmittedEvents[1].Size) 115 << "We don't know how big the function will be, but it had better" 116 << " contain some bytes."; 117 118 EXPECT_EQ(2U, Listener.FreedEvents[0].Index); 119 EXPECT_EQ(F1, Listener.FreedEvents[0].F); 120 EXPECT_EQ(F1_addr, Listener.FreedEvents[0].Code); 121 122 EXPECT_EQ(3U, Listener.FreedEvents[1].Index); 123 EXPECT_EQ(F2, Listener.FreedEvents[1].F); 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, Listener1.FreedEvents[0].F); 168 EXPECT_EQ(F2_addr, Listener1.FreedEvents[0].Code); 169 170 // Listener 2. 171 ASSERT_EQ(2U, Listener2.EmittedEvents.size()); 172 ASSERT_EQ(1U, Listener2.FreedEvents.size()); 173 174 EXPECT_EQ(0U, Listener2.EmittedEvents[0].Index); 175 EXPECT_EQ(F1, Listener2.EmittedEvents[0].F); 176 EXPECT_EQ(F1_addr, Listener2.EmittedEvents[0].Code); 177 EXPECT_LT(0U, Listener2.EmittedEvents[0].Size) 178 << "We don't know how big the function will be, but it had better" 179 << " contain some bytes."; 180 181 EXPECT_EQ(1U, Listener2.EmittedEvents[1].Index); 182 EXPECT_EQ(F2, Listener2.EmittedEvents[1].F); 183 EXPECT_EQ(F2_addr, Listener2.EmittedEvents[1].Code); 184 EXPECT_LT(0U, Listener2.EmittedEvents[1].Size) 185 << "We don't know how big the function will be, but it had better" 186 << " contain some bytes."; 187 188 EXPECT_EQ(2U, Listener2.FreedEvents[0].Index); 189 EXPECT_EQ(F2, Listener2.FreedEvents[0].F); 190 EXPECT_EQ(F2_addr, Listener2.FreedEvents[0].Code); 191 192 // Listener 3. 193 ASSERT_EQ(1U, Listener3.EmittedEvents.size()); 194 ASSERT_EQ(1U, Listener3.FreedEvents.size()); 195 196 EXPECT_EQ(0U, Listener3.EmittedEvents[0].Index); 197 EXPECT_EQ(F2, Listener3.EmittedEvents[0].F); 198 EXPECT_EQ(F2_addr, Listener3.EmittedEvents[0].Code); 199 EXPECT_LT(0U, Listener3.EmittedEvents[0].Size) 200 << "We don't know how big the function will be, but it had better" 201 << " contain some bytes."; 202 203 EXPECT_EQ(1U, Listener3.FreedEvents[0].Index); 204 EXPECT_EQ(F2, Listener3.FreedEvents[0].F); 205 EXPECT_EQ(F2_addr, Listener3.FreedEvents[0].Code); 206 207 F1->eraseFromParent(); 208 F2->eraseFromParent(); 209} 210 211TEST_F(JITEventListenerTest, MatchesMachineCodeInfo) { 212 RecordingJITEventListener Listener; 213 MachineCodeInfo MCI; 214 Function *F = buildFunction(M); 215 216 EE->RegisterJITEventListener(&Listener); 217 EE->runJITOnFunction(F, &MCI); 218 void *F_addr = EE->getPointerToFunction(F); 219 EE->freeMachineCodeForFunction(F); 220 221 ASSERT_EQ(1U, Listener.EmittedEvents.size()); 222 ASSERT_EQ(1U, Listener.FreedEvents.size()); 223 224 EXPECT_EQ(0U, Listener.EmittedEvents[0].Index); 225 EXPECT_EQ(F, Listener.EmittedEvents[0].F); 226 EXPECT_EQ(F_addr, Listener.EmittedEvents[0].Code); 227 EXPECT_EQ(MCI.address(), Listener.EmittedEvents[0].Code); 228 EXPECT_EQ(MCI.size(), Listener.EmittedEvents[0].Size); 229 230 EXPECT_EQ(1U, Listener.FreedEvents[0].Index); 231 EXPECT_EQ(F, Listener.FreedEvents[0].F); 232 EXPECT_EQ(F_addr, Listener.FreedEvents[0].Code); 233} 234 235class JITEnvironment : public testing::Environment { 236 virtual void SetUp() { 237 // Required to create a JIT. 238 InitializeNativeTarget(); 239 } 240}; 241testing::Environment* const jit_env = 242 testing::AddGlobalTestEnvironment(new JITEnvironment); 243 244} // anonymous namespace 245