69 Register temp = S0; |
69 Register temp = S0; |
70 Label L_ok, L_bad; |
70 Label L_ok, L_bad; |
71 BLOCK_COMMENT("verify_klass {"); |
71 BLOCK_COMMENT("verify_klass {"); |
72 __ verify_oop(obj); |
72 __ verify_oop(obj); |
73 __ beq(obj, R0, L_bad); |
73 __ beq(obj, R0, L_bad); |
74 __ nop(); |
74 __ delayed()->nop(); |
75 __ push(temp); //if (temp2 != noreg) __ push(temp2); |
75 __ push(temp); //if (temp2 != noreg) __ push(temp2); |
76 #define UNPUSH { __ pop(temp); } |
76 #define UNPUSH { __ pop(temp); } |
77 __ load_klass(temp, obj); |
77 __ load_klass(temp, obj); |
78 __ li(AT, (long)&klass_addr); |
78 __ li(AT, (long)&klass_addr); |
79 __ ld(AT, AT, 0); |
79 __ ld(AT, AT, 0); |
80 __ beq(temp, AT, L_ok); |
80 __ beq(temp, AT, L_ok); |
81 __ nop(); |
81 __ delayed()->nop(); |
82 intptr_t super_check_offset = klass->super_check_offset(); |
82 intptr_t super_check_offset = klass->super_check_offset(); |
83 __ ld(temp, Address(temp, super_check_offset)); |
83 __ ld(temp, Address(temp, super_check_offset)); |
84 __ li(AT, (long)&klass_addr); |
84 __ li(AT, (long)&klass_addr); |
85 __ ld(AT, AT, 0); |
85 __ ld(AT, AT, 0); |
86 __ beq(AT, temp, L_ok); |
86 __ beq(AT, temp, L_ok); |
87 __ nop(); |
87 __ delayed()->nop(); |
88 UNPUSH; |
88 UNPUSH; |
89 __ bind(L_bad); |
89 __ bind(L_bad); |
90 __ STOP(error_message); |
90 __ STOP(error_message); |
91 __ BIND(L_ok); |
91 __ BIND(L_ok); |
92 UNPUSH; |
92 UNPUSH; |
101 __ sra(temp, temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT); |
101 __ sra(temp, temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT); |
102 __ move(AT, java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK); |
102 __ move(AT, java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK); |
103 __ andr(temp, temp, AT); |
103 __ andr(temp, temp, AT); |
104 __ move(AT, ref_kind); |
104 __ move(AT, ref_kind); |
105 __ beq(temp, AT, L); |
105 __ beq(temp, AT, L); |
106 __ nop(); |
106 __ delayed()->nop(); |
107 { char* buf = NEW_C_HEAP_ARRAY(char, 100, mtInternal); |
107 { char* buf = NEW_C_HEAP_ARRAY(char, 100, mtInternal); |
108 jio_snprintf(buf, 100, "verify_ref_kind expected %x", ref_kind); |
108 jio_snprintf(buf, 100, "verify_ref_kind expected %x", ref_kind); |
109 if (ref_kind == JVM_REF_invokeVirtual || |
109 if (ref_kind == JVM_REF_invokeVirtual || |
110 ref_kind == JVM_REF_invokeSpecial) |
110 ref_kind == JVM_REF_invokeSpecial) |
111 // could do this for all ref_kinds, but would explode assembly code size |
111 // could do this for all ref_kinds, but would explode assembly code size |
122 bool for_compiler_entry) { |
122 bool for_compiler_entry) { |
123 assert(method == Rmethod, "interpreter calling convention"); |
123 assert(method == Rmethod, "interpreter calling convention"); |
124 |
124 |
125 Label L_no_such_method; |
125 Label L_no_such_method; |
126 __ beq(method, R0, L_no_such_method); |
126 __ beq(method, R0, L_no_such_method); |
127 __ nop(); |
127 __ delayed()->nop(); |
128 |
128 |
129 __ verify_method_ptr(method); |
129 __ verify_method_ptr(method); |
130 |
130 |
131 if (!for_compiler_entry && JvmtiExport::can_post_interpreter_events()) { |
131 if (!for_compiler_entry && JvmtiExport::can_post_interpreter_events()) { |
132 Label run_compiled_code; |
132 Label run_compiled_code; |
141 #endif |
141 #endif |
142 // interp_only is an int, on little endian it is sufficient to test the byte only |
142 // interp_only is an int, on little endian it is sufficient to test the byte only |
143 // Is a cmpl faster? |
143 // Is a cmpl faster? |
144 __ lbu(AT, rthread, in_bytes(JavaThread::interp_only_mode_offset())); |
144 __ lbu(AT, rthread, in_bytes(JavaThread::interp_only_mode_offset())); |
145 __ beq(AT, R0, run_compiled_code); |
145 __ beq(AT, R0, run_compiled_code); |
146 __ nop(); |
146 __ delayed()->nop(); |
147 __ ld(T9, method, in_bytes(Method::interpreter_entry_offset())); |
147 __ ld(T9, method, in_bytes(Method::interpreter_entry_offset())); |
148 __ jr(T9); |
148 __ jr(T9); |
149 __ nop(); |
149 __ delayed()->nop(); |
150 __ BIND(run_compiled_code); |
150 __ BIND(run_compiled_code); |
151 } |
151 } |
152 |
152 |
153 const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() : |
153 const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() : |
154 Method::from_interpreted_offset(); |
154 Method::from_interpreted_offset(); |
155 __ ld(T9, method, in_bytes(entry_offset)); |
155 __ ld(T9, method, in_bytes(entry_offset)); |
156 __ jr(T9); |
156 __ jr(T9); |
157 __ nop(); |
157 __ delayed()->nop(); |
158 |
158 |
159 __ bind(L_no_such_method); |
159 __ bind(L_no_such_method); |
160 address wrong_method = StubRoutines::throw_AbstractMethodError_entry(); |
160 address wrong_method = StubRoutines::throw_AbstractMethodError_entry(); |
161 __ jmp(wrong_method, relocInfo::runtime_call_type); |
161 __ jmp(wrong_method, relocInfo::runtime_call_type); |
162 __ nop(); |
162 __ delayed()->nop(); |
163 } |
163 } |
164 |
164 |
165 void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm, |
165 void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm, |
166 Register recv, Register method_temp, |
166 Register recv, Register method_temp, |
167 Register temp2, |
167 Register temp2, |
193 // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), ""); |
193 // assert(sizeof(u2) == sizeof(Method::_size_of_parameters), ""); |
194 Label L; |
194 Label L; |
195 Address recv_addr = __ argument_address(temp2, -1); |
195 Address recv_addr = __ argument_address(temp2, -1); |
196 __ ld(AT, recv_addr); |
196 __ ld(AT, recv_addr); |
197 __ beq(recv, AT, L); |
197 __ beq(recv, AT, L); |
198 __ nop(); |
198 __ delayed()->nop(); |
199 |
199 |
200 recv_addr = __ argument_address(temp2, -1); |
200 recv_addr = __ argument_address(temp2, -1); |
201 __ ld(V0, recv_addr); |
201 __ ld(V0, recv_addr); |
202 __ STOP("receiver not on stack"); |
202 __ STOP("receiver not on stack"); |
203 __ BIND(L); |
203 __ BIND(L); |
240 BLOCK_COMMENT("verify_intrinsic_id {"); |
240 BLOCK_COMMENT("verify_intrinsic_id {"); |
241 __ lbu(AT, rbx_method, Method::intrinsic_id_offset_in_bytes()); |
241 __ lbu(AT, rbx_method, Method::intrinsic_id_offset_in_bytes()); |
242 guarantee(Assembler::is_simm16(iid), "Oops, iid is not simm16! Change the instructions."); |
242 guarantee(Assembler::is_simm16(iid), "Oops, iid is not simm16! Change the instructions."); |
243 __ addiu(AT, AT, -1 * (int) iid); |
243 __ addiu(AT, AT, -1 * (int) iid); |
244 __ beq(AT, R0, L); |
244 __ beq(AT, R0, L); |
245 __ nop(); |
245 __ delayed()->nop(); |
246 if (iid == vmIntrinsics::_linkToVirtual || |
246 if (iid == vmIntrinsics::_linkToVirtual || |
247 iid == vmIntrinsics::_linkToSpecial) { |
247 iid == vmIntrinsics::_linkToSpecial) { |
248 // could do this for all kinds, but would explode assembly code size |
248 // could do this for all kinds, but would explode assembly code size |
249 trace_method_handle(_masm, "bad Method*::intrinsic_id"); |
249 trace_method_handle(_masm, "bad Method*::intrinsic_id"); |
250 } |
250 } |
417 |
417 |
418 if (VerifyMethodHandles) { |
418 if (VerifyMethodHandles) { |
419 Label L_index_ok; |
419 Label L_index_ok; |
420 __ slt(AT, R0, temp2_index); |
420 __ slt(AT, R0, temp2_index); |
421 __ bne(AT, R0, L_index_ok); |
421 __ bne(AT, R0, L_index_ok); |
422 __ nop(); |
422 __ delayed()->nop(); |
423 __ STOP("no virtual index"); |
423 __ STOP("no virtual index"); |
424 __ BIND(L_index_ok); |
424 __ BIND(L_index_ok); |
425 } |
425 } |
426 |
426 |
427 // Note: The verifier invariants allow us to ignore MemberName.clazz and vmtarget |
427 // Note: The verifier invariants allow us to ignore MemberName.clazz and vmtarget |
449 __ ld(rbx_index, member_vmindex); |
449 __ ld(rbx_index, member_vmindex); |
450 if (VerifyMethodHandles) { |
450 if (VerifyMethodHandles) { |
451 Label L; |
451 Label L; |
452 __ slt(AT, rbx_index, R0); |
452 __ slt(AT, rbx_index, R0); |
453 __ beq(AT, R0, L); |
453 __ beq(AT, R0, L); |
454 __ nop(); |
454 __ delayed()->nop(); |
455 __ STOP("invalid vtable index for MH.invokeInterface"); |
455 __ STOP("invalid vtable index for MH.invokeInterface"); |
456 __ bind(L); |
456 __ bind(L); |
457 } |
457 } |
458 |
458 |
459 // given intf, index, and recv klass, dispatch to the implementation method |
459 // given intf, index, and recv klass, dispatch to the implementation method |
482 |
482 |
483 if (iid == vmIntrinsics::_linkToInterface) { |
483 if (iid == vmIntrinsics::_linkToInterface) { |
484 __ bind(L_incompatible_class_change_error); |
484 __ bind(L_incompatible_class_change_error); |
485 address icce_entry= StubRoutines::throw_IncompatibleClassChangeError_entry(); |
485 address icce_entry= StubRoutines::throw_IncompatibleClassChangeError_entry(); |
486 __ jmp(icce_entry, relocInfo::runtime_call_type); |
486 __ jmp(icce_entry, relocInfo::runtime_call_type); |
487 __ nop(); |
487 __ delayed()->nop(); |
488 } |
488 } |
489 } |
489 } |
490 } |
490 } |
491 |
491 |
492 #ifndef PRODUCT |
492 #ifndef PRODUCT |