JITEventListenerTest.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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. #include "llvm/ExecutionEngine/JITEventListener.h"
  10. #include "llvm/CodeGen/MachineCodeInfo.h"
  11. #include "llvm/ExecutionEngine/JIT.h"
  12. #include "llvm/IR/Instructions.h"
  13. #include "llvm/IR/LLVMContext.h"
  14. #include "llvm/IR/Module.h"
  15. #include "llvm/IR/TypeBuilder.h"
  16. #include "llvm/Support/TargetSelect.h"
  17. #include "gtest/gtest.h"
  18. #include <vector>
  19. using namespace llvm;
  20. namespace {
  21. struct FunctionEmittedEvent {
  22. // Indices are local to the RecordingJITEventListener, since the
  23. // JITEventListener interface makes no guarantees about the order of
  24. // calls between Listeners.
  25. unsigned Index;
  26. const Function *F;
  27. void *Code;
  28. size_t Size;
  29. JITEvent_EmittedFunctionDetails Details;
  30. };
  31. struct FunctionFreedEvent {
  32. unsigned Index;
  33. void *Code;
  34. };
  35. struct RecordingJITEventListener : public JITEventListener {
  36. std::vector<FunctionEmittedEvent> EmittedEvents;
  37. std::vector<FunctionFreedEvent> FreedEvents;
  38. unsigned NextIndex;
  39. RecordingJITEventListener() : NextIndex(0) {}
  40. virtual void NotifyFunctionEmitted(const Function &F,
  41. void *Code, size_t Size,
  42. const EmittedFunctionDetails &Details) {
  43. FunctionEmittedEvent Event = {NextIndex++, &F, Code, Size, Details};
  44. EmittedEvents.push_back(Event);
  45. }
  46. virtual void NotifyFreeingMachineCode(void *OldPtr) {
  47. FunctionFreedEvent Event = {NextIndex++, OldPtr};
  48. FreedEvents.push_back(Event);
  49. }
  50. };
  51. class JITEventListenerTest : public testing::Test {
  52. protected:
  53. JITEventListenerTest() {
  54. auto Owner = make_unique<Module>("module", getGlobalContext());
  55. M = Owner.get();
  56. EE.reset(EngineBuilder(std::move(Owner))
  57. .setEngineKind(EngineKind::JIT)
  58. .create());
  59. }
  60. Module *M;
  61. std::unique_ptr<ExecutionEngine> EE;
  62. };
  63. // Tests on SystemZ disabled as we're running the old JIT
  64. #if !defined(__s390__) && !defined(__aarch64__)
  65. Function *buildFunction(Module *M) {
  66. Function *Result = Function::Create(
  67. TypeBuilder<int32_t(int32_t), false>::get(getGlobalContext()),
  68. GlobalValue::ExternalLinkage, "id", M);
  69. Value *Arg = Result->arg_begin();
  70. BasicBlock *BB = BasicBlock::Create(M->getContext(), "entry", Result);
  71. ReturnInst::Create(M->getContext(), Arg, BB);
  72. return Result;
  73. }
  74. // Tests that a single JITEventListener follows JIT events accurately.
  75. TEST_F(JITEventListenerTest, Simple) {
  76. RecordingJITEventListener Listener;
  77. EE->RegisterJITEventListener(&Listener);
  78. Function *F1 = buildFunction(M);
  79. Function *F2 = buildFunction(M);
  80. void *F1_addr = EE->getPointerToFunction(F1);
  81. void *F2_addr = EE->getPointerToFunction(F2);
  82. EE->getPointerToFunction(F1); // Should do nothing.
  83. EE->freeMachineCodeForFunction(F1);
  84. EE->freeMachineCodeForFunction(F2);
  85. ASSERT_EQ(2U, Listener.EmittedEvents.size());
  86. ASSERT_EQ(2U, Listener.FreedEvents.size());
  87. EXPECT_EQ(0U, Listener.EmittedEvents[0].Index);
  88. EXPECT_EQ(F1, Listener.EmittedEvents[0].F);
  89. EXPECT_EQ(F1_addr, Listener.EmittedEvents[0].Code);
  90. EXPECT_LT(0U, Listener.EmittedEvents[0].Size)
  91. << "We don't know how big the function will be, but it had better"
  92. << " contain some bytes.";
  93. EXPECT_EQ(1U, Listener.EmittedEvents[1].Index);
  94. EXPECT_EQ(F2, Listener.EmittedEvents[1].F);
  95. EXPECT_EQ(F2_addr, Listener.EmittedEvents[1].Code);
  96. EXPECT_LT(0U, Listener.EmittedEvents[1].Size)
  97. << "We don't know how big the function will be, but it had better"
  98. << " contain some bytes.";
  99. EXPECT_EQ(2U, Listener.FreedEvents[0].Index);
  100. EXPECT_EQ(F1_addr, Listener.FreedEvents[0].Code);
  101. EXPECT_EQ(3U, Listener.FreedEvents[1].Index);
  102. EXPECT_EQ(F2_addr, Listener.FreedEvents[1].Code);
  103. F1->eraseFromParent();
  104. F2->eraseFromParent();
  105. }
  106. // Tests that a single JITEventListener follows JIT events accurately.
  107. TEST_F(JITEventListenerTest, MultipleListenersDontInterfere) {
  108. RecordingJITEventListener Listener1;
  109. RecordingJITEventListener Listener2;
  110. RecordingJITEventListener Listener3;
  111. Function *F1 = buildFunction(M);
  112. Function *F2 = buildFunction(M);
  113. EE->RegisterJITEventListener(&Listener1);
  114. EE->RegisterJITEventListener(&Listener2);
  115. void *F1_addr = EE->getPointerToFunction(F1);
  116. EE->RegisterJITEventListener(&Listener3);
  117. EE->UnregisterJITEventListener(&Listener1);
  118. void *F2_addr = EE->getPointerToFunction(F2);
  119. EE->UnregisterJITEventListener(&Listener2);
  120. EE->UnregisterJITEventListener(&Listener3);
  121. EE->freeMachineCodeForFunction(F1);
  122. EE->RegisterJITEventListener(&Listener2);
  123. EE->RegisterJITEventListener(&Listener3);
  124. EE->RegisterJITEventListener(&Listener1);
  125. EE->freeMachineCodeForFunction(F2);
  126. EE->UnregisterJITEventListener(&Listener1);
  127. EE->UnregisterJITEventListener(&Listener2);
  128. EE->UnregisterJITEventListener(&Listener3);
  129. // Listener 1.
  130. ASSERT_EQ(1U, Listener1.EmittedEvents.size());
  131. ASSERT_EQ(1U, Listener1.FreedEvents.size());
  132. EXPECT_EQ(0U, Listener1.EmittedEvents[0].Index);
  133. EXPECT_EQ(F1, Listener1.EmittedEvents[0].F);
  134. EXPECT_EQ(F1_addr, Listener1.EmittedEvents[0].Code);
  135. EXPECT_LT(0U, Listener1.EmittedEvents[0].Size)
  136. << "We don't know how big the function will be, but it had better"
  137. << " contain some bytes.";
  138. EXPECT_EQ(1U, Listener1.FreedEvents[0].Index);
  139. EXPECT_EQ(F2_addr, Listener1.FreedEvents[0].Code);
  140. // Listener 2.
  141. ASSERT_EQ(2U, Listener2.EmittedEvents.size());
  142. ASSERT_EQ(1U, Listener2.FreedEvents.size());
  143. EXPECT_EQ(0U, Listener2.EmittedEvents[0].Index);
  144. EXPECT_EQ(F1, Listener2.EmittedEvents[0].F);
  145. EXPECT_EQ(F1_addr, Listener2.EmittedEvents[0].Code);
  146. EXPECT_LT(0U, Listener2.EmittedEvents[0].Size)
  147. << "We don't know how big the function will be, but it had better"
  148. << " contain some bytes.";
  149. EXPECT_EQ(1U, Listener2.EmittedEvents[1].Index);
  150. EXPECT_EQ(F2, Listener2.EmittedEvents[1].F);
  151. EXPECT_EQ(F2_addr, Listener2.EmittedEvents[1].Code);
  152. EXPECT_LT(0U, Listener2.EmittedEvents[1].Size)
  153. << "We don't know how big the function will be, but it had better"
  154. << " contain some bytes.";
  155. EXPECT_EQ(2U, Listener2.FreedEvents[0].Index);
  156. EXPECT_EQ(F2_addr, Listener2.FreedEvents[0].Code);
  157. // Listener 3.
  158. ASSERT_EQ(1U, Listener3.EmittedEvents.size());
  159. ASSERT_EQ(1U, Listener3.FreedEvents.size());
  160. EXPECT_EQ(0U, Listener3.EmittedEvents[0].Index);
  161. EXPECT_EQ(F2, Listener3.EmittedEvents[0].F);
  162. EXPECT_EQ(F2_addr, Listener3.EmittedEvents[0].Code);
  163. EXPECT_LT(0U, Listener3.EmittedEvents[0].Size)
  164. << "We don't know how big the function will be, but it had better"
  165. << " contain some bytes.";
  166. EXPECT_EQ(1U, Listener3.FreedEvents[0].Index);
  167. EXPECT_EQ(F2_addr, Listener3.FreedEvents[0].Code);
  168. F1->eraseFromParent();
  169. F2->eraseFromParent();
  170. }
  171. TEST_F(JITEventListenerTest, MatchesMachineCodeInfo) {
  172. RecordingJITEventListener Listener;
  173. MachineCodeInfo MCI;
  174. Function *F = buildFunction(M);
  175. EE->RegisterJITEventListener(&Listener);
  176. EE->runJITOnFunction(F, &MCI);
  177. void *F_addr = EE->getPointerToFunction(F);
  178. EE->freeMachineCodeForFunction(F);
  179. ASSERT_EQ(1U, Listener.EmittedEvents.size());
  180. ASSERT_EQ(1U, Listener.FreedEvents.size());
  181. EXPECT_EQ(0U, Listener.EmittedEvents[0].Index);
  182. EXPECT_EQ(F, Listener.EmittedEvents[0].F);
  183. EXPECT_EQ(F_addr, Listener.EmittedEvents[0].Code);
  184. EXPECT_EQ(MCI.address(), Listener.EmittedEvents[0].Code);
  185. EXPECT_EQ(MCI.size(), Listener.EmittedEvents[0].Size);
  186. EXPECT_EQ(1U, Listener.FreedEvents[0].Index);
  187. EXPECT_EQ(F_addr, Listener.FreedEvents[0].Code);
  188. }
  189. #endif
  190. class JITEnvironment : public testing::Environment {
  191. virtual void SetUp() {
  192. // Required to create a JIT.
  193. InitializeNativeTarget();
  194. }
  195. };
  196. testing::Environment* const jit_env =
  197. testing::AddGlobalTestEnvironment(new JITEnvironment);
  198. } // anonymous namespace