@@ -149,6 +149,22 @@ typedef enum {
149
149
#include <sys/types.h>
150
150
#include <unistd.h>
151
151
152
+ #if defined(__arm__ ) || defined(__arm64__ ) || defined(__aarch64__ )
153
+ #define PY_HAVE_INVALIDATE_ICACHE
154
+
155
+ #if defined(__clang__ ) || defined(__GNUC__ )
156
+ extern void __clear_cache (void * , void * );
157
+ #endif
158
+
159
+ static void invalidate_icache (char * begin , char * end ) {
160
+ #if defined(__clang__ ) || defined(__GNUC__ )
161
+ return __clear_cache (begin , end );
162
+ #else
163
+ return ;
164
+ #endif
165
+ }
166
+ #endif
167
+
152
168
/* The function pointer is passed as last argument. The other three arguments
153
169
* are passed in the same order as the function requires. This results in
154
170
* shorter, more efficient ASM code for trampoline.
@@ -185,6 +201,7 @@ struct trampoline_api_st {
185
201
186
202
typedef struct trampoline_api_st trampoline_api_t ;
187
203
204
+
188
205
static perf_status_t perf_status = PERF_STATUS_NO_INIT ;
189
206
static Py_ssize_t extra_code_index = -1 ;
190
207
static code_arena_t * code_arena ;
@@ -297,10 +314,6 @@ new_code_arena(void)
297
314
memcpy (memory + i * code_size , start , code_size * sizeof (char ));
298
315
}
299
316
// Some systems may prevent us from creating executable code on the fly.
300
- // TODO: Call icache invalidation intrinsics if available:
301
- // __builtin___clear_cache/__clear_cache (depending if clang/gcc). This is
302
- // technically not necessary but we could be missing something so better be
303
- // safe.
304
317
int res = mprotect (memory , mem_size , PROT_READ | PROT_EXEC );
305
318
if (res == -1 ) {
306
319
PyErr_SetFromErrno (PyExc_OSError );
@@ -311,6 +324,12 @@ new_code_arena(void)
311
324
return -1 ;
312
325
}
313
326
327
+ #ifdef PY_HAVE_INVALIDATE_ICACHE
328
+ // Before the JIT can run a block of code that has been emitted it must invalidate
329
+ // the instruction cache on some platforms like arm and aarch64.
330
+ invalidate_icache (memory , memory + mem_size );
331
+ #endif
332
+
314
333
code_arena_t * new_arena = PyMem_RawCalloc (1 , sizeof (code_arena_t ));
315
334
if (new_arena == NULL ) {
316
335
PyErr_NoMemory ();
0 commit comments