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