JITEventListenerTest.cpp revision 9815582faddd8d6a194472e02ce408018d8cacec
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 28namespace { 29 30struct FunctionEmittedEvent { 31 // Indices are local to the RecordingJITEventListener, since the 32 // JITEventListener interface makes no guarantees about the order of 33 // calls between Listeners. 34 unsigned Index; 35 const Function *F; 36 void *Code; 37 size_t Size; 38 JITEvent_EmittedFunctionDetails Details; 39}; 40struct FunctionFreedEvent { 41 unsigned Index; 42 void *Code; 43}; 44 45struct RecordingJITEventListener : public JITEventListener { 46 std::vector<FunctionEmittedEvent> EmittedEvents; 47 std::vector<FunctionFreedEvent> FreedEvents; 48 49 int NextIndex; 50 51 RecordingJITEventListener() : NextIndex(0) {} 52 53 virtual void NotifyFunctionEmitted(const Function &F, 54 void *Code, size_t Size, 55 const EmittedFunctionDetails &Details) { 56 FunctionEmittedEvent Event = {NextIndex++, &F, Code, Size, Details}; 57 EmittedEvents.push_back(Event); 58 } 59 60 virtual void NotifyFreeingMachineCode(void *OldPtr) { 61 FunctionFreedEvent Event = {NextIndex++, OldPtr}; 62 FreedEvents.push_back(Event); 63 } 64}; 65 66class JITEventListenerTest : public testing::Test { 67 protected: 68 JITEventListenerTest() 69 : M(new Module("module", getGlobalContext())), 70 EE(EngineBuilder(M) 71 .setEngineKind(EngineKind::JIT) 72 .create()) { 73 } 74 75 Module *M; 76 const OwningPtr<ExecutionEngine> EE; 77}; 78 79Function *buildFunction(Module *M) { 80 Function *Result = Function::Create( 81 TypeBuilder<int32_t(int32_t), false>::get(getGlobalContext()), 82 GlobalValue::ExternalLinkage, "id", M); 83 Value *Arg = Result->arg_begin(); 84 BasicBlock *BB = BasicBlock::Create(M->getContext(), "entry", Result); 85 ReturnInst::Create(M->getContext(), Arg, BB); 86 return Result; 87} 88 89// Tests that a single JITEventListener follows JIT events accurately. 90TEST_F(JITEventListenerTest, Simple) { 91 RecordingJITEventListener Listener; 92 EE->RegisterJITEventListener(&Listener); 93 Function *F1 = buildFunction(M); 94 Function *F2 = buildFunction(M); 95 96 void *F1_addr = EE->getPointerToFunction(F1); 97 void *F2_addr = EE->getPointerToFunction(F2); 98 EE->getPointerToFunction(F1); // Should do nothing. 99 EE->freeMachineCodeForFunction(F1); 100 EE->freeMachineCodeForFunction(F2); 101 102 ASSERT_EQ(2U, Listener.EmittedEvents.size()); 103 ASSERT_EQ(2U, Listener.FreedEvents.size()); 104 105 EXPECT_EQ(0U, Listener.EmittedEvents[0].Index); 106 EXPECT_EQ(F1, Listener.EmittedEvents[0].F); 107 EXPECT_EQ(F1_addr, Listener.EmittedEvents[0].Code); 108 EXPECT_LT(0U, Listener.EmittedEvents[0].Size) 109 << "We don't know how big the function will be, but it had better" 110 << " contain some bytes."; 111 112 EXPECT_EQ(1U, Listener.EmittedEvents[1].Index); 113 EXPECT_EQ(F2, Listener.EmittedEvents[1].F); 114 EXPECT_EQ(F2_addr, Listener.EmittedEvents[1].Code); 115 EXPECT_LT(0U, Listener.EmittedEvents[1].Size) 116 << "We don't know how big the function will be, but it had better" 117 << " contain some bytes."; 118 119 EXPECT_EQ(2U, Listener.FreedEvents[0].Index); 120 EXPECT_EQ(F1_addr, Listener.FreedEvents[0].Code); 121 122 EXPECT_EQ(3U, Listener.FreedEvents[1].Index); 123 EXPECT_EQ(F2_addr, Listener.FreedEvents[1].Code); 124 125 F1->eraseFromParent(); 126 F2->eraseFromParent(); 127} 128 129// Tests that a single JITEventListener follows JIT events accurately. 130TEST_F(JITEventListenerTest, MultipleListenersDontInterfere) { 131 RecordingJITEventListener Listener1; 132 RecordingJITEventListener Listener2; 133 RecordingJITEventListener Listener3; 134 Function *F1 = buildFunction(M); 135 Function *F2 = buildFunction(M); 136 137 EE->RegisterJITEventListener(&Listener1); 138 EE->RegisterJITEventListener(&Listener2); 139 void *F1_addr = EE->getPointerToFunction(F1); 140 EE->RegisterJITEventListener(&Listener3); 141 EE->UnregisterJITEventListener(&Listener1); 142 void *F2_addr = EE->getPointerToFunction(F2); 143 EE->UnregisterJITEventListener(&Listener2); 144 EE->UnregisterJITEventListener(&Listener3); 145 EE->freeMachineCodeForFunction(F1); 146 EE->RegisterJITEventListener(&Listener2); 147 EE->RegisterJITEventListener(&Listener3); 148 EE->RegisterJITEventListener(&Listener1); 149 EE->freeMachineCodeForFunction(F2); 150 EE->UnregisterJITEventListener(&Listener1); 151 EE->UnregisterJITEventListener(&Listener2); 152 EE->UnregisterJITEventListener(&Listener3); 153 154 // Listener 1. 155 ASSERT_EQ(1U, Listener1.EmittedEvents.size()); 156 ASSERT_EQ(1U, Listener1.FreedEvents.size()); 157 158 EXPECT_EQ(0U, Listener1.EmittedEvents[0].Index); 159 EXPECT_EQ(F1, Listener1.EmittedEvents[0].F); 160 EXPECT_EQ(F1_addr, Listener1.EmittedEvents[0].Code); 161 EXPECT_LT(0U, Listener1.EmittedEvents[0].Size) 162 << "We don't know how big the function will be, but it had better" 163 << " contain some bytes."; 164 165 EXPECT_EQ(1U, Listener1.FreedEvents[0].Index); 166 EXPECT_EQ(F2_addr, Listener1.FreedEvents[0].Code); 167 168 // Listener 2. 169 ASSERT_EQ(2U, Listener2.EmittedEvents.size()); 170 ASSERT_EQ(1U, Listener2.FreedEvents.size()); 171 172 EXPECT_EQ(0U, Listener2.EmittedEvents[0].Index); 173 EXPECT_EQ(F1, Listener2.EmittedEvents[0].F); 174 EXPECT_EQ(F1_addr, Listener2.EmittedEvents[0].Code); 175 EXPECT_LT(0U, Listener2.EmittedEvents[0].Size) 176 << "We don't know how big the function will be, but it had better" 177 << " contain some bytes."; 178 179 EXPECT_EQ(1U, Listener2.EmittedEvents[1].Index); 180 EXPECT_EQ(F2, Listener2.EmittedEvents[1].F); 181 EXPECT_EQ(F2_addr, Listener2.EmittedEvents[1].Code); 182 EXPECT_LT(0U, Listener2.EmittedEvents[1].Size) 183 << "We don't know how big the function will be, but it had better" 184 << " contain some bytes."; 185 186 EXPECT_EQ(2U, Listener2.FreedEvents[0].Index); 187 EXPECT_EQ(F2_addr, Listener2.FreedEvents[0].Code); 188 189 // Listener 3. 190 ASSERT_EQ(1U, Listener3.EmittedEvents.size()); 191 ASSERT_EQ(1U, Listener3.FreedEvents.size()); 192 193 EXPECT_EQ(0U, Listener3.EmittedEvents[0].Index); 194 EXPECT_EQ(F2, Listener3.EmittedEvents[0].F); 195 EXPECT_EQ(F2_addr, Listener3.EmittedEvents[0].Code); 196 EXPECT_LT(0U, Listener3.EmittedEvents[0].Size) 197 << "We don't know how big the function will be, but it had better" 198 << " contain some bytes."; 199 200 EXPECT_EQ(1U, Listener3.FreedEvents[0].Index); 201 EXPECT_EQ(F2_addr, Listener3.FreedEvents[0].Code); 202 203 F1->eraseFromParent(); 204 F2->eraseFromParent(); 205} 206 207TEST_F(JITEventListenerTest, MatchesMachineCodeInfo) { 208 RecordingJITEventListener Listener; 209 MachineCodeInfo MCI; 210 Function *F = buildFunction(M); 211 212 EE->RegisterJITEventListener(&Listener); 213 EE->runJITOnFunction(F, &MCI); 214 void *F_addr = EE->getPointerToFunction(F); 215 EE->freeMachineCodeForFunction(F); 216 217 ASSERT_EQ(1U, Listener.EmittedEvents.size()); 218 ASSERT_EQ(1U, Listener.FreedEvents.size()); 219 220 EXPECT_EQ(0U, Listener.EmittedEvents[0].Index); 221 EXPECT_EQ(F, Listener.EmittedEvents[0].F); 222 EXPECT_EQ(F_addr, Listener.EmittedEvents[0].Code); 223 EXPECT_EQ(MCI.address(), Listener.EmittedEvents[0].Code); 224 EXPECT_EQ(MCI.size(), Listener.EmittedEvents[0].Size); 225 226 EXPECT_EQ(1U, Listener.FreedEvents[0].Index); 227 EXPECT_EQ(F_addr, Listener.FreedEvents[0].Code); 228} 229 230class JITEnvironment : public testing::Environment { 231 virtual void SetUp() { 232 // Required to create a JIT. 233 InitializeNativeTarget(); 234 } 235}; 236testing::Environment* const jit_env = 237 testing::AddGlobalTestEnvironment(new JITEnvironment); 238 239} // anonymous namespace 240