comparison src/cpu/sparc/vm/methodHandles_sparc.cpp @ 1849:5beba6174298

6987555: JSR 292 unboxing to a boolean value fails on big-endian SPARC Reviewed-by: never, jrose
author twisti
date Wed, 13 Oct 2010 01:19:43 -0700
parents d55217dc206f
children 7aff5786cc02
comparison
equal deleted inserted replaced
1847:a932f331ef90 1849:5beba6174298
25 #include "incls/_precompiled.incl" 25 #include "incls/_precompiled.incl"
26 #include "incls/_methodHandles_sparc.cpp.incl" 26 #include "incls/_methodHandles_sparc.cpp.incl"
27 27
28 #define __ _masm-> 28 #define __ _masm->
29 29
30 #ifdef PRODUCT
31 #define BLOCK_COMMENT(str) /* nothing */
32 #else
33 #define BLOCK_COMMENT(str) __ block_comment(str)
34 #endif
35
36 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
37
30 address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm, 38 address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm,
31 address interpreted_entry) { 39 address interpreted_entry) {
32 // Just before the actual machine code entry point, allocate space 40 // Just before the actual machine code entry point, allocate space
33 // for a MethodHandleEntry::Data record, so that we can manage everything 41 // for a MethodHandleEntry::Data record, so that we can manage everything
34 // from one base pointer. 42 // from one base pointer.
103 111
104 #ifdef ASSERT 112 #ifdef ASSERT
105 static void verify_argslot(MacroAssembler* _masm, Register argslot_reg, Register temp_reg, const char* error_message) { 113 static void verify_argslot(MacroAssembler* _masm, Register argslot_reg, Register temp_reg, const char* error_message) {
106 // Verify that argslot lies within (Gargs, FP]. 114 // Verify that argslot lies within (Gargs, FP].
107 Label L_ok, L_bad; 115 Label L_ok, L_bad;
116 BLOCK_COMMENT("{ verify_argslot");
108 #ifdef _LP64 117 #ifdef _LP64
109 __ add(FP, STACK_BIAS, temp_reg); 118 __ add(FP, STACK_BIAS, temp_reg);
110 __ cmp(argslot_reg, temp_reg); 119 __ cmp(argslot_reg, temp_reg);
111 #else 120 #else
112 __ cmp(argslot_reg, FP); 121 __ cmp(argslot_reg, FP);
117 __ brx(Assembler::lessEqualUnsigned, false, Assembler::pt, L_ok); 126 __ brx(Assembler::lessEqualUnsigned, false, Assembler::pt, L_ok);
118 __ delayed()->nop(); 127 __ delayed()->nop();
119 __ bind(L_bad); 128 __ bind(L_bad);
120 __ stop(error_message); 129 __ stop(error_message);
121 __ bind(L_ok); 130 __ bind(L_ok);
131 BLOCK_COMMENT("} verify_argslot");
122 } 132 }
123 #endif 133 #endif
124 134
125 135
126 // Helper to insert argument slots into the stack. 136 // Helper to insert argument slots into the stack.
173 // That is, copy [sp, argslot) downward by -size words. In pseudo-code: 183 // That is, copy [sp, argslot) downward by -size words. In pseudo-code:
174 // sp -= size; 184 // sp -= size;
175 // for (temp = sp + size; temp < argslot; temp++) 185 // for (temp = sp + size; temp < argslot; temp++)
176 // temp[-size] = temp[0] 186 // temp[-size] = temp[0]
177 // argslot -= size; 187 // argslot -= size;
188 BLOCK_COMMENT("insert_arg_slots {");
178 RegisterOrConstant offset = __ regcon_sll_ptr(arg_slots, LogBytesPerWord, temp3_reg); 189 RegisterOrConstant offset = __ regcon_sll_ptr(arg_slots, LogBytesPerWord, temp3_reg);
179 190
180 // Keep the stack pointer 2*wordSize aligned. 191 // Keep the stack pointer 2*wordSize aligned.
181 const int TwoWordAlignmentMask = right_n_bits(LogBytesPerWord + 1); 192 const int TwoWordAlignmentMask = right_n_bits(LogBytesPerWord + 1);
182 RegisterOrConstant masked_offset = __ regcon_andn_ptr(offset, TwoWordAlignmentMask, temp_reg); 193 RegisterOrConstant masked_offset = __ regcon_andn_ptr(offset, TwoWordAlignmentMask, temp_reg);
185 __ mov(Gargs, temp_reg); // source pointer for copy 196 __ mov(Gargs, temp_reg); // source pointer for copy
186 __ add(Gargs, offset, Gargs); 197 __ add(Gargs, offset, Gargs);
187 198
188 { 199 {
189 Label loop; 200 Label loop;
190 __ bind(loop); 201 __ BIND(loop);
191 // pull one word down each time through the loop 202 // pull one word down each time through the loop
192 __ ld_ptr(Address(temp_reg, 0), temp2_reg); 203 __ ld_ptr(Address(temp_reg, 0), temp2_reg);
193 __ st_ptr(temp2_reg, Address(temp_reg, offset)); 204 __ st_ptr(temp2_reg, Address(temp_reg, offset));
194 __ add(temp_reg, wordSize, temp_reg); 205 __ add(temp_reg, wordSize, temp_reg);
195 __ cmp(temp_reg, argslot_reg); 206 __ cmp(temp_reg, argslot_reg);
197 __ delayed()->nop(); // FILLME 208 __ delayed()->nop(); // FILLME
198 } 209 }
199 210
200 // Now move the argslot down, to point to the opened-up space. 211 // Now move the argslot down, to point to the opened-up space.
201 __ add(argslot_reg, offset, argslot_reg); 212 __ add(argslot_reg, offset, argslot_reg);
213 BLOCK_COMMENT("} insert_arg_slots");
202 } 214 }
203 215
204 216
205 // Helper to remove argument slots from the stack. 217 // Helper to remove argument slots from the stack.
206 // arg_slots must be a multiple of stack_move_unit() and >= 0 218 // arg_slots must be a multiple of stack_move_unit() and >= 0
233 assert(arg_slots.as_constant() >= 0, ""); 245 assert(arg_slots.as_constant() >= 0, "");
234 assert(arg_slots.as_constant() % -stack_move_unit() == 0, ""); 246 assert(arg_slots.as_constant() % -stack_move_unit() == 0, "");
235 } 247 }
236 #endif // ASSERT 248 #endif // ASSERT
237 249
250 BLOCK_COMMENT("remove_arg_slots {");
238 // Pull up everything shallower than argslot. 251 // Pull up everything shallower than argslot.
239 // Then remove the excess space on the stack. 252 // Then remove the excess space on the stack.
240 // The stacked return address gets pulled up with everything else. 253 // The stacked return address gets pulled up with everything else.
241 // That is, copy [sp, argslot) upward by size words. In pseudo-code: 254 // That is, copy [sp, argslot) upward by size words. In pseudo-code:
242 // for (temp = argslot-1; temp >= sp; --temp) 255 // for (temp = argslot-1; temp >= sp; --temp)
244 // argslot += size; 257 // argslot += size;
245 // sp += size; 258 // sp += size;
246 __ sub(argslot_reg, wordSize, temp_reg); // source pointer for copy 259 __ sub(argslot_reg, wordSize, temp_reg); // source pointer for copy
247 { 260 {
248 Label loop; 261 Label loop;
249 __ bind(loop); 262 __ BIND(loop);
250 // pull one word up each time through the loop 263 // pull one word up each time through the loop
251 __ ld_ptr(Address(temp_reg, 0), temp2_reg); 264 __ ld_ptr(Address(temp_reg, 0), temp2_reg);
252 __ st_ptr(temp2_reg, Address(temp_reg, offset)); 265 __ st_ptr(temp2_reg, Address(temp_reg, offset));
253 __ sub(temp_reg, wordSize, temp_reg); 266 __ sub(temp_reg, wordSize, temp_reg);
254 __ cmp(temp_reg, Gargs); 267 __ cmp(temp_reg, Gargs);
263 276
264 // Keep the stack pointer 2*wordSize aligned. 277 // Keep the stack pointer 2*wordSize aligned.
265 const int TwoWordAlignmentMask = right_n_bits(LogBytesPerWord + 1); 278 const int TwoWordAlignmentMask = right_n_bits(LogBytesPerWord + 1);
266 RegisterOrConstant masked_offset = __ regcon_andn_ptr(offset, TwoWordAlignmentMask, temp_reg); 279 RegisterOrConstant masked_offset = __ regcon_andn_ptr(offset, TwoWordAlignmentMask, temp_reg);
267 __ add(SP, masked_offset, SP); 280 __ add(SP, masked_offset, SP);
281 BLOCK_COMMENT("} remove_arg_slots");
268 } 282 }
269 283
270 284
271 #ifndef PRODUCT 285 #ifndef PRODUCT
272 extern "C" void print_method_handle(oop mh); 286 extern "C" void print_method_handle(oop mh);
273 void trace_method_handle_stub(const char* adaptername, 287 void trace_method_handle_stub(const char* adaptername,
274 oop mh) { 288 oopDesc* mh) {
275 #if 0
276 intptr_t* entry_sp,
277 intptr_t* saved_sp,
278 intptr_t* saved_bp) {
279 // called as a leaf from native code: do not block the JVM!
280 intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset];
281 intptr_t* base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset];
282 printf("MH %s mh="INTPTR_FORMAT" sp=("INTPTR_FORMAT"+"INTX_FORMAT") stack_size="INTX_FORMAT" bp="INTPTR_FORMAT"\n",
283 adaptername, (intptr_t)mh, (intptr_t)entry_sp, (intptr_t)(saved_sp - entry_sp), (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp);
284 if (last_sp != saved_sp)
285 printf("*** last_sp="INTPTR_FORMAT"\n", (intptr_t)last_sp);
286 #endif
287
288 printf("MH %s mh="INTPTR_FORMAT"\n", adaptername, (intptr_t) mh); 289 printf("MH %s mh="INTPTR_FORMAT"\n", adaptername, (intptr_t) mh);
289 print_method_handle(mh); 290 print_method_handle(mh);
291 }
292 void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
293 if (!TraceMethodHandles) return;
294 BLOCK_COMMENT("trace_method_handle {");
295 // save: Gargs, O5_savedSP
296 __ save_frame(16);
297 __ set((intptr_t) adaptername, O0);
298 __ mov(G3_method_handle, O1);
299 __ mov(G3_method_handle, L3);
300 __ mov(Gargs, L4);
301 __ mov(G5_method_type, L5);
302 __ call_VM_leaf(L7, CAST_FROM_FN_PTR(address, trace_method_handle_stub));
303
304 __ mov(L3, G3_method_handle);
305 __ mov(L4, Gargs);
306 __ mov(L5, G5_method_type);
307 __ restore();
308 BLOCK_COMMENT("} trace_method_handle");
290 } 309 }
291 #endif // PRODUCT 310 #endif // PRODUCT
292 311
293 // which conversion op types are implemented here? 312 // which conversion op types are implemented here?
294 int MethodHandles::adapter_conversion_ops_supported_mask() { 313 int MethodHandles::adapter_conversion_ops_supported_mask() {
347 return; 366 return;
348 } 367 }
349 368
350 address interp_entry = __ pc(); 369 address interp_entry = __ pc();
351 370
352 #ifndef PRODUCT 371 trace_method_handle(_masm, entry_name(ek));
353 if (TraceMethodHandles) {
354 // save: Gargs, O5_savedSP
355 __ save(SP, -16*wordSize, SP);
356 __ set((intptr_t) entry_name(ek), O0);
357 __ mov(G3_method_handle, O1);
358 __ call_VM_leaf(Lscratch, CAST_FROM_FN_PTR(address, trace_method_handle_stub));
359 __ restore(SP, 16*wordSize, SP);
360 }
361 #endif // PRODUCT
362 372
363 switch ((int) ek) { 373 switch ((int) ek) {
364 case _raise_exception: 374 case _raise_exception:
365 { 375 {
366 // Not a real MH entry, but rather shared code for raising an 376 // Not a real MH entry, but rather shared code for raising an