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
13#ifndef LLVM_EXECUTIONENGINE_JITLINK_JITLINKMEMORYMANAGER_H
14#define LLVM_EXECUTIONENGINE_JITLINK_JITLINKMEMORYMANAGER_H
15
16#include "llvm/ADT/DenseMap.h"
17#include "llvm/ExecutionEngine/JITSymbol.h"
18#include "llvm/Support/Error.h"
19#include "llvm/Support/Memory.h"
20#include <cstdint>
21
22namespace llvm {
23namespace jitlink {
24
25/// Manages allocations of JIT memory.
26///
27/// Instances of this class may be accessed concurrently from multiple threads
28/// and their implemetations should include any necessary synchronization.
29class JITLinkMemoryManager {
30public:
31  using ProtectionFlags = sys::Memory::ProtectionFlags;
32
33  class SegmentRequest {
34  public:
35    SegmentRequest() = default;
36    SegmentRequest(uint64_t Alignment, size_t ContentSize,
37                   uint64_t ZeroFillSize)
38        : Alignment(Alignment), ContentSize(ContentSize),
39          ZeroFillSize(ZeroFillSize) {
40      assert(isPowerOf2_32(Alignment) && "Alignment must be power of 2");
41    }
42    uint64_t getAlignment() const { return Alignment; }
43    size_t getContentSize() const { return ContentSize; }
44    uint64_t getZeroFillSize() const { return ZeroFillSize; }
45  private:
46    uint64_t Alignment = 0;
47    size_t ContentSize = 0;
48    uint64_t ZeroFillSize = 0;
49  };
50
51  using SegmentsRequestMap = DenseMap<unsigned, SegmentRequest>;
52
53  /// Represents an allocation created by the memory manager.
54  ///
55  /// An allocation object is responsible for allocating and owning jit-linker
56  /// working and target memory, and for transfering from working to target
57  /// memory.
58  ///
59  class Allocation {
60  public:
61    using FinalizeContinuation = std::function<void(Error)>;
62
63    virtual ~Allocation();
64
65    /// Should return the address of linker working memory for the segment with
66    /// the given protection flags.
67    virtual MutableArrayRef<char> getWorkingMemory(ProtectionFlags Seg) = 0;
68
69    /// Should return the final address in the target process where the segment
70    /// will reside.
71    virtual JITTargetAddress getTargetMemory(ProtectionFlags Seg) = 0;
72
73    /// Should transfer from working memory to target memory, and release
74    /// working memory.
75    virtual void finalizeAsync(FinalizeContinuation OnFinalize) = 0;
76
77    /// Should deallocate target memory.
78    virtual Error deallocate() = 0;
79  };
80
81  virtual ~JITLinkMemoryManager();
82
83  /// Create an Allocation object.
84  virtual Expected<std::unique_ptr<Allocation>>
85  allocate(const SegmentsRequestMap &Request) = 0;
86};
87
88/// A JITLinkMemoryManager that allocates in-process memory.
89class InProcessMemoryManager : public JITLinkMemoryManager {
90public:
91  Expected<std::unique_ptr<Allocation>>
92  allocate(const SegmentsRequestMap &Request) override;
93};
94
95} // end namespace jitlink
96} // end namespace llvm
97
98#endif // LLVM_EXECUTIONENGINE_JITLINK_JITLINK_H
99