@@ -74,27 +74,57 @@ mark_executable(unsigned char *memory, size_t pages)
7474 return 0 ;
7575 }
7676#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+ }
7782 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+ }
8288#else
8389 __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+ }
8695#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 );
89118 return -1 ;
90119 }
120+ #endif
91121 return 0 ;
92122}
93123
94124static size_t
95- bytes_to_pages (size_t nbytes )
125+ size_to_pages (size_t size )
96126{
97- return (nbytes + page_size - 1 ) / page_size ;
127+ return (size + page_size - 1 ) / page_size ;
98128}
99129
100130static void
@@ -177,8 +207,8 @@ patch(unsigned char *base, const Hole *hole, uint64_t *patches)
177207static void
178208copy_and_patch (unsigned char * base , const Stencil * stencil , uint64_t * patches )
179209{
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 ++ ) {
182212 patch (base , & stencil -> holes [i ], patches );
183213 }
184214}
@@ -188,8 +218,8 @@ emit(const StencilGroup *stencil_group, uint64_t patches[])
188218{
189219 unsigned char * data = (unsigned char * )(uintptr_t )patches [_JIT_DATA ];
190220 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 );
193223}
194224
195225static int
@@ -229,46 +259,48 @@ initialize_jit(void)
229259 // Write our deopt stub:
230260 {
231261 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 ) {
235265 return needs_initializing ;
236266 }
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 );
239269 if (data == NULL ) {
240270 return needs_initializing ;
241271 }
242272 uint64_t patches [] = GET_PATCHES ();
243- patches [_JIT_BODY ] = (uintptr_t )deoptimize_stub ;
273+ patches [_JIT_BODY ] = (uintptr_t )text ;
244274 patches [_JIT_DATA ] = (uintptr_t )data ;
245275 patches [_JIT_ZERO ] = 0 ;
246276 emit (stencil_group , patches );
247- if (mark_executable (deoptimize_stub , pages_body )) {
277+ if (mark_executable (text , text_pages ) || mark_readable ( data , data_pages )) {
248278 return needs_initializing ;
249279 }
280+ deoptimize_stub = text ;
250281 }
251282 // Write our error stub:
252283 {
253284 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 ) {
257288 return needs_initializing ;
258289 }
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 );
261292 if (data == NULL ) {
262293 return needs_initializing ;
263294 }
264295 uint64_t patches [] = GET_PATCHES ();
265- patches [_JIT_BODY ] = (uintptr_t )error_stub ;
296+ patches [_JIT_BODY ] = (uintptr_t )text ;
266297 patches [_JIT_DATA ] = (uintptr_t )data ;
267298 patches [_JIT_ZERO ] = 0 ;
268299 emit (stencil_group , patches );
269- if (mark_executable (error_stub , pages_body )) {
300+ if (mark_executable (text , text_pages ) || mark_readable ( data , data_pages )) {
270301 return needs_initializing ;
271302 }
303+ error_stub = text ;
272304 }
273305 // Done:
274306 needs_initializing = 0 ;
@@ -283,62 +315,62 @@ _PyJIT_CompileTrace(_PyUOpExecutorObject *executor, _PyUOpInstruction *trace, in
283315 return NULL ;
284316 }
285317 // 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 ;
288320 for (int i = 0 ; i < size ; i ++ ) {
289321 _PyUOpInstruction * instruction = & trace [i ];
290322 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 );
294326 };
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 ) {
298330 return NULL ;
299331 }
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 );
302334 if (data == NULL ) {
303335 return NULL ;
304336 }
305- unsigned char * head_body = body ;
337+ unsigned char * head_text = text ;
306338 unsigned char * head_data = data ;
307339 // First, the trampoline:
308340 const StencilGroup * stencil_group = & trampoline_stencil_group ;
309341 uint64_t patches [] = GET_PATCHES ();
310- patches [_JIT_BODY ] = (uintptr_t )head_body ;
342+ patches [_JIT_BODY ] = (uintptr_t )head_text ;
311343 patches [_JIT_DATA ] = (uintptr_t )head_data ;
312- patches [_JIT_CONTINUE ] = (uintptr_t )head_body + stencil_group -> body . nbytes ;
344+ patches [_JIT_CONTINUE ] = (uintptr_t )head_text + stencil_group -> text . body_size ;
313345 patches [_JIT_ZERO ] = 0 ;
314346 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 ;
317349 // Then, all of the stencils:
318350 for (int i = 0 ; i < size ; i ++ ) {
319351 _PyUOpInstruction * instruction = & trace [i ];
320352 const StencilGroup * stencil_group = & stencil_groups [instruction -> opcode ];
321353 uint64_t patches [] = GET_PATCHES ();
322- patches [_JIT_BODY ] = (uintptr_t )head_body ;
354+ patches [_JIT_BODY ] = (uintptr_t )head_text ;
323355 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 ;
325357 patches [_JIT_CURRENT_EXECUTOR ] = (uintptr_t )executor ;
326358 patches [_JIT_DEOPTIMIZE ] = (uintptr_t )deoptimize_stub ;
327359 patches [_JIT_ERROR ] = (uintptr_t )error_stub ;
328360 patches [_JIT_OPARG ] = instruction -> oparg ;
329361 patches [_JIT_OPERAND ] = instruction -> operand ;
330362 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 ;
332364 patches [_JIT_ZERO ] = 0 ;
333365 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 ;
336368 };
337- if (mark_executable (body , pages_body )) {
369+ if (mark_executable (text , text_pages ) || mark_readable ( data , data_pages )) {
338370 return NULL ;
339371 }
340372 // 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 ;
344376}
0 commit comments