99#include "pycore_opcode.h" // _PyOpcode_Deopt
1010#include "pycore_pystate.h" // _PyInterpreterState_GET()
1111#include "pycore_tuple.h" // _PyTuple_ITEMS()
12+ #include "pycore_ceval.h" // _PyTuple_ITEMS()
1213#include "clinic/codeobject.c.h"
1314
15+ #include <stdio.h>
16+ #include <stdlib.h>
17+ #include <sys/mman.h>
18+ #include <stdio.h>
19+ #include <unistd.h>
20+
21+ #include <sys/types.h>
22+ #include <stdio.h>
23+ #include <stdlib.h>
24+ #include <errno.h>
25+
26+
27+
1428
1529/******************
1630 * generic helpers
@@ -286,6 +300,101 @@ _PyCode_Validate(struct _PyCodeConstructor *con)
286300 return 0 ;
287301}
288302
303+ py_trampoline compile_blech (void ) {
304+ char * memory = mmap (NULL , // address
305+ 4096 , // size
306+ PROT_READ | PROT_WRITE | PROT_EXEC ,
307+ MAP_PRIVATE | MAP_ANONYMOUS ,
308+ -1 , // fd (not used here)
309+ 0 ); // offset (not used here)
310+ if (!memory ) {
311+ perror ("failed to allocate memory" );
312+ exit (1 );
313+ }
314+
315+ int i = 0 ;
316+
317+ memory [i ++ ] = 0x55 ;
318+ memory [i ++ ] = 0x48 ;
319+ memory [i ++ ] = 0x89 ;
320+ memory [i ++ ] = 0xe5 ;
321+ memory [i ++ ] = 0x48 ;
322+ memory [i ++ ] = 0x83 ;
323+ memory [i ++ ] = 0xec ;
324+ memory [i ++ ] = 0x20 ;
325+ memory [i ++ ] = 0x48 ;
326+ memory [i ++ ] = 0x89 ;
327+ memory [i ++ ] = 0x7d ;
328+ memory [i ++ ] = 0xf8 ;
329+ memory [i ++ ] = 0x48 ;
330+ memory [i ++ ] = 0x89 ;
331+ memory [i ++ ] = 0x75 ;
332+ memory [i ++ ] = 0xf0 ;
333+ memory [i ++ ] = 0x48 ;
334+ memory [i ++ ] = 0x89 ;
335+ memory [i ++ ] = 0x55 ;
336+ memory [i ++ ] = 0xe8 ;
337+ memory [i ++ ] = 0x89 ;
338+ memory [i ++ ] = 0x4d ;
339+ memory [i ++ ] = 0xe4 ;
340+ memory [i ++ ] = 0x8b ;
341+ memory [i ++ ] = 0x55 ;
342+ memory [i ++ ] = 0xe4 ;
343+ memory [i ++ ] = 0x48 ;
344+ memory [i ++ ] = 0x8b ;
345+ memory [i ++ ] = 0x4d ;
346+ memory [i ++ ] = 0xe8 ;
347+ memory [i ++ ] = 0x48 ;
348+ memory [i ++ ] = 0x8b ;
349+ memory [i ++ ] = 0x45 ;
350+ memory [i ++ ] = 0xf0 ;
351+ memory [i ++ ] = 0x4c ;
352+ memory [i ++ ] = 0x8b ;
353+ memory [i ++ ] = 0x45 ;
354+ memory [i ++ ] = 0xf8 ;
355+ memory [i ++ ] = 0x48 ;
356+ memory [i ++ ] = 0x89 ;
357+ memory [i ++ ] = 0xce ;
358+ memory [i ++ ] = 0x48 ;
359+ memory [i ++ ] = 0x89 ;
360+ memory [i ++ ] = 0xc7 ;
361+ memory [i ++ ] = 0x41 ;
362+ memory [i ++ ] = 0xff ;
363+ memory [i ++ ] = 0xd0 ;
364+ memory [i ++ ] = 0xc9 ;
365+ memory [i ++ ] = 0xc3 ;
366+
367+ return (py_trampoline ) memory ;
368+ }
369+
370+ FILE * perf_map_open (pid_t pid ) {
371+ char filename [500 ];
372+ snprintf (filename , sizeof (filename ), "/tmp/perf-%d.map" , pid );
373+ FILE * res = fopen (filename , "a" );
374+ if (!res ) {
375+ fprintf (stderr , "Couldn't open %s: errno(%d)" , filename , errno );
376+ exit (0 );
377+ }
378+ return res ;
379+ }
380+
381+ int perf_map_close (FILE * fp ) {
382+ if (fp )
383+ return fclose (fp );
384+ else
385+ return 0 ;
386+ }
387+
388+ void perf_map_write_entry (FILE * method_file , const void * code_addr , unsigned int code_size , const char * entry ) {
389+ fprintf (method_file , "%lx %x %s\n" , (unsigned long ) code_addr , code_size , entry );
390+ }
391+
392+ typedef PyObject * (* py_evaluator )(PyThreadState * , _PyInterpreterFrame * , int throwflag );
393+
394+ PyObject * the_trampoline (py_evaluator eval , PyThreadState * t , _PyInterpreterFrame * f , int p ) {
395+ return eval (t , f ,p );
396+ }
397+
289398static void
290399init_code (PyCodeObject * co , struct _PyCodeConstructor * con )
291400{
@@ -300,6 +409,13 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
300409 co -> co_name = con -> name ;
301410 Py_INCREF (con -> qualname );
302411 co -> co_qualname = con -> qualname ;
412+
413+ py_trampoline f = compile_blech ();
414+ FILE * pfile = perf_map_open (getpid ());
415+ perf_map_write_entry (pfile , f , 4096 , PyUnicode_AsUTF8 (con -> qualname ));
416+ perf_map_close (pfile );
417+
418+ co -> co_trampoline = f ;
303419 co -> co_flags = con -> flags ;
304420
305421 co -> co_firstlineno = con -> firstlineno ;
0 commit comments