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 |