comparison src/cpu/sparc/vm/methodHandles_sparc.cpp @ 4970:33df1aeaebbf

Merge with http://hg.openjdk.java.net/hsx/hsx24/hotspot/
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Mon, 27 Feb 2012 13:10:13 +0100
parents 04b9a2566eec 5dbed2f542ff
children 18a5539bf19b
comparison
equal deleted inserted replaced
4703:2cfb7fb2dce7 4970:33df1aeaebbf
1 /* 1 /*
2 * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
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
992 } 994 }
993 BLOCK_COMMENT("} move_return_value"); 995 BLOCK_COMMENT("} move_return_value");
994 } 996 }
995 997
996 #ifndef PRODUCT 998 #ifndef PRODUCT
999 void MethodHandles::RicochetFrame::describe(const frame* fr, FrameValues& values, int frame_no) {
1000 RicochetFrame* rf = new RicochetFrame(*fr);
1001
1002 // ricochet slots (kept in registers for sparc)
1003 values.describe(frame_no, rf->register_addr(I5_savedSP), err_msg("exact_sender_sp reg for #%d", frame_no));
1004 values.describe(frame_no, rf->register_addr(L5_conversion), err_msg("conversion reg for #%d", frame_no));
1005 values.describe(frame_no, rf->register_addr(L4_saved_args_base), err_msg("saved_args_base reg for #%d", frame_no));
1006 values.describe(frame_no, rf->register_addr(L3_saved_args_layout), err_msg("saved_args_layout reg for #%d", frame_no));
1007 values.describe(frame_no, rf->register_addr(L2_saved_target), err_msg("saved_target reg for #%d", frame_no));
1008 values.describe(frame_no, rf->register_addr(L1_continuation), err_msg("continuation reg for #%d", frame_no));
1009
1010 // relevant ricochet targets (in caller frame)
1011 values.describe(-1, rf->saved_args_base(), err_msg("*saved_args_base for #%d", frame_no));
1012 values.describe(-1, (intptr_t *)(STACK_BIAS+(uintptr_t)rf->exact_sender_sp()), err_msg("*exact_sender_sp+STACK_BIAS for #%d", frame_no));
1013 }
1014 #endif // ASSERT
1015
1016 #ifndef PRODUCT
997 extern "C" void print_method_handle(oop mh); 1017 extern "C" void print_method_handle(oop mh);
998 void trace_method_handle_stub(const char* adaptername, 1018 void trace_method_handle_stub(const char* adaptername,
999 oopDesc* mh, 1019 oopDesc* mh,
1000 intptr_t* saved_sp) { 1020 intptr_t* saved_sp,
1021 intptr_t* args,
1022 intptr_t* tracing_fp) {
1001 bool has_mh = (strstr(adaptername, "return/") == NULL); // return adapters don't have mh 1023 bool has_mh = (strstr(adaptername, "return/") == NULL); // return adapters don't have mh
1002 tty->print_cr("MH %s mh="INTPTR_FORMAT " saved_sp=" INTPTR_FORMAT, adaptername, (intptr_t) mh, saved_sp); 1024
1003 if (has_mh) 1025 tty->print_cr("MH %s mh="INTPTR_FORMAT " saved_sp=" INTPTR_FORMAT " args=" INTPTR_FORMAT, adaptername, (intptr_t) mh, saved_sp, args);
1026
1027 if (Verbose) {
1028 // dumping last frame with frame::describe
1029
1030 JavaThread* p = JavaThread::active();
1031
1032 ResourceMark rm;
1033 PRESERVE_EXCEPTION_MARK; // may not be needed by safer and unexpensive here
1034 FrameValues values;
1035
1036 // Note: We want to allow trace_method_handle from any call site.
1037 // While trace_method_handle creates a frame, it may be entered
1038 // without a valid return PC in O7 (e.g. not just after a call).
1039 // Walking that frame could lead to failures due to that invalid PC.
1040 // => carefully detect that frame when doing the stack walking
1041
1042 // walk up to the right frame using the "tracing_fp" argument
1043 intptr_t* cur_sp = StubRoutines::Sparc::flush_callers_register_windows_func()();
1044 frame cur_frame(cur_sp, frame::unpatchable, NULL);
1045
1046 while (cur_frame.fp() != (intptr_t *)(STACK_BIAS+(uintptr_t)tracing_fp)) {
1047 cur_frame = os::get_sender_for_C_frame(&cur_frame);
1048 }
1049
1050 // safely create a frame and call frame::describe
1051 intptr_t *dump_sp = cur_frame.sender_sp();
1052 intptr_t *dump_fp = cur_frame.link();
1053
1054 bool walkable = has_mh; // whether the traced frame shoud be walkable
1055
1056 // the sender for cur_frame is the caller of trace_method_handle
1057 if (walkable) {
1058 // The previous definition of walkable may have to be refined
1059 // if new call sites cause the next frame constructor to start
1060 // failing. Alternatively, frame constructors could be
1061 // modified to support the current or future non walkable
1062 // frames (but this is more intrusive and is not considered as
1063 // part of this RFE, which will instead use a simpler output).
1064 frame dump_frame = frame(dump_sp,
1065 cur_frame.sp(), // younger_sp
1066 false); // no adaptation
1067 dump_frame.describe(values, 1);
1068 } else {
1069 // Robust dump for frames which cannot be constructed from sp/younger_sp
1070 // Add descriptions without building a Java frame to avoid issues
1071 values.describe(-1, dump_fp, "fp for #1 <not parsed, cannot trust pc>");
1072 values.describe(-1, dump_sp, "sp");
1073 }
1074
1075 bool has_args = has_mh; // whether Gargs is meaningful
1076
1077 // mark args, if seems valid (may not be valid for some adapters)
1078 if (has_args) {
1079 if ((args >= dump_sp) && (args < dump_fp)) {
1080 values.describe(-1, args, "*G4_args");
1081 }
1082 }
1083
1084 // mark saved_sp, if seems valid (may not be valid for some adapters)
1085 intptr_t *unbiased_sp = (intptr_t *)(STACK_BIAS+(uintptr_t)saved_sp);
1086 if ((unbiased_sp >= dump_sp - UNREASONABLE_STACK_MOVE) && (unbiased_sp < dump_fp)) {
1087 values.describe(-1, unbiased_sp, "*saved_sp+STACK_BIAS");
1088 }
1089
1090 // Note: the unextended_sp may not be correct
1091 tty->print_cr(" stack layout:");
1092 values.print(p);
1093 }
1094
1095 if (has_mh) {
1004 print_method_handle(mh); 1096 print_method_handle(mh);
1005 } 1097 }
1098 }
1099
1006 void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { 1100 void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
1007 if (!TraceMethodHandles) return; 1101 if (!TraceMethodHandles) return;
1008 BLOCK_COMMENT("trace_method_handle {"); 1102 BLOCK_COMMENT("trace_method_handle {");
1009 // save: Gargs, O5_savedSP 1103 // save: Gargs, O5_savedSP
1010 __ save_frame(16); 1104 __ save_frame(16); // need space for saving required FPU state
1105
1011 __ set((intptr_t) adaptername, O0); 1106 __ set((intptr_t) adaptername, O0);
1012 __ mov(G3_method_handle, O1); 1107 __ mov(G3_method_handle, O1);
1013 __ mov(I5_savedSP, O2); 1108 __ mov(I5_savedSP, O2);
1109 __ mov(Gargs, O3);
1110 __ mov(I6, O4); // frame identifier for safe stack walking
1111
1112 // Save scratched registers that might be needed. Robustness is more
1113 // important than optimizing the saves for this debug only code.
1114
1115 // save FP result, valid at some call sites (adapter_opt_return_float, ...)
1116 Address d_save(FP, -sizeof(jdouble) + STACK_BIAS);
1117 __ stf(FloatRegisterImpl::D, Ftos_d, d_save);
1118 // Safely save all globals but G2 (handled by call_VM_leaf) and G7
1119 // (OS reserved).
1014 __ mov(G3_method_handle, L3); 1120 __ mov(G3_method_handle, L3);
1015 __ mov(Gargs, L4); 1121 __ mov(Gargs, L4);
1016 __ mov(G5_method_type, L5); 1122 __ mov(G5_method_type, L5);
1017 __ call_VM_leaf(L7, CAST_FROM_FN_PTR(address, trace_method_handle_stub)); 1123 __ mov(G6, L6);
1124 __ mov(G1, L1);
1125
1126 __ call_VM_leaf(L2 /* for G2 */, CAST_FROM_FN_PTR(address, trace_method_handle_stub));
1018 1127
1019 __ mov(L3, G3_method_handle); 1128 __ mov(L3, G3_method_handle);
1020 __ mov(L4, Gargs); 1129 __ mov(L4, Gargs);
1021 __ mov(L5, G5_method_type); 1130 __ mov(L5, G5_method_type);
1131 __ mov(L6, G6);
1132 __ mov(L1, G1);
1133 __ ldf(FloatRegisterImpl::D, d_save, Ftos_d);
1134
1022 __ restore(); 1135 __ restore();
1023 BLOCK_COMMENT("} trace_method_handle"); 1136 BLOCK_COMMENT("} trace_method_handle");
1024 } 1137 }
1025 #endif // PRODUCT 1138 #endif // PRODUCT
1026 1139
1036 |(1<<java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS) 1149 |(1<<java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS)
1037 |(1<<java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS) 1150 |(1<<java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS)
1038 |(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS) 1151 |(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS)
1039 // OP_COLLECT_ARGS is below... 1152 // OP_COLLECT_ARGS is below...
1040 |(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS) 1153 |(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS)
1041 |(!UseRicochetFrames ? 0 : 1154 |(
1042 java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() <= 0 ? 0 : 1155 java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() <= 0 ? 0 :
1043 ((1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF) 1156 ((1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF)
1044 |(1<<java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS) 1157 |(1<<java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS)
1045 |(1<<java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS) 1158 |(1<<java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS)
1046 ) 1159 )
1089 1202
1090 Address G3_amh_vmargslot( G3_method_handle, java_lang_invoke_AdapterMethodHandle::vmargslot_offset_in_bytes()); 1203 Address G3_amh_vmargslot( G3_method_handle, java_lang_invoke_AdapterMethodHandle::vmargslot_offset_in_bytes());
1091 Address G3_amh_argument ( G3_method_handle, java_lang_invoke_AdapterMethodHandle::argument_offset_in_bytes()); 1204 Address G3_amh_argument ( G3_method_handle, java_lang_invoke_AdapterMethodHandle::argument_offset_in_bytes());
1092 Address G3_amh_conversion(G3_method_handle, java_lang_invoke_AdapterMethodHandle::conversion_offset_in_bytes()); 1205 Address G3_amh_conversion(G3_method_handle, java_lang_invoke_AdapterMethodHandle::conversion_offset_in_bytes());
1093 1206
1094 const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes(); 1207 const int java_mirror_offset = in_bytes(Klass::java_mirror_offset());
1095 1208
1096 if (have_entry(ek)) { 1209 if (have_entry(ek)) {
1097 __ nop(); // empty stubs make SG sick 1210 __ nop(); // empty stubs make SG sick
1098 return; 1211 return;
1099 } 1212 }
1241 } else { 1354 } else {
1242 Address prim_value_addr(O1_scratch, java_lang_boxing_object::value_offset_in_bytes(arg_type)); 1355 Address prim_value_addr(O1_scratch, java_lang_boxing_object::value_offset_in_bytes(arg_type));
1243 move_typed_arg(_masm, arg_type, false, 1356 move_typed_arg(_masm, arg_type, false,
1244 prim_value_addr, 1357 prim_value_addr,
1245 Address(O0_argslot, 0), 1358 Address(O0_argslot, 0),
1246 O2_scratch); // must be an even register for !_LP64 long moves (uses O2/O3) 1359 O2_scratch); // must be an even register for !_LP64 long moves (uses O2/O3)
1247 } 1360 }
1248 1361
1249 if (direct_to_method) { 1362 if (direct_to_method) {
1250 __ load_heap_oop(G3_mh_vmtarget, G5_method); // target is a methodOop 1363 __ load_heap_oop(G3_mh_vmtarget, G5_method); // target is a methodOop
1251 jump_from_method_handle(_masm, G5_method, O1_scratch, O2_scratch); 1364 jump_from_method_handle(_masm, G5_method, O1_scratch, O2_scratch);