6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "interpreter/interpreter.hpp"
27 #include "interpreter/interpreterRuntime.hpp"
28 #include "interpreter/interp_masm.hpp"
29 #include "interpreter/templateTable.hpp"
30 #include "memory/universe.inline.hpp"
31 #include "oops/methodData.hpp"
32 #include "oops/objArrayKlass.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "prims/methodHandles.hpp"
35 #include "runtime/sharedRuntime.hpp"
36 #include "runtime/stubRoutines.hpp"
37 #include "runtime/synchronizer.hpp"
38 #include "utilities/macros.hpp"
39
40 #define __ _masm->
41
42 // Misc helpers
43
44 // Do an oop store like *(base + index + offset) = val
45 // index can be noreg,
46 static void do_oop_store(InterpreterMacroAssembler* _masm,
47 Register base,
48 Register index,
49 int offset,
50 Register val,
51 Register tmp,
52 BarrierSet::Name barrier,
53 bool precise) {
54 assert(tmp != val && tmp != base && tmp != index, "register collision");
55 assert(index == noreg || offset == 0, "only one offset");
56 switch (barrier) {
57 #if INCLUDE_ALL_GCS
58 case BarrierSet::G1SATBCTLogging:
59 {
60 // Load and record the previous value.
61 __ g1_write_barrier_pre(base, index, offset,
62 noreg /* pre_val */,
63 tmp, true /*preserve_o_regs*/);
64
65 // G1 barrier needs uncompressed oop for region cross check.
66 Register new_val = val;
67 if (UseCompressedOops && val != G0) {
68 new_val = tmp;
69 __ mov(val, new_val);
70 }
71
72 if (index == noreg ) {
73 assert(Assembler::is_simm13(offset), "fix this code");
74 __ store_heap_oop(val, base, offset);
75 } else {
76 __ store_heap_oop(val, base, index);
77 }
78
79 // No need for post barrier if storing NULL
80 if (val != G0) {
81 if (precise) {
82 if (index == noreg) {
83 __ add(base, offset, base);
84 } else {
85 __ add(base, index, base);
86 }
87 }
88 __ g1_write_barrier_post(base, new_val, tmp);
89 }
90 }
91 break;
92 #endif // INCLUDE_ALL_GCS
93 case BarrierSet::CardTableForRS:
94 case BarrierSet::CardTableExtension:
95 {
96 if (index == noreg ) {
97 assert(Assembler::is_simm13(offset), "fix this code");
98 __ store_heap_oop(val, base, offset);
99 } else {
100 __ store_heap_oop(val, base, index);
101 }
102 // No need for post barrier if storing NULL
103 if (val != G0) {
104 if (precise) {
105 if (index == noreg) {
106 __ add(base, offset, base);
107 } else {
108 __ add(base, index, base);
109 }
110 }
111 __ card_write_barrier_post(base, val, tmp);
112 }
113 }
114 break;
115 case BarrierSet::ModRef:
116 ShouldNotReachHere();
117 break;
118 default :
119 ShouldNotReachHere();
120
121 }
122 }
123
124
125 //----------------------------------------------------------------------------------------------------
126 // Platform-dependent initialization
127
128 void TemplateTable::pd_initialize() {
129 // (none)
130 }
131
132
133 //----------------------------------------------------------------------------------------------------
134 // Condition conversion
135 Assembler::Condition ccNot(TemplateTable::Condition cc) {
136 switch (cc) {
137 case TemplateTable::equal : return Assembler::notEqual;
138 case TemplateTable::not_equal : return Assembler::equal;
139 case TemplateTable::less : return Assembler::greaterEqual;
140 case TemplateTable::less_equal : return Assembler::greater;
141 case TemplateTable::greater : return Assembler::lessEqual;
142 case TemplateTable::greater_equal: return Assembler::less;
143 }
569 // O2: array
570 __ index_check(O2, Otos_i, LogBytesPerInt, G3_scratch, O3);
571 __ ldf(FloatRegisterImpl::S, O3, arrayOopDesc::base_offset_in_bytes(T_FLOAT), Ftos_f);
572 }
573
574
575 void TemplateTable::daload() {
576 transition(itos, dtos);
577 // Otos_i: index
578 // O2: array
579 __ index_check(O2, Otos_i, LogBytesPerLong, G3_scratch, O3);
580 __ ldf(FloatRegisterImpl::D, O3, arrayOopDesc::base_offset_in_bytes(T_DOUBLE), Ftos_d);
581 }
582
583
584 void TemplateTable::aaload() {
585 transition(itos, atos);
586 // Otos_i: index
587 // tos: array
588 __ index_check(O2, Otos_i, UseCompressedOops ? 2 : LogBytesPerWord, G3_scratch, O3);
589 __ load_heap_oop(O3, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Otos_i);
590 __ verify_oop(Otos_i);
591 }
592
593
594 void TemplateTable::baload() {
595 transition(itos, itos);
596 // Otos_i: index
597 // tos: array
598 __ index_check(O2, Otos_i, 0, G3_scratch, O3);
599 __ ldsb(O3, arrayOopDesc::base_offset_in_bytes(T_BYTE), Otos_i);
600 }
601
602
603 void TemplateTable::caload() {
604 transition(itos, itos);
605 // Otos_i: index
606 // tos: array
607 __ index_check(O2, Otos_i, LogBytesPerShort, G3_scratch, O3);
608 __ lduh(O3, arrayOopDesc::base_offset_in_bytes(T_CHAR), Otos_i);
609 }
869 assert(Otos_i == O0, "just checking");
870
871 // Otos_i: value
872 // O1: addr - offset
873 // O2: index
874 // O3: array
875 // O4: array element klass
876 // O5: value klass
877
878 // Address element(O1, 0, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
879
880 // Generate a fast subtype check. Branch to store_ok if no
881 // failure. Throw if failure.
882 __ gen_subtype_check( O5, O4, G3_scratch, G4_scratch, G1_scratch, store_ok );
883
884 // Not a subtype; so must throw exception
885 __ throw_if_not_x( Assembler::never, Interpreter::_throw_ArrayStoreException_entry, G3_scratch );
886
887 // Store is OK.
888 __ bind(store_ok);
889 do_oop_store(_masm, O1, noreg, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Otos_i, G3_scratch, _bs->kind(), true);
890
891 __ ba(done);
892 __ delayed()->inc(Lesp, 3* Interpreter::stackElementSize); // adj sp (pops array, index and value)
893
894 __ bind(is_null);
895 do_oop_store(_masm, O1, noreg, arrayOopDesc::base_offset_in_bytes(T_OBJECT), G0, G4_scratch, _bs->kind(), true);
896
897 __ profile_null_seen(G3_scratch);
898 __ inc(Lesp, 3* Interpreter::stackElementSize); // adj sp (pops array, index and value)
899 __ bind(done);
900 }
901
902
903 void TemplateTable::bastore() {
904 transition(itos, vtos);
905 __ pop_i(O2); // index
906 // Otos_i: val
907 // O2: index
908 // O3: array
909 __ index_check(O3, O2, 0, G3_scratch, O2);
910 // Need to check whether array is boolean or byte
911 // since both types share the bastore bytecode.
912 __ load_klass(O3, G4_scratch);
913 __ ld(G4_scratch, in_bytes(Klass::layout_helper_offset()), G4_scratch);
914 __ set(Klass::layout_helper_boolean_diffbit(), G3_scratch);
915 __ andcc(G3_scratch, G4_scratch, G0);
2506 }
2507 }
2508
2509 __ srl(Rflags, ConstantPoolCacheEntry::tos_state_shift, Rflags);
2510 // Make sure we don't need to mask Rflags after the above shift
2511 ConstantPoolCacheEntry::verify_tos_state_shift();
2512
2513 // compute field type
2514 Label notInt, notShort, notChar, notObj, notByte, notBool, notLong, notFloat;
2515
2516 if (is_static) {
2517 // putstatic with object type most likely, check that first
2518 __ cmp(Rflags, atos);
2519 __ br(Assembler::notEqual, false, Assembler::pt, notObj);
2520 __ delayed()->cmp(Rflags, itos);
2521
2522 // atos
2523 {
2524 __ pop_ptr();
2525 __ verify_oop(Otos_i);
2526 do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false);
2527 __ ba(checkVolatile);
2528 __ delayed()->tst(Lscratch);
2529 }
2530
2531 __ bind(notObj);
2532 // cmp(Rflags, itos);
2533 __ br(Assembler::notEqual, false, Assembler::pt, notInt);
2534 __ delayed()->cmp(Rflags, btos);
2535
2536 // itos
2537 {
2538 __ pop_i();
2539 __ st(Otos_i, Rclass, Roffset);
2540 __ ba(checkVolatile);
2541 __ delayed()->tst(Lscratch);
2542 }
2543
2544 __ bind(notInt);
2545 } else {
2546 // putfield with int type most likely, check that first
2551 // itos
2552 {
2553 __ pop_i();
2554 pop_and_check_object(Rclass);
2555 __ st(Otos_i, Rclass, Roffset);
2556 if (rc == may_rewrite) patch_bytecode(Bytecodes::_fast_iputfield, G3_scratch, G4_scratch, true, byte_no);
2557 __ ba(checkVolatile);
2558 __ delayed()->tst(Lscratch);
2559 }
2560
2561 __ bind(notInt);
2562 // cmp(Rflags, atos);
2563 __ br(Assembler::notEqual, false, Assembler::pt, notObj);
2564 __ delayed()->cmp(Rflags, btos);
2565
2566 // atos
2567 {
2568 __ pop_ptr();
2569 pop_and_check_object(Rclass);
2570 __ verify_oop(Otos_i);
2571 do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false);
2572 if (rc == may_rewrite) patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch, true, byte_no);
2573 __ ba(checkVolatile);
2574 __ delayed()->tst(Lscratch);
2575 }
2576
2577 __ bind(notObj);
2578 }
2579
2580 // cmp(Rflags, btos);
2581 __ br(Assembler::notEqual, false, Assembler::pt, notByte);
2582 __ delayed()->cmp(Rflags, ztos);
2583
2584 // btos
2585 {
2586 __ pop_i();
2587 if (!is_static) pop_and_check_object(Rclass);
2588 __ stb(Otos_i, Rclass, Roffset);
2589 if (!is_static && rc == may_rewrite) {
2590 patch_bytecode(Bytecodes::_fast_bputfield, G3_scratch, G4_scratch, true, byte_no);
2591 }
2732 }
2733 }
2734
2735 __ ld_ptr(Rcache, cp_base_offset + ConstantPoolCacheEntry::f2_offset(), Roffset);
2736 pop_and_check_object(Rclass);
2737
2738 switch (bytecode()) {
2739 case Bytecodes::_fast_zputfield: __ and3(Otos_i, 1, Otos_i); // fall through to bputfield
2740 case Bytecodes::_fast_bputfield: __ stb(Otos_i, Rclass, Roffset); break;
2741 case Bytecodes::_fast_cputfield: /* fall through */
2742 case Bytecodes::_fast_sputfield: __ sth(Otos_i, Rclass, Roffset); break;
2743 case Bytecodes::_fast_iputfield: __ st(Otos_i, Rclass, Roffset); break;
2744 case Bytecodes::_fast_lputfield: __ st_long(Otos_l, Rclass, Roffset); break;
2745 case Bytecodes::_fast_fputfield:
2746 __ stf(FloatRegisterImpl::S, Ftos_f, Rclass, Roffset);
2747 break;
2748 case Bytecodes::_fast_dputfield:
2749 __ stf(FloatRegisterImpl::D, Ftos_d, Rclass, Roffset);
2750 break;
2751 case Bytecodes::_fast_aputfield:
2752 do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false);
2753 break;
2754 default:
2755 ShouldNotReachHere();
2756 }
2757
2758 if (__ membar_has_effect(write_bits)) {
2759 __ cmp_and_br_short(Lscratch, 0, Assembler::equal, Assembler::pt, exit);
2760 volatile_barrier(Assembler::StoreLoad);
2761 __ bind(exit);
2762 }
2763 }
2764
2765 void TemplateTable::putfield(int byte_no) {
2766 putfield_or_static(byte_no, false);
2767 }
2768
2769 void TemplateTable::nofast_putfield(int byte_no) {
2770 putfield_or_static(byte_no, false, may_not_rewrite);
2771 }
2772
|
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/shared/barrierSetCodeGen.hpp"
27 #include "interpreter/interpreter.hpp"
28 #include "interpreter/interpreterRuntime.hpp"
29 #include "interpreter/interp_masm.hpp"
30 #include "interpreter/templateTable.hpp"
31 #include "memory/universe.inline.hpp"
32 #include "oops/methodData.hpp"
33 #include "oops/objArrayKlass.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "prims/methodHandles.hpp"
36 #include "runtime/sharedRuntime.hpp"
37 #include "runtime/stubRoutines.hpp"
38 #include "runtime/synchronizer.hpp"
39 #include "utilities/macros.hpp"
40
41 #define __ _masm->
42
43 // Misc helpers
44
45 // Do an oop store like *(base + index + offset) = val
46 // index can be noreg,
47 static void do_oop_store(InterpreterMacroAssembler* _masm,
48 Register base,
49 Register index,
50 int offset,
51 Register val,
52 Register tmp,
53 DecoratorSet decorators) {
54 assert(tmp != val && tmp != base && tmp != index, "register collision");
55 assert(index == noreg || offset == 0, "only one offset");
56 BarrierSetCodeGen *code_gen = Universe::heap()->barrier_set()->code_gen();
57 code_gen->store_at(_masm, decorators, T_OBJECT, base, index, offset, val, tmp);
58 }
59
60 static void do_oop_load(InterpreterMacroAssembler* _masm,
61 Register base,
62 Register index,
63 int offset,
64 Register dst,
65 Register tmp,
66 DecoratorSet decorators) {
67 assert(tmp != dst && tmp != base && tmp != index, "register collision");
68 assert(index == noreg || offset == 0, "only one offset");
69 BarrierSetCodeGen *code_gen = Universe::heap()->barrier_set()->code_gen();
70 code_gen->load_at(_masm, decorators, T_OBJECT, base, index, offset, dst, tmp);
71 }
72
73 //----------------------------------------------------------------------------------------------------
74 // Platform-dependent initialization
75
76 void TemplateTable::pd_initialize() {
77 // (none)
78 }
79
80
81 //----------------------------------------------------------------------------------------------------
82 // Condition conversion
83 Assembler::Condition ccNot(TemplateTable::Condition cc) {
84 switch (cc) {
85 case TemplateTable::equal : return Assembler::notEqual;
86 case TemplateTable::not_equal : return Assembler::equal;
87 case TemplateTable::less : return Assembler::greaterEqual;
88 case TemplateTable::less_equal : return Assembler::greater;
89 case TemplateTable::greater : return Assembler::lessEqual;
90 case TemplateTable::greater_equal: return Assembler::less;
91 }
517 // O2: array
518 __ index_check(O2, Otos_i, LogBytesPerInt, G3_scratch, O3);
519 __ ldf(FloatRegisterImpl::S, O3, arrayOopDesc::base_offset_in_bytes(T_FLOAT), Ftos_f);
520 }
521
522
523 void TemplateTable::daload() {
524 transition(itos, dtos);
525 // Otos_i: index
526 // O2: array
527 __ index_check(O2, Otos_i, LogBytesPerLong, G3_scratch, O3);
528 __ ldf(FloatRegisterImpl::D, O3, arrayOopDesc::base_offset_in_bytes(T_DOUBLE), Ftos_d);
529 }
530
531
532 void TemplateTable::aaload() {
533 transition(itos, atos);
534 // Otos_i: index
535 // tos: array
536 __ index_check(O2, Otos_i, UseCompressedOops ? 2 : LogBytesPerWord, G3_scratch, O3);
537 do_oop_load(_masm,
538 O3,
539 noreg,
540 arrayOopDesc::base_offset_in_bytes(T_OBJECT),
541 Otos_i,
542 G3_scratch,
543 ACCESS_ON_HEAP | ACCESS_ON_ARRAY);
544 __ verify_oop(Otos_i);
545 }
546
547
548 void TemplateTable::baload() {
549 transition(itos, itos);
550 // Otos_i: index
551 // tos: array
552 __ index_check(O2, Otos_i, 0, G3_scratch, O3);
553 __ ldsb(O3, arrayOopDesc::base_offset_in_bytes(T_BYTE), Otos_i);
554 }
555
556
557 void TemplateTable::caload() {
558 transition(itos, itos);
559 // Otos_i: index
560 // tos: array
561 __ index_check(O2, Otos_i, LogBytesPerShort, G3_scratch, O3);
562 __ lduh(O3, arrayOopDesc::base_offset_in_bytes(T_CHAR), Otos_i);
563 }
823 assert(Otos_i == O0, "just checking");
824
825 // Otos_i: value
826 // O1: addr - offset
827 // O2: index
828 // O3: array
829 // O4: array element klass
830 // O5: value klass
831
832 // Address element(O1, 0, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
833
834 // Generate a fast subtype check. Branch to store_ok if no
835 // failure. Throw if failure.
836 __ gen_subtype_check( O5, O4, G3_scratch, G4_scratch, G1_scratch, store_ok );
837
838 // Not a subtype; so must throw exception
839 __ throw_if_not_x( Assembler::never, Interpreter::_throw_ArrayStoreException_entry, G3_scratch );
840
841 // Store is OK.
842 __ bind(store_ok);
843 do_oop_store(_masm, O1, noreg, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Otos_i, G3_scratch, ACCESS_ON_HEAP | ACCESS_ON_ARRAY);
844
845 __ ba(done);
846 __ delayed()->inc(Lesp, 3* Interpreter::stackElementSize); // adj sp (pops array, index and value)
847
848 __ bind(is_null);
849 do_oop_store(_masm, O1, noreg, arrayOopDesc::base_offset_in_bytes(T_OBJECT), G0, G4_scratch, ACCESS_ON_HEAP | ACCESS_ON_ARRAY);
850
851 __ profile_null_seen(G3_scratch);
852 __ inc(Lesp, 3* Interpreter::stackElementSize); // adj sp (pops array, index and value)
853 __ bind(done);
854 }
855
856
857 void TemplateTable::bastore() {
858 transition(itos, vtos);
859 __ pop_i(O2); // index
860 // Otos_i: val
861 // O2: index
862 // O3: array
863 __ index_check(O3, O2, 0, G3_scratch, O2);
864 // Need to check whether array is boolean or byte
865 // since both types share the bastore bytecode.
866 __ load_klass(O3, G4_scratch);
867 __ ld(G4_scratch, in_bytes(Klass::layout_helper_offset()), G4_scratch);
868 __ set(Klass::layout_helper_boolean_diffbit(), G3_scratch);
869 __ andcc(G3_scratch, G4_scratch, G0);
2460 }
2461 }
2462
2463 __ srl(Rflags, ConstantPoolCacheEntry::tos_state_shift, Rflags);
2464 // Make sure we don't need to mask Rflags after the above shift
2465 ConstantPoolCacheEntry::verify_tos_state_shift();
2466
2467 // compute field type
2468 Label notInt, notShort, notChar, notObj, notByte, notBool, notLong, notFloat;
2469
2470 if (is_static) {
2471 // putstatic with object type most likely, check that first
2472 __ cmp(Rflags, atos);
2473 __ br(Assembler::notEqual, false, Assembler::pt, notObj);
2474 __ delayed()->cmp(Rflags, itos);
2475
2476 // atos
2477 {
2478 __ pop_ptr();
2479 __ verify_oop(Otos_i);
2480 do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, ACCESS_ON_HEAP);
2481 __ ba(checkVolatile);
2482 __ delayed()->tst(Lscratch);
2483 }
2484
2485 __ bind(notObj);
2486 // cmp(Rflags, itos);
2487 __ br(Assembler::notEqual, false, Assembler::pt, notInt);
2488 __ delayed()->cmp(Rflags, btos);
2489
2490 // itos
2491 {
2492 __ pop_i();
2493 __ st(Otos_i, Rclass, Roffset);
2494 __ ba(checkVolatile);
2495 __ delayed()->tst(Lscratch);
2496 }
2497
2498 __ bind(notInt);
2499 } else {
2500 // putfield with int type most likely, check that first
2505 // itos
2506 {
2507 __ pop_i();
2508 pop_and_check_object(Rclass);
2509 __ st(Otos_i, Rclass, Roffset);
2510 if (rc == may_rewrite) patch_bytecode(Bytecodes::_fast_iputfield, G3_scratch, G4_scratch, true, byte_no);
2511 __ ba(checkVolatile);
2512 __ delayed()->tst(Lscratch);
2513 }
2514
2515 __ bind(notInt);
2516 // cmp(Rflags, atos);
2517 __ br(Assembler::notEqual, false, Assembler::pt, notObj);
2518 __ delayed()->cmp(Rflags, btos);
2519
2520 // atos
2521 {
2522 __ pop_ptr();
2523 pop_and_check_object(Rclass);
2524 __ verify_oop(Otos_i);
2525 do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, ACCESS_ON_HEAP);
2526 if (rc == may_rewrite) patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch, true, byte_no);
2527 __ ba(checkVolatile);
2528 __ delayed()->tst(Lscratch);
2529 }
2530
2531 __ bind(notObj);
2532 }
2533
2534 // cmp(Rflags, btos);
2535 __ br(Assembler::notEqual, false, Assembler::pt, notByte);
2536 __ delayed()->cmp(Rflags, ztos);
2537
2538 // btos
2539 {
2540 __ pop_i();
2541 if (!is_static) pop_and_check_object(Rclass);
2542 __ stb(Otos_i, Rclass, Roffset);
2543 if (!is_static && rc == may_rewrite) {
2544 patch_bytecode(Bytecodes::_fast_bputfield, G3_scratch, G4_scratch, true, byte_no);
2545 }
2686 }
2687 }
2688
2689 __ ld_ptr(Rcache, cp_base_offset + ConstantPoolCacheEntry::f2_offset(), Roffset);
2690 pop_and_check_object(Rclass);
2691
2692 switch (bytecode()) {
2693 case Bytecodes::_fast_zputfield: __ and3(Otos_i, 1, Otos_i); // fall through to bputfield
2694 case Bytecodes::_fast_bputfield: __ stb(Otos_i, Rclass, Roffset); break;
2695 case Bytecodes::_fast_cputfield: /* fall through */
2696 case Bytecodes::_fast_sputfield: __ sth(Otos_i, Rclass, Roffset); break;
2697 case Bytecodes::_fast_iputfield: __ st(Otos_i, Rclass, Roffset); break;
2698 case Bytecodes::_fast_lputfield: __ st_long(Otos_l, Rclass, Roffset); break;
2699 case Bytecodes::_fast_fputfield:
2700 __ stf(FloatRegisterImpl::S, Ftos_f, Rclass, Roffset);
2701 break;
2702 case Bytecodes::_fast_dputfield:
2703 __ stf(FloatRegisterImpl::D, Ftos_d, Rclass, Roffset);
2704 break;
2705 case Bytecodes::_fast_aputfield:
2706 do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, ACCESS_ON_HEAP);
2707 break;
2708 default:
2709 ShouldNotReachHere();
2710 }
2711
2712 if (__ membar_has_effect(write_bits)) {
2713 __ cmp_and_br_short(Lscratch, 0, Assembler::equal, Assembler::pt, exit);
2714 volatile_barrier(Assembler::StoreLoad);
2715 __ bind(exit);
2716 }
2717 }
2718
2719 void TemplateTable::putfield(int byte_no) {
2720 putfield_or_static(byte_no, false);
2721 }
2722
2723 void TemplateTable::nofast_putfield(int byte_no) {
2724 putfield_or_static(byte_no, false, may_not_rewrite);
2725 }
2726
|