Skip to content

Commit

Permalink
Improvements to JITLink, to ease transition (JuliaLang#54841)
Browse files Browse the repository at this point in the history
This doesn't switch the default to JITLink, but does some updates to
get JITLink working (and more efficient) across all of our supported
platforms.

Refs JuliaLang#50248
  • Loading branch information
vtjnash authored Oct 5, 2024
2 parents ae94729 + 218edea commit 0c8c20c
Show file tree
Hide file tree
Showing 6 changed files with 252 additions and 252 deletions.
29 changes: 0 additions & 29 deletions src/cgmemmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -833,28 +833,6 @@ class RTDyldMemoryManagerJL : public SectionMemoryManager {
mapAddresses(Dyld, ro_alloc);
mapAddresses(Dyld, exe_alloc);
}
#ifdef _OS_WINDOWS_
template <typename Alloc>
void *lookupWriteAddressFor(void *rt_addr, Alloc &&allocator)
{
for (auto &alloc: allocator->allocations) {
if (alloc.rt_addr == rt_addr) {
return alloc.wr_addr;
}
}
return nullptr;
}
void *lookupWriteAddressFor(void *rt_addr)
{
if (!ro_alloc)
return rt_addr;
if (void *ptr = lookupWriteAddressFor(rt_addr, ro_alloc))
return ptr;
if (void *ptr = lookupWriteAddressFor(rt_addr, exe_alloc))
return ptr;
return rt_addr;
}
#endif // _OS_WINDOWS_
};

