Mercurial > hg > truffle
comparison src/cpu/sparc/vm/templateTable_sparc.cpp @ 3852:fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
Reviewed-by: kvn, never, bdelsart
author | twisti |
---|---|
date | Tue, 16 Aug 2011 04:14:05 -0700 |
parents | 3d42f82cd811 |
children | baf763f388e6 |
comparison
equal
deleted
inserted
replaced
3851:95134e034042 | 3852:fdb992d83a87 |
---|---|
147 assert(_desc->uses_bcp(), "inconsistent uses_bcp information"); | 147 assert(_desc->uses_bcp(), "inconsistent uses_bcp information"); |
148 return Address(Lbcp, offset); | 148 return Address(Lbcp, offset); |
149 } | 149 } |
150 | 150 |
151 | 151 |
152 void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register Rbyte_code, | 152 void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg, |
153 Register Rscratch, | 153 Register temp_reg, bool load_bc_into_bc_reg/*=true*/, |
154 bool load_bc_into_scratch /*=true*/) { | 154 int byte_no) { |
155 // With sharing on, may need to test methodOop flag. | 155 // With sharing on, may need to test methodOop flag. |
156 if (!RewriteBytecodes) return; | 156 if (!RewriteBytecodes) return; |
157 if (load_bc_into_scratch) __ set(bc, Rbyte_code); | 157 Label L_patch_done; |
158 Label patch_done; | 158 |
159 switch (bc) { | |
160 case Bytecodes::_fast_aputfield: | |
161 case Bytecodes::_fast_bputfield: | |
162 case Bytecodes::_fast_cputfield: | |
163 case Bytecodes::_fast_dputfield: | |
164 case Bytecodes::_fast_fputfield: | |
165 case Bytecodes::_fast_iputfield: | |
166 case Bytecodes::_fast_lputfield: | |
167 case Bytecodes::_fast_sputfield: | |
168 { | |
169 // We skip bytecode quickening for putfield instructions when | |
170 // the put_code written to the constant pool cache is zero. | |
171 // This is required so that every execution of this instruction | |
172 // calls out to InterpreterRuntime::resolve_get_put to do | |
173 // additional, required work. | |
174 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); | |
175 assert(load_bc_into_bc_reg, "we use bc_reg as temp"); | |
176 __ get_cache_and_index_and_bytecode_at_bcp(bc_reg, temp_reg, temp_reg, byte_no, 1); | |
177 __ set(bc, bc_reg); | |
178 __ cmp_and_br_short(temp_reg, 0, Assembler::equal, Assembler::pn, L_patch_done); // don't patch | |
179 } | |
180 break; | |
181 default: | |
182 assert(byte_no == -1, "sanity"); | |
183 if (load_bc_into_bc_reg) { | |
184 __ set(bc, bc_reg); | |
185 } | |
186 } | |
187 | |
159 if (JvmtiExport::can_post_breakpoint()) { | 188 if (JvmtiExport::can_post_breakpoint()) { |
160 Label fast_patch; | 189 Label L_fast_patch; |
161 __ ldub(at_bcp(0), Rscratch); | 190 __ ldub(at_bcp(0), temp_reg); |
162 __ cmp_and_br_short(Rscratch, Bytecodes::_breakpoint, Assembler::notEqual, Assembler::pt, fast_patch); | 191 __ cmp_and_br_short(temp_reg, Bytecodes::_breakpoint, Assembler::notEqual, Assembler::pt, L_fast_patch); |
163 // perform the quickening, slowly, in the bowels of the breakpoint table | 192 // perform the quickening, slowly, in the bowels of the breakpoint table |
164 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), Lmethod, Lbcp, Rbyte_code); | 193 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), Lmethod, Lbcp, bc_reg); |
165 __ ba_short(patch_done); | 194 __ ba_short(L_patch_done); |
166 __ bind(fast_patch); | 195 __ bind(L_fast_patch); |
167 } | 196 } |
197 | |
168 #ifdef ASSERT | 198 #ifdef ASSERT |
169 Bytecodes::Code orig_bytecode = Bytecodes::java_code(bc); | 199 Bytecodes::Code orig_bytecode = Bytecodes::java_code(bc); |
170 Label okay; | 200 Label L_okay; |
171 __ ldub(at_bcp(0), Rscratch); | 201 __ ldub(at_bcp(0), temp_reg); |
172 __ cmp(Rscratch, orig_bytecode); | 202 __ cmp(temp_reg, orig_bytecode); |
173 __ br(Assembler::equal, false, Assembler::pt, okay); | 203 __ br(Assembler::equal, false, Assembler::pt, L_okay); |
174 __ delayed() ->cmp(Rscratch, Rbyte_code); | 204 __ delayed()->cmp(temp_reg, bc_reg); |
175 __ br(Assembler::equal, false, Assembler::pt, okay); | 205 __ br(Assembler::equal, false, Assembler::pt, L_okay); |
176 __ delayed()->nop(); | 206 __ delayed()->nop(); |
177 __ stop("Rewriting wrong bytecode location"); | 207 __ stop("patching the wrong bytecode"); |
178 __ bind(okay); | 208 __ bind(L_okay); |
179 #endif | 209 #endif |
180 __ stb(Rbyte_code, at_bcp(0)); | 210 |
181 __ bind(patch_done); | 211 // patch bytecode |
212 __ stb(bc_reg, at_bcp(0)); | |
213 __ bind(L_patch_done); | |
182 } | 214 } |
183 | 215 |
184 //---------------------------------------------------------------------------------------------------- | 216 //---------------------------------------------------------------------------------------------------- |
185 // Individual instructions | 217 // Individual instructions |
186 | 218 |
2059 Register index, | 2091 Register index, |
2060 size_t index_size) { | 2092 size_t index_size) { |
2061 // Depends on cpCacheOop layout! | 2093 // Depends on cpCacheOop layout! |
2062 Label resolved; | 2094 Label resolved; |
2063 | 2095 |
2064 __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size); | |
2065 if (byte_no == f1_oop) { | 2096 if (byte_no == f1_oop) { |
2066 // We are resolved if the f1 field contains a non-null object (CallSite, etc.) | 2097 // We are resolved if the f1 field contains a non-null object (CallSite, etc.) |
2067 // This kind of CP cache entry does not need to match the flags byte, because | 2098 // This kind of CP cache entry does not need to match the flags byte, because |
2068 // there is a 1-1 relation between bytecode type and CP entry type. | 2099 // there is a 1-1 relation between bytecode type and CP entry type. |
2069 assert_different_registers(result, Rcache); | 2100 assert_different_registers(result, Rcache); |
2101 __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size); | |
2070 __ ld_ptr(Rcache, constantPoolCacheOopDesc::base_offset() + | 2102 __ ld_ptr(Rcache, constantPoolCacheOopDesc::base_offset() + |
2071 ConstantPoolCacheEntry::f1_offset(), result); | 2103 ConstantPoolCacheEntry::f1_offset(), result); |
2072 __ tst(result); | 2104 __ tst(result); |
2073 __ br(Assembler::notEqual, false, Assembler::pt, resolved); | 2105 __ br(Assembler::notEqual, false, Assembler::pt, resolved); |
2074 __ delayed()->set((int)bytecode(), O1); | 2106 __ delayed()->set((int)bytecode(), O1); |
2075 } else { | 2107 } else { |
2076 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); | 2108 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); |
2077 assert(result == noreg, ""); //else change code for setting result | 2109 assert(result == noreg, ""); //else change code for setting result |
2078 const int shift_count = (1 + byte_no)*BitsPerByte; | 2110 __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, Lbyte_code, byte_no, 1, index_size); |
2079 | 2111 __ cmp(Lbyte_code, (int) bytecode()); // have we resolved this bytecode? |
2080 __ ld_ptr(Rcache, constantPoolCacheOopDesc::base_offset() + | 2112 __ br(Assembler::equal, false, Assembler::pt, resolved); |
2081 ConstantPoolCacheEntry::indices_offset(), Lbyte_code); | |
2082 | |
2083 __ srl( Lbyte_code, shift_count, Lbyte_code ); | |
2084 __ and3( Lbyte_code, 0xFF, Lbyte_code ); | |
2085 __ cmp( Lbyte_code, (int)bytecode()); | |
2086 __ br( Assembler::equal, false, Assembler::pt, resolved); | |
2087 __ delayed()->set((int)bytecode(), O1); | 2113 __ delayed()->set((int)bytecode(), O1); |
2088 } | 2114 } |
2089 | 2115 |
2090 address entry; | 2116 address entry; |
2091 switch (bytecode()) { | 2117 switch (bytecode()) { |
2616 // compute field type | 2642 // compute field type |
2617 Label notInt, notShort, notChar, notObj, notByte, notLong, notFloat; | 2643 Label notInt, notShort, notChar, notObj, notByte, notLong, notFloat; |
2618 | 2644 |
2619 if (is_static) { | 2645 if (is_static) { |
2620 // putstatic with object type most likely, check that first | 2646 // putstatic with object type most likely, check that first |
2621 __ cmp(Rflags, atos ); | 2647 __ cmp(Rflags, atos); |
2622 __ br(Assembler::notEqual, false, Assembler::pt, notObj); | 2648 __ br(Assembler::notEqual, false, Assembler::pt, notObj); |
2623 __ delayed() ->cmp(Rflags, itos ); | 2649 __ delayed()->cmp(Rflags, itos); |
2624 | 2650 |
2625 // atos | 2651 // atos |
2626 __ pop_ptr(); | 2652 { |
2627 __ verify_oop(Otos_i); | 2653 __ pop_ptr(); |
2628 | 2654 __ verify_oop(Otos_i); |
2629 do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false); | 2655 do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false); |
2630 | 2656 __ ba(checkVolatile); |
2657 __ delayed()->tst(Lscratch); | |
2658 } | |
2659 | |
2660 __ bind(notObj); | |
2661 // cmp(Rflags, itos); | |
2662 __ br(Assembler::notEqual, false, Assembler::pt, notInt); | |
2663 __ delayed()->cmp(Rflags, btos); | |
2664 | |
2665 // itos | |
2666 { | |
2667 __ pop_i(); | |
2668 __ st(Otos_i, Rclass, Roffset); | |
2669 __ ba(checkVolatile); | |
2670 __ delayed()->tst(Lscratch); | |
2671 } | |
2672 | |
2673 __ bind(notInt); | |
2674 } else { | |
2675 // putfield with int type most likely, check that first | |
2676 __ cmp(Rflags, itos); | |
2677 __ br(Assembler::notEqual, false, Assembler::pt, notInt); | |
2678 __ delayed()->cmp(Rflags, atos); | |
2679 | |
2680 // itos | |
2681 { | |
2682 __ pop_i(); | |
2683 pop_and_check_object(Rclass); | |
2684 __ st(Otos_i, Rclass, Roffset); | |
2685 patch_bytecode(Bytecodes::_fast_iputfield, G3_scratch, G4_scratch, true, byte_no); | |
2686 __ ba(checkVolatile); | |
2687 __ delayed()->tst(Lscratch); | |
2688 } | |
2689 | |
2690 __ bind(notInt); | |
2691 // cmp(Rflags, atos); | |
2692 __ br(Assembler::notEqual, false, Assembler::pt, notObj); | |
2693 __ delayed()->cmp(Rflags, btos); | |
2694 | |
2695 // atos | |
2696 { | |
2697 __ pop_ptr(); | |
2698 pop_and_check_object(Rclass); | |
2699 __ verify_oop(Otos_i); | |
2700 do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false); | |
2701 patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch, true, byte_no); | |
2702 __ ba(checkVolatile); | |
2703 __ delayed()->tst(Lscratch); | |
2704 } | |
2705 | |
2706 __ bind(notObj); | |
2707 } | |
2708 | |
2709 // cmp(Rflags, btos); | |
2710 __ br(Assembler::notEqual, false, Assembler::pt, notByte); | |
2711 __ delayed()->cmp(Rflags, ltos); | |
2712 | |
2713 // btos | |
2714 { | |
2715 __ pop_i(); | |
2716 if (!is_static) pop_and_check_object(Rclass); | |
2717 __ stb(Otos_i, Rclass, Roffset); | |
2718 if (!is_static) { | |
2719 patch_bytecode(Bytecodes::_fast_bputfield, G3_scratch, G4_scratch, true, byte_no); | |
2720 } | |
2631 __ ba(checkVolatile); | 2721 __ ba(checkVolatile); |
2632 __ delayed()->tst(Lscratch); | 2722 __ delayed()->tst(Lscratch); |
2633 | 2723 } |
2634 __ bind(notObj); | 2724 |
2635 | 2725 __ bind(notByte); |
2636 // cmp(Rflags, itos ); | 2726 // cmp(Rflags, ltos); |
2637 __ br(Assembler::notEqual, false, Assembler::pt, notInt); | 2727 __ br(Assembler::notEqual, false, Assembler::pt, notLong); |
2638 __ delayed() ->cmp(Rflags, btos ); | 2728 __ delayed()->cmp(Rflags, ctos); |
2639 | 2729 |
2640 // itos | 2730 // ltos |
2641 __ pop_i(); | 2731 { |
2642 __ st(Otos_i, Rclass, Roffset); | 2732 __ pop_l(); |
2733 if (!is_static) pop_and_check_object(Rclass); | |
2734 __ st_long(Otos_l, Rclass, Roffset); | |
2735 if (!is_static) { | |
2736 patch_bytecode(Bytecodes::_fast_lputfield, G3_scratch, G4_scratch, true, byte_no); | |
2737 } | |
2643 __ ba(checkVolatile); | 2738 __ ba(checkVolatile); |
2644 __ delayed()->tst(Lscratch); | 2739 __ delayed()->tst(Lscratch); |
2645 | 2740 } |
2646 __ bind(notInt); | 2741 |
2647 | 2742 __ bind(notLong); |
2648 } else { | 2743 // cmp(Rflags, ctos); |
2649 // putfield with int type most likely, check that first | 2744 __ br(Assembler::notEqual, false, Assembler::pt, notChar); |
2650 __ cmp(Rflags, itos ); | 2745 __ delayed()->cmp(Rflags, stos); |
2651 __ br(Assembler::notEqual, false, Assembler::pt, notInt); | 2746 |
2652 __ delayed() ->cmp(Rflags, atos ); | 2747 // ctos (char) |
2653 | 2748 { |
2654 // itos | |
2655 __ pop_i(); | 2749 __ pop_i(); |
2656 pop_and_check_object(Rclass); | 2750 if (!is_static) pop_and_check_object(Rclass); |
2657 __ st(Otos_i, Rclass, Roffset); | 2751 __ sth(Otos_i, Rclass, Roffset); |
2658 patch_bytecode(Bytecodes::_fast_iputfield, G3_scratch, G4_scratch); | 2752 if (!is_static) { |
2753 patch_bytecode(Bytecodes::_fast_cputfield, G3_scratch, G4_scratch, true, byte_no); | |
2754 } | |
2659 __ ba(checkVolatile); | 2755 __ ba(checkVolatile); |
2660 __ delayed()->tst(Lscratch); | 2756 __ delayed()->tst(Lscratch); |
2661 | 2757 } |
2662 __ bind(notInt); | 2758 |
2663 // cmp(Rflags, atos ); | 2759 __ bind(notChar); |
2664 __ br(Assembler::notEqual, false, Assembler::pt, notObj); | 2760 // cmp(Rflags, stos); |
2665 __ delayed() ->cmp(Rflags, btos ); | 2761 __ br(Assembler::notEqual, false, Assembler::pt, notShort); |
2666 | 2762 __ delayed()->cmp(Rflags, ftos); |
2667 // atos | 2763 |
2668 __ pop_ptr(); | 2764 // stos (short) |
2669 pop_and_check_object(Rclass); | 2765 { |
2670 __ verify_oop(Otos_i); | 2766 __ pop_i(); |
2671 | 2767 if (!is_static) pop_and_check_object(Rclass); |
2672 do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false); | 2768 __ sth(Otos_i, Rclass, Roffset); |
2673 | 2769 if (!is_static) { |
2674 patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch); | 2770 patch_bytecode(Bytecodes::_fast_sputfield, G3_scratch, G4_scratch, true, byte_no); |
2771 } | |
2675 __ ba(checkVolatile); | 2772 __ ba(checkVolatile); |
2676 __ delayed()->tst(Lscratch); | 2773 __ delayed()->tst(Lscratch); |
2677 | 2774 } |
2678 __ bind(notObj); | |
2679 } | |
2680 | |
2681 // cmp(Rflags, btos ); | |
2682 __ br(Assembler::notEqual, false, Assembler::pt, notByte); | |
2683 __ delayed() ->cmp(Rflags, ltos ); | |
2684 | |
2685 // btos | |
2686 __ pop_i(); | |
2687 if (!is_static) pop_and_check_object(Rclass); | |
2688 __ stb(Otos_i, Rclass, Roffset); | |
2689 if (!is_static) { | |
2690 patch_bytecode(Bytecodes::_fast_bputfield, G3_scratch, G4_scratch); | |
2691 } | |
2692 __ ba(checkVolatile); | |
2693 __ delayed()->tst(Lscratch); | |
2694 | |
2695 __ bind(notByte); | |
2696 | |
2697 // cmp(Rflags, ltos ); | |
2698 __ br(Assembler::notEqual, false, Assembler::pt, notLong); | |
2699 __ delayed() ->cmp(Rflags, ctos ); | |
2700 | |
2701 // ltos | |
2702 __ pop_l(); | |
2703 if (!is_static) pop_and_check_object(Rclass); | |
2704 __ st_long(Otos_l, Rclass, Roffset); | |
2705 if (!is_static) { | |
2706 patch_bytecode(Bytecodes::_fast_lputfield, G3_scratch, G4_scratch); | |
2707 } | |
2708 __ ba(checkVolatile); | |
2709 __ delayed()->tst(Lscratch); | |
2710 | |
2711 __ bind(notLong); | |
2712 | |
2713 // cmp(Rflags, ctos ); | |
2714 __ br(Assembler::notEqual, false, Assembler::pt, notChar); | |
2715 __ delayed() ->cmp(Rflags, stos ); | |
2716 | |
2717 // ctos (char) | |
2718 __ pop_i(); | |
2719 if (!is_static) pop_and_check_object(Rclass); | |
2720 __ sth(Otos_i, Rclass, Roffset); | |
2721 if (!is_static) { | |
2722 patch_bytecode(Bytecodes::_fast_cputfield, G3_scratch, G4_scratch); | |
2723 } | |
2724 __ ba(checkVolatile); | |
2725 __ delayed()->tst(Lscratch); | |
2726 | |
2727 __ bind(notChar); | |
2728 // cmp(Rflags, stos ); | |
2729 __ br(Assembler::notEqual, false, Assembler::pt, notShort); | |
2730 __ delayed() ->cmp(Rflags, ftos ); | |
2731 | |
2732 // stos (char) | |
2733 __ pop_i(); | |
2734 if (!is_static) pop_and_check_object(Rclass); | |
2735 __ sth(Otos_i, Rclass, Roffset); | |
2736 if (!is_static) { | |
2737 patch_bytecode(Bytecodes::_fast_sputfield, G3_scratch, G4_scratch); | |
2738 } | |
2739 __ ba(checkVolatile); | |
2740 __ delayed()->tst(Lscratch); | |
2741 | 2775 |
2742 __ bind(notShort); | 2776 __ bind(notShort); |
2743 // cmp(Rflags, ftos ); | 2777 // cmp(Rflags, ftos); |
2744 __ br(Assembler::notZero, false, Assembler::pt, notFloat); | 2778 __ br(Assembler::notZero, false, Assembler::pt, notFloat); |
2745 __ delayed()->nop(); | 2779 __ delayed()->nop(); |
2746 | 2780 |
2747 // ftos | 2781 // ftos |
2748 __ pop_f(); | 2782 { |
2749 if (!is_static) pop_and_check_object(Rclass); | 2783 __ pop_f(); |
2750 __ stf(FloatRegisterImpl::S, Ftos_f, Rclass, Roffset); | 2784 if (!is_static) pop_and_check_object(Rclass); |
2751 if (!is_static) { | 2785 __ stf(FloatRegisterImpl::S, Ftos_f, Rclass, Roffset); |
2752 patch_bytecode(Bytecodes::_fast_fputfield, G3_scratch, G4_scratch); | 2786 if (!is_static) { |
2753 } | 2787 patch_bytecode(Bytecodes::_fast_fputfield, G3_scratch, G4_scratch, true, byte_no); |
2754 __ ba(checkVolatile); | 2788 } |
2755 __ delayed()->tst(Lscratch); | 2789 __ ba(checkVolatile); |
2790 __ delayed()->tst(Lscratch); | |
2791 } | |
2756 | 2792 |
2757 __ bind(notFloat); | 2793 __ bind(notFloat); |
2758 | 2794 |
2759 // dtos | 2795 // dtos |
2760 __ pop_d(); | 2796 { |
2761 if (!is_static) pop_and_check_object(Rclass); | 2797 __ pop_d(); |
2762 __ stf(FloatRegisterImpl::D, Ftos_d, Rclass, Roffset); | 2798 if (!is_static) pop_and_check_object(Rclass); |
2763 if (!is_static) { | 2799 __ stf(FloatRegisterImpl::D, Ftos_d, Rclass, Roffset); |
2764 patch_bytecode(Bytecodes::_fast_dputfield, G3_scratch, G4_scratch); | 2800 if (!is_static) { |
2801 patch_bytecode(Bytecodes::_fast_dputfield, G3_scratch, G4_scratch, true, byte_no); | |
2802 } | |
2765 } | 2803 } |
2766 | 2804 |
2767 __ bind(checkVolatile); | 2805 __ bind(checkVolatile); |
2768 __ tst(Lscratch); | 2806 __ tst(Lscratch); |
2769 | 2807 |