JITLinkMemoryManager.h 4.4 KB

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