uint8_t *RTDyldMemoryManagerJL::allocateCodeSection(uintptr_t Size,
Expand Down Expand Up @@ -947,13 +925,6 @@ void RTDyldMemoryManagerJL::deregisterEHFrames(uint8_t *Addr,

}

#ifdef _OS_WINDOWS_
void *lookupWriteAddressFor(RTDyldMemoryManager *memmgr, void *rt_addr)
{
return ((RTDyldMemoryManagerJL*)memmgr)->lookupWriteAddressFor(rt_addr);
}
#endif

RTDyldMemoryManager* createRTDyldMemoryManager()
{
return new RTDyldMemoryManagerJL();
Expand Down
15 changes: 6 additions & 9 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10371,6 +10371,7 @@ static void init_jit_functions(void)

#ifdef _OS_WINDOWS_
#if defined(_CPU_X86_64_)
add_named_global("__julia_personality", &__julia_personality);
#if defined(_COMPILER_GCC_)
add_named_global("___chkstk_ms", &___chkstk_ms);
#else
Expand All @@ -10396,7 +10397,7 @@ static void init_jit_functions(void)
}

#ifdef JL_USE_INTEL_JITEVENTS
char jl_using_intel_jitevents; // Non-zero if running under Intel VTune Amplifier
char jl_using_intel_jitevents = 0; // Non-zero if running under Intel VTune Amplifier
#endif

#ifdef JL_USE_OPROFILE_JITEVENTS
Expand Down Expand Up @@ -10510,9 +10511,6 @@ extern "C" void jl_init_llvm(void)
#if defined(JL_USE_INTEL_JITEVENTS) || \
defined(JL_USE_OPROFILE_JITEVENTS) || \
defined(JL_USE_PERF_JITEVENTS)
#ifdef JL_USE_JITLINK
#pragma message("JIT profiling support (JL_USE_*_JITEVENTS) not yet available on platforms that use JITLink")
#else
const char *jit_profiling = getenv("ENABLE_JITPROFILING");

#if defined(JL_USE_INTEL_JITEVENTS)
Expand All @@ -10529,24 +10527,23 @@ extern "C" void jl_init_llvm(void)

#if defined(JL_USE_PERF_JITEVENTS)
if (jit_profiling && atoi(jit_profiling)) {
jl_using_perf_jitevents= 1;
jl_using_perf_jitevents = 1;
}
#endif

#ifdef JL_USE_INTEL_JITEVENTS
if (jl_using_intel_jitevents)
jl_ExecutionEngine->RegisterJITEventListener(JITEventListener::createIntelJITEventListener());
jl_ExecutionEngine->enableIntelJITEventListener();
#endif

#ifdef JL_USE_OPROFILE_JITEVENTS
if (jl_using_oprofile_jitevents)
jl_ExecutionEngine->RegisterJITEventListener(JITEventListener::createOProfileJITEventListener());
jl_ExecutionEngine->enableOProfileJITEventListener();
#endif

#ifdef JL_USE_PERF_JITEVENTS
if (jl_using_perf_jitevents)
jl_ExecutionEngine->RegisterJITEventListener(JITEventListener::createPerfJITEventListener());
#endif
jl_ExecutionEngine->enablePerfJITEventListener();
#endif
#endif

Expand Down
3 changes: 1 addition & 2 deletions src/debug-registry.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,7 @@ class JITDebugInfoRegistry
void add_code_in_flight(llvm::StringRef name, jl_code_instance_t *codeinst, const llvm::DataLayout &DL) JL_NOTSAFEPOINT;
jl_method_instance_t *lookupLinfo(size_t pointer) JL_NOTSAFEPOINT;
void registerJITObject(const llvm::object::ObjectFile &Object,
std::function<uint64_t(const llvm::StringRef &)> getLoadAddress,
std::function<void*(void*)> lookupWriteAddress);
std::function<uint64_t(const llvm::StringRef &)> getLoadAddress);
objectmap_t& getObjectMap() JL_NOTSAFEPOINT;
void add_image_info(image_info_t info) JL_NOTSAFEPOINT;
bool get_image_info(uint64_t base, image_info_t *info) const JL_NOTSAFEPOINT;
Expand Down
47 changes: 17 additions & 30 deletions src/debuginfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,21 @@ static void create_PRUNTIME_FUNCTION(uint8_t *Code, size_t Size, StringRef fnnam
#endif

void JITDebugInfoRegistry::registerJITObject(const object::ObjectFile &Object,
std::function<uint64_t(const StringRef &)> getLoadAddress,
std::function<void*(void*)> lookupWriteAddress)
std::function<uint64_t(const StringRef &)> getLoadAddress)
{
object::section_iterator EndSection = Object.section_end();

bool anyfunctions = false;
for (const object::SymbolRef &sym_iter : Object.symbols()) {
object::SymbolRef::Type SymbolType = cantFail(sym_iter.getType());
if (SymbolType != object::SymbolRef::ST_Function)
continue;
anyfunctions = true;
break;
}
if (!anyfunctions)
return;

#ifdef _CPU_ARM_
// ARM does not have/use .eh_frame
uint64_t arm_exidx_addr = 0;
Expand Down Expand Up @@ -281,14 +291,13 @@ void JITDebugInfoRegistry::registerJITObject(const object::ObjectFile &Object,
#if defined(_OS_WINDOWS_)
uint64_t SectionAddrCheck = 0;
uint64_t SectionLoadCheck = 0; (void)SectionLoadCheck;
uint64_t SectionWriteCheck = 0; (void)SectionWriteCheck;
uint8_t *UnwindData = NULL;
#if defined(_CPU_X86_64_)
uint8_t *catchjmp = NULL;
for (const object::SymbolRef &sym_iter : Object.symbols()) {
StringRef sName = cantFail(sym_iter.getName());
if (sName.equals("__UnwindData") || sName.equals("__catchjmp")) {
uint64_t Addr = cantFail(sym_iter.getAddress());
uint64_t Addr = cantFail(sym_iter.getAddress()); // offset into object (including section offset)
auto Section = cantFail(sym_iter.getSection());
assert(Section != EndSection && Section->isText());
uint64_t SectionAddr = Section->getAddress();
Expand All @@ -300,10 +309,7 @@ void JITDebugInfoRegistry::registerJITObject(const object::ObjectFile &Object,
SectionLoadCheck == SectionLoadAddr);
SectionAddrCheck = SectionAddr;
SectionLoadCheck = SectionLoadAddr;
SectionWriteCheck = SectionLoadAddr;
if (lookupWriteAddress)
SectionWriteCheck = (uintptr_t)lookupWriteAddress((void*)SectionLoadAddr);
Addr += SectionWriteCheck - SectionLoadCheck;
Addr += SectionLoadAddr - SectionAddr;
if (sName.equals("__UnwindData")) {
UnwindData = (uint8_t*)Addr;
}
Expand All @@ -314,25 +320,7 @@ void JITDebugInfoRegistry::registerJITObject(const object::ObjectFile &Object,
}
assert(catchjmp);
assert(UnwindData);
assert(SectionAddrCheck);
assert(SectionLoadCheck);
assert(!memcmp(catchjmp, "\0\0\0\0\0\0\0\0\0\0\0\0", 12) &&
!memcmp(UnwindData, "\0\0\0\0\0\0\0\0\0\0\0\0", 12));
catchjmp[0] = 0x48;
catchjmp[1] = 0xb8; // mov RAX, QWORD PTR [&__julia_personality]
*(uint64_t*)(&catchjmp[2]) = (uint64_t)&__julia_personality;
catchjmp[10] = 0xff;
catchjmp[11] = 0xe0; // jmp RAX
UnwindData[0] = 0x09; // version info, UNW_FLAG_EHANDLER
UnwindData[1] = 4; // size of prolog (bytes)
UnwindData[2] = 2; // count of unwind codes (slots)
UnwindData[3] = 0x05; // frame register (rbp) = rsp
UnwindData[4] = 4; // second instruction
UnwindData[5] = 0x03; // mov RBP, RSP
UnwindData[6] = 1; // first instruction
UnwindData[7] = 0x50; // push RBP
*(DWORD*)&UnwindData[8] = (DWORD)(catchjmp - (uint8_t*)SectionWriteCheck); // relative location of catchjmp
UnwindData -= SectionWriteCheck - SectionLoadCheck;
#endif // defined(_OS_X86_64_)
#endif // defined(_OS_WINDOWS_)

Expand All @@ -353,7 +341,7 @@ void JITDebugInfoRegistry::registerJITObject(const object::ObjectFile &Object,
uint64_t SectionAddr = Section->getAddress();
StringRef secName = cantFail(Section->getName());
uint64_t SectionLoadAddr = getLoadAddress(secName);
Addr -= SectionAddr - SectionLoadAddr;
Addr += SectionLoadAddr - SectionAddr;
StringRef sName = cantFail(sym_iter.getName());
uint64_t SectionSize = Section->getSize();
size_t Size = sym_size.second;
Expand Down Expand Up @@ -404,10 +392,9 @@ void JITDebugInfoRegistry::registerJITObject(const object::ObjectFile &Object,
}

void jl_register_jit_object(const object::ObjectFile &Object,
std::function<uint64_t(const StringRef &)> getLoadAddress,
std::function<void *(void *)> lookupWriteAddress)
std::function<uint64_t(const StringRef &)> getLoadAddress)
{
getJITDebugRegistry().registerJITObject(Object, getLoadAddress, lookupWriteAddress);
getJITDebugRegistry().registerJITObject(Object, getLoadAddress);
}

// TODO: convert the safe names from aotcomile.cpp:makeSafeName back into symbols
Expand Down
Loading

0 comments on commit 0c8c20c

Please sign in to comment.