@@ -180,6 +180,8 @@ static jl_callptr_t _jl_compile_codeinst(
180
180
size_t world,
181
181
orc::ThreadSafeContext context)
182
182
{
183
+ PTR_PIN (codeinst);
184
+ PTR_PIN (src);
183
185
// caller must hold codegen_lock
184
186
// and have disabled finalizers
185
187
uint64_t start_time = 0 ;
@@ -246,6 +248,7 @@ static jl_callptr_t _jl_compile_codeinst(
246
248
IndirectCodeinsts += emitted.size () - 1 ;
247
249
}
248
250
JL_TIMING (LLVM_MODULE_FINISH);
251
+ PTR_UNPIN (src);
249
252
250
253
for (auto &def : emitted) {
251
254
jl_code_instance_t *this_code = def.first ;
@@ -307,6 +310,7 @@ static jl_callptr_t _jl_compile_codeinst(
307
310
jl_printf (stream, " \"\n " );
308
311
}
309
312
}
313
+ PTR_UNPIN (codeinst);
310
314
return fptr;
311
315
}
312
316
@@ -316,6 +320,8 @@ const char *jl_generate_ccallable(LLVMOrcThreadSafeModuleRef llvmmod, void *sysi
316
320
extern " C" JL_DLLEXPORT
317
321
int jl_compile_extern_c_impl (LLVMOrcThreadSafeModuleRef llvmmod, void *p, void *sysimg, jl_value_t *declrt, jl_value_t *sigt)
318
322
{
323
+ PTR_PIN (declrt);
324
+ PTR_PIN (sigt);
319
325
auto ct = jl_current_task;
320
326
ct->reentrant_timing ++;
321
327
uint64_t compiler_start_time = 0 ;
@@ -339,6 +345,8 @@ int jl_compile_extern_c_impl(LLVMOrcThreadSafeModuleRef llvmmod, void *p, void *
339
345
pparams = ¶ms;
340
346
assert (pparams->tsctx .getContext () == into->getContext ().getContext ());
341
347
const char *name = jl_generate_ccallable (wrap (into), sysimg, declrt, sigt, *pparams);
348
+ PTR_UNPIN (declrt);
349
+ PTR_UNPIN (sigt);
342
350
bool success = true ;
343
351
if (!sysimg) {
344
352
if (jl_ExecutionEngine->getGlobalValueAddress (name)) {
@@ -368,13 +376,18 @@ int jl_compile_extern_c_impl(LLVMOrcThreadSafeModuleRef llvmmod, void *p, void *
368
376
extern " C" JL_DLLEXPORT
369
377
void jl_extern_c_impl (jl_value_t *declrt, jl_tupletype_t *sigt)
370
378
{
379
+ PTR_PIN (declrt);
380
+ PTR_PIN (sigt);
381
+ jl_svec_t *params = ((jl_datatype_t *)(sigt))->parameters ;
382
+ PTR_PIN (params);
371
383
// validate arguments. try to do as many checks as possible here to avoid
372
384
// throwing errors later during codegen.
373
385
JL_TYPECHK (@ccallable, type, declrt);
374
386
if (!jl_is_tuple_type (sigt))
375
387
jl_type_error (" @ccallable" , (jl_value_t *)jl_anytuple_type_type, (jl_value_t *)sigt);
376
388
// check that f is a guaranteed singleton type
377
389
jl_datatype_t *ft = (jl_datatype_t *)jl_tparam0 (sigt);
390
+ PTR_PIN (ft);
378
391
if (!jl_is_datatype (ft) || ft->instance == NULL )
379
392
jl_error (" @ccallable: function object must be a singleton" );
380
393
@@ -385,12 +398,13 @@ void jl_extern_c_impl(jl_value_t *declrt, jl_tupletype_t *sigt)
385
398
jl_error (" @ccallable: return type doesn't correspond to a C type" );
386
399
387
400
// validate method signature
388
- size_t i, nargs = jl_nparams (sigt );
401
+ size_t i, nargs = jl_svec_len (params );
389
402
for (i = 1 ; i < nargs; i++) {
390
- jl_value_t *ati = jl_tparam (sigt , i);
403
+ jl_value_t *ati = jl_svecref (params , i);
391
404
if (!jl_is_concrete_type (ati) || jl_is_kind (ati) || !jl_type_mappable_to_c (ati))
392
405
jl_error (" @ccallable: argument types must be concrete" );
393
406
}
407
+ PTR_UNPIN (params);
394
408
395
409
// save a record of this so that the alias is generated when we write an object file
396
410
jl_method_t *meth = (jl_method_t *)jl_methtable_lookup (ft->name ->mt , (jl_value_t *)sigt, jl_atomic_load_acquire (&jl_world_counter));
@@ -403,6 +417,9 @@ void jl_extern_c_impl(jl_value_t *declrt, jl_tupletype_t *sigt)
403
417
404
418
// create the alias in the current runtime environment
405
419
int success = jl_compile_extern_c (NULL , NULL , NULL , declrt, (jl_value_t *)sigt);
420
+ PTR_UNPIN (declrt);
421
+ PTR_UNPIN (sigt);
422
+ PTR_UNPIN (ft);
406
423
if (!success)
407
424
jl_error (" @ccallable was already defined for this method name" );
408
425
}
@@ -411,6 +428,9 @@ void jl_extern_c_impl(jl_value_t *declrt, jl_tupletype_t *sigt)
411
428
extern " C" JL_DLLEXPORT
412
429
jl_code_instance_t *jl_generate_fptr_impl (jl_method_instance_t *mi JL_PROPAGATES_ROOT, size_t world)
413
430
{
431
+ PTR_PIN (mi);
432
+ jl_method_t * method = mi->def .method ;
433
+ PTR_PIN (method);
414
434
auto ct = jl_current_task;
415
435
ct->reentrant_timing ++;
416
436
uint64_t compiler_start_time = 0 ;
@@ -425,19 +445,20 @@ jl_code_instance_t *jl_generate_fptr_impl(jl_method_instance_t *mi JL_PROPAGATES
425
445
jl_value_t *ci = jl_rettype_inferred (mi, world, world);
426
446
jl_code_instance_t *codeinst = (ci == jl_nothing ? NULL : (jl_code_instance_t *)ci);
427
447
if (codeinst) {
448
+ PTR_PIN (codeinst);
428
449
src = (jl_code_info_t *)jl_atomic_load_relaxed (&codeinst->inferred );
429
450
if ((jl_value_t *)src == jl_nothing)
430
451
src = NULL ;
431
- else if (jl_is_method (mi-> def . method ))
432
- src = jl_uncompress_ir (mi-> def . method , codeinst, (jl_array_t *)src);
452
+ else if (jl_is_method (method))
453
+ src = jl_uncompress_ir (method, codeinst, (jl_array_t *)src);
433
454
}
434
455
else {
435
456
// identify whether this is an invalidated method that is being recompiled
436
457
is_recompile = jl_atomic_load_relaxed (&mi->cache ) != NULL ;
437
458
}
438
- if (src == NULL && jl_is_method (mi-> def . method ) &&
439
- jl_symbol_name (mi-> def . method ->name )[0 ] != ' @' ) {
440
- if (mi-> def . method ->source != jl_nothing) {
459
+ if (src == NULL && jl_is_method (method) &&
460
+ jl_symbol_name (method->name )[0 ] != ' @' ) {
461
+ if (method->source != jl_nothing) {
441
462
// If the caller didn't provide the source and IR is available,
442
463
// see if it is inferred, or try to infer it for ourself.
443
464
// (but don't bother with typeinf on macros or toplevel thunks)
@@ -446,22 +467,28 @@ jl_code_instance_t *jl_generate_fptr_impl(jl_method_instance_t *mi JL_PROPAGATES
446
467
}
447
468
jl_code_instance_t *compiled = jl_method_compiled (mi, world);
448
469
if (compiled) {
470
+ if (codeinst) PTR_UNPIN (codeinst);
449
471
codeinst = compiled;
472
+ PTR_PIN (codeinst);
450
473
}
451
474
else if (src && jl_is_code_info (src)) {
452
475
if (!codeinst) {
453
476
codeinst = jl_get_method_inferred (mi, src->rettype , src->min_world , src->max_world );
477
+ PTR_PIN (codeinst);
454
478
if (src->inferred ) {
455
479
jl_value_t *null = nullptr ;
456
480
jl_atomic_cmpswap_relaxed (&codeinst->inferred , &null, jl_nothing);
457
481
}
458
482
}
459
483
++SpecFPtrCount;
460
484
_jl_compile_codeinst (codeinst, src, world, *jl_ExecutionEngine->getContext ());
461
- if (jl_atomic_load_relaxed (&codeinst->invoke ) == NULL )
485
+ if (jl_atomic_load_relaxed (&codeinst->invoke ) == NULL ) {
486
+ if (codeinst) PTR_UNPIN (codeinst);
462
487
codeinst = NULL ;
488
+ }
463
489
}
464
490
else {
491
+ if (codeinst) PTR_UNPIN (codeinst);
465
492
codeinst = NULL ;
466
493
}
467
494
JL_UNLOCK (&jl_codegen_lock);
@@ -473,6 +500,9 @@ jl_code_instance_t *jl_generate_fptr_impl(jl_method_instance_t *mi JL_PROPAGATES
473
500
jl_atomic_fetch_add_relaxed (&jl_cumulative_compile_time, t_comp);
474
501
}
475
502
JL_GC_POP ();
503
+ PTR_UNPIN (mi);
504
+ PTR_UNPIN (method);
505
+ if (codeinst) PTR_UNPIN (codeinst);
476
506
return codeinst;
477
507
}
478
508
@@ -482,6 +512,7 @@ void jl_generate_fptr_for_unspecialized_impl(jl_code_instance_t *unspec)
482
512
if (jl_atomic_load_relaxed (&unspec->invoke ) != NULL ) {
483
513
return ;
484
514
}
515
+ PTR_PIN (unspec);
485
516
auto ct = jl_current_task;
486
517
ct->reentrant_timing ++;
487
518
uint64_t compiler_start_time = 0 ;
@@ -494,6 +525,7 @@ void jl_generate_fptr_for_unspecialized_impl(jl_code_instance_t *unspec)
494
525
JL_GC_PUSH1 (&src);
495
526
jl_method_t *def = unspec->def ->def .method ;
496
527
if (jl_is_method (def)) {
528
+ PTR_PIN (def);
497
529
src = (jl_code_info_t *)def->source ;
498
530
if (src == NULL ) {
499
531
// TODO: this is wrong
@@ -503,6 +535,7 @@ void jl_generate_fptr_for_unspecialized_impl(jl_code_instance_t *unspec)
503
535
}
504
536
if (src && (jl_value_t *)src != jl_nothing)
505
537
src = jl_uncompress_ir (def, NULL , (jl_array_t *)src);
538
+ PTR_UNPIN (def);
506
539
}
507
540
else {
508
541
src = (jl_code_info_t *)unspec->def ->uninferred ;
@@ -515,6 +548,7 @@ void jl_generate_fptr_for_unspecialized_impl(jl_code_instance_t *unspec)
515
548
jl_atomic_cmpswap (&unspec->invoke , &null, jl_fptr_interpret_call_addr);
516
549
JL_GC_POP ();
517
550
}
551
+ PTR_UNPIN (unspec);
518
552
JL_UNLOCK (&jl_codegen_lock); // Might GC
519
553
if (!--ct->reentrant_timing && measure_compile_time_enabled) {
520
554
auto end = jl_hrtime ();
@@ -528,12 +562,15 @@ extern "C" JL_DLLEXPORT
528
562
jl_value_t *jl_dump_method_asm_impl (jl_method_instance_t *mi, size_t world,
529
563
char raw_mc, char getwrapper, const char * asm_variant, const char *debuginfo, char binary)
530
564
{
565
+ PTR_PIN (mi);
531
566
// printing via disassembly
532
567
jl_code_instance_t *codeinst = jl_generate_fptr (mi, world);
533
568
if (codeinst) {
534
569
uintptr_t fptr = (uintptr_t )jl_atomic_load_acquire (&codeinst->invoke );
535
- if (getwrapper)
570
+ if (getwrapper) {
571
+ PTR_UNPIN (mi);
536
572
return jl_dump_fptr_asm (fptr, raw_mc, asm_variant, debuginfo, binary);
573
+ }
537
574
uintptr_t specfptr = (uintptr_t )jl_atomic_load_relaxed (&codeinst->specptr .fptr );
538
575
if (fptr == (uintptr_t )jl_fptr_const_return_addr && specfptr == 0 ) {
539
576
// normally we prevent native code from being generated for these functions,
@@ -545,6 +582,7 @@ jl_value_t *jl_dump_method_asm_impl(jl_method_instance_t *mi, size_t world,
545
582
uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed (&jl_measure_compile_time_enabled);
546
583
if (measure_compile_time_enabled)
547
584
compiler_start_time = jl_hrtime ();
585
+ PTR_PIN (codeinst);
548
586
JL_LOCK (&jl_codegen_lock); // also disables finalizers, to prevent any unexpected recursion
549
587
specfptr = (uintptr_t )jl_atomic_load_relaxed (&codeinst->specptr .fptr );
550
588
if (specfptr == 0 ) {
@@ -569,19 +607,23 @@ jl_value_t *jl_dump_method_asm_impl(jl_method_instance_t *mi, size_t world,
569
607
}
570
608
JL_GC_POP ();
571
609
}
610
+ PTR_UNPIN (codeinst);
572
611
JL_UNLOCK (&jl_codegen_lock);
573
612
if (!--ct->reentrant_timing && measure_compile_time_enabled) {
574
613
auto end = jl_hrtime ();
575
614
jl_atomic_fetch_add_relaxed (&jl_cumulative_compile_time, end - compiler_start_time);
576
615
}
577
616
}
578
- if (specfptr != 0 )
617
+ if (specfptr != 0 ) {
618
+ PTR_UNPIN (mi);
579
619
return jl_dump_fptr_asm (specfptr, raw_mc, asm_variant, debuginfo, binary);
620
+ }
580
621
}
581
622
582
623
// whatever, that didn't work - use the assembler output instead
583
624
jl_llvmf_dump_t llvmf_dump;
584
625
jl_get_llvmf_defn (&llvmf_dump, mi, world, getwrapper, true , jl_default_cgparams);
626
+ PTR_UNPIN (mi);
585
627
if (!llvmf_dump.F )
586
628
return jl_an_empty_string;
587
629
return jl_dump_function_asm (&llvmf_dump, raw_mc, asm_variant, debuginfo, binary);
0 commit comments