Skip to content

Commit 04859c2

Browse files
yoneymeta-codesync[bot]
authored andcommitted
Guard JIT allocator state in FT mode
Summary: Add FT-only allocator mutexes around allocator-owned mutable state in `CodeAllocatorCinder` and `MultipleSectionCodeAllocator`. ThreadSanitizer: data race fbcode/cinderx/Jit/code_allocator.cpp:189 in jit::CodeAllocatorCinder::addCode(asmjit::_abi_1_13::CodeHolder*) ================== ``` Reviewed By: alexmalyshev Differential Revision: D96948112 fbshipit-source-id: d4ec434a75425927569cbb3287222830bbae9db5
1 parent f0bb308 commit 04859c2

2 files changed

Lines changed: 18 additions & 11 deletions

File tree

cinderx/Jit/code_allocator.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ CodeAllocatorCinder::~CodeAllocatorCinder() {
137137

138138
AllocateResult CodeAllocatorCinder::addCode(asmjit::CodeHolder* code) {
139139
ThreadedCompileSerialize guard;
140+
#ifdef Py_GIL_DISABLED
141+
std::lock_guard lock{allocator_mutex_};
142+
#endif
140143

141144
PROPAGATE_ERROR(code->flatten());
142145
PROPAGATE_ERROR(code->resolveUnresolvedLinks());
@@ -153,12 +156,7 @@ AllocateResult CodeAllocatorCinder::addCode(asmjit::CodeHolder* code) {
153156
huge_allocs_++;
154157
}
155158
current_alloc_ = static_cast<uint8_t*>(res);
156-
{
157-
#ifdef Py_GIL_DISABLED
158-
std::lock_guard lock{allocations_mutex_};
159-
#endif
160-
allocations_.emplace_back(res, alloc_size);
161-
}
159+
allocations_.emplace_back(res, alloc_size);
162160
current_alloc_free_ = alloc_size;
163161
}
164162

@@ -200,7 +198,7 @@ asmjit::Error CodeAllocatorCinder::releaseCode([[maybe_unused]] void* code) {
200198

201199
bool CodeAllocatorCinder::contains(const void* ptr) const {
202200
#ifdef Py_GIL_DISABLED
203-
std::lock_guard lock{allocations_mutex_};
201+
std::lock_guard lock{allocator_mutex_};
204202
#endif
205203
for (std::span<uint8_t> alloc : allocations_) {
206204
if (alloc.data() <= ptr && ptr < alloc.data() + alloc.size()) {
@@ -257,6 +255,9 @@ void MultipleSectionCodeAllocator::createSlabs() noexcept {
257255

258256
AllocateResult MultipleSectionCodeAllocator::addCode(asmjit::CodeHolder* code) {
259257
ThreadedCompileSerialize guard;
258+
#ifdef Py_GIL_DISABLED
259+
std::lock_guard lock{allocator_mutex_};
260+
#endif
260261

261262
if (code_sections_.empty()) {
262263
createSlabs();
@@ -338,6 +339,9 @@ bool MultipleSectionCodeAllocator::contains(const void* ptr) const {
338339
// is already thread-safe.
339340
{
340341
ThreadedCompileSerialize guard;
342+
#ifdef Py_GIL_DISABLED
343+
std::lock_guard lock{allocator_mutex_};
344+
#endif
341345
if (code_alloc_ <= ptr && ptr < code_alloc_ + total_allocation_size_) {
342346
return true;
343347
}

cinderx/Jit/code_allocator.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,9 @@ class CodeAllocatorCinder : public CodeAllocator {
6969
bool contains(const void* ptr) const override;
7070

7171
private:
72-
// Protects allocations_ from concurrent access between addCode() and
73-
// contains(). In free-threaded Python, one thread may be compiling a
74-
// function while another checks isJitCompiled() via a function watcher.
7572
#ifdef Py_GIL_DISABLED
76-
mutable std::mutex allocations_mutex_;
73+
// Protects all allocator-owned state used by addCode()/contains().
74+
mutable std::mutex allocator_mutex_;
7775
#endif
7876

7977
// List of chunks allocated for use in deallocation
@@ -104,6 +102,11 @@ class MultipleSectionCodeAllocator : public CodeAllocator {
104102
private:
105103
void createSlabs() noexcept;
106104

105+
#ifdef Py_GIL_DISABLED
106+
// Protects all allocator-owned state used by addCode()/contains().
107+
mutable std::mutex allocator_mutex_;
108+
#endif
109+
107110
std::unordered_map<codegen::CodeSection, uint8_t*> code_sections_;
108111
std::unordered_map<codegen::CodeSection, size_t> code_section_free_sizes_;
109112

0 commit comments

Comments
 (0)