hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp
changeset 11571 23f825a42a85
parent 11565 713a0398ca58
child 13391 30245956af37
equal deleted inserted replaced
11570:25f3e9348905 11571:23f825a42a85
   175 
   175 
   176   (*bounce_offset) = __ pc() - start;
   176   (*bounce_offset) = __ pc() - start;
   177   BLOCK_COMMENT("ricochet_blob.bounce");
   177   BLOCK_COMMENT("ricochet_blob.bounce");
   178 
   178 
   179   if (VerifyMethodHandles)  RicochetFrame::verify_clean(_masm);
   179   if (VerifyMethodHandles)  RicochetFrame::verify_clean(_masm);
   180   trace_method_handle(_masm, "ricochet_blob.bounce");
   180   trace_method_handle(_masm, "return/ricochet_blob.bounce");
   181 
   181 
   182   __ JMP(L1_continuation, 0);
   182   __ JMP(L1_continuation, 0);
   183   __ delayed()->nop();
   183   __ delayed()->nop();
   184   __ illtrap(0);
   184   __ illtrap(0);
   185 
   185 
   266     __ mov(L2_saved_target, recv_reg);
   266     __ mov(L2_saved_target, recv_reg);
   267   BLOCK_COMMENT("} end_ricochet_frame");
   267   BLOCK_COMMENT("} end_ricochet_frame");
   268 }
   268 }
   269 
   269 
   270 // Emit code to verify that FP is pointing at a valid ricochet frame.
   270 // Emit code to verify that FP is pointing at a valid ricochet frame.
   271 #ifdef ASSERT
   271 #ifndef PRODUCT
   272 enum {
   272 enum {
   273   ARG_LIMIT = 255, SLOP = 45,
   273   ARG_LIMIT = 255, SLOP = 45,
   274   // use this parameter for checking for garbage stack movements:
   274   // use this parameter for checking for garbage stack movements:
   275   UNREASONABLE_STACK_MOVE = (ARG_LIMIT + SLOP)
   275   UNREASONABLE_STACK_MOVE = (ARG_LIMIT + SLOP)
   276   // the slop defends against false alarms due to fencepost errors
   276   // the slop defends against false alarms due to fencepost errors
   277 };
   277 };
   278 
   278 #endif
       
   279 
       
   280 #ifdef ASSERT
   279 void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) {
   281 void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) {
   280   // The stack should look like this:
   282   // The stack should look like this:
   281   //    ... keep1 | dest=42 | keep2 | magic | handler | magic | recursive args | [RF]
   283   //    ... keep1 | dest=42 | keep2 | magic | handler | magic | recursive args | [RF]
   282   // Check various invariants.
   284   // Check various invariants.
   283 
   285 
   998     ShouldNotReachHere();
  1000     ShouldNotReachHere();
   999   }
  1001   }
  1000   BLOCK_COMMENT("} move_return_value");
  1002   BLOCK_COMMENT("} move_return_value");
  1001 }
  1003 }
  1002 
  1004 
  1003 #ifdef ASSERT
  1005 #ifndef PRODUCT
  1004 void MethodHandles::RicochetFrame::describe(const frame* fr, FrameValues& values, int frame_no)  {
  1006 void MethodHandles::RicochetFrame::describe(const frame* fr, FrameValues& values, int frame_no)  {
  1005     RicochetFrame* rf = new RicochetFrame(*fr);
  1007     RicochetFrame* rf = new RicochetFrame(*fr);
  1006 
  1008 
  1007     // ricochet slots (kept in registers for sparc)
  1009     // ricochet slots (kept in registers for sparc)
  1008     values.describe(frame_no, rf->register_addr(I5_savedSP), err_msg("exact_sender_sp reg for #%d", frame_no));
  1010     values.describe(frame_no, rf->register_addr(I5_savedSP), err_msg("exact_sender_sp reg for #%d", frame_no));
  1020 
  1022 
  1021 #ifndef PRODUCT
  1023 #ifndef PRODUCT
  1022 extern "C" void print_method_handle(oop mh);
  1024 extern "C" void print_method_handle(oop mh);
  1023 void trace_method_handle_stub(const char* adaptername,
  1025 void trace_method_handle_stub(const char* adaptername,
  1024                               oopDesc* mh,
  1026                               oopDesc* mh,
  1025                               intptr_t* saved_sp) {
  1027                               intptr_t* saved_sp,
       
  1028                               intptr_t* args,
       
  1029                               intptr_t* tracing_fp) {
  1026   bool has_mh = (strstr(adaptername, "return/") == NULL);  // return adapters don't have mh
  1030   bool has_mh = (strstr(adaptername, "return/") == NULL);  // return adapters don't have mh
  1027   tty->print_cr("MH %s mh="INTPTR_FORMAT " saved_sp=" INTPTR_FORMAT, adaptername, (intptr_t) mh, saved_sp);
  1031 
  1028   if (has_mh)
  1032   tty->print_cr("MH %s mh="INTPTR_FORMAT " saved_sp=" INTPTR_FORMAT " args=" INTPTR_FORMAT, adaptername, (intptr_t) mh, saved_sp, args);
       
  1033 
       
  1034   if (Verbose) {
       
  1035     // dumping last frame with frame::describe
       
  1036 
       
  1037     JavaThread* p = JavaThread::active();
       
  1038 
       
  1039     ResourceMark rm;
       
  1040     PRESERVE_EXCEPTION_MARK; // may not be needed by safer and unexpensive here
       
  1041     FrameValues values;
       
  1042 
       
  1043     // Note: We want to allow trace_method_handle from any call site.
       
  1044     // While trace_method_handle creates a frame, it may be entered
       
  1045     // without a valid return PC in O7 (e.g. not just after a call).
       
  1046     // Walking that frame could lead to failures due to that invalid PC.
       
  1047     // => carefully detect that frame when doing the stack walking
       
  1048 
       
  1049     // walk up to the right frame using the "tracing_fp" argument
       
  1050     intptr_t* cur_sp = StubRoutines::Sparc::flush_callers_register_windows_func()();
       
  1051     frame cur_frame(cur_sp, frame::unpatchable, NULL);
       
  1052 
       
  1053     while (cur_frame.fp() != (intptr_t *)(STACK_BIAS+(uintptr_t)tracing_fp)) {
       
  1054       cur_frame = os::get_sender_for_C_frame(&cur_frame);
       
  1055     }
       
  1056 
       
  1057     // safely create a frame and call frame::describe
       
  1058     intptr_t *dump_sp = cur_frame.sender_sp();
       
  1059     intptr_t *dump_fp = cur_frame.link();
       
  1060 
       
  1061     bool walkable = has_mh; // whether the traced frame shoud be walkable
       
  1062 
       
  1063     // the sender for cur_frame is the caller of trace_method_handle
       
  1064     if (walkable) {
       
  1065       // The previous definition of walkable may have to be refined
       
  1066       // if new call sites cause the next frame constructor to start
       
  1067       // failing. Alternatively, frame constructors could be
       
  1068       // modified to support the current or future non walkable
       
  1069       // frames (but this is more intrusive and is not considered as
       
  1070       // part of this RFE, which will instead use a simpler output).
       
  1071       frame dump_frame = frame(dump_sp,
       
  1072                                cur_frame.sp(), // younger_sp
       
  1073                                false); // no adaptation
       
  1074       dump_frame.describe(values, 1);
       
  1075     } else {
       
  1076       // Robust dump for frames which cannot be constructed from sp/younger_sp
       
  1077       // Add descriptions without building a Java frame to avoid issues
       
  1078       values.describe(-1, dump_fp, "fp for #1 <not parsed, cannot trust pc>");
       
  1079       values.describe(-1, dump_sp, "sp");
       
  1080     }
       
  1081 
       
  1082     bool has_args = has_mh; // whether Gargs is meaningful
       
  1083 
       
  1084     // mark args, if seems valid (may not be valid for some adapters)
       
  1085     if (has_args) {
       
  1086       if ((args >= dump_sp) && (args < dump_fp)) {
       
  1087         values.describe(-1, args, "*G4_args");
       
  1088       }
       
  1089     }
       
  1090 
       
  1091     // mark saved_sp, if seems valid (may not be valid for some adapters)
       
  1092     intptr_t *unbiased_sp = (intptr_t *)(STACK_BIAS+(uintptr_t)saved_sp);
       
  1093     if ((unbiased_sp >= dump_sp - UNREASONABLE_STACK_MOVE) && (unbiased_sp < dump_fp)) {
       
  1094       values.describe(-1, unbiased_sp, "*saved_sp+STACK_BIAS");
       
  1095     }
       
  1096 
       
  1097     // Note: the unextended_sp may not be correct
       
  1098     tty->print_cr("  stack layout:");
       
  1099     values.print(p);
       
  1100   }
       
  1101 
       
  1102   if (has_mh) {
  1029     print_method_handle(mh);
  1103     print_method_handle(mh);
  1030 }
  1104   }
       
  1105 }
       
  1106 
  1031 void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
  1107 void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
  1032   if (!TraceMethodHandles)  return;
  1108   if (!TraceMethodHandles)  return;
  1033   BLOCK_COMMENT("trace_method_handle {");
  1109   BLOCK_COMMENT("trace_method_handle {");
  1034   // save: Gargs, O5_savedSP
  1110   // save: Gargs, O5_savedSP
  1035   __ save_frame(16);
  1111   __ save_frame(16); // need space for saving required FPU state
       
  1112 
  1036   __ set((intptr_t) adaptername, O0);
  1113   __ set((intptr_t) adaptername, O0);
  1037   __ mov(G3_method_handle, O1);
  1114   __ mov(G3_method_handle, O1);
  1038   __ mov(I5_savedSP, O2);
  1115   __ mov(I5_savedSP, O2);
       
  1116   __ mov(Gargs, O3);
       
  1117   __ mov(I6, O4); // frame identifier for safe stack walking
       
  1118 
       
  1119   // Save scratched registers that might be needed. Robustness is more
       
  1120   // important than optimizing the saves for this debug only code.
       
  1121 
       
  1122   // save FP result, valid at some call sites (adapter_opt_return_float, ...)
       
  1123   Address d_save(FP, -sizeof(jdouble) + STACK_BIAS);
       
  1124   __ stf(FloatRegisterImpl::D, Ftos_d, d_save);
       
  1125   // Safely save all globals but G2 (handled by call_VM_leaf) and G7
       
  1126   // (OS reserved).
  1039   __ mov(G3_method_handle, L3);
  1127   __ mov(G3_method_handle, L3);
  1040   __ mov(Gargs, L4);
  1128   __ mov(Gargs, L4);
  1041   __ mov(G5_method_type, L5);
  1129   __ mov(G5_method_type, L5);
  1042   __ call_VM_leaf(L7, CAST_FROM_FN_PTR(address, trace_method_handle_stub));
  1130   __ mov(G6, L6);
       
  1131   __ mov(G1, L1);
       
  1132 
       
  1133   __ call_VM_leaf(L2 /* for G2 */, CAST_FROM_FN_PTR(address, trace_method_handle_stub));
  1043 
  1134 
  1044   __ mov(L3, G3_method_handle);
  1135   __ mov(L3, G3_method_handle);
  1045   __ mov(L4, Gargs);
  1136   __ mov(L4, Gargs);
  1046   __ mov(L5, G5_method_type);
  1137   __ mov(L5, G5_method_type);
       
  1138   __ mov(L6, G6);
       
  1139   __ mov(L1, G1);
       
  1140   __ ldf(FloatRegisterImpl::D, d_save, Ftos_d);
       
  1141 
  1047   __ restore();
  1142   __ restore();
  1048   BLOCK_COMMENT("} trace_method_handle");
  1143   BLOCK_COMMENT("} trace_method_handle");
  1049 }
  1144 }
  1050 #endif // PRODUCT
  1145 #endif // PRODUCT
  1051 
  1146 
  1266       } else {
  1361       } else {
  1267         Address prim_value_addr(O1_scratch, java_lang_boxing_object::value_offset_in_bytes(arg_type));
  1362         Address prim_value_addr(O1_scratch, java_lang_boxing_object::value_offset_in_bytes(arg_type));
  1268         move_typed_arg(_masm, arg_type, false,
  1363         move_typed_arg(_masm, arg_type, false,
  1269                        prim_value_addr,
  1364                        prim_value_addr,
  1270                        Address(O0_argslot, 0),
  1365                        Address(O0_argslot, 0),
  1271                        O2_scratch);  // must be an even register for !_LP64 long moves (uses O2/O3)
  1366                       O2_scratch);  // must be an even register for !_LP64 long moves (uses O2/O3)
  1272       }
  1367       }
  1273 
  1368 
  1274       if (direct_to_method) {
  1369       if (direct_to_method) {
  1275         __ load_heap_oop(G3_mh_vmtarget, G5_method);  // target is a methodOop
  1370         __ load_heap_oop(G3_mh_vmtarget, G5_method);  // target is a methodOop
  1276         jump_from_method_handle(_masm, G5_method, O1_scratch, O2_scratch);
  1371         jump_from_method_handle(_masm, G5_method, O1_scratch, O2_scratch);