src/cpu/sparc/vm/methodHandles_sparc.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 7055355 Sdiff src/cpu/sparc/vm

src/cpu/sparc/vm/methodHandles_sparc.cpp

Print this page




 290   __ cmp(O7_temp, L0_magic_number_1);
 291   __ br(Assembler::equal, false, Assembler::pt, L_ok_1);
 292   __ delayed()->nop();
 293   __ stop("damaged ricochet frame: MAGIC_NUMBER_1 not found");
 294 
 295   __ BIND(L_ok_1);
 296 
 297   // Arguments pointer must look reasonable:
 298 #ifdef _LP64
 299   Register FP_temp = O5_temp;
 300   __ add(FP, STACK_BIAS, FP_temp);
 301 #else
 302   Register FP_temp = FP;
 303 #endif
 304   __ cmp(L4_saved_args_base, FP_temp);
 305   __ br(Assembler::greaterEqualUnsigned, false, Assembler::pt, L_ok_2);
 306   __ delayed()->nop();
 307   __ stop("damaged ricochet frame: L4 < FP");
 308 
 309   __ BIND(L_ok_2);
 310   __ sub(L4_saved_args_base, UNREASONABLE_STACK_MOVE * Interpreter::stackElementSize, O7_temp);
 311   __ cmp(O7_temp, FP_temp);
 312   __ br(Assembler::lessEqualUnsigned, false, Assembler::pt, L_ok_3);
 313   __ delayed()->nop();
 314   __ stop("damaged ricochet frame: (L4 - UNREASONABLE_STACK_MOVE) > FP");

 315 
 316   __ BIND(L_ok_3);
 317   extract_conversion_dest_type(_masm, L5_conversion, O7_temp);
 318   __ cmp(O7_temp, T_VOID);
 319   __ br(Assembler::equal, false, Assembler::pt, L_ok_4);
 320   __ delayed()->nop();
 321   extract_conversion_vminfo(_masm, L5_conversion, O5_temp);
 322   __ ld_ptr(L4_saved_args_base, __ argument_offset(O5_temp, O5_temp), O7_temp);
 323   assert(__ is_simm13(RETURN_VALUE_PLACEHOLDER), "must be simm13");
 324   __ cmp(O7_temp, (int32_t) RETURN_VALUE_PLACEHOLDER);
 325   __ brx(Assembler::equal, false, Assembler::pt, L_ok_4);
 326   __ delayed()->nop();
 327   __ stop("damaged ricochet frame: RETURN_VALUE_PLACEHOLDER not found");
 328   __ BIND(L_ok_4);
 329   BLOCK_COMMENT("} verify_clean");
 330 }
 331 #endif //ASSERT
 332 
 333 void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg, Register temp_reg, Register temp2_reg) {
 334   if (VerifyMethodHandles)


 530   // G5_method:  invoke methodOop
 531   // G3_method_handle: receiver method handle (must load from sp[MethodTypeForm.vmslots])
 532   // O0, O1, O2, O3, O4: garbage temps, blown away
 533   Register O0_mtype   = O0;
 534   Register O1_scratch = O1;
 535   Register O2_scratch = O2;
 536   Register O3_scratch = O3;
 537   Register O4_argslot = O4;
 538   Register O4_argbase = O4;
 539 
 540   // emit WrongMethodType path first, to enable back-branch from main path
 541   Label wrong_method_type;
 542   __ bind(wrong_method_type);
 543   Label invoke_generic_slow_path;
 544   assert(methodOopDesc::intrinsic_id_size_in_bytes() == sizeof(u1), "");;
 545   __ ldub(Address(G5_method, methodOopDesc::intrinsic_id_offset_in_bytes()), O1_scratch);
 546   __ cmp(O1_scratch, (int) vmIntrinsics::_invokeExact);
 547   __ brx(Assembler::notEqual, false, Assembler::pt, invoke_generic_slow_path);
 548   __ delayed()->nop();
 549   __ mov(O0_mtype, G5_method_type);  // required by throw_WrongMethodType
 550   // mov(G3_method_handle, G3_method_handle);  // already in this register
 551   __ jump_to(AddressLiteral(Interpreter::throw_WrongMethodType_entry()), O1_scratch);

 552   __ delayed()->nop();
 553 
 554   // here's where control starts out:
 555   __ align(CodeEntryAlignment);
 556   address entry_point = __ pc();
 557 
 558   // fetch the MethodType from the method handle
 559   // FIXME: Interpreter should transmit pre-popped stack pointer, to locate base of arg list.
 560   // This would simplify several touchy bits of code.
 561   // See 6984712: JSR 292 method handle calls need a clean argument base pointer
 562   {
 563     Register tem = G5_method;
 564     for (jint* pchase = methodOopDesc::method_type_offsets_chain(); (*pchase) != -1; pchase++) {
 565       __ ld_ptr(Address(tem, *pchase), O0_mtype);
 566       tem = O0_mtype;          // in case there is another indirection
 567     }
 568   }
 569 
 570   // given the MethodType, find out where the MH argument is buried
 571   __ load_heap_oop(Address(O0_mtype,   __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes,        O1_scratch)), O4_argslot);


