comparison src/cpu/sparc/vm/assembler_sparc.cpp @ 6790:2cb2f30450c7

7196262: JSR 292: java/lang/invoke/PrivateInvokeTest.java fails on solaris-sparc Reviewed-by: kvn, jrose, bdelsart
author twisti
date Mon, 17 Sep 2012 12:57:58 -0700
parents da91efe96a93
children 8e47bac5643a
comparison
equal deleted inserted replaced
6749:a6fe94b9759f 6790:2cb2f30450c7
723 void MacroAssembler::jump(const AddressLiteral& addrlit, Register temp, int offset, const char* file, int line) { 723 void MacroAssembler::jump(const AddressLiteral& addrlit, Register temp, int offset, const char* file, int line) {
724 jumpl(addrlit, temp, G0, offset, file, line); 724 jumpl(addrlit, temp, G0, offset, file, line);
725 } 725 }
726 726
727 727
728 // Convert to C varargs format
729 void MacroAssembler::set_varargs( Argument inArg, Register d ) {
730 // spill register-resident args to their memory slots
731 // (SPARC calling convention requires callers to have already preallocated these)
732 // Note that the inArg might in fact be an outgoing argument,
733 // if a leaf routine or stub does some tricky argument shuffling.
734 // This routine must work even though one of the saved arguments
735 // is in the d register (e.g., set_varargs(Argument(0, false), O0)).
736 for (Argument savePtr = inArg;
737 savePtr.is_register();
738 savePtr = savePtr.successor()) {
739 st_ptr(savePtr.as_register(), savePtr.address_in_frame());
740 }
741 // return the address of the first memory slot
742 Address a = inArg.address_in_frame();
743 add(a.base(), a.disp(), d);
744 }
745
746 // Conditional breakpoint (for assertion checks in assembly code) 728 // Conditional breakpoint (for assertion checks in assembly code)
747 void MacroAssembler::breakpoint_trap(Condition c, CC cc) { 729 void MacroAssembler::breakpoint_trap(Condition c, CC cc) {
748 trap(c, cc, G0, ST_RESERVED_FOR_USER_0); 730 trap(c, cc, G0, ST_RESERVED_FOR_USER_0);
749 } 731 }
750 732
2941 Label& L_no_such_interface) { 2923 Label& L_no_such_interface) {
2942 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp); 2924 assert_different_registers(recv_klass, intf_klass, method_result, scan_temp);
2943 assert(itable_index.is_constant() || itable_index.as_register() == method_result, 2925 assert(itable_index.is_constant() || itable_index.as_register() == method_result,
2944 "caller must use same register for non-constant itable index as for method"); 2926 "caller must use same register for non-constant itable index as for method");
2945 2927
2928 Label L_no_such_interface_restore;
2929 bool did_save = false;
2930 if (scan_temp == noreg || sethi_temp == noreg) {
2931 Register recv_2 = recv_klass->is_global() ? recv_klass : L0;
2932 Register intf_2 = intf_klass->is_global() ? intf_klass : L1;
2933 assert(method_result->is_global(), "must be able to return value");
2934 scan_temp = L2;
2935 sethi_temp = L3;
2936 save_frame_and_mov(0, recv_klass, recv_2, intf_klass, intf_2);
2937 recv_klass = recv_2;
2938 intf_klass = intf_2;
2939 did_save = true;
2940 }
2941
2946 // Compute start of first itableOffsetEntry (which is at the end of the vtable) 2942 // Compute start of first itableOffsetEntry (which is at the end of the vtable)
2947 int vtable_base = InstanceKlass::vtable_start_offset() * wordSize; 2943 int vtable_base = InstanceKlass::vtable_start_offset() * wordSize;
2948 int scan_step = itableOffsetEntry::size() * wordSize; 2944 int scan_step = itableOffsetEntry::size() * wordSize;
2949 int vte_size = vtableEntry::size() * wordSize; 2945 int vte_size = vtableEntry::size() * wordSize;
2950 2946
2979 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) { 2975 // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
2980 // if (scan->interface() == intf) { 2976 // if (scan->interface() == intf) {
2981 // result = (klass + scan->offset() + itable_index); 2977 // result = (klass + scan->offset() + itable_index);
2982 // } 2978 // }
2983 // } 2979 // }
2984 Label search, found_method; 2980 Label L_search, L_found_method;
2985 2981
2986 for (int peel = 1; peel >= 0; peel--) { 2982 for (int peel = 1; peel >= 0; peel--) {
2987 // %%%% Could load both offset and interface in one ldx, if they were 2983 // %%%% Could load both offset and interface in one ldx, if they were
2988 // in the opposite order. This would save a load. 2984 // in the opposite order. This would save a load.
2989 ld_ptr(scan_temp, itableOffsetEntry::interface_offset_in_bytes(), method_result); 2985 ld_ptr(scan_temp, itableOffsetEntry::interface_offset_in_bytes(), method_result);
2990 2986
2991 // Check that this entry is non-null. A null entry means that 2987 // Check that this entry is non-null. A null entry means that
2992 // the receiver class doesn't implement the interface, and wasn't the 2988 // the receiver class doesn't implement the interface, and wasn't the
2993 // same as when the caller was compiled. 2989 // same as when the caller was compiled.
2994 bpr(Assembler::rc_z, false, Assembler::pn, method_result, L_no_such_interface); 2990 bpr(Assembler::rc_z, false, Assembler::pn, method_result, did_save ? L_no_such_interface_restore : L_no_such_interface);
2995 delayed()->cmp(method_result, intf_klass); 2991 delayed()->cmp(method_result, intf_klass);
2996 2992
2997 if (peel) { 2993 if (peel) {
2998 brx(Assembler::equal, false, Assembler::pt, found_method); 2994 brx(Assembler::equal, false, Assembler::pt, L_found_method);
2999 } else { 2995 } else {
3000 brx(Assembler::notEqual, false, Assembler::pn, search); 2996 brx(Assembler::notEqual, false, Assembler::pn, L_search);
3001 // (invert the test to fall through to found_method...) 2997 // (invert the test to fall through to found_method...)
3002 } 2998 }
3003 delayed()->add(scan_temp, scan_step, scan_temp); 2999 delayed()->add(scan_temp, scan_step, scan_temp);
3004 3000
3005 if (!peel) break; 3001 if (!peel) break;
3006 3002
3007 bind(search); 3003 bind(L_search);
3008 } 3004 }
3009 3005
3010 bind(found_method); 3006 bind(L_found_method);
3011 3007
3012 // Got a hit. 3008 // Got a hit.
3013 int ito_offset = itableOffsetEntry::offset_offset_in_bytes(); 3009 int ito_offset = itableOffsetEntry::offset_offset_in_bytes();
3014 // scan_temp[-scan_step] points to the vtable offset we need 3010 // scan_temp[-scan_step] points to the vtable offset we need
3015 ito_offset -= scan_step; 3011 ito_offset -= scan_step;
3016 lduw(scan_temp, ito_offset, scan_temp); 3012 lduw(scan_temp, ito_offset, scan_temp);
3017 ld_ptr(recv_klass, scan_temp, method_result); 3013 ld_ptr(recv_klass, scan_temp, method_result);
3014
3015 if (did_save) {
3016 Label L_done;
3017 ba(L_done);
3018 delayed()->restore();
3019
3020 bind(L_no_such_interface_restore);
3021 ba(L_no_such_interface);
3022 delayed()->restore();
3023
3024 bind(L_done);
3025 }
3018 } 3026 }
3019 3027
3020 3028
3021 // virtual method calling 3029 // virtual method calling
3022 void MacroAssembler::lookup_virtual_method(Register recv_klass, 3030 void MacroAssembler::lookup_virtual_method(Register recv_klass,