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 18 #include <mutex> 19 20 namespace llvm { 21 namespace orc { 22 23 /// Manages mapping, content transfer and protections for JIT memory 24 class MemoryMapper { 25 public: 26 /// Represents a single allocation containing multiple segments and 27 /// initialization and deinitialization actions 28 struct AllocInfo { 29 struct SegInfo { 30 ExecutorAddrDiff Offset; 31 const char *WorkingMem; 32 size_t ContentSize; 33 size_t ZeroFillSize; 34 unsigned Prot; 35 }; 36 37 ExecutorAddr MappingBase; 38 std::vector<SegInfo> Segments; 39 shared::AllocActions Actions; 40 }; 41 42 using OnReservedFunction = unique_function<void(Expected<ExecutorAddrRange>)>; 43 44 /// Reserves address space in executor process 45 virtual void reserve(size_t NumBytes, OnReservedFunction OnReserved) = 0; 46 47 /// Provides working memory 48 virtual char *prepare(ExecutorAddr Addr, size_t ContentSize) = 0; 49 50 using OnInitializedFunction = unique_function<void(Expected<ExecutorAddr>)>; 51 52 /// Ensures executor memory is synchronized with working copy memory, sends 53 /// functions to be called after initilization and before deinitialization and 54 /// applies memory protections 55 /// Returns a unique address identifying the allocation. This address should 56 /// be passed to deinitialize to run deallocation actions (and reset 57 /// permissions where possible). 58 virtual void initialize(AllocInfo &AI, 59 OnInitializedFunction OnInitialized) = 0; 60 61 using OnDeinitializedFunction = unique_function<void(Error)>; 62 63 /// Runs previously specified deinitialization actions 64 /// Executor addresses returned by initialize should be passed 65 virtual void deinitialize(ArrayRef<ExecutorAddr> Allocations, 66 OnDeinitializedFunction OnDeInitialized) = 0; 67 68 using OnReleasedFunction = unique_function<void(Error)>; 69 70 /// Release address space acquired through reserve() 71 virtual void release(ArrayRef<ExecutorAddr> Reservations, 72 OnReleasedFunction OnRelease) = 0; 73 74 virtual ~MemoryMapper(); 75 }; 76 77 class InProcessMemoryMapper final : public MemoryMapper { 78 public: 79 InProcessMemoryMapper() {} 80 81 void reserve(size_t NumBytes, OnReservedFunction OnReserved) override; 82 83 void initialize(AllocInfo &AI, OnInitializedFunction OnInitialized) override; 84 85 char *prepare(ExecutorAddr Addr, size_t ContentSize) override; 86 87 void deinitialize(ArrayRef<ExecutorAddr> Allocations, 88 OnDeinitializedFunction OnDeInitialized) override; 89 90 void release(ArrayRef<ExecutorAddr> Reservations, 91 OnReleasedFunction OnRelease) override; 92 93 ~InProcessMemoryMapper() override; 94 95 private: 96 struct Allocation { 97 std::vector<shared::WrapperFunctionCall> DeinitializationActions; 98 }; 99 using AllocationMap = DenseMap<ExecutorAddr, Allocation>; 100 101 struct Reservation { 102 size_t Size; 103 std::vector<ExecutorAddr> Allocations; 104 }; 105 using ReservationMap = DenseMap<void *, Reservation>; 106 107 std::mutex Mutex; 108 ReservationMap Reservations; 109 AllocationMap Allocations; 110 }; 111 112 } // namespace orc 113 } // end namespace llvm 114 115 #endif // LLVM_EXECUTIONENGINE_ORC_MEMORYMAPPER_H 116