1Client Code . Generated . libgccjit.so 2 . code . 3 . . JIT API . JIT "Frontend". (libbackend.a) 4.................................................................................... 5 │ . . . . 6 ──────────────────────────> . . 7 . . │ . . 8 . . V . . 9 . . ──> libgccjit.c . 10 . . │ (error-checking). 11 . . │ . 12 . . ──> jit-recording.c 13 . . (record API calls) 14 . . <─────── . 15 . . │ . . 16 <─────────────────────────── . . 17 │ . . . . 18 │ . . . . 19 V . . gcc_jit_context_compile . 20 ──────────────────────────> . . 21 . . │ start of recording::context::compile () 22 . . │ . . 23 . . │ start of playback::context::compile () 24 . . │ (create tempdir) . 25 . . │ . . 26 . . │ ACQUIRE MUTEX . 27 . . │ . . 28 . . V───────────────────────> toplev::main (for now) 29 . . . . │ 30 . . . . (various code) 31 . . . . │ 32 . . . . V 33 . . . <───────────────── langhook:parse_file 34 . . . │ . 35 . . . │ (jit_langhook_parse_file) 36 . . . │ . 37..........................................│..................VVVVVVVVVVVVV... 38 . . . │ . No GC in here 39 . . . │ jit-playback.c 40 . . . │ (playback of API calls) 41 . . . ───────────────> creation of functions, 42 . . . . types, expression trees 43 . . . <──────────────── etc 44 . . . │(handle_locations: add locations to 45 . . . │ linemap and associate them with trees) 46 . . . │ . 47 . . . │ . No GC in here 48..........................................│..................AAAAAAAAAAAAA... 49 . . . │ for each function 50 . . . ──> postprocess 51 . . . │ . 52 . . . ────────────> cgraph_finalize_function 53 . . . <──────────── 54 . . . <── . 55 . . . │ . 56 . . . ──────────────────> (end of 57 . . . . │ langhook_parse_file) 58 . . . . │ 59 . . . . (various code) 60 . . . . │ 61 . . . . ↓ 62 . . . <───────────────── langhook:write_globals 63 . . . │ . 64 . . . │ (jit_langhook_write_globals) 65 . . . │ . 66 . . . │ . 67 . . . ──────────────────> finalize_compilation_unit 68 . . . . │ 69 . . . . (the middle─end and backend) 70 . . . . ↓ 71 . . <───────────────────────────── end of toplev::main 72 . . │ . . 73 . . V───────────────────────> toplev::finalize 74 . . . . │ (purge internal state) 75 . . <──────────────────────── end of toplev::finalize 76 . . │ . . 77 . . V─> playback::context::postprocess: 78 . . │ . . 79 . . │ (assuming an in-memory compile): 80 . . │ . . 81 . . --> Convert assembler to DSO, via embedded 82 . . copy of driver: 83 . . driver::main () 84 . . invocation of "as" 85 . . invocation of "ld" 86 . . driver::finalize () 87 . . <---- 88 . . │ . . 89 . . │ . Load DSO (dlopen "fake.so") 90 . . │ . . 91 . . │ . Bundle it up in a jit::result 92 . . <── . . 93 . . │ . . 94 . . │ RELEASE MUTEX . 95 . . │ . . 96 . . │ end of playback::context::compile () 97 . . │ . . 98 . . │ playback::context dtor 99 . . ──> . . 100 . . │ Normally we cleanup the tempdir here: 101 . . │ ("fake.so" is unlinked from the 102 . . │ filesystem at this point) 103 . . │ If the client code requested debuginfo, the 104 . . │ cleanup happens later (in gcc_jit_result_release) 105 . . │ to make it easier on the debugger (see PR jit/64206) 106 . . <── . . 107 . . │ . . 108 . . │ end of recording::context::compile () 109 <─────────────────────────── . . 110 │ . . . . 111 V . . gcc_jit_result_get_code . 112 ──────────────────────────> . . 113 . . │ dlsym () within loaded DSO 114 <─────────────────────────── . . 115 Get (void*). . . . 116 │ . . . . 117 │ Call it . . . . 118 ───────────────> . . . 119 . │ . . . 120 . │ . . . 121 <─────────────── . . . 122 │ . . . . 123etc│ . . . . 124 │ . . . . 125 V . . gcc_jit_result_release . 126 ──────────────────────────> . . 127 . . │ dlclose () the loaded DSO 128 . . │ (code becomes uncallable) 129 . . │ . . 130 . . │ If the client code requested debuginfo, then 131 . . │ cleanup of the tempdir was delayed. 132 . . │ If that was the case, clean it up now. 133 <─────────────────────────── . . 134 │ . . . . 135