1128 
1129   trace_method_handle(_masm, entry_name(ek));
1130 
1131   BLOCK_COMMENT(err_msg("Entry %s {", entry_name(ek)));
1132 
1133   switch ((int) ek) {
1134   case _raise_exception:
1135     {
1136       // Not a real MH entry, but rather shared code for raising an
1137       // exception.  Since we use the compiled entry, arguments are
1138       // expected in compiler argument registers.
1139       assert(raise_exception_method(), "must be set");
1140       assert(raise_exception_method()->from_compiled_entry(), "method must be linked");
1141 
1142       __ mov(O5_savedSP, SP);  // Cut the stack back to where the caller started.
1143 
1144       Label L_no_method;
1145       // FIXME: fill in _raise_exception_method with a suitable java.lang.invoke method
1146       __ set(AddressLiteral((address) &_raise_exception_method), G5_method);
1147       __ ld_ptr(Address(G5_method, 0), G5_method);
1148       __ tst(G5_method);
1149       __ brx(Assembler::zero, false, Assembler::pn, L_no_method);
1150       __ delayed()->nop();
1151 
1152       const int jobject_oop_offset = 0;
1153       __ ld_ptr(Address(G5_method, jobject_oop_offset), G5_method);
1154       __ tst(G5_method);
1155       __ brx(Assembler::zero, false, Assembler::pn, L_no_method);
1156       __ delayed()->nop();
1157 
1158       __ verify_oop(G5_method);
1159       __ jump_indirect_to(G5_method_fce, O3_scratch);  // jump to compiled entry
1160       __ delayed()->nop();
1161 
1162       // Do something that is at least causes a valid throw from the interpreter.
1163       __ bind(L_no_method);
1164       __ unimplemented("call throw_WrongMethodType_entry");
1165     }
1166     break;
1167 
1168   case _invokestatic_mh:
1169   case _invokespecial_mh:
1170     {
1171       __ load_heap_oop(G3_mh_vmtarget, G5_method);  // target is a methodOop
1172       __ verify_oop(G5_method);
1173       // Same as TemplateTable::invokestatic or invokespecial,
1174       // minus the CP setup and profiling:
1175       if (ek == _invokespecial_mh) {
1176         // Must load & check the first argument before entering the target method.
1177         __ load_method_handle_vmslots(O0_argslot, G3_method_handle, O1_scratch);
1178         __ ld_ptr(__ argument_address(O0_argslot, O0_argslot, -1), G3_method_handle);
1179         __ null_check(G3_method_handle);
1180         __ verify_oop(G3_method_handle);
1181       }
1182       __ jump_indirect_to(G5_method_fie, O1_scratch);
1183       __ delayed()->nop();
1184     }




 290   __ cmp(O7_temp, L0_magic_number_1);
 291   __ br(Assembler::equal, false, Assembler::pt, L_ok_1);
 292   __ delayed()->nop();
 293   __ stop("damaged ricochet frame: MAGIC_NUMBER_1 not found");
 294 
 295   __ BIND(L_ok_1);
 296 
 297   // Arguments pointer must look reasonable:
 298 #ifdef _LP64
 299   Register FP_temp = O5_temp;
 300   __ add(FP, STACK_BIAS, FP_temp);
 301 #else
 302   Register FP_temp = FP;
 303 #endif
 304   __ cmp(L4_saved_args_base, FP_temp);
 305   __ br(Assembler::greaterEqualUnsigned, false, Assembler::pt, L_ok_2);
 306   __ delayed()->nop();
 307   __ stop("damaged ricochet frame: L4 < FP");
 308 
 309   __ BIND(L_ok_2);
 310   // Disable until we decide on it's fate
 311   // __ sub(L4_saved_args_base, UNREASONABLE_STACK_MOVE * Interpreter::stackElementSize, O7_temp);
 312   // __ cmp(O7_temp, FP_temp);
 313   // __ br(Assembler::lessEqualUnsigned, false, Assembler::pt, L_ok_3);
 314   // __ delayed()->nop();
 315   // __ stop("damaged ricochet frame: (L4 - UNREASONABLE_STACK_MOVE) > FP");
 316 
 317   __ BIND(L_ok_3);
 318   extract_conversion_dest_type(_masm, L5_conversion, O7_temp);
 319   __ cmp(O7_temp, T_VOID);
 320   __ br(Assembler::equal, false, Assembler::pt, L_ok_4);
 321   __ delayed()->nop();
 322   extract_conversion_vminfo(_masm, L5_conversion, O5_temp);
 323   __ ld_ptr(L4_saved_args_base, __ argument_offset(O5_temp, O5_temp), O7_temp);
 324   assert(__ is_simm13(RETURN_VALUE_PLACEHOLDER), "must be simm13");
 325   __ cmp(O7_temp, (int32_t) RETURN_VALUE_PLACEHOLDER);
 326   __ brx(Assembler::equal, false, Assembler::pt, L_ok_4);
 327   __ delayed()->nop();
 328   __ stop("damaged ricochet frame: RETURN_VALUE_PLACEHOLDER not found");
 329   __ BIND(L_ok_4);
 330   BLOCK_COMMENT("} verify_clean");
 331 }
 332 #endif //ASSERT
 333 
 334 void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg, Register temp_reg, Register temp2_reg) {
 335   if (VerifyMethodHandles)


 531   // G5_method:  invoke methodOop
 532   // G3_method_handle: receiver method handle (must load from sp[MethodTypeForm.vmslots])
 533   // O0, O1, O2, O3, O4: garbage temps, blown away
 534   Register O0_mtype   = O0;
 535   Register O1_scratch = O1;
 536   Register O2_scratch = O2;
 537   Register O3_scratch = O3;
 538   Register O4_argslot = O4;
 539   Register O4_argbase = O4;
 540 
 541   // emit WrongMethodType path first, to enable back-branch from main path
 542   Label wrong_method_type;
 543   __ bind(wrong_method_type);
 544   Label invoke_generic_slow_path;
 545   assert(methodOopDesc::intrinsic_id_size_in_bytes() == sizeof(u1), "");;
 546   __ ldub(Address(G5_method, methodOopDesc::intrinsic_id_offset_in_bytes()), O1_scratch);
 547   __ cmp(O1_scratch, (int) vmIntrinsics::_invokeExact);
 548   __ brx(Assembler::notEqual, false, Assembler::pt, invoke_generic_slow_path);
 549   __ delayed()->nop();
 550   __ mov(O0_mtype, G5_method_type);  // required by throw_WrongMethodType
 551   __ mov(G3_method_handle, G3_method_handle);  // already in this register
 552   // O0 will be filled in with JavaThread in stub
 553   __ jump_to(AddressLiteral(StubRoutines::throw_WrongMethodTypeException_entry()), O3_scratch);
 554   __ delayed()->nop();
 555 
 556   // here's where control starts out:
 557   __ align(CodeEntryAlignment);
 558   address entry_point = __ pc();
 559 
 560   // fetch the MethodType from the method handle
 561   // FIXME: Interpreter should transmit pre-popped stack pointer, to locate base of arg list.
 562   // This would simplify several touchy bits of code.
 563   // See 6984712: JSR 292 method handle calls need a clean argument base pointer
 564   {
 565     Register tem = G5_method;
 566     for (jint* pchase = methodOopDesc::method_type_offsets_chain(); (*pchase) != -1; pchase++) {
 567       __ ld_ptr(Address(tem, *pchase), O0_mtype);
 568       tem = O0_mtype;          // in case there is another indirection
 569     }
 570   }
 571 
 572   // given the MethodType, find out where the MH argument is buried
 573   __ load_heap_oop(Address(O0_mtype,   __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes,        O1_scratch)), O4_argslot);


