Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 68 additions & 13 deletions src/cgmemmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,17 @@ static bool check_fd_or_close(int fd) JL_NOTSAFEPOINT
return false;
}
// This can fail due to `noexec` mount option ....
# ifndef _OS_DARWIN_
void *ptr = mmap(nullptr, jl_page_size, PROT_READ | PROT_EXEC,
MAP_SHARED, fd, 0);
# else
// Darwin requires mmap -> mprotect to get RX pages
void *ptr = mmap(nullptr, jl_page_size, 0, MAP_SHARED, fd, 0);
if (ptr != MAP_FAILED && mprotect(ptr, jl_page_size, PROT_READ | PROT_EXEC)) {
munmap(ptr, jl_page_size);
ptr = MAP_FAILED;
}
# endif
if (ptr == MAP_FAILED) {
close(fd);
return false;
Expand Down Expand Up @@ -258,6 +267,8 @@ static void *create_shared_map(size_t size, size_t id) JL_NOTSAFEPOINT

static intptr_t init_shared_map() JL_NOTSAFEPOINT
{
if (anon_hdl != -1)
return anon_hdl;
anon_hdl = get_anon_hdl();
if (anon_hdl == -1)
return -1;
Expand Down Expand Up @@ -550,8 +561,6 @@ class ROAllocator {
{
for (auto &alloc: allocations) {
// ensure the mapped pages are consistent
sys::Memory::InvalidateInstructionCache(alloc.wr_addr,
alloc.sz);
sys::Memory::InvalidateInstructionCache(alloc.rt_addr,
alloc.sz);
}
Expand Down Expand Up @@ -596,17 +605,14 @@ class ROAllocator {
new_block.reset(nullptr, 0);
}
void *ptr = block.alloc(size, align);
#ifdef _OS_WINDOWS_
block.state = SplitPtrBlock::Alloc;
void *wr_ptr = get_wr_ptr(block, ptr, size, align);
block.state |= SplitPtrBlock::Alloc;
void *wr_ptr;
if (block.state & SplitPtrBlock::InitAlloc)
wr_ptr = ptr;
else
wr_ptr = get_wr_ptr(block, ptr, size, align);
Allocation a{wr_ptr, ptr, size, false};
allocations.push_back(a);
ptr = wr_ptr;
#else
block.state = SplitPtrBlock::Alloc | SplitPtrBlock::InitAlloc;
Allocation a{ptr, ptr, size, false};
allocations.push_back(a);
#endif
return a;
}
};
Expand Down Expand Up @@ -636,6 +642,9 @@ class DualMapAllocator : public ROAllocator {
// use `wr_ptr` to record the id initially
auto ptr = alloc_shared_page(size, (size_t*)&new_block.wr_ptr, exec);
new_block.reset(ptr, size);
#ifndef _OS_WINDOWS_
new_block.state = SplitPtrBlock::InitAlloc;
#endif
return new_block;
}
void finalize_block(SplitPtrBlock &block, bool reset) JL_NOTSAFEPOINT
Expand Down Expand Up @@ -715,6 +724,7 @@ class SelfMemAllocator : public ROAllocator {
{
SplitPtrBlock new_block;
new_block.reset(map_anon_page(size), size);
new_block.state = SplitPtrBlock::InitAlloc;
return new_block;
}
void finalize_block(SplitPtrBlock &block, bool reset) JL_NOTSAFEPOINT
Expand Down Expand Up @@ -769,13 +779,55 @@ class SelfMemAllocator : public ROAllocator {
};
#endif // _OS_LINUX_

#if defined(_OS_DARWIN_) && defined(_CPU_AARCH64_)
class MapJITAllocator : public ROAllocator {
static inline thread_local bool jit_rw;

protected:
void *get_wr_ptr(SplitPtrBlock &block, void *rt_ptr, size_t size,
size_t align) override JL_NOTSAFEPOINT
{
if (!jit_rw) {
pthread_jit_write_protect_np(0);
jit_rw = true;
}
return rt_ptr;
}

SplitPtrBlock alloc_block(size_t size) override JL_NOTSAFEPOINT
{
SplitPtrBlock block;
void *mem = mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_JIT | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
assert(mem != MAP_FAILED && "Cannot allocate MAP_JIT memory");
block.reset(mem, size);
return block;
}

public:
void finalize() override JL_NOTSAFEPOINT
{
if (jit_rw) {
pthread_jit_write_protect_np(1);
jit_rw = false;
}
ROAllocator::finalize();
}
};
#endif // defined(_OS_DARWIN_) && defined(_CPU_AARCH64_)

std::pair<std::unique_ptr<ROAllocator>, std::unique_ptr<ROAllocator>>
get_preferred_allocators() JL_NOTSAFEPOINT
{
#ifdef _OS_LINUX_
if (get_self_mem_fd() != -1)
return {std::make_unique<SelfMemAllocator>(false),
std::make_unique<SelfMemAllocator>(true)};
#endif
#if defined(_OS_DARWIN_) && defined(_CPU_AARCH64_)
if (pthread_jit_write_protect_supported_np() && init_shared_map() != -1)
return {std::make_unique<DualMapAllocator>(false),
std::make_unique<MapJITAllocator>()};
#endif
if (init_shared_map() != -1)
return {std::make_unique<DualMapAllocator>(false),
Expand Down Expand Up @@ -960,7 +1012,7 @@ class JLJITLinkMemoryManager : public jitlink::JITLinkMemoryManager {
void deallocate(std::vector<FinalizedAlloc> Allocs,
OnDeallocatedFunction OnDeallocated) override
{
jl_unreachable();
OnDeallocated(Error::success());
}

protected:
Expand Down Expand Up @@ -998,7 +1050,10 @@ class JLJITLinkMemoryManager::InFlightAlloc
public:
InFlightAlloc(JLJITLinkMemoryManager &MM, jitlink::LinkGraph &G) : MM(MM), G(G) {}

void abandon(OnAbandonedFunction OnAbandoned) override { jl_unreachable(); }
void abandon(OnAbandonedFunction OnAbandoned) override
{
OnAbandoned(Error::success());
}

void finalize(OnFinalizedFunction OnFinalized) override
{
Expand Down