src/cpu/x86/vm/assembler_x86.cpp

changeset 1145
e5b0439ef4ae
parent 1116
fbde8ec322d0
child 1210
93c14e5562c4
     1.1 --- a/src/cpu/x86/vm/assembler_x86.cpp	Wed Apr 08 00:12:59 2009 -0700
     1.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp	Wed Apr 08 10:56:49 2009 -0700
     1.3 @@ -7609,6 +7609,83 @@
     1.4  }
     1.5  
     1.6  
     1.7 +// registers on entry:
     1.8 +//  - rax ('check' register): required MethodType
     1.9 +//  - rcx: method handle
    1.10 +//  - rdx, rsi, or ?: killable temp
    1.11 +void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg,
    1.12 +                                              Register temp_reg,
    1.13 +                                              Label& wrong_method_type) {
    1.14 +  if (UseCompressedOops)  unimplemented();  // field accesses must decode
    1.15 +  // compare method type against that of the receiver
    1.16 +  cmpptr(mtype_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)));
    1.17 +  jcc(Assembler::notEqual, wrong_method_type);
    1.18 +}
    1.19 +
    1.20 +
    1.21 +// A method handle has a "vmslots" field which gives the size of its
    1.22 +// argument list in JVM stack slots.  This field is either located directly
    1.23 +// in every method handle, or else is indirectly accessed through the
    1.24 +// method handle's MethodType.  This macro hides the distinction.
    1.25 +void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register mh_reg,
    1.26 +                                                Register temp_reg) {
    1.27 +  if (UseCompressedOops)  unimplemented();  // field accesses must decode
    1.28 +  // load mh.type.form.vmslots
    1.29 +  if (java_dyn_MethodHandle::vmslots_offset_in_bytes() != 0) {
    1.30 +    // hoist vmslots into every mh to avoid dependent load chain
    1.31 +    movl(vmslots_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg)));
    1.32 +  } else {
    1.33 +    Register temp2_reg = vmslots_reg;
    1.34 +    movptr(temp2_reg, Address(mh_reg,    delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)));
    1.35 +    movptr(temp2_reg, Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg)));
    1.36 +    movl(vmslots_reg, Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)));
    1.37 +  }
    1.38 +}
    1.39 +
    1.40 +
    1.41 +// registers on entry:
    1.42 +//  - rcx: method handle
    1.43 +//  - rdx: killable temp (interpreted only)
    1.44 +//  - rax: killable temp (compiled only)
    1.45 +void MacroAssembler::jump_to_method_handle_entry(Register mh_reg, Register temp_reg) {
    1.46 +  assert(mh_reg == rcx, "caller must put MH object in rcx");
    1.47 +  assert_different_registers(mh_reg, temp_reg);
    1.48 +
    1.49 +  if (UseCompressedOops)  unimplemented();  // field accesses must decode
    1.50 +
    1.51 +  // pick out the interpreted side of the handler
    1.52 +  movptr(temp_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg)));
    1.53 +
    1.54 +  // off we go...
    1.55 +  jmp(Address(temp_reg, MethodHandleEntry::from_interpreted_entry_offset_in_bytes()));
    1.56 +
    1.57 +  // for the various stubs which take control at this point,
    1.58 +  // see MethodHandles::generate_method_handle_stub
    1.59 +}
    1.60 +
    1.61 +
    1.62 +Address MacroAssembler::argument_address(RegisterOrConstant arg_slot,
    1.63 +                                         int extra_slot_offset) {
    1.64 +  // cf. TemplateTable::prepare_invoke(), if (load_receiver).
    1.65 +  int stackElementSize = Interpreter::stackElementSize();
    1.66 +  int offset = Interpreter::expr_offset_in_bytes(extra_slot_offset+0);
    1.67 +#ifdef ASSERT
    1.68 +  int offset1 = Interpreter::expr_offset_in_bytes(extra_slot_offset+1);
    1.69 +  assert(offset1 - offset == stackElementSize, "correct arithmetic");
    1.70 +#endif
    1.71 +  Register             scale_reg    = noreg;
    1.72 +  Address::ScaleFactor scale_factor = Address::no_scale;
    1.73 +  if (arg_slot.is_constant()) {
    1.74 +    offset += arg_slot.as_constant() * stackElementSize;
    1.75 +  } else {
    1.76 +    scale_reg    = arg_slot.as_register();
    1.77 +    scale_factor = Address::times(stackElementSize);
    1.78 +  }
    1.79 +  offset += wordSize;           // return PC is on stack
    1.80 +  return Address(rsp, scale_reg, scale_factor, offset);
    1.81 +}
    1.82 +
    1.83 +
    1.84  void MacroAssembler::verify_oop_addr(Address addr, const char* s) {
    1.85    if (!VerifyOops) return;
    1.86  

mercurial