82 // Materialize the store address internally (as opposed to defining 'mem' as
83 // an indirect memory operand) to reduce the overhead of LCM when processing
84 // large basic blocks with many stores. Such basic blocks arise, for
85 // instance, from static initializations of large String arrays.
86 // The same holds for g1StoreN and g1EncodePAndStoreN.
87 __ lea($tmp1$$Register, $mem$$Address);
88 write_barrier_pre(masm, this,
89 $tmp1$$Register /* obj */,
90 $tmp2$$Register /* pre_val */,
91 $tmp3$$Register /* tmp */,
92 RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
93 __ movq(Address($tmp1$$Register, 0), $src$$Register);
94 write_barrier_post(masm, this,
95 $tmp1$$Register /* store_addr */,
96 $src$$Register /* new_val */,
97 $tmp3$$Register /* tmp1 */);
98 %}
99 ins_pipe(ialu_mem_reg);
100 %}
101
102 instruct g1StoreN(memory mem, rRegN src, rRegP tmp1, rRegP tmp2, rRegP tmp3, rFlagsReg cr)
103 %{
104 predicate(UseG1GC && n->as_Store()->barrier_data() != 0);
105 match(Set mem (StoreN mem src));
106 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
107 ins_cost(125); // XXX
108 format %{ "movl $mem, $src\t# ptr" %}
109 ins_encode %{
110 __ lea($tmp1$$Register, $mem$$Address);
111 write_barrier_pre(masm, this,
112 $tmp1$$Register /* obj */,
113 $tmp2$$Register /* pre_val */,
114 $tmp3$$Register /* tmp */,
115 RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
116 __ movl(Address($tmp1$$Register, 0), $src$$Register);
117 if ((barrier_data() & G1C2BarrierPost) != 0) {
118 __ movl($tmp2$$Register, $src$$Register);
119 if ((barrier_data() & G1C2BarrierPostNotNull) == 0) {
120 __ decode_heap_oop($tmp2$$Register);
121 } else {
|
82 // Materialize the store address internally (as opposed to defining 'mem' as
83 // an indirect memory operand) to reduce the overhead of LCM when processing
84 // large basic blocks with many stores. Such basic blocks arise, for
85 // instance, from static initializations of large String arrays.
86 // The same holds for g1StoreN and g1EncodePAndStoreN.
87 __ lea($tmp1$$Register, $mem$$Address);
88 write_barrier_pre(masm, this,
89 $tmp1$$Register /* obj */,
90 $tmp2$$Register /* pre_val */,
91 $tmp3$$Register /* tmp */,
92 RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
93 __ movq(Address($tmp1$$Register, 0), $src$$Register);
94 write_barrier_post(masm, this,
95 $tmp1$$Register /* store_addr */,
96 $src$$Register /* new_val */,
97 $tmp3$$Register /* tmp1 */);
98 %}
99 ins_pipe(ialu_mem_reg);
100 %}
101
102 // TODO 8350865 (same applies to g1StoreLSpecialTwoOops)
103 // - Can we use an unbound register for src?
104 // - Do no set/overwrite barrier data here, also handle G1C2BarrierPostNotNull
105 // - Is the zero-extend really required in all the places?
106 instruct g1StoreLSpecialOneOop(memory mem, rdx_RegL src, immI off, rRegP tmp1, rRegP tmp2, rRegP tmp3, rFlagsReg cr)
107 %{
108 predicate(UseG1GC);
109 match(Set mem (StoreLSpecial mem (Binary src off)));
110 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL src, KILL cr);
111 format %{ "movq $mem, $src\t# g1StoreLSpecialOneOop" %}
112 ins_encode %{
113 ((MachNode*)this)->set_barrier_data(G1C2BarrierPre | G1C2BarrierPost);
114
115 __ lea($tmp1$$Register, $mem$$Address);
116 // Adjust address to point to narrow oop
117 __ addq($tmp1$$Register, $off$$constant);
118 write_barrier_pre(masm, this,
119 $tmp1$$Register /* obj */,
120 $tmp2$$Register /* pre_val */,
121 $tmp3$$Register /* tmp */,
122 RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
123
124 __ movq(Address($tmp1$$Register, 0), $src$$Register);
125
126 // Shift long value to extract the narrow oop field value and zero-extend it
127 __ shrq($src$$Register, $off$$constant << LogBitsPerByte);
128 __ movl($src$$Register, $src$$Register);
129
130 write_barrier_post(masm, this,
131 $tmp1$$Register /* store_addr */,
132 $src$$Register /* new_val */,
133 $tmp3$$Register /* tmp1 */);
134 %}
135 ins_pipe(ialu_mem_reg);
136 %}
137
138 instruct g1StoreLSpecialTwoOops(memory mem, rdx_RegL src, rRegP tmp1, rRegP tmp2, rRegP tmp3, rRegP tmp4, rFlagsReg cr)
139 %{
140 predicate(UseG1GC);
141 match(Set mem (StoreLSpecial mem src));
142 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, KILL cr);
143 format %{ "movq $mem, $src\t# g1StoreLSpecialTwoOops" %}
144 ins_encode %{
145 ((MachNode*)this)->set_barrier_data(G1C2BarrierPre | G1C2BarrierPost);
146
147 __ lea($tmp1$$Register, $mem$$Address);
148 write_barrier_pre(masm, this,
149 $tmp1$$Register /* obj */,
150 $tmp2$$Register /* pre_val */,
151 $tmp3$$Register /* tmp */,
152 RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
153 // Adjust address to point to the second narrow oop in the long value
154 __ addq($tmp1$$Register, 4);
155 write_barrier_pre(masm, this,
156 $tmp1$$Register /* obj */,
157 $tmp2$$Register /* pre_val */,
158 $tmp3$$Register /* tmp */,
159 RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
160 // Adjust address again to point to the first narrow oop in the long value
161 __ subq($tmp1$$Register, 4);
162
163 __ movq(Address($tmp1$$Register, 0), $src$$Register);
164
165 // Zero-extend first narrow oop to long
166 __ movl($tmp4$$Register, $src$$Register);
167
168 // Shift long value to extract the second narrow oop field value
169 __ shrq($src$$Register, 32);
170 write_barrier_post(masm, this,
171 $tmp1$$Register /* store_addr */,
172 $tmp4$$Register /* new_val */,
173 $tmp3$$Register /* tmp1 */);
174 __ addq($tmp1$$Register, 4);
175 write_barrier_post(masm, this,
176 $tmp1$$Register /* store_addr */,
177 $src$$Register /* new_val */,
178 $tmp3$$Register /* tmp1 */);
179 %}
180 ins_pipe(ialu_mem_reg);
181 %}
182
183 instruct g1StoreN(memory mem, rRegN src, rRegP tmp1, rRegP tmp2, rRegP tmp3, rFlagsReg cr)
184 %{
185 predicate(UseG1GC && n->as_Store()->barrier_data() != 0);
186 match(Set mem (StoreN mem src));
187 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
188 ins_cost(125); // XXX
189 format %{ "movl $mem, $src\t# ptr" %}
190 ins_encode %{
191 __ lea($tmp1$$Register, $mem$$Address);
192 write_barrier_pre(masm, this,
193 $tmp1$$Register /* obj */,
194 $tmp2$$Register /* pre_val */,
195 $tmp3$$Register /* tmp */,
196 RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
197 __ movl(Address($tmp1$$Register, 0), $src$$Register);
198 if ((barrier_data() & G1C2BarrierPost) != 0) {
199 __ movl($tmp2$$Register, $src$$Register);
200 if ((barrier_data() & G1C2BarrierPostNotNull) == 0) {
201 __ decode_heap_oop($tmp2$$Register);
202 } else {
|