@@ -113,12 +113,6 @@ void jl_add_code_in_flight(StringRef name, jl_code_instance_t *codeinst, const D
113
113
}
114
114
115
115
116
- #ifdef _OS_WINDOWS_
117
- #if defined(_CPU_X86_64_)
118
- void *lookupWriteAddressFor (RTDyldMemoryManager *memmgr, void *rt_addr);
119
- #endif
120
- #endif
121
-
122
116
#if defined(_OS_WINDOWS_)
123
117
static void create_PRUNTIME_FUNCTION (uint8_t *Code, size_t Size, StringRef fnname,
124
118
uint8_t *Section, size_t Allocated, uint8_t *UnwindData)
@@ -177,7 +171,14 @@ struct revcomp {
177
171
};
178
172
179
173
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
181
182
{
182
183
std::map<size_t , ObjectInfo, revcomp> objectmap;
183
184
std::map<size_t , std::pair<size_t , jl_method_instance_t *>, revcomp> linfomap;
@@ -194,44 +195,16 @@ class JuliaJITEventListener
194
195
return linfo;
195
196
}
196
197
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 )
200
201
{
201
202
jl_ptls_t ptls = jl_current_task->ptls ;
202
203
// This function modify codeinst->fptr in GC safe region.
203
204
// This should be fine since the GC won't scan this field.
204
205
int8_t gc_state = jl_gc_safe_enter (ptls);
205
206
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 ();
235
208
236
209
#ifdef _CPU_ARM_
237
210
// ARM does not have/use .eh_frame
@@ -290,7 +263,7 @@ class JuliaJITEventListener
290
263
uint8_t *UnwindData = NULL ;
291
264
#if defined(_CPU_X86_64_)
292
265
uint8_t *catchjmp = NULL ;
293
- for (const object::SymbolRef &sym_iter : debugObj .symbols ()) {
266
+ for (const object::SymbolRef &sym_iter : Object .symbols ()) {
294
267
StringRef sName = cantFail (sym_iter.getName ());
295
268
uint8_t **pAddr = NULL ;
296
269
if (sName .equals (" __UnwindData" )) {
@@ -313,9 +286,8 @@ class JuliaJITEventListener
313
286
SectionAddrCheck = SectionAddr;
314
287
SectionLoadCheck = SectionLoadAddr;
315
288
SectionWriteCheck = SectionLoadAddr;
316
- if (memmgr)
317
- SectionWriteCheck = (uintptr_t )lookupWriteAddressFor (memmgr,
318
- (void *)SectionLoadAddr);
289
+ if (lookupWriteAddress)
290
+ SectionWriteCheck = (uintptr_t )lookupWriteAddress ((void *)SectionLoadAddr);
319
291
Addr += SectionWriteCheck - SectionLoadAddr;
320
292
*pAddr = (uint8_t *)Addr;
321
293
}
@@ -343,7 +315,7 @@ class JuliaJITEventListener
343
315
#endif // defined(_OS_X86_64_)
344
316
#endif // defined(_OS_WINDOWS_)
345
317
346
- auto symbols = object::computeSymbolSizes (debugObj );
318
+ auto symbols = object::computeSymbolSizes (Object );
347
319
bool first = true ;
348
320
for (const auto &sym_size : symbols) {
349
321
const object::SymbolRef &sym_iter = sym_size.first ;
@@ -380,7 +352,7 @@ class JuliaJITEventListener
380
352
if (codeinst)
381
353
linfomap[Addr] = std::make_pair (Size, codeinst->def );
382
354
if (first) {
383
- ObjectInfo tmp = {&debugObj ,
355
+ ObjectInfo tmp = {&Object ,
384
356
(size_t )SectionSize,
385
357
(ptrdiff_t )(SectionAddr - SectionLoadAddr),
386
358
*Section,
@@ -394,22 +366,18 @@ class JuliaJITEventListener
394
366
jl_gc_safe_leave (ptls, gc_state);
395
367
}
396
368
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
-
401
369
std::map<size_t , ObjectInfo, revcomp>& getObjectMap () JL_NOTSAFEPOINT
402
370
{
403
371
return objectmap;
404
372
}
405
373
};
406
374
407
- static JuliaJITEventListener jl_jit_events ;
408
- JL_DLLEXPORT void ORCNotifyObjectEmitted (const object::ObjectFile &Object,
409
- const RuntimeDyld::LoadedObjectInfo &L ,
410
- RTDyldMemoryManager *memmgr )
375
+ static JITObjectRegistry jl_jit_object_registry ;
376
+ void jl_register_jit_object (const object::ObjectFile &Object,
377
+ std::function< uint64_t ( const StringRef &)> getLoadAddress ,
378
+ std::function<void *( void *)> lookupWriteAddress )
411
379
{
412
- jl_jit_events. NotifyObjectEmitted (Object, L, memmgr );
380
+ jl_jit_object_registry. registerJITObject (Object, getLoadAddress, lookupWriteAddress );
413
381
}
414
382
415
383
// TODO: convert the safe names from aotcomile.cpp:makeSafeName back into symbols
@@ -1178,7 +1146,7 @@ int jl_DI_for_fptr(uint64_t fptr, uint64_t *symsize, int64_t *slide,
1178
1146
{
1179
1147
int found = 0 ;
1180
1148
uv_rwlock_wrlock (&threadsafe);
1181
- std::map<size_t , ObjectInfo, revcomp> &objmap = jl_jit_events .getObjectMap ();
1149
+ std::map<size_t , ObjectInfo, revcomp> &objmap = jl_jit_object_registry .getObjectMap ();
1182
1150
std::map<size_t , ObjectInfo, revcomp>::iterator fit = objmap.lower_bound (fptr);
1183
1151
1184
1152
if (symsize)
@@ -1212,7 +1180,7 @@ extern "C" JL_DLLEXPORT int jl_getFunctionInfo_impl(jl_frame_t **frames_out, siz
1212
1180
int64_t slide;
1213
1181
uint64_t symsize;
1214
1182
if (jl_DI_for_fptr (pointer, &symsize, &slide, &Section, &context)) {
1215
- frames[0 ].linfo = jl_jit_events .lookupLinfo (pointer);
1183
+ frames[0 ].linfo = jl_jit_object_registry .lookupLinfo (pointer);
1216
1184
int nf = lookup_pointer (Section, context, frames_out, pointer, slide, true , noInline);
1217
1185
return nf;
1218
1186
}
@@ -1221,7 +1189,7 @@ extern "C" JL_DLLEXPORT int jl_getFunctionInfo_impl(jl_frame_t **frames_out, siz
1221
1189
1222
1190
extern " C" jl_method_instance_t *jl_gdblookuplinfo (void *p) JL_NOTSAFEPOINT
1223
1191
{
1224
- return jl_jit_events .lookupLinfo ((size_t )p);
1192
+ return jl_jit_object_registry .lookupLinfo ((size_t )p);
1225
1193
}
1226
1194
1227
1195
#if (defined(_OS_LINUX_) || defined(_OS_FREEBSD_) || (defined(_OS_DARWIN_) && defined(LLVM_SHLIB)))
@@ -1643,7 +1611,7 @@ uint64_t jl_getUnwindInfo_impl(uint64_t dwAddr)
1643
1611
{
1644
1612
// Might be called from unmanaged thread
1645
1613
uv_rwlock_rdlock (&threadsafe);
1646
- std::map<size_t , ObjectInfo, revcomp> &objmap = jl_jit_events .getObjectMap ();
1614
+ std::map<size_t , ObjectInfo, revcomp> &objmap = jl_jit_object_registry .getObjectMap ();
1647
1615
std::map<size_t , ObjectInfo, revcomp>::iterator it = objmap.lower_bound (dwAddr);
1648
1616
uint64_t ipstart = 0 ; // ip of the start of the section (if found)
1649
1617
if (it != objmap.end () && dwAddr < it->first + it->second .SectionSize ) {
0 commit comments