Mercurial > hg > graal-jvmci-8
comparison src/cpu/x86/vm/assembler_x86.cpp @ 710:e5b0439ef4ae
6655638: dynamic languages need method handles
Summary: initial implementation, with known omissions (x86/64, sparc, compiler optim., c-oops, C++ interp.)
Reviewed-by: kvn, twisti, never
author | jrose |
---|---|
date | Wed, 08 Apr 2009 10:56:49 -0700 |
parents | fbde8ec322d0 |
children | 93c14e5562c4 |
comparison
equal
deleted
inserted
replaced
709:1d037ecd7960 | 710:e5b0439ef4ae |
---|---|
7607 | 7607 |
7608 return RegisterOrConstant(tmp); | 7608 return RegisterOrConstant(tmp); |
7609 } | 7609 } |
7610 | 7610 |
7611 | 7611 |
7612 // registers on entry: | |
7613 // - rax ('check' register): required MethodType | |
7614 // - rcx: method handle | |
7615 // - rdx, rsi, or ?: killable temp | |
7616 void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg, | |
7617 Register temp_reg, | |
7618 Label& wrong_method_type) { | |
7619 if (UseCompressedOops) unimplemented(); // field accesses must decode | |
7620 // compare method type against that of the receiver | |
7621 cmpptr(mtype_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg))); | |
7622 jcc(Assembler::notEqual, wrong_method_type); | |
7623 } | |
7624 | |
7625 | |
7626 // A method handle has a "vmslots" field which gives the size of its | |
7627 // argument list in JVM stack slots. This field is either located directly | |
7628 // in every method handle, or else is indirectly accessed through the | |
7629 // method handle's MethodType. This macro hides the distinction. | |
7630 void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register mh_reg, | |
7631 Register temp_reg) { | |
7632 if (UseCompressedOops) unimplemented(); // field accesses must decode | |
7633 // load mh.type.form.vmslots | |
7634 if (java_dyn_MethodHandle::vmslots_offset_in_bytes() != 0) { | |
7635 // hoist vmslots into every mh to avoid dependent load chain | |
7636 movl(vmslots_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg))); | |
7637 } else { | |
7638 Register temp2_reg = vmslots_reg; | |
7639 movptr(temp2_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg))); | |
7640 movptr(temp2_reg, Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg))); | |
7641 movl(vmslots_reg, Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg))); | |
7642 } | |
7643 } | |
7644 | |
7645 | |
7646 // registers on entry: | |
7647 // - rcx: method handle | |
7648 // - rdx: killable temp (interpreted only) | |
7649 // - rax: killable temp (compiled only) | |
7650 void MacroAssembler::jump_to_method_handle_entry(Register mh_reg, Register temp_reg) { | |
7651 assert(mh_reg == rcx, "caller must put MH object in rcx"); | |
7652 assert_different_registers(mh_reg, temp_reg); | |
7653 | |
7654 if (UseCompressedOops) unimplemented(); // field accesses must decode | |
7655 | |
7656 // pick out the interpreted side of the handler | |
7657 movptr(temp_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg))); | |
7658 | |
7659 // off we go... | |
7660 jmp(Address(temp_reg, MethodHandleEntry::from_interpreted_entry_offset_in_bytes())); | |
7661 | |
7662 // for the various stubs which take control at this point, | |
7663 // see MethodHandles::generate_method_handle_stub | |
7664 } | |
7665 | |
7666 | |
7667 Address MacroAssembler::argument_address(RegisterOrConstant arg_slot, | |
7668 int extra_slot_offset) { | |
7669 // cf. TemplateTable::prepare_invoke(), if (load_receiver). | |
7670 int stackElementSize = Interpreter::stackElementSize(); | |
7671 int offset = Interpreter::expr_offset_in_bytes(extra_slot_offset+0); | |
7672 #ifdef ASSERT | |
7673 int offset1 = Interpreter::expr_offset_in_bytes(extra_slot_offset+1); | |
7674 assert(offset1 - offset == stackElementSize, "correct arithmetic"); | |
7675 #endif | |
7676 Register scale_reg = noreg; | |
7677 Address::ScaleFactor scale_factor = Address::no_scale; | |
7678 if (arg_slot.is_constant()) { | |
7679 offset += arg_slot.as_constant() * stackElementSize; | |
7680 } else { | |
7681 scale_reg = arg_slot.as_register(); | |
7682 scale_factor = Address::times(stackElementSize); | |
7683 } | |
7684 offset += wordSize; // return PC is on stack | |
7685 return Address(rsp, scale_reg, scale_factor, offset); | |
7686 } | |
7687 | |
7688 | |
7612 void MacroAssembler::verify_oop_addr(Address addr, const char* s) { | 7689 void MacroAssembler::verify_oop_addr(Address addr, const char* s) { |
7613 if (!VerifyOops) return; | 7690 if (!VerifyOops) return; |
7614 | 7691 |
7615 // Address adjust(addr.base(), addr.index(), addr.scale(), addr.disp() + BytesPerWord); | 7692 // Address adjust(addr.base(), addr.index(), addr.scale(), addr.disp() + BytesPerWord); |
7616 // Pass register number to verify_oop_subroutine | 7693 // Pass register number to verify_oop_subroutine |