@@ -113,12 +113,6 @@ void jl_add_code_in_flight(StringRef name, jl_code_instance_t *codeinst, const D
113113}
114114
115115
116- #ifdef _OS_WINDOWS_
117- #if defined(_CPU_X86_64_)
118- void *lookupWriteAddressFor (RTDyldMemoryManager *memmgr, void *rt_addr);
119- #endif
120- #endif
121-
122116#if defined(_OS_WINDOWS_)
123117static void create_PRUNTIME_FUNCTION (uint8_t *Code, size_t Size, StringRef fnname,
124118 uint8_t *Section, size_t Allocated, uint8_t *UnwindData)
@@ -177,7 +171,14 @@ struct revcomp {
177171};
178172
179173
180- class JuliaJITEventListener
174+ // Central registry for resolving function addresses to `jl_method_instance_t`s and
175+ // originating `ObjectFile`s (for the DWARF debug info).
176+ //
177+ // A global singleton instance is notified by the JIT whenever a new object is emitted,
178+ // and later queried by the various function info APIs. We also use the chance to handle
179+ // some platform-specific unwind info registration (which is unrelated to the query
180+ // functionality).
181+ class JITObjectRegistry
181182{
182183 std::map<size_t , ObjectInfo, revcomp> objectmap;
183184 std::map<size_t , std::pair<size_t , jl_method_instance_t *>, revcomp> linfomap;
@@ -194,44 +195,16 @@ class JuliaJITEventListener
194195 return linfo;
195196 }
196197
197- void NotifyObjectEmitted (const object::ObjectFile &Object,
198- const RuntimeDyld::LoadedObjectInfo &L ,
199- RTDyldMemoryManager *memmgr )
198+ void registerJITObject (const object::ObjectFile &Object,
199+ std::function< uint64_t ( const StringRef &)> getLoadAddress ,
200+ std::function<void*( void *)> lookupWriteAddress )
200201 {
201202 jl_ptls_t ptls = jl_current_task->ptls ;
202203 // This function modify codeinst->fptr in GC safe region.
203204 // This should be fine since the GC won't scan this field.
204205 int8_t gc_state = jl_gc_safe_enter (ptls);
205206
206- auto SavedObject = L.getObjectForDebug (Object).takeBinary ();
207- // If the debug object is unavailable, save (a copy of) the original object
208- // for our backtraces.
209- // This copy seems unfortunate, but there doesn't seem to be a way to take
210- // ownership of the original buffer.
211- if (!SavedObject.first ) {
212- auto NewBuffer = MemoryBuffer::getMemBufferCopy (
213- Object.getData (), Object.getFileName ());
214- auto NewObj = cantFail (object::ObjectFile::createObjectFile (NewBuffer->getMemBufferRef ()));
215- SavedObject = std::make_pair (std::move (NewObj), std::move (NewBuffer));
216- }
217- const object::ObjectFile &debugObj = *SavedObject.first .release ();
218- SavedObject.second .release ();
219-
220- object::section_iterator EndSection = debugObj.section_end ();
221- StringMap<object::SectionRef> loadedSections;
222- for (const object::SectionRef &lSection: Object.sections ()) {
223- auto sName = lSection.getName ();
224- if (sName ) {
225- bool inserted = loadedSections.insert (std::make_pair (*sName , lSection)).second ;
226- assert (inserted); (void )inserted;
227- }
228- }
229- auto getLoadAddress = [&] (const StringRef &sName ) -> uint64_t {
230- auto search = loadedSections.find (sName );
231- if (search == loadedSections.end ())
232- return 0 ;
233- return L.getSectionLoadAddress (search->second );
234- };
207+ object::section_iterator EndSection = Object.section_end ();
235208
236209#ifdef _CPU_ARM_
237210 // ARM does not have/use .eh_frame
@@ -290,7 +263,7 @@ class JuliaJITEventListener
290263 uint8_t *UnwindData = NULL ;
291264#if defined(_CPU_X86_64_)
292265 uint8_t *catchjmp = NULL ;
293- for (const object::SymbolRef &sym_iter : debugObj .symbols ()) {
266+ for (const object::SymbolRef &sym_iter : Object .symbols ()) {
294267 StringRef sName = cantFail (sym_iter.getName ());
295268 uint8_t **pAddr = NULL ;
296269 if (sName .equals (" __UnwindData" )) {
@@ -314,8 +287,7 @@ class JuliaJITEventListener
314287 SectionLoadCheck = SectionLoadAddr;
315288 SectionWriteCheck = SectionLoadAddr;
316289 if (memmgr)
317- SectionWriteCheck = (uintptr_t )lookupWriteAddressFor (memmgr,
318- (void *)SectionLoadAddr);
290+ SectionWriteCheck = (uintptr_t )getWriteAddress ((void *)SectionLoadAddr);
319291 Addr += SectionWriteCheck - SectionLoadAddr;
320292 *pAddr = (uint8_t *)Addr;
321293 }
@@ -343,7 +315,7 @@ class JuliaJITEventListener
343315#endif // defined(_OS_X86_64_)
344316#endif // defined(_OS_WINDOWS_)
345317
346- auto symbols = object::computeSymbolSizes (debugObj );
318+ auto symbols = object::computeSymbolSizes (Object );
347319 bool first = true ;
348320 for (const auto &sym_size : symbols) {
349321 const object::SymbolRef &sym_iter = sym_size.first ;
@@ -360,6 +332,7 @@ class JuliaJITEventListener
360332 StringRef sName = cantFail (sym_iter.getName ());
361333 uint64_t SectionSize = Section->getSize ();
362334 size_t Size = sym_size.second ;
335+ // jl_safe_printf("Loaded symbol %.*s @ %llx (+%llx)\n", (int)sName.size(), sName.begin(), Addr, Size);
363336#if defined(_OS_WINDOWS_)
364337 if (SectionAddrCheck)
365338 assert (SectionAddrCheck == SectionAddr &&
@@ -380,7 +353,7 @@ class JuliaJITEventListener
380353 if (codeinst)
381354 linfomap[Addr] = std::make_pair (Size, codeinst->def );
382355 if (first) {
383- ObjectInfo tmp = {&debugObj ,
356+ ObjectInfo tmp = {&Object ,
384357 (size_t )SectionSize,
385358 (ptrdiff_t )(SectionAddr - SectionLoadAddr),
386359 *Section,
@@ -394,22 +367,18 @@ class JuliaJITEventListener
394367 jl_gc_safe_leave (ptls, gc_state);
395368 }
396369
397- // must implement if we ever start freeing code
398- // virtual void NotifyFreeingObject(const ObjectImage &Object) {}
399- // virtual void NotifyFreeingObject(const object::ObjectFile &Obj) {}
400-
401370 std::map<size_t , ObjectInfo, revcomp>& getObjectMap () JL_NOTSAFEPOINT
402371 {
403372 return objectmap;
404373 }
405374};
406375
407- static JuliaJITEventListener jl_jit_events ;
408- JL_DLLEXPORT void ORCNotifyObjectEmitted (const object::ObjectFile &Object,
409- const RuntimeDyld::LoadedObjectInfo &L ,
410- RTDyldMemoryManager *memmgr )
376+ static JITObjectRegistry jl_jit_object_registry ;
377+ void jl_register_jit_object (const object::ObjectFile &Object,
378+ std::function< uint64_t ( const StringRef &)> getLoadAddress ,
379+ std::function<void *( void *)> lookupWriteAddress )
411380{
412- jl_jit_events. NotifyObjectEmitted (Object, L, memmgr );
381+ jl_jit_object_registry. registerJITObject (Object, getLoadAddress, lookupWriteAddress );
413382}
414383
415384// TODO: convert the safe names from aotcomile.cpp:makeSafeName back into symbols
@@ -1178,7 +1147,7 @@ int jl_DI_for_fptr(uint64_t fptr, uint64_t *symsize, int64_t *slide,
11781147{
11791148 int found = 0 ;
11801149 uv_rwlock_wrlock (&threadsafe);
1181- std::map<size_t , ObjectInfo, revcomp> &objmap = jl_jit_events .getObjectMap ();
1150+ std::map<size_t , ObjectInfo, revcomp> &objmap = jl_jit_object_registry .getObjectMap ();
11821151 std::map<size_t , ObjectInfo, revcomp>::iterator fit = objmap.lower_bound (fptr);
11831152
11841153 if (symsize)
@@ -1212,7 +1181,7 @@ extern "C" JL_DLLEXPORT int jl_getFunctionInfo_impl(jl_frame_t **frames_out, siz
12121181 int64_t slide;
12131182 uint64_t symsize;
12141183 if (jl_DI_for_fptr (pointer, &symsize, &slide, &Section, &context)) {
1215- frames[0 ].linfo = jl_jit_events .lookupLinfo (pointer);
1184+ frames[0 ].linfo = jl_jit_object_registry .lookupLinfo (pointer);
12161185 int nf = lookup_pointer (Section, context, frames_out, pointer, slide, true , noInline);
12171186 return nf;
12181187 }
@@ -1221,7 +1190,7 @@ extern "C" JL_DLLEXPORT int jl_getFunctionInfo_impl(jl_frame_t **frames_out, siz
12211190
12221191extern " C" jl_method_instance_t *jl_gdblookuplinfo (void *p) JL_NOTSAFEPOINT
12231192{
1224- return jl_jit_events .lookupLinfo ((size_t )p);
1193+ return jl_jit_object_registry .lookupLinfo ((size_t )p);
12251194}
12261195
12271196#if (defined(_OS_LINUX_) || defined(_OS_FREEBSD_) || (defined(_OS_DARWIN_) && defined(LLVM_SHLIB)))
@@ -1643,7 +1612,7 @@ uint64_t jl_getUnwindInfo_impl(uint64_t dwAddr)
16431612{
16441613 // Might be called from unmanaged thread
16451614 uv_rwlock_rdlock (&threadsafe);
1646- std::map<size_t , ObjectInfo, revcomp> &objmap = jl_jit_events .getObjectMap ();
1615+ std::map<size_t , ObjectInfo, revcomp> &objmap = jl_jit_object_registry .getObjectMap ();
16471616 std::map<size_t , ObjectInfo, revcomp>::iterator it = objmap.lower_bound (dwAddr);
16481617 uint64_t ipstart = 0 ; // ip of the start of the section (if found)
16491618 if (it != objmap.end () && dwAddr < it->first + it->second .SectionSize ) {
0 commit comments