Mercurial > hg > truffle
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, |