JITLinkMemoryManager.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. //===-- JITLinkMemoryManager.h - JITLink mem manager interface --*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Contains the JITLinkMemoryManager interface.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_EXECUTIONENGINE_JITLINK_JITLINKMEMORYMANAGER_H
  13. #define LLVM_EXECUTIONENGINE_JITLINK_JITLINKMEMORYMANAGER_H
  14. #include "llvm/ADT/DenseMap.h"
  15. #include "llvm/ExecutionEngine/JITLink/JITLinkDylib.h"
  16. #include "llvm/ExecutionEngine/JITSymbol.h"
  17. #include "llvm/Support/Error.h"
  18. #include "llvm/Support/MSVCErrorWorkarounds.h"
  19. #include "llvm/Support/Memory.h"
  20. #include <cstdint>
  21. #include <future>
  22. namespace llvm {
  23. namespace jitlink {
  24. /// Manages allocations of JIT memory.
  25. ///
  26. /// Instances of this class may be accessed concurrently from multiple threads
  27. /// and their implemetations should include any necessary synchronization.
  28. class JITLinkMemoryManager {
  29. public:
  30. using ProtectionFlags = sys::Memory::ProtectionFlags;
  31. class SegmentRequest {
  32. public:
  33. SegmentRequest() = default;
  34. SegmentRequest(uint64_t Alignment, size_t ContentSize,
  35. uint64_t ZeroFillSize)
  36. : Alignment(Alignment), ContentSize(ContentSize),
  37. ZeroFillSize(ZeroFillSize) {
  38. assert(isPowerOf2_32(Alignment) && "Alignment must be power of 2");
  39. }
  40. uint64_t getAlignment() const { return Alignment; }
  41. size_t getContentSize() const { return ContentSize; }
  42. uint64_t getZeroFillSize() const { return ZeroFillSize; }
  43. private:
  44. uint64_t Alignment = 0;
  45. size_t ContentSize = 0;
  46. uint64_t ZeroFillSize = 0;
  47. };
  48. using SegmentsRequestMap = DenseMap<unsigned, SegmentRequest>;
  49. /// Represents an allocation created by the memory manager.
  50. ///
  51. /// An allocation object is responsible for allocating and owning jit-linker
  52. /// working and target memory, and for transfering from working to target
  53. /// memory.
  54. ///
  55. class Allocation {
  56. public:
  57. using FinalizeContinuation = std::function<void(Error)>;
  58. virtual ~Allocation();
  59. /// Should return the address of linker working memory for the segment with
  60. /// the given protection flags.
  61. virtual MutableArrayRef<char> getWorkingMemory(ProtectionFlags Seg) = 0;
  62. /// Should return the final address in the target process where the segment
  63. /// will reside.
  64. virtual JITTargetAddress getTargetMemory(ProtectionFlags Seg) = 0;
  65. /// Should transfer from working memory to target memory, and release
  66. /// working memory.
  67. virtual void finalizeAsync(FinalizeContinuation OnFinalize) = 0;
  68. /// Calls finalizeAsync and waits for completion.
  69. Error finalize() {
  70. std::promise<MSVCPError> FinalizeResultP;
  71. auto FinalizeResultF = FinalizeResultP.get_future();
  72. finalizeAsync(
  73. [&](Error Err) { FinalizeResultP.set_value(std::move(Err)); });
  74. return FinalizeResultF.get();
  75. }
  76. /// Should deallocate target memory.
  77. virtual Error deallocate() = 0;
  78. };
  79. virtual ~JITLinkMemoryManager();
  80. /// Create an Allocation object.
  81. ///
  82. /// The JD argument represents the target JITLinkDylib, and can be used by
  83. /// JITLinkMemoryManager implementers to manage per-dylib allocation pools
  84. /// (e.g. one pre-reserved address space slab per dylib to ensure that all
  85. /// allocations for the dylib are within a certain range). The JD argument
  86. /// may be null (representing an allocation not associated with any
  87. /// JITDylib.
  88. ///
  89. /// The request argument describes the segment sizes and permisssions being
  90. /// requested.
  91. virtual Expected<std::unique_ptr<Allocation>>
  92. allocate(const JITLinkDylib *JD, const SegmentsRequestMap &Request) = 0;
  93. };
  94. /// A JITLinkMemoryManager that allocates in-process memory.
  95. class InProcessMemoryManager : public JITLinkMemoryManager {
  96. public:
  97. Expected<std::unique_ptr<Allocation>>
  98. allocate(const JITLinkDylib *JD, const SegmentsRequestMap &Request) override;
  99. };
  100. } // end namespace jitlink
  101. } // end namespace llvm
  102. #endif // LLVM_EXECUTIONENGINE_JITLINK_JITLINKMEMORYMANAGER_H