7707 // - rcx: method handle |
7707 // - rcx: method handle |
7708 // - rdx, rsi, or ?: killable temp |
7708 // - rdx, rsi, or ?: killable temp |
7709 void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg, |
7709 void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg, |
7710 Register temp_reg, |
7710 Register temp_reg, |
7711 Label& wrong_method_type) { |
7711 Label& wrong_method_type) { |
7712 if (UseCompressedOops) unimplemented(); // field accesses must decode |
7712 Address type_addr(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)); |
7713 // compare method type against that of the receiver |
7713 // compare method type against that of the receiver |
7714 cmpptr(mtype_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg))); |
7714 if (UseCompressedOops) { |
|
7715 load_heap_oop(temp_reg, type_addr); |
|
7716 cmpptr(mtype_reg, temp_reg); |
|
7717 } else { |
|
7718 cmpptr(mtype_reg, type_addr); |
|
7719 } |
7715 jcc(Assembler::notEqual, wrong_method_type); |
7720 jcc(Assembler::notEqual, wrong_method_type); |
7716 } |
7721 } |
7717 |
7722 |
7718 |
7723 |
7719 // A method handle has a "vmslots" field which gives the size of its |
7724 // A method handle has a "vmslots" field which gives the size of its |
7721 // in every method handle, or else is indirectly accessed through the |
7726 // in every method handle, or else is indirectly accessed through the |
7722 // method handle's MethodType. This macro hides the distinction. |
7727 // method handle's MethodType. This macro hides the distinction. |
7723 void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register mh_reg, |
7728 void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register mh_reg, |
7724 Register temp_reg) { |
7729 Register temp_reg) { |
7725 assert_different_registers(vmslots_reg, mh_reg, temp_reg); |
7730 assert_different_registers(vmslots_reg, mh_reg, temp_reg); |
7726 if (UseCompressedOops) unimplemented(); // field accesses must decode |
|
7727 // load mh.type.form.vmslots |
7731 // load mh.type.form.vmslots |
7728 if (java_dyn_MethodHandle::vmslots_offset_in_bytes() != 0) { |
7732 if (java_dyn_MethodHandle::vmslots_offset_in_bytes() != 0) { |
7729 // hoist vmslots into every mh to avoid dependent load chain |
7733 // hoist vmslots into every mh to avoid dependent load chain |
7730 movl(vmslots_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg))); |
7734 movl(vmslots_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg))); |
7731 } else { |
7735 } else { |
7732 Register temp2_reg = vmslots_reg; |
7736 Register temp2_reg = vmslots_reg; |
7733 movptr(temp2_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg))); |
7737 load_heap_oop(temp2_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg))); |
7734 movptr(temp2_reg, Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg))); |
7738 load_heap_oop(temp2_reg, Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg))); |
7735 movl(vmslots_reg, Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg))); |
7739 movl(vmslots_reg, Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg))); |
7736 } |
7740 } |
7737 } |
7741 } |
7738 |
7742 |
7739 |
7743 |
7743 // - rax: killable temp (compiled only) |
7747 // - rax: killable temp (compiled only) |
7744 void MacroAssembler::jump_to_method_handle_entry(Register mh_reg, Register temp_reg) { |
7748 void MacroAssembler::jump_to_method_handle_entry(Register mh_reg, Register temp_reg) { |
7745 assert(mh_reg == rcx, "caller must put MH object in rcx"); |
7749 assert(mh_reg == rcx, "caller must put MH object in rcx"); |
7746 assert_different_registers(mh_reg, temp_reg); |
7750 assert_different_registers(mh_reg, temp_reg); |
7747 |
7751 |
7748 if (UseCompressedOops) unimplemented(); // field accesses must decode |
|
7749 |
|
7750 // pick out the interpreted side of the handler |
7752 // pick out the interpreted side of the handler |
|
7753 // NOTE: vmentry is not an oop! |
7751 movptr(temp_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg))); |
7754 movptr(temp_reg, Address(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg))); |
7752 |
7755 |
7753 // off we go... |
7756 // off we go... |
7754 jmp(Address(temp_reg, MethodHandleEntry::from_interpreted_entry_offset_in_bytes())); |
7757 jmp(Address(temp_reg, MethodHandleEntry::from_interpreted_entry_offset_in_bytes())); |
7755 |
7758 |
8236 } else |
8239 } else |
8237 #endif |
8240 #endif |
8238 movptr(Address(dst, oopDesc::klass_offset_in_bytes()), src); |
8241 movptr(Address(dst, oopDesc::klass_offset_in_bytes()), src); |
8239 } |
8242 } |
8240 |
8243 |
|
8244 void MacroAssembler::load_heap_oop(Register dst, Address src) { |
|
8245 #ifdef _LP64 |
|
8246 if (UseCompressedOops) { |
|
8247 movl(dst, src); |
|
8248 decode_heap_oop(dst); |
|
8249 } else |
|
8250 #endif |
|
8251 movptr(dst, src); |
|
8252 } |
|
8253 |
|
8254 void MacroAssembler::store_heap_oop(Address dst, Register src) { |
|
8255 #ifdef _LP64 |
|
8256 if (UseCompressedOops) { |
|
8257 assert(!dst.uses(src), "not enough registers"); |
|
8258 encode_heap_oop(src); |
|
8259 movl(dst, src); |
|
8260 } else |
|
8261 #endif |
|
8262 movptr(dst, src); |
|
8263 } |
|
8264 |
|
8265 // Used for storing NULLs. |
|
8266 void MacroAssembler::store_heap_oop_null(Address dst) { |
|
8267 #ifdef _LP64 |
|
8268 if (UseCompressedOops) { |
|
8269 movl(dst, (int32_t)NULL_WORD); |
|
8270 } else { |
|
8271 movslq(dst, (int32_t)NULL_WORD); |
|
8272 } |
|
8273 #else |
|
8274 movl(dst, (int32_t)NULL_WORD); |
|
8275 #endif |
|
8276 } |
|
8277 |
8241 #ifdef _LP64 |
8278 #ifdef _LP64 |
8242 void MacroAssembler::store_klass_gap(Register dst, Register src) { |
8279 void MacroAssembler::store_klass_gap(Register dst, Register src) { |
8243 if (UseCompressedOops) { |
8280 if (UseCompressedOops) { |
8244 // Store to klass gap in destination |
8281 // Store to klass gap in destination |
8245 movl(Address(dst, oopDesc::klass_gap_offset_in_bytes()), src); |
8282 movl(Address(dst, oopDesc::klass_gap_offset_in_bytes()), src); |
8246 } |
|
8247 } |
|
8248 |
|
8249 void MacroAssembler::load_heap_oop(Register dst, Address src) { |
|
8250 if (UseCompressedOops) { |
|
8251 movl(dst, src); |
|
8252 decode_heap_oop(dst); |
|
8253 } else { |
|
8254 movq(dst, src); |
|
8255 } |
|
8256 } |
|
8257 |
|
8258 void MacroAssembler::store_heap_oop(Address dst, Register src) { |
|
8259 if (UseCompressedOops) { |
|
8260 assert(!dst.uses(src), "not enough registers"); |
|
8261 encode_heap_oop(src); |
|
8262 movl(dst, src); |
|
8263 } else { |
|
8264 movq(dst, src); |
|
8265 } |
|
8266 } |
|
8267 |
|
8268 // Used for storing NULLs. |
|
8269 void MacroAssembler::store_heap_oop_null(Address dst) { |
|
8270 if (UseCompressedOops) { |
|
8271 movl(dst, (int32_t)NULL_WORD); |
|
8272 } else { |
|
8273 movslq(dst, (int32_t)NULL_WORD); |
|
8274 } |
8283 } |
8275 } |
8284 } |
8276 |
8285 |
8277 #ifdef ASSERT |
8286 #ifdef ASSERT |
8278 void MacroAssembler::verify_heapbase(const char* msg) { |
8287 void MacroAssembler::verify_heapbase(const char* msg) { |