26 #include "incls/_templateTable_sparc.cpp.incl" |
26 #include "incls/_templateTable_sparc.cpp.incl" |
27 |
27 |
28 #ifndef CC_INTERP |
28 #ifndef CC_INTERP |
29 #define __ _masm-> |
29 #define __ _masm-> |
30 |
30 |
|
31 // Misc helpers |
|
32 |
|
33 // Do an oop store like *(base + index + offset) = val |
|
34 // index can be noreg, |
|
35 static void do_oop_store(InterpreterMacroAssembler* _masm, |
|
36 Register base, |
|
37 Register index, |
|
38 int offset, |
|
39 Register val, |
|
40 Register tmp, |
|
41 BarrierSet::Name barrier, |
|
42 bool precise) { |
|
43 assert(tmp != val && tmp != base && tmp != index, "register collision"); |
|
44 assert(index == noreg || offset == 0, "only one offset"); |
|
45 switch (barrier) { |
|
46 #ifndef SERIALGC |
|
47 case BarrierSet::G1SATBCT: |
|
48 case BarrierSet::G1SATBCTLogging: |
|
49 { |
|
50 __ g1_write_barrier_pre( base, index, offset, tmp, /*preserve_o_regs*/true); |
|
51 if (index == noreg ) { |
|
52 assert(Assembler::is_simm13(offset), "fix this code"); |
|
53 __ store_heap_oop(val, base, offset); |
|
54 } else { |
|
55 __ store_heap_oop(val, base, index); |
|
56 } |
|
57 |
|
58 // No need for post barrier if storing NULL |
|
59 if (val != G0) { |
|
60 if (precise) { |
|
61 if (index == noreg) { |
|
62 __ add(base, offset, base); |
|
63 } else { |
|
64 __ add(base, index, base); |
|
65 } |
|
66 } |
|
67 __ g1_write_barrier_post(base, val, tmp); |
|
68 } |
|
69 } |
|
70 break; |
|
71 #endif // SERIALGC |
|
72 case BarrierSet::CardTableModRef: |
|
73 case BarrierSet::CardTableExtension: |
|
74 { |
|
75 if (index == noreg ) { |
|
76 assert(Assembler::is_simm13(offset), "fix this code"); |
|
77 __ store_heap_oop(val, base, offset); |
|
78 } else { |
|
79 __ store_heap_oop(val, base, index); |
|
80 } |
|
81 // No need for post barrier if storing NULL |
|
82 if (val != G0) { |
|
83 if (precise) { |
|
84 if (index == noreg) { |
|
85 __ add(base, offset, base); |
|
86 } else { |
|
87 __ add(base, index, base); |
|
88 } |
|
89 } |
|
90 __ card_write_barrier_post(base, val, tmp); |
|
91 } |
|
92 } |
|
93 break; |
|
94 case BarrierSet::ModRef: |
|
95 case BarrierSet::Other: |
|
96 ShouldNotReachHere(); |
|
97 break; |
|
98 default : |
|
99 ShouldNotReachHere(); |
|
100 |
|
101 } |
|
102 } |
|
103 |
31 |
104 |
32 //---------------------------------------------------------------------------------------------------- |
105 //---------------------------------------------------------------------------------------------------- |
33 // Platform-dependent initialization |
106 // Platform-dependent initialization |
34 |
107 |
35 void TemplateTable::pd_initialize() { |
108 void TemplateTable::pd_initialize() { |
756 // O2: index |
829 // O2: index |
757 // O3: array |
830 // O3: array |
758 // O4: array element klass |
831 // O4: array element klass |
759 // O5: value klass |
832 // O5: value klass |
760 |
833 |
|
834 // Address element(O1, 0, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); |
|
835 |
761 // Generate a fast subtype check. Branch to store_ok if no |
836 // Generate a fast subtype check. Branch to store_ok if no |
762 // failure. Throw if failure. |
837 // failure. Throw if failure. |
763 __ gen_subtype_check( O5, O4, G3_scratch, G4_scratch, G1_scratch, store_ok ); |
838 __ gen_subtype_check( O5, O4, G3_scratch, G4_scratch, G1_scratch, store_ok ); |
764 |
839 |
765 // Not a subtype; so must throw exception |
840 // Not a subtype; so must throw exception |
766 __ throw_if_not_x( Assembler::never, Interpreter::_throw_ArrayStoreException_entry, G3_scratch ); |
841 __ throw_if_not_x( Assembler::never, Interpreter::_throw_ArrayStoreException_entry, G3_scratch ); |
767 |
842 |
768 // Store is OK. |
843 // Store is OK. |
769 __ bind(store_ok); |
844 __ bind(store_ok); |
770 __ store_heap_oop(Otos_i, O1, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); |
845 do_oop_store(_masm, O1, noreg, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Otos_i, G3_scratch, _bs->kind(), true); |
771 // Quote from rememberedSet.hpp: For objArrays, the precise card |
846 |
772 // corresponding to the pointer store is dirtied so we don't need to |
|
773 // scavenge the entire array. |
|
774 Address element(O1, 0, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); |
|
775 __ add(element, O1); // address the element precisely |
|
776 __ store_check(G3_scratch, O1); |
|
777 __ ba(false,done); |
847 __ ba(false,done); |
778 __ delayed()->inc(Lesp, 3* Interpreter::stackElementSize()); // adj sp (pops array, index and value) |
848 __ delayed()->inc(Lesp, 3* Interpreter::stackElementSize()); // adj sp (pops array, index and value) |
779 |
849 |
780 __ bind(is_null); |
850 __ bind(is_null); |
781 __ store_heap_oop(Otos_i, element); |
851 do_oop_store(_masm, O1, noreg, arrayOopDesc::base_offset_in_bytes(T_OBJECT), G0, G4_scratch, _bs->kind(), true); |
|
852 |
782 __ profile_null_seen(G3_scratch); |
853 __ profile_null_seen(G3_scratch); |
783 __ inc(Lesp, 3* Interpreter::stackElementSize()); // adj sp (pops array, index and value) |
854 __ inc(Lesp, 3* Interpreter::stackElementSize()); // adj sp (pops array, index and value) |
784 __ bind(done); |
855 __ bind(done); |
785 } |
856 } |
786 |
857 |
2447 __ delayed() ->cmp(Rflags, itos ); |
2518 __ delayed() ->cmp(Rflags, itos ); |
2448 |
2519 |
2449 // atos |
2520 // atos |
2450 __ pop_ptr(); |
2521 __ pop_ptr(); |
2451 __ verify_oop(Otos_i); |
2522 __ verify_oop(Otos_i); |
2452 __ store_heap_oop(Otos_i, Rclass, Roffset); |
2523 |
2453 __ store_check(G1_scratch, Rclass, Roffset); |
2524 do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false); |
|
2525 |
2454 __ ba(false, checkVolatile); |
2526 __ ba(false, checkVolatile); |
2455 __ delayed()->tst(Lscratch); |
2527 __ delayed()->tst(Lscratch); |
2456 |
2528 |
2457 __ bind(notObj); |
2529 __ bind(notObj); |
2458 |
2530 |
2489 |
2561 |
2490 // atos |
2562 // atos |
2491 __ pop_ptr(); |
2563 __ pop_ptr(); |
2492 pop_and_check_object(Rclass); |
2564 pop_and_check_object(Rclass); |
2493 __ verify_oop(Otos_i); |
2565 __ verify_oop(Otos_i); |
2494 __ store_heap_oop(Otos_i, Rclass, Roffset); |
2566 |
2495 __ store_check(G1_scratch, Rclass, Roffset); |
2567 do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false); |
|
2568 |
2496 patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch); |
2569 patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch); |
2497 __ ba(false, checkVolatile); |
2570 __ ba(false, checkVolatile); |
2498 __ delayed()->tst(Lscratch); |
2571 __ delayed()->tst(Lscratch); |
2499 |
2572 |
2500 __ bind(notObj); |
2573 __ bind(notObj); |
2644 break; |
2717 break; |
2645 case Bytecodes::_fast_dputfield: |
2718 case Bytecodes::_fast_dputfield: |
2646 __ stf(FloatRegisterImpl::D, Ftos_d, Rclass, Roffset); |
2719 __ stf(FloatRegisterImpl::D, Ftos_d, Rclass, Roffset); |
2647 break; |
2720 break; |
2648 case Bytecodes::_fast_aputfield: |
2721 case Bytecodes::_fast_aputfield: |
2649 __ store_heap_oop(Otos_i, Rclass, Roffset); |
2722 do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false); |
2650 __ store_check(G1_scratch, Rclass, Roffset); |
|
2651 break; |
2723 break; |
2652 default: |
2724 default: |
2653 ShouldNotReachHere(); |
2725 ShouldNotReachHere(); |
2654 } |
2726 } |
2655 |
2727 |