22
33#include " cinderx/Jit/code_allocator.h"
44
5+ #include " cinderx/Common/log.h"
56#include " cinderx/Jit/config.h"
67#include " cinderx/Jit/threaded_compile.h"
78
@@ -16,6 +17,11 @@ using codegen::codeSectionFromName;
1617
1718namespace {
1819
20+ #define PROPAGATE_ERROR (EXPR ) \
21+ if (asmjit::Error err = (EXPR ); err != asmjit::kErrorOk ) { \
22+ return AllocateResult{nullptr , err}; \
23+ }
24+
1925// 2MiB to match Linux's huge-page size.
2026constexpr size_t kAllocSize = 1024 * 1024 * 2 ;
2127
@@ -51,26 +57,24 @@ bool setHugePages([[maybe_unused]] void* ptr, [[maybe_unused]] size_t size) {
5157
5258} // namespace
5359
54- CodeAllocator* CodeAllocator::s_global_code_allocator_ = nullptr ;
55-
56- CodeAllocator::~CodeAllocator () {}
57-
58- void CodeAllocator::makeGlobalCodeAllocator () {
59- JIT_CHECK (
60- s_global_code_allocator_ == nullptr , " Global allocator already set" );
60+ ICodeAllocator* CodeAllocator::make () {
6161 if (getConfig ().multiple_code_sections ) {
62- s_global_code_allocator_ = new MultipleSectionCodeAllocator;
62+ return new MultipleSectionCodeAllocator{} ;
6363 } else if (getConfig ().use_huge_pages ) {
64- s_global_code_allocator_ = new CodeAllocatorCinder;
65- } else {
66- s_global_code_allocator_ = new CodeAllocator;
64+ return new CodeAllocatorCinder{};
6765 }
66+ return new CodeAllocator{};
6867}
6968
70- void CodeAllocator::freeGlobalCodeAllocator () {
71- JIT_CHECK (s_global_code_allocator_ != nullptr , " Global allocator not set" );
72- delete s_global_code_allocator_;
73- s_global_code_allocator_ = nullptr ;
69+ AllocateResult CodeAllocator::addCode (asmjit::CodeHolder* code) {
70+ void * addr = nullptr ;
71+ asmjit::Error error = runtime_.add (&addr, code);
72+
73+ if (addr != nullptr && error == asmjit::kErrorOk ) {
74+ used_bytes_.fetch_add (code->codeSize (), std::memory_order_relaxed);
75+ }
76+
77+ return AllocateResult{addr, error};
7478}
7579
7680bool CodeAllocator::contains (const void * ptr) const {
@@ -81,22 +85,26 @@ bool CodeAllocator::contains(const void* ptr) const {
8185 asmjit::kErrorOk ;
8286}
8387
88+ size_t CodeAllocator::usedBytes () const {
89+ return used_bytes_.load (std::memory_order_relaxed);
90+ }
91+
92+ const asmjit::Environment& CodeAllocator::asmJitEnvironment () const {
93+ return runtime_.environment ();
94+ }
95+
8496CodeAllocatorCinder::~CodeAllocatorCinder () {
8597 for (std::span<uint8_t > alloc : allocations_) {
8698 JIT_CHECK (
8799 munmap (alloc.data (), alloc.size ()) == 0 , " Freeing code memory failed" );
88100 }
89101}
90102
91- asmjit::Error CodeAllocatorCinder::addCode (
92- void ** dst,
93- asmjit::CodeHolder* code) noexcept {
103+ AllocateResult CodeAllocatorCinder::addCode (asmjit::CodeHolder* code) {
94104 ThreadedCompileSerialize guard;
95105
96- *dst = nullptr ;
97-
98- ASMJIT_PROPAGATE (code->flatten ());
99- ASMJIT_PROPAGATE (code->resolveUnresolvedLinks ());
106+ PROPAGATE_ERROR (code->flatten ());
107+ PROPAGATE_ERROR (code->resolveUnresolvedLinks ());
100108
101109 size_t max_code_size = code->codeSize ();
102110 size_t alloc_size = ((max_code_size / kAllocSize ) + 1 ) * kAllocSize ;
@@ -114,7 +122,7 @@ asmjit::Error CodeAllocatorCinder::addCode(
114122 current_alloc_free_ = alloc_size;
115123 }
116124
117- ASMJIT_PROPAGATE (code->relocateToBase (uintptr_t (current_alloc_)));
125+ PROPAGATE_ERROR (code->relocateToBase (uintptr_t (current_alloc_)));
118126
119127 size_t actual_code_size = code->codeSize ();
120128 JIT_CHECK (actual_code_size <= max_code_size, " Code grew during relocation" );
@@ -136,13 +144,13 @@ asmjit::Error CodeAllocatorCinder::addCode(
136144 }
137145 }
138146
139- *dst = current_alloc_;
147+ void * addr = current_alloc_;
140148
141149 current_alloc_ += actual_code_size;
142150 current_alloc_free_ -= actual_code_size;
143151 used_bytes_ += actual_code_size;
144152
145- return asmjit::kErrorOk ;
153+ return AllocateResult{addr, asmjit::kErrorOk } ;
146154}
147155
148156bool CodeAllocatorCinder::contains (const void * ptr) const {
@@ -196,15 +204,12 @@ void MultipleSectionCodeAllocator::createSlabs() noexcept {
196204 code_sections_[CodeSection::kCold ] = region;
197205}
198206
199- asmjit::Error MultipleSectionCodeAllocator::addCode (
200- void ** dst,
201- asmjit::CodeHolder* code) noexcept {
207+ AllocateResult MultipleSectionCodeAllocator::addCode (asmjit::CodeHolder* code) {
202208 ThreadedCompileSerialize guard;
203209
204210 if (code_sections_.empty ()) {
205211 createSlabs ();
206212 }
207- *dst = nullptr ;
208213
209214 size_t potential_code_size = code->codeSize ();
210215 used_bytes_ += potential_code_size;
@@ -216,8 +221,11 @@ asmjit::Error MultipleSectionCodeAllocator::addCode(
216221 JIT_LOG (
217222 " Not enough memory to split code across sections, falling back to "
218223 " normal allocation." );
219- return runtime_.add (dst, code);
224+ void * addr = nullptr ;
225+ asmjit::Error err = runtime_.add (&addr, code);
226+ return AllocateResult{addr, err};
220227 }
228+
221229 // Fix up the offsets for each code section before resolving links.
222230 // Both the `.text` and `.addrtab` sections are written to the hot section,
223231 // and we need to resolve offsets between them properly.
@@ -242,16 +250,16 @@ asmjit::Error MultipleSectionCodeAllocator::addCode(
242250
243251 // Assuming that the offsets are set properly, relocating all code to be
244252 // relative to the start of the hot code will ensure jumps are correct.
245- ASMJIT_PROPAGATE (code->resolveUnresolvedLinks ());
246- ASMJIT_PROPAGATE (
253+ PROPAGATE_ERROR (code->resolveUnresolvedLinks ());
254+ PROPAGATE_ERROR (
247255 code->relocateToBase (uintptr_t (code_sections_[CodeSection::kHot ])));
248256
249257 // We assume that the hot section of the code is non-empty. This would be
250258 // incorrect for a completely cold function.
251259 JIT_CHECK (
252260 code->textSection ()->realSize () > 0 ,
253261 " Every function must have a non-empty hot section." );
254- *dst = code_sections_[CodeSection::kHot ];
262+ void * addr = code_sections_[CodeSection::kHot ];
255263
256264 for (asmjit::Section* section : code->_sections ) {
257265 size_t buffer_size = section->bufferSize ();
@@ -265,7 +273,7 @@ asmjit::Error MultipleSectionCodeAllocator::addCode(
265273 code_sections_[code_section] += buffer_size;
266274 }
267275
268- return asmjit::kErrorOk ;
276+ return AllocateResult{addr, asmjit::kErrorOk } ;
269277}
270278
271279bool MultipleSectionCodeAllocator::contains (const void * ptr) const {
0 commit comments