hello there,
in one of my endless tours inside the JIT world, I came up with this idea
which seems to give a major speed increase.

basically, I'm substituting the Parrot method for subroutines (push the
current address in the call stack and then jump) with a plain native
x86 ASM call instruction. and of course, the ret instruction is just a
plain native ret instruction.

that way I'm completely avoiding the call stack, just relaying to the
CPU internal stack for this.

to make it work, I had to JIT all the 2-parameters eq/ne instructions
to perform a ret on successful comparison instead of a pop and goto.

this is of course a major change in the internal working of the interpreter
when using the -j option, so I'm not sure it is a Good Thing. you would
not be able, for example, to inspect the call stack from inside a Parrot
program anymore.

anyway, this is a little sample of the implementation:

  Parrot_bsr_ic {
    emit_call_op2(jit_info, *INT_CONST[1]);
  }

  Parrot_ret {
    emitm_ret(NATIVECODE);
  }

  Parrot_eq_i_i {
    emitm_movl_m_r(NATIVECODE, emit_EAX, emit_None, emit_None, emit_None, 
    &INT_REG[1]);
    emitm_cmpl_r_m(NATIVECODE, emit_EAX, emit_None, emit_None, emit_None, 
    &INT_REG[2]);
    emitm_jxs(NATIVECODE, emitm_jne, +1);
    emitm_ret(NATIVECODE);
  }

there are of course a lot more eq_X_X and ne_X_X combination, but they're
all similar to this.

the emit_call_op2 in jit.h is just a slight variant of emit_call_op which
only uses 32 bit displacement for backward calls (don't ask me why, but it 
seems to work like this):

  static void emit_call_op2(Parrot_jit_info *jit_info, opcode_t disp){
    long offset;
    opcode_t opcode;

    opcode = jit_info->op_i + disp;

    if(opcode <= jit_info->op_i) {
      offset = jit_info->op_map[opcode].offset -
               (jit_info->native_ptr - jit_info->arena_start);
      emitm_calll(jit_info->native_ptr, offset - 5);
      return;
    }

    Parrot_jit_newfixup(jit_info);
    jit_info->fixups->type = JIT_X86JUMP;
    jit_info->fixups->param.opcode = opcode;
    emitm_calll(jit_info->native_ptr, 0xc0def00d);
  }

if anybody sees a problem with this approach, please let me know, otherwise
I'll go on with the patch.

cheers,
Aldo

__END__
$_=q,just perl,,s, , another ,,s,$, hacker,,print;

Reply via email to