1130 
1131   trace_method_handle(_masm, entry_name(ek));
1132 
1133   BLOCK_COMMENT(err_msg("Entry %s {", entry_name(ek)));
1134 
1135   switch ((int) ek) {
1136   case _raise_exception:
1137     {
1138       // Not a real MH entry, but rather shared code for raising an
1139       // exception.  Since we use the compiled entry, arguments are
1140       // expected in compiler argument registers.
1141       assert(raise_exception_method(), "must be set");
1142       assert(raise_exception_method()->from_compiled_entry(), "method must be linked");
1143 
1144       __ mov(O5_savedSP, SP);  // Cut the stack back to where the caller started.
1145 
1146       Label L_no_method;
1147       // FIXME: fill in _raise_exception_method with a suitable java.lang.invoke method
1148       __ set(AddressLiteral((address) &_raise_exception_method), G5_method);
1149       __ ld_ptr(Address(G5_method, 0), G5_method);



1150 
1151       const int jobject_oop_offset = 0;
1152       __ ld_ptr(Address(G5_method, jobject_oop_offset), G5_method);



1153 
1154       __ verify_oop(G5_method);
1155       __ jump_indirect_to(G5_method_fce, O3_scratch);  // jump to compiled entry
1156       __ delayed()->nop();




1157     }
1158     break;
1159 
1160   case _invokestatic_mh:
1161   case _invokespecial_mh:
1162     {
1163       __ load_heap_oop(G3_mh_vmtarget, G5_method);  // target is a methodOop
1164       __ verify_oop(G5_method);
1165       // Same as TemplateTable::invokestatic or invokespecial,
1166       // minus the CP setup and profiling:
1167       if (ek == _invokespecial_mh) {
1168         // Must load & check the first argument before entering the target method.
1169         __ load_method_handle_vmslots(O0_argslot, G3_method_handle, O1_scratch);
1170         __ ld_ptr(__ argument_address(O0_argslot, O0_argslot, -1), G3_method_handle);
1171         __ null_check(G3_method_handle);
1172         __ verify_oop(G3_method_handle);
1173       }
1174       __ jump_indirect_to(G5_method_fie, O1_scratch);
1175       __ delayed()->nop();
1176     }


src/cpu/sparc/vm/methodHandles_sparc.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File