LazyCallThroughAndReexportsTest.cpp 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #include "OrcTestCommon.h"
  2. #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
  3. #include "llvm/ExecutionEngine/Orc/LazyReexports.h"
  4. #include "gtest/gtest.h"
  5. using namespace llvm;
  6. using namespace llvm::orc;
  7. class LazyReexportsTest : public CoreAPIsBasedStandardTest {};
  8. static int dummyTarget() { return 42; }
  9. TEST_F(LazyReexportsTest, BasicLocalCallThroughManagerOperation) {
  10. // Create a callthrough manager for the host (if possible) and verify that
  11. // a call to the lazy call-through:
  12. // (1) Materializes the MU. This verifies that the symbol was looked up, and
  13. // that we didn't arrive at the target via some other path
  14. // (2) Returns the expected value (which we take as proof that the call
  15. // reached the target).
  16. auto JTMB = JITTargetMachineBuilder::detectHost();
  17. // Bail out if we can not detect the host.
  18. if (!JTMB) {
  19. consumeError(JTMB.takeError());
  20. return;
  21. }
  22. // Bail out if we can not build a local call-through manager.
  23. auto LCTM = createLocalLazyCallThroughManager(JTMB->getTargetTriple(), ES, 0);
  24. if (!LCTM) {
  25. consumeError(LCTM.takeError());
  26. return;
  27. }
  28. auto DummyTarget = ES.intern("DummyTarget");
  29. bool DummyTargetMaterialized = false;
  30. cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(
  31. SymbolFlagsMap({{DummyTarget, JITSymbolFlags::Exported}}),
  32. [&](MaterializationResponsibility R) {
  33. DummyTargetMaterialized = true;
  34. // No dependencies registered, can't fail.
  35. cantFail(R.notifyResolved(
  36. {{DummyTarget,
  37. JITEvaluatedSymbol(static_cast<JITTargetAddress>(
  38. reinterpret_cast<uintptr_t>(&dummyTarget)),
  39. JITSymbolFlags::Exported)}}));
  40. cantFail(R.notifyEmitted());
  41. })));
  42. unsigned NotifyResolvedCount = 0;
  43. auto NotifyResolved = LazyCallThroughManager::createNotifyResolvedFunction(
  44. [&](JITDylib &JD, const SymbolStringPtr &SymbolName,
  45. JITTargetAddress ResolvedAddr) {
  46. ++NotifyResolvedCount;
  47. return Error::success();
  48. });
  49. auto CallThroughTrampoline = cantFail((*LCTM)->getCallThroughTrampoline(
  50. JD, DummyTarget, std::move(NotifyResolved)));
  51. auto CTTPtr = reinterpret_cast<int (*)()>(
  52. static_cast<uintptr_t>(CallThroughTrampoline));
  53. // Call twice to verify nothing unexpected happens on redundant calls.
  54. auto Result = CTTPtr();
  55. (void)CTTPtr();
  56. EXPECT_TRUE(DummyTargetMaterialized)
  57. << "CallThrough did not materialize target";
  58. EXPECT_EQ(NotifyResolvedCount, 1U)
  59. << "CallThrough should have generated exactly one 'NotifyResolved' call";
  60. EXPECT_EQ(Result, 42) << "Failed to call through to target";
  61. }