@@ -74,27 +74,57 @@ mark_executable(unsigned char *memory, size_t pages)
74
74
return 0 ;
75
75
}
76
76
#ifdef MS_WINDOWS
77
+ if (!FlushInstructionCache (GetCurrentProcess (), memory , size )) {
78
+ const char * w = "JIT unable to flush instruction cache (%d)" ;
79
+ PyErr_WarnFormat (PyExc_RuntimeWarning , 0 , w , GetLastError ());
80
+ return -1 ;
81
+ }
77
82
DWORD old ;
78
- if (!FlushInstructionCache (GetCurrentProcess (), memory , size ) ||
79
- !VirtualProtect (memory , size , PAGE_EXECUTE_READ , & old ))
80
- {
81
- int code = GetLastError ();
83
+ if (!VirtualProtect (memory , size , PAGE_EXECUTE , & old )) {
84
+ const char * w = "JIT unable to protect executable memory (%d)" ;
85
+ PyErr_WarnFormat (PyExc_RuntimeWarning , 0 , w , GetLastError ());
86
+ return -1 ;
87
+ }
82
88
#else
83
89
__builtin___clear_cache ((char * )memory , (char * )memory + size );
84
- if (mprotect (memory , size , PROT_EXEC | PROT_READ )) {
85
- int code = errno ;
90
+ if (mprotect (memory , size , PROT_EXEC )) {
91
+ const char * w = "JIT unable to protect executable memory (%d)" ;
92
+ PyErr_WarnFormat (PyExc_RuntimeWarning , 0 , w , errno );
93
+ return -1 ;
94
+ }
86
95
#endif
87
- const char * w = "JIT unable to map executable memory (%d)" ;
88
- PyErr_WarnFormat (PyExc_RuntimeWarning , 0 , w , code );
96
+ return 0 ;
97
+ }
98
+
99
+ static int
100
+ mark_readable (unsigned char * memory , size_t pages )
101
+ {
102
+ assert (is_page_aligned (memory ));
103
+ size_t size = pages * page_size ;
104
+ if (size == 0 ) {
105
+ return 0 ;
106
+ }
107
+ #ifdef MS_WINDOWS
108
+ DWORD old ;
109
+ if (!VirtualProtect (memory , size , PAGE_READONLY , & old )) {
110
+ const char * w = "JIT unable to protect readable memory (%d)" ;
111
+ PyErr_WarnFormat (PyExc_RuntimeWarning , 0 , w , GetLastError ());
112
+ return -1 ;
113
+ }
114
+ #else
115
+ if (mprotect (memory , size , PROT_READ )) {
116
+ const char * w = "JIT unable to protect readable memory (%d)" ;
117
+ PyErr_WarnFormat (PyExc_RuntimeWarning , 0 , w , errno );
89
118
return -1 ;
90
119
}
120
+ #endif
91
121
return 0 ;
92
122
}
93
123
94
124
static size_t
95
- bytes_to_pages (size_t nbytes )
125
+ size_to_pages (size_t size )
96
126
{
97
- return (nbytes + page_size - 1 ) / page_size ;
127
+ return (size + page_size - 1 ) / page_size ;
98
128
}
99
129
100
130
static void
@@ -177,8 +207,8 @@ patch(unsigned char *base, const Hole *hole, uint64_t *patches)
177
207
static void
178
208
copy_and_patch (unsigned char * base , const Stencil * stencil , uint64_t * patches )
179
209
{
180
- memcpy (base , stencil -> bytes , stencil -> nbytes );
181
- for (size_t i = 0 ; i < stencil -> nholes ; i ++ ) {
210
+ memcpy (base , stencil -> body , stencil -> body_size );
211
+ for (size_t i = 0 ; i < stencil -> holes_size ; i ++ ) {
182
212
patch (base , & stencil -> holes [i ], patches );
183
213
}
184
214
}
@@ -188,8 +218,8 @@ emit(const StencilGroup *stencil_group, uint64_t patches[])
188
218
{
189
219
unsigned char * data = (unsigned char * )(uintptr_t )patches [_JIT_DATA ];
190
220
copy_and_patch (data , & stencil_group -> data , patches );
191
- unsigned char * body = (unsigned char * )(uintptr_t )patches [_JIT_BODY ];
192
- copy_and_patch (body , & stencil_group -> body , patches );
221
+ unsigned char * text = (unsigned char * )(uintptr_t )patches [_JIT_BODY ];
222
+ copy_and_patch (text , & stencil_group -> text , patches );
193
223
}
194
224
195
225
static int
@@ -229,46 +259,48 @@ initialize_jit(void)
229
259
// Write our deopt stub:
230
260
{
231
261
const StencilGroup * stencil_group = & deoptimize_stencil_group ;
232
- size_t pages_body = bytes_to_pages (stencil_group -> body . nbytes );
233
- deoptimize_stub = alloc (pages_body );
234
- if (deoptimize_stub == NULL ) {
262
+ size_t text_pages = size_to_pages (stencil_group -> text . body_size );
263
+ unsigned char * text = alloc (text_pages );
264
+ if (text == NULL ) {
235
265
return needs_initializing ;
236
266
}
237
- size_t pages_data = bytes_to_pages (stencil_group -> data .nbytes );
238
- unsigned char * data = alloc (pages_data );
267
+ size_t data_pages = size_to_pages (stencil_group -> data .body_size );
268
+ unsigned char * data = alloc (data_pages );
239
269
if (data == NULL ) {
240
270
return needs_initializing ;
241
271
}
242
272
uint64_t patches [] = GET_PATCHES ();
243
- patches [_JIT_BODY ] = (uintptr_t )deoptimize_stub ;
273
+ patches [_JIT_BODY ] = (uintptr_t )text ;
244
274
patches [_JIT_DATA ] = (uintptr_t )data ;
245
275
patches [_JIT_ZERO ] = 0 ;
246
276
emit (stencil_group , patches );
247
- if (mark_executable (deoptimize_stub , pages_body )) {
277
+ if (mark_executable (text , text_pages ) || mark_readable ( data , data_pages )) {
248
278
return needs_initializing ;
249
279
}
280
+ deoptimize_stub = text ;
250
281
}
251
282
// Write our error stub:
252
283
{
253
284
const StencilGroup * stencil_group = & error_stencil_group ;
254
- size_t pages_body = bytes_to_pages (stencil_group -> body . nbytes );
255
- error_stub = alloc (pages_body );
256
- if (error_stub == NULL ) {
285
+ size_t text_pages = size_to_pages (stencil_group -> text . body_size );
286
+ unsigned char * text = alloc (text_pages );
287
+ if (text == NULL ) {
257
288
return needs_initializing ;
258
289
}
259
- size_t pages_data = bytes_to_pages (stencil_group -> data .nbytes );
260
- unsigned char * data = alloc (pages_data );
290
+ size_t data_pages = size_to_pages (stencil_group -> data .body_size );
291
+ unsigned char * data = alloc (data_pages );
261
292
if (data == NULL ) {
262
293
return needs_initializing ;
263
294
}
264
295
uint64_t patches [] = GET_PATCHES ();
265
- patches [_JIT_BODY ] = (uintptr_t )error_stub ;
296
+ patches [_JIT_BODY ] = (uintptr_t )text ;
266
297
patches [_JIT_DATA ] = (uintptr_t )data ;
267
298
patches [_JIT_ZERO ] = 0 ;
268
299
emit (stencil_group , patches );
269
- if (mark_executable (error_stub , pages_body )) {
300
+ if (mark_executable (text , text_pages ) || mark_readable ( data , data_pages )) {
270
301
return needs_initializing ;
271
302
}
303
+ error_stub = text ;
272
304
}
273
305
// Done:
274
306
needs_initializing = 0 ;
@@ -283,62 +315,62 @@ _PyJIT_CompileTrace(_PyUOpExecutorObject *executor, _PyUOpInstruction *trace, in
283
315
return NULL ;
284
316
}
285
317
// First, loop over everything once to find the total compiled size:
286
- size_t nbytes_body = trampoline_stencil_group .body . nbytes ;
287
- size_t nbytes_data = trampoline_stencil_group .data .nbytes ;
318
+ size_t text_size = trampoline_stencil_group .text . body_size ;
319
+ size_t data_size = trampoline_stencil_group .data .body_size ;
288
320
for (int i = 0 ; i < size ; i ++ ) {
289
321
_PyUOpInstruction * instruction = & trace [i ];
290
322
const StencilGroup * stencil_group = & stencil_groups [instruction -> opcode ];
291
- nbytes_body += stencil_group -> body . nbytes ;
292
- nbytes_data += stencil_group -> data .nbytes ;
293
- assert (stencil_group -> body . nbytes );
323
+ text_size += stencil_group -> text . body_size ;
324
+ data_size += stencil_group -> data .body_size ;
325
+ assert (stencil_group -> text . body_size );
294
326
};
295
- size_t pages_body = bytes_to_pages ( nbytes_body );
296
- unsigned char * body = alloc (pages_body );
297
- if (body == NULL ) {
327
+ size_t text_pages = size_to_pages ( text_size );
328
+ unsigned char * text = alloc (text_pages );
329
+ if (text == NULL ) {
298
330
return NULL ;
299
331
}
300
- size_t pages_data = bytes_to_pages ( nbytes_data );
301
- unsigned char * data = alloc (pages_data );
332
+ size_t data_pages = size_to_pages ( data_size );
333
+ unsigned char * data = alloc (data_pages );
302
334
if (data == NULL ) {
303
335
return NULL ;
304
336
}
305
- unsigned char * head_body = body ;
337
+ unsigned char * head_text = text ;
306
338
unsigned char * head_data = data ;
307
339
// First, the trampoline:
308
340
const StencilGroup * stencil_group = & trampoline_stencil_group ;
309
341
uint64_t patches [] = GET_PATCHES ();
310
- patches [_JIT_BODY ] = (uintptr_t )head_body ;
342
+ patches [_JIT_BODY ] = (uintptr_t )head_text ;
311
343
patches [_JIT_DATA ] = (uintptr_t )head_data ;
312
- patches [_JIT_CONTINUE ] = (uintptr_t )head_body +
F42D
stencil_group -> body . nbytes ;
344
+ patches [_JIT_CONTINUE ] = (uintptr_t )head_text + stencil_group -> text . body_size ;
313
345
patches [_JIT_ZERO ] = 0 ;
314
346
emit (stencil_group , patches );
315
- head_body += stencil_group -> body . nbytes ;
316
- head_data += stencil_group -> data .nbytes ;
347
+ head_text += stencil_group -> text . body_size ;
348
+ head_data += stencil_group -> data .body_size ;
317
349
// Then, all of the stencils:
318
350
for (int i = 0 ; i < size ; i ++ ) {
319
351
_PyUOpInstruction * instruction = & trace [i ];
320
352
const StencilGroup * stencil_group = & stencil_groups [instruction -> opcode ];
321
353
uint64_t patches [] = GET_PATCHES ();
322
- patches [_JIT_BODY ] = (uintptr_t )head_body ;
354
+ patches [_JIT_BODY ] = (uintptr_t )head_text ;
323
355
patches [_JIT_DATA ] = (uintptr_t )head_data ;
324
- patches [_JIT_CONTINUE ] = (uintptr_t )head_body + stencil_group -> body . nbytes ;
356
+ patches [_JIT_CONTINUE ] = (uintptr_t )head_text + stencil_group -> text . body_size ;
325
357
patches [_JIT_CURRENT_EXECUTOR ] = (uintptr_t )executor ;
326
358
patches [_JIT_DEOPTIMIZE ] = (uintptr_t )deoptimize_stub ;
327
359
patches [_JIT_ERROR ] = (uintptr_t )error_stub ;
328
360
patches [_JIT_OPARG ] = instruction -> oparg ;
329
361
patches [_JIT_OPERAND ] = instruction -> operand ;
330
362
patches [_JIT_TARGET ] = instruction -> target ;
331
- patches [_JIT_TOP ] = (uintptr_t )body + trampoline_stencil_group .body . nbytes ;
363
+ patches [_JIT_TOP ] = (uintptr_t )text + trampoline_stencil_group .text . body_size ;
332
364
patches [_JIT_ZERO ] = 0 ;
333
365
emit (stencil_group , patches );
334
- head_body += stencil_group -> body . nbytes ;
335
- head_data += stencil_group -> data .nbytes ;
366
+ head_text += stencil_group -> text . body_size ;
367
+ head_data += stencil_group -> data .body_size ;
336
368
};
337
- if (mark_executable (body , pages_body )) {
369
+ if (mark_executable (text , text_pages ) || mark_readable ( data , data_pages )) {
338
370
return NULL ;
339
371
}
340
372
// Wow, done already?
341
- assert (head_body == body + nbytes_body );
342
- assert (head_data == data + nbytes_data );
343
- return (_PyJITFunction )body ;
373
+ assert (head_text == text + text_size );
374
+ assert (head_data == data + data_size );
375
+ return (_PyJITFunction )text ;
344
376
}
0 commit comments