• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifdef _Py_JIT
2 
3 #include "Python.h"
4 
5 #include "pycore_abstract.h"
6 #include "pycore_call.h"
7 #include "pycore_ceval.h"
8 #include "pycore_critical_section.h"
9 #include "pycore_dict.h"
10 #include "pycore_intrinsics.h"
11 #include "pycore_long.h"
12 #include "pycore_opcode_metadata.h"
13 #include "pycore_opcode_utils.h"
14 #include "pycore_optimizer.h"
15 #include "pycore_pyerrors.h"
16 #include "pycore_setobject.h"
17 #include "pycore_sliceobject.h"
18 #include "pycore_jit.h"
19 
20 // Memory management stuff: ////////////////////////////////////////////////////
21 
22 #ifndef MS_WINDOWS
23     #include <sys/mman.h>
24 #endif
25 
26 static size_t
get_page_size(void)27 get_page_size(void)
28 {
29 #ifdef MS_WINDOWS
30     SYSTEM_INFO si;
31     GetSystemInfo(&si);
32     return si.dwPageSize;
33 #else
34     return sysconf(_SC_PAGESIZE);
35 #endif
36 }
37 
38 static void
jit_error(const char * message)39 jit_error(const char *message)
40 {
41 #ifdef MS_WINDOWS
42     int hint = GetLastError();
43 #else
44     int hint = errno;
45 #endif
46     PyErr_Format(PyExc_RuntimeWarning, "JIT %s (%d)", message, hint);
47 }
48 
49 static unsigned char *
jit_alloc(size_t size)50 jit_alloc(size_t size)
51 {
52     assert(size);
53     assert(size % get_page_size() == 0);
54 #ifdef MS_WINDOWS
55     int flags = MEM_COMMIT | MEM_RESERVE;
56     unsigned char *memory = VirtualAlloc(NULL, size, flags, PAGE_READWRITE);
57     int failed = memory == NULL;
58 #else
59     int flags = MAP_ANONYMOUS | MAP_PRIVATE;
60     unsigned char *memory = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, -1, 0);
61     int failed = memory == MAP_FAILED;
62 #endif
63     if (failed) {
64         jit_error("unable to allocate memory");
65         return NULL;
66     }
67     return memory;
68 }
69 
70 static int
jit_free(unsigned char * memory,size_t size)71 jit_free(unsigned char *memory, size_t size)
72 {
73     assert(size);
74     assert(size % get_page_size() == 0);
75 #ifdef MS_WINDOWS
76     int failed = !VirtualFree(memory, 0, MEM_RELEASE);
77 #else
78     int failed = munmap(memory, size);
79 #endif
80     if (failed) {
81         jit_error("unable to free memory");
82         return -1;
83     }
84     return 0;
85 }
86 
87 static int
mark_executable(unsigned char * memory,size_t size)88 mark_executable(unsigned char *memory, size_t size)
89 {
90     if (size == 0) {
91         return 0;
92     }
93     assert(size % get_page_size() == 0);
94     // Do NOT ever leave the memory writable! Also, don't forget to flush the
95     // i-cache (I cannot begin to tell you how horrible that is to debug):
96 #ifdef MS_WINDOWS
97     if (!FlushInstructionCache(GetCurrentProcess(), memory, size)) {
98         jit_error("unable to flush instruction cache");
99         return -1;
100     }
101     int old;
102     int failed = !VirtualProtect(memory, size, PAGE_EXECUTE_READ, &old);
103 #else
104     __builtin___clear_cache((char *)memory, (char *)memory + size);
105     int failed = mprotect(memory, size, PROT_EXEC | PROT_READ);
106 #endif
107     if (failed) {
108         jit_error("unable to protect executable memory");
109         return -1;
110     }
111     return 0;
112 }
113 
114 // JIT compiler stuff: /////////////////////////////////////////////////////////
115 
116 // Warning! AArch64 requires you to get your hands dirty. These are your gloves:
117 
118 // value[value_start : value_start + len]
119 static uint32_t
get_bits(uint64_t value,uint8_t value_start,uint8_t width)120 get_bits(uint64_t value, uint8_t value_start, uint8_t width)
121 {
122     assert(width <= 32);
123     return (value >> value_start) & ((1ULL << width) - 1);
124 }
125 
126 // *loc[loc_start : loc_start + width] = value[value_start : value_start + width]
127 static void
set_bits(uint32_t * loc,uint8_t loc_start,uint64_t value,uint8_t value_start,uint8_t width)128 set_bits(uint32_t *loc, uint8_t loc_start, uint64_t value, uint8_t value_start,
129          uint8_t width)
130 {
131     assert(loc_start + width <= 32);
132     // Clear the bits we're about to patch:
133     *loc &= ~(((1ULL << width) - 1) << loc_start);
134     assert(get_bits(*loc, loc_start, width) == 0);
135     // Patch the bits:
136     *loc |= get_bits(value, value_start, width) << loc_start;
137     assert(get_bits(*loc, loc_start, width) == get_bits(value, value_start, width));
138 }
139 
140 // See https://developer.arm.com/documentation/ddi0602/2023-09/Base-Instructions
141 // for instruction encodings:
142 #define IS_AARCH64_ADD_OR_SUB(I) (((I) & 0x11C00000) == 0x11000000)
143 #define IS_AARCH64_ADRP(I)       (((I) & 0x9F000000) == 0x90000000)
144 #define IS_AARCH64_BRANCH(I)     (((I) & 0x7C000000) == 0x14000000)
145 #define IS_AARCH64_LDR_OR_STR(I) (((I) & 0x3B000000) == 0x39000000)
146 #define IS_AARCH64_MOV(I)        (((I) & 0x9F800000) == 0x92800000)
147 
148 // LLD is a great reference for performing relocations... just keep in
149 // mind that Tools/jit/build.py does filtering and preprocessing for us!
150 // Here's a good place to start for each platform:
151 // - aarch64-apple-darwin:
152 //   - https://github.com/llvm/llvm-project/blob/main/lld/MachO/Arch/ARM64.cpp
153 //   - https://github.com/llvm/llvm-project/blob/main/lld/MachO/Arch/ARM64Common.cpp
154 //   - https://github.com/llvm/llvm-project/blob/main/lld/MachO/Arch/ARM64Common.h
155 // - aarch64-pc-windows-msvc:
156 //   - https://github.com/llvm/llvm-project/blob/main/lld/COFF/Chunks.cpp
157 // - aarch64-unknown-linux-gnu:
158 //   - https://github.com/llvm/llvm-project/blob/main/lld/ELF/Arch/AArch64.cpp
159 // - i686-pc-windows-msvc:
160 //   - https://github.com/llvm/llvm-project/blob/main/lld/COFF/Chunks.cpp
161 // - x86_64-apple-darwin:
162 //   - https://github.com/llvm/llvm-project/blob/main/lld/MachO/Arch/X86_64.cpp
163 // - x86_64-pc-windows-msvc:
164 //   - https://github.com/llvm/llvm-project/blob/main/lld/COFF/Chunks.cpp
165 // - x86_64-unknown-linux-gnu:
166 //   - https://github.com/llvm/llvm-project/blob/main/lld/ELF/Arch/X86_64.cpp
167 
168 // Many of these patches are "relaxing", meaning that they can rewrite the
169 // code they're patching to be more efficient (like turning a 64-bit memory
170 // load into a 32-bit immediate load). These patches have an "x" in their name.
171 // Relative patches have an "r" in their name.
172 
173 // 32-bit absolute address.
174 void
patch_32(unsigned char * location,uint64_t value)175 patch_32(unsigned char *location, uint64_t value)
176 {
177     uint32_t *loc32 = (uint32_t *)location;
178     // Check that we're not out of range of 32 unsigned bits:
179     assert(value < (1ULL << 32));
180     *loc32 = (uint32_t)value;
181 }
182 
183 // 32-bit relative address.
184 void
patch_32r(unsigned char * location,uint64_t value)185 patch_32r(unsigned char *location, uint64_t value)
186 {
187     uint32_t *loc32 = (uint32_t *)location;
188     value -= (uintptr_t)location;
189     // Check that we're not out of range of 32 signed bits:
190     assert((int64_t)value >= -(1LL << 31));
191     assert((int64_t)value < (1LL << 31));
192     *loc32 = (uint32_t)value;
193 }
194 
195 // 64-bit absolute address.
196 void
patch_64(unsigned char * location,uint64_t value)197 patch_64(unsigned char *location, uint64_t value)
198 {
199     uint64_t *loc64 = (uint64_t *)location;
200     *loc64 = value;
201 }
202 
203 // 12-bit low part of an absolute address. Pairs nicely with patch_aarch64_21r
204 // (below).
205 void
patch_aarch64_12(unsigned char * location,uint64_t value)206 patch_aarch64_12(unsigned char *location, uint64_t value)
207 {
208     uint32_t *loc32 = (uint32_t *)location;
209     assert(IS_AARCH64_LDR_OR_STR(*loc32) || IS_AARCH64_ADD_OR_SUB(*loc32));
210     // There might be an implicit shift encoded in the instruction:
211     uint8_t shift = 0;
212     if (IS_AARCH64_LDR_OR_STR(*loc32)) {
213         shift = (uint8_t)get_bits(*loc32, 30, 2);
214         // If both of these are set, the shift is supposed to be 4.
215         // That's pretty weird, and it's never actually been observed...
216         assert(get_bits(*loc32, 23, 1) == 0 || get_bits(*loc32, 26, 1) == 0);
217     }
218     value = get_bits(value, 0, 12);
219     assert(get_bits(value, 0, shift) == 0);
220     set_bits(loc32, 10, value, shift, 12);
221 }
222 
223 // Relaxable 12-bit low part of an absolute address. Pairs nicely with
224 // patch_aarch64_21rx (below).
225 void
patch_aarch64_12x(unsigned char * location,uint64_t value)226 patch_aarch64_12x(unsigned char *location, uint64_t value)
227 {
228     // This can *only* be relaxed if it occurs immediately before a matching
229     // patch_aarch64_21rx. If that happens, the JIT build step will replace both
230     // calls with a single call to patch_aarch64_33rx. Otherwise, we end up
231     // here, and the instruction is patched normally:
232     patch_aarch64_12(location, value);
233 }
234 
235 // 16-bit low part of an absolute address.
236 void
patch_aarch64_16a(unsigned char * location,uint64_t value)237 patch_aarch64_16a(unsigned char *location, uint64_t value)
238 {
239     uint32_t *loc32 = (uint32_t *)location;
240     assert(IS_AARCH64_MOV(*loc32));
241     // Check the implicit shift (this is "part 0 of 3"):
242     assert(get_bits(*loc32, 21, 2) == 0);
243     set_bits(loc32, 5, value, 0, 16);
244 }
245 
246 // 16-bit middle-low part of an absolute address.
247 void
patch_aarch64_16b(unsigned char * location,uint64_t value)248 patch_aarch64_16b(unsigned char *location, uint64_t value)
249 {
250     uint32_t *loc32 = (uint32_t *)location;
251     assert(IS_AARCH64_MOV(*loc32));
252     // Check the implicit shift (this is "part 1 of 3"):
253     assert(get_bits(*loc32, 21, 2) == 1);
254     set_bits(loc32, 5, value, 16, 16);
255 }
256 
257 // 16-bit middle-high part of an absolute address.
258 void
patch_aarch64_16c(unsigned char * location,uint64_t value)259 patch_aarch64_16c(unsigned char *location, uint64_t value)
260 {
261     uint32_t *loc32 = (uint32_t *)location;
262     assert(IS_AARCH64_MOV(*loc32));
263     // Check the implicit shift (this is "part 2 of 3"):
264     assert(get_bits(*loc32, 21, 2) == 2);
265     set_bits(loc32, 5, value, 32, 16);
266 }
267 
268 // 16-bit high part of an absolute address.
269 void
patch_aarch64_16d(unsigned char * location,uint64_t value)270 patch_aarch64_16d(unsigned char *location, uint64_t value)
271 {
272     uint32_t *loc32 = (uint32_t *)location;
273     assert(IS_AARCH64_MOV(*loc32));
274     // Check the implicit shift (this is "part 3 of 3"):
275     assert(get_bits(*loc32, 21, 2) == 3);
276     set_bits(loc32, 5, value, 48, 16);
277 }
278 
279 // 21-bit count of pages between this page and an absolute address's page... I
280 // know, I know, it's weird. Pairs nicely with patch_aarch64_12 (above).
281 void
patch_aarch64_21r(unsigned char * location,uint64_t value)282 patch_aarch64_21r(unsigned char *location, uint64_t value)
283 {
284     uint32_t *loc32 = (uint32_t *)location;
285     value = (value >> 12) - ((uintptr_t)location >> 12);
286     // Check that we're not out of range of 21 signed bits:
287     assert((int64_t)value >= -(1 << 20));
288     assert((int64_t)value < (1 << 20));
289     // value[0:2] goes in loc[29:31]:
290     set_bits(loc32, 29, value, 0, 2);
291     // value[2:21] goes in loc[5:26]:
292     set_bits(loc32, 5, value, 2, 19);
293 }
294 
295 // Relaxable 21-bit count of pages between this page and an absolute address's
296 // page. Pairs nicely with patch_aarch64_12x (above).
297 void
patch_aarch64_21rx(unsigned char * location,uint64_t value)298 patch_aarch64_21rx(unsigned char *location, uint64_t value)
299 {
300     // This can *only* be relaxed if it occurs immediately before a matching
301     // patch_aarch64_12x. If that happens, the JIT build step will replace both
302     // calls with a single call to patch_aarch64_33rx. Otherwise, we end up
303     // here, and the instruction is patched normally:
304     patch_aarch64_21r(location, value);
305 }
306 
307 // 28-bit relative branch.
308 void
patch_aarch64_26r(unsigned char * location,uint64_t value)309 patch_aarch64_26r(unsigned char *location, uint64_t value)
310 {
311     uint32_t *loc32 = (uint32_t *)location;
312     assert(IS_AARCH64_BRANCH(*loc32));
313     value -= (uintptr_t)location;
314     // Check that we're not out of range of 28 signed bits:
315     assert((int64_t)value >= -(1 << 27));
316     assert((int64_t)value < (1 << 27));
317     // Since instructions are 4-byte aligned, only use 26 bits:
318     assert(get_bits(value, 0, 2) == 0);
319     set_bits(loc32, 0, value, 2, 26);
320 }
321 
322 // A pair of patch_aarch64_21rx and patch_aarch64_12x.
323 void
patch_aarch64_33rx(unsigned char * location,uint64_t value)324 patch_aarch64_33rx(unsigned char *location, uint64_t value)
325 {
326     uint32_t *loc32 = (uint32_t *)location;
327     // Try to relax the pair of GOT loads into an immediate value:
328     assert(IS_AARCH64_ADRP(*loc32));
329     unsigned char reg = get_bits(loc32[0], 0, 5);
330     assert(IS_AARCH64_LDR_OR_STR(loc32[1]));
331     // There should be only one register involved:
332     assert(reg == get_bits(loc32[1], 0, 5));  // ldr's output register.
333     assert(reg == get_bits(loc32[1], 5, 5));  // ldr's input register.
334     uint64_t relaxed = *(uint64_t *)value;
335     if (relaxed < (1UL << 16)) {
336         // adrp reg, AAA; ldr reg, [reg + BBB] -> movz reg, XXX; nop
337         loc32[0] = 0xD2800000 | (get_bits(relaxed, 0, 16) << 5) | reg;
338         loc32[1] = 0xD503201F;
339         return;
340     }
341     if (relaxed < (1ULL << 32)) {
342         // adrp reg, AAA; ldr reg, [reg + BBB] -> movz reg, XXX; movk reg, YYY
343         loc32[0] = 0xD2800000 | (get_bits(relaxed,  0, 16) << 5) | reg;
344         loc32[1] = 0xF2A00000 | (get_bits(relaxed, 16, 16) << 5) | reg;
345         return;
346     }
347     relaxed = value - (uintptr_t)location;
348     if ((relaxed & 0x3) == 0 &&
349         (int64_t)relaxed >= -(1L << 19) &&
350         (int64_t)relaxed < (1L << 19))
351     {
352         // adrp reg, AAA; ldr reg, [reg + BBB] -> ldr reg, XXX; nop
353         loc32[0] = 0x58000000 | (get_bits(relaxed, 2, 19) << 5) | reg;
354         loc32[1] = 0xD503201F;
355         return;
356     }
357     // Couldn't do it. Just patch the two instructions normally:
358     patch_aarch64_21rx(location, value);
359     patch_aarch64_12x(location + 4, value);
360 }
361 
362 // Relaxable 32-bit relative address.
363 void
patch_x86_64_32rx(unsigned char * location,uint64_t value)364 patch_x86_64_32rx(unsigned char *location, uint64_t value)
365 {
366     uint8_t *loc8 = (uint8_t *)location;
367     // Try to relax the GOT load into an immediate value:
368     uint64_t relaxed = *(uint64_t *)(value + 4) - 4;
369     if ((int64_t)relaxed - (int64_t)location >= -(1LL << 31) &&
370         (int64_t)relaxed - (int64_t)location + 1 < (1LL << 31))
371     {
372         if (loc8[-2] == 0x8B) {
373             // mov reg, dword ptr [rip + AAA] -> lea reg, [rip + XXX]
374             loc8[-2] = 0x8D;
375             value = relaxed;
376         }
377         else if (loc8[-2] == 0xFF && loc8[-1] == 0x15) {
378             // call qword ptr [rip + AAA] -> nop; call XXX
379             loc8[-2] = 0x90;
380             loc8[-1] = 0xE8;
381             value = relaxed;
382         }
383         else if (loc8[-2] == 0xFF && loc8[-1] == 0x25) {
384             // jmp qword ptr [rip + AAA] -> nop; jmp XXX
385             loc8[-2] = 0x90;
386             loc8[-1] = 0xE9;
387             value = relaxed;
388         }
389     }
390     patch_32r(location, value);
391 }
392 
393 #include "jit_stencils.h"
394 
395 // Compiles executor in-place. Don't forget to call _PyJIT_Free later!
396 int
_PyJIT_Compile(_PyExecutorObject * executor,const _PyUOpInstruction trace[],size_t length)397 _PyJIT_Compile(_PyExecutorObject *executor, const _PyUOpInstruction trace[], size_t length)
398 {
399     const StencilGroup *group;
400     // Loop once to find the total compiled size:
401     uintptr_t instruction_starts[UOP_MAX_TRACE_LENGTH];
402     size_t code_size = 0;
403     size_t data_size = 0;
404     group = &trampoline;
405     code_size += group->code_size;
406     data_size += group->data_size;
407     for (size_t i = 0; i < length; i++) {
408         const _PyUOpInstruction *instruction = &trace[i];
409         group = &stencil_groups[instruction->opcode];
410         instruction_starts[i] = code_size;
411         code_size += group->code_size;
412         data_size += group->data_size;
413     }
414     group = &stencil_groups[_FATAL_ERROR];
415     code_size += group->code_size;
416     data_size += group->data_size;
417     // Round up to the nearest page:
418     size_t page_size = get_page_size();
419     assert((page_size & (page_size - 1)) == 0);
420     size_t padding = page_size - ((code_size + data_size) & (page_size - 1));
421     size_t total_size = code_size + data_size + padding;
422     unsigned char *memory = jit_alloc(total_size);
423     if (memory == NULL) {
424         return -1;
425     }
426     // Update the offsets of each instruction:
427     for (size_t i = 0; i < length; i++) {
428         instruction_starts[i] += (uintptr_t)memory;
429     }
430     // Loop again to emit the code:
431     unsigned char *code = memory;
432     unsigned char *data = memory + code_size;
433     // Compile the trampoline, which handles converting between the native
434     // calling convention and the calling convention used by jitted code
435     // (which may be different for efficiency reasons). On platforms where
436     // we don't change calling conventions, the trampoline is empty and
437     // nothing is emitted here:
438     group = &trampoline;
439     group->emit(code, data, executor, NULL, instruction_starts);
440     code += group->code_size;
441     data += group->data_size;
442     assert(trace[0].opcode == _START_EXECUTOR || trace[0].opcode == _COLD_EXIT);
443     for (size_t i = 0; i < length; i++) {
444         const _PyUOpInstruction *instruction = &trace[i];
445         group = &stencil_groups[instruction->opcode];
446         group->emit(code, data, executor, instruction, instruction_starts);
447         code += group->code_size;
448         data += group->data_size;
449     }
450     // Protect against accidental buffer overrun into data:
451     group = &stencil_groups[_FATAL_ERROR];
452     group->emit(code, data, executor, NULL, instruction_starts);
453     code += group->code_size;
454     data += group->data_size;
455     assert(code == memory + code_size);
456     assert(data == memory + code_size + data_size);
457     if (mark_executable(memory, total_size)) {
458         jit_free(memory, total_size);
459         return -1;
460     }
461     executor->jit_code = memory;
462     executor->jit_side_entry = memory + trampoline.code_size;
463     executor->jit_size = total_size;
464     return 0;
465 }
466 
467 void
_PyJIT_Free(_PyExecutorObject * executor)468 _PyJIT_Free(_PyExecutorObject *executor)
469 {
470     unsigned char *memory = (unsigned char *)executor->jit_code;
471     size_t size = executor->jit_size;
472     if (memory) {
473         executor->jit_code = NULL;
474         executor->jit_side_entry = NULL;
475         executor->jit_size = 0;
476         if (jit_free(memory, size)) {
477             PyErr_WriteUnraisable(NULL);
478         }
479     }
480 }
481 
482 #endif  // _Py_JIT
483