JITEventListenerTest.cpp 8.1 KB

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