Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===- MemoryMapper.h - Cross-process memory mapper -------------*- 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
// Cross-process (and in-process) memory mapping and transfer
10
//
11
//===----------------------------------------------------------------------===//
12
 
13
#ifndef LLVM_EXECUTIONENGINE_ORC_MEMORYMAPPER_H
14
#define LLVM_EXECUTIONENGINE_ORC_MEMORYMAPPER_H
15
 
16
#include "llvm/ExecutionEngine/Orc/Core.h"
17
#include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h"
18
#include "llvm/Support/Process.h"
19
 
20
#include <mutex>
21
 
22
namespace llvm {
23
namespace orc {
24
 
25
/// Manages mapping, content transfer and protections for JIT memory
26
class MemoryMapper {
27
public:
28
  /// Represents a single allocation containing multiple segments and
29
  /// initialization and deinitialization actions
30
  struct AllocInfo {
31
    struct SegInfo {
32
      ExecutorAddrDiff Offset;
33
      const char *WorkingMem;
34
      size_t ContentSize;
35
      size_t ZeroFillSize;
36
      AllocGroup AG;
37
    };
38
 
39
    ExecutorAddr MappingBase;
40
    std::vector<SegInfo> Segments;
41
    shared::AllocActions Actions;
42
  };
43
 
44
  using OnReservedFunction = unique_function<void(Expected<ExecutorAddrRange>)>;
45
 
46
  // Page size of the target process
47
  virtual unsigned int getPageSize() = 0;
48
 
49
  /// Reserves address space in executor process
50
  virtual void reserve(size_t NumBytes, OnReservedFunction OnReserved) = 0;
51
 
52
  /// Provides working memory
53
  virtual char *prepare(ExecutorAddr Addr, size_t ContentSize) = 0;
54
 
55
  using OnInitializedFunction = unique_function<void(Expected<ExecutorAddr>)>;
56
 
57
  /// Ensures executor memory is synchronized with working copy memory, sends
58
  /// functions to be called after initilization and before deinitialization and
59
  /// applies memory protections
60
  /// Returns a unique address identifying the allocation. This address should
61
  /// be passed to deinitialize to run deallocation actions (and reset
62
  /// permissions where possible).
63
  virtual void initialize(AllocInfo &AI,
64
                          OnInitializedFunction OnInitialized) = 0;
65
 
66
  using OnDeinitializedFunction = unique_function<void(Error)>;
67
 
68
  /// Runs previously specified deinitialization actions
69
  /// Executor addresses returned by initialize should be passed
70
  virtual void deinitialize(ArrayRef<ExecutorAddr> Allocations,
71
                            OnDeinitializedFunction OnDeInitialized) = 0;
72
 
73
  using OnReleasedFunction = unique_function<void(Error)>;
74
 
75
  /// Release address space acquired through reserve()
76
  virtual void release(ArrayRef<ExecutorAddr> Reservations,
77
                       OnReleasedFunction OnRelease) = 0;
78
 
79
  virtual ~MemoryMapper();
80
};
81
 
82
class InProcessMemoryMapper : public MemoryMapper {
83
public:
84
  InProcessMemoryMapper(size_t PageSize);
85
 
86
  static Expected<std::unique_ptr<InProcessMemoryMapper>> Create();
87
 
88
  unsigned int getPageSize() override { return PageSize; }
89
 
90
  void reserve(size_t NumBytes, OnReservedFunction OnReserved) override;
91
 
92
  void initialize(AllocInfo &AI, OnInitializedFunction OnInitialized) override;
93
 
94
  char *prepare(ExecutorAddr Addr, size_t ContentSize) override;
95
 
96
  void deinitialize(ArrayRef<ExecutorAddr> Allocations,
97
                    OnDeinitializedFunction OnDeInitialized) override;
98
 
99
  void release(ArrayRef<ExecutorAddr> Reservations,
100
               OnReleasedFunction OnRelease) override;
101
 
102
  ~InProcessMemoryMapper() override;
103
 
104
private:
105
  struct Allocation {
106
    size_t Size;
107
    std::vector<shared::WrapperFunctionCall> DeinitializationActions;
108
  };
109
  using AllocationMap = DenseMap<ExecutorAddr, Allocation>;
110
 
111
  struct Reservation {
112
    size_t Size;
113
    std::vector<ExecutorAddr> Allocations;
114
  };
115
  using ReservationMap = DenseMap<void *, Reservation>;
116
 
117
  std::mutex Mutex;
118
  ReservationMap Reservations;
119
  AllocationMap Allocations;
120
 
121
  size_t PageSize;
122
};
123
 
124
class SharedMemoryMapper final : public MemoryMapper {
125
public:
126
  struct SymbolAddrs {
127
    ExecutorAddr Instance;
128
    ExecutorAddr Reserve;
129
    ExecutorAddr Initialize;
130
    ExecutorAddr Deinitialize;
131
    ExecutorAddr Release;
132
  };
133
 
134
  SharedMemoryMapper(ExecutorProcessControl &EPC, SymbolAddrs SAs,
135
                     size_t PageSize);
136
 
137
  static Expected<std::unique_ptr<SharedMemoryMapper>>
138
  Create(ExecutorProcessControl &EPC, SymbolAddrs SAs);
139
 
140
  unsigned int getPageSize() override { return PageSize; }
141
 
142
  void reserve(size_t NumBytes, OnReservedFunction OnReserved) override;
143
 
144
  char *prepare(ExecutorAddr Addr, size_t ContentSize) override;
145
 
146
  void initialize(AllocInfo &AI, OnInitializedFunction OnInitialized) override;
147
 
148
  void deinitialize(ArrayRef<ExecutorAddr> Allocations,
149
                    OnDeinitializedFunction OnDeInitialized) override;
150
 
151
  void release(ArrayRef<ExecutorAddr> Reservations,
152
               OnReleasedFunction OnRelease) override;
153
 
154
  ~SharedMemoryMapper() override;
155
 
156
private:
157
  struct Reservation {
158
    void *LocalAddr;
159
    size_t Size;
160
  };
161
 
162
  ExecutorProcessControl &EPC;
163
  SymbolAddrs SAs;
164
 
165
  std::mutex Mutex;
166
 
167
  std::map<ExecutorAddr, Reservation> Reservations;
168
 
169
  size_t PageSize;
170
};
171
 
172
} // namespace orc
173
} // end namespace llvm
174
 
175
#endif // LLVM_EXECUTIONENGINE_ORC_MEMORYMAPPER_H