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;

Reply via email to