hello people, I've implemented some print opcodes in JIT (for i386), but I would like to know your opinion about these before submitting a patch.
in reality, there isn't a big performance boost, because I'm just calling printf as the C opcode does. it just saves some push/pop/call/ret instructions. the advantage is that such hack is portable across platform. implementing a more low-level print mechanism (involving system calls probably) would require several #ifdef..#endif, I suppose. anyway, this implements a new function in jit_emit.h which makes a call to a C function (an absolute address, that is). this is the function I've added to jit_emit.h: void emit_call_abs(Parrot_jit_info *jit_info, long absaddr, int putback) { Parrot_jit_newfixup(jit_info); jit_info->fixups->type = JIT_X86CALL; jit_info->fixups->param.fptr = (void (*)(void)) absaddr; emitm_calll(jit_info->native_ptr, 0xdeafc0de); emitm_addl_i_r(jit_info->native_ptr, putback, emit_ESP); } this is very similar to Parrot_jit_normal_op, except that the address is stored 'as it is' and the bytes to be added to ESP are variable. and this is how print_ic is implemented in core.jit: Parrot_print_ic { emitm_pushl_i(NATIVECODE, *INT_CONST[1]); emitm_pushl_i(NATIVECODE, (long) INTVAL_FMT); emit_call_abs(jit_info, (long) printf, 8); } print_nc looks like this (I needed to define a private long because simply saying (&NUM_CONST[1])+4 doesn't work): Parrot_print_nc { long mydouble = (long) &NUM_CONST[1]; NATIVECODE = emit_pushl_m(NATIVECODE, emit_None, emit_None, emit_None, mydouble+4); NATIVECODE = emit_pushl_m(NATIVECODE, emit_None, emit_None, emit_None, mydouble); emitm_pushl_i(NATIVECODE, (long) FLOATVAL_FMT); emit_call_abs(jit_info, (long) printf, 12); } also print_sc is similar, except that there isn't a STRINGVAL_FMT defined in config.h: Parrot_print_sc { NATIVECODE = emit_pushl_m(NATIVECODE, emit_None, emit_None, emit_None, (long) &STRING_CONST[1]->bufstart); emitm_pushl_i(NATIVECODE, (long) "%s"); emit_call_abs(jit_info, (long) printf, 8); } another little thing I've done, but I'm not sure if there's need for this, is having added these lines to jit.c in the build_asm routine, just before returning: if (Interp_flags_TEST(interpreter, PARROT_DEBUG_FLAG)) { fprintf(stderr, "*** Parrot VM: JITted code at 0x%08x. ***\n", jit_info.arena_start); } this way when I start 'parrot -j -d something' it tells me where to find the JIT, and I can goto there directly in the debugger. it's really a time saver for me. cheers, Aldo __END__ $_=q,just perl,,s, , another ,,s,$, hacker,,print;