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 "c1/c1_LIRGenerator.hpp"
26 #include "c1/c1_CodeStubs.hpp"
27 #include "gc/g1/c1/g1BarrierSetC1.hpp"
28 #include "gc/g1/g1BarrierSet.hpp"
29 #include "gc/g1/g1BarrierSetAssembler.hpp"
30 #include "gc/g1/g1HeapRegion.hpp"
31 #include "gc/g1/g1ThreadLocalData.hpp"
32 #include "utilities/macros.hpp"
33
34 #ifdef ASSERT
35 #define __ gen->lir(__FILE__, __LINE__)->
36 #else
37 #define __ gen->lir()->
38 #endif
39
40 void G1PreBarrierStub::emit_code(LIR_Assembler* ce) {
41 G1BarrierSetAssembler* bs = (G1BarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
42 bs->gen_pre_barrier_stub(ce, this);
43 }
44
45 void G1PostBarrierStub::emit_code(LIR_Assembler* ce) {
46 G1BarrierSetAssembler* bs = (G1BarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
135 }
136 new_val = new_val_reg;
137 }
138 assert(new_val->is_register(), "must be a register at this point");
139
140 if (addr->is_address()) {
141 LIR_Address* address = addr->as_address_ptr();
142 LIR_Opr ptr = gen->new_pointer_register();
143 if (!address->index()->is_valid() && address->disp() == 0) {
144 __ move(address->base(), ptr);
145 } else {
146 assert(address->disp() != max_jint, "lea doesn't support patched addresses!");
147 __ leal(addr, ptr);
148 }
149 addr = ptr;
150 }
151 assert(addr->is_register(), "must be a register at this point");
152
153 LIR_Opr xor_res = gen->new_pointer_register();
154 LIR_Opr xor_shift_res = gen->new_pointer_register();
155 if (two_operand_lir_form) {
156 __ move(addr, xor_res);
157 __ logical_xor(xor_res, new_val, xor_res);
158 __ move(xor_res, xor_shift_res);
159 __ unsigned_shift_right(xor_shift_res,
160 LIR_OprFact::intConst(checked_cast<jint>(G1HeapRegion::LogOfHRGrainBytes)),
161 xor_shift_res,
162 LIR_Opr::illegalOpr());
163 } else {
164 __ logical_xor(addr, new_val, xor_res);
165 __ unsigned_shift_right(xor_res,
166 LIR_OprFact::intConst(checked_cast<jint>(G1HeapRegion::LogOfHRGrainBytes)),
167 xor_shift_res,
168 LIR_Opr::illegalOpr());
169 }
170
171 __ cmp(lir_cond_notEqual, xor_shift_res, LIR_OprFact::intptrConst(NULL_WORD));
172
173 CodeStub* slow = new G1PostBarrierStub(addr, new_val);
174 __ branch(lir_cond_notEqual, slow);
175 __ branch_destination(slow->continuation());
176 }
177
178 void G1BarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result) {
179 DecoratorSet decorators = access.decorators();
180 bool is_weak = (decorators & ON_WEAK_OOP_REF) != 0;
181 bool is_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
182 bool is_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0;
183 LIRGenerator *gen = access.gen();
184
185 BarrierSetC1::load_at_resolved(access, result);
186
187 if (access.is_oop() && (is_weak || is_phantom || is_anonymous)) {
188 // Register the value in the referent field with the pre-barrier
|
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 "c1/c1_LIRGenerator.hpp"
26 #include "c1/c1_CodeStubs.hpp"
27 #if INCLUDE_CDS
28 #include "code/SCCache.hpp"
29 #endif
30 #include "gc/g1/c1/g1BarrierSetC1.hpp"
31 #include "gc/g1/g1BarrierSet.hpp"
32 #include "gc/g1/g1BarrierSetAssembler.hpp"
33 #include "gc/g1/g1HeapRegion.hpp"
34 #include "gc/g1/g1ThreadLocalData.hpp"
35 #include "utilities/macros.hpp"
36
37 #ifdef ASSERT
38 #define __ gen->lir(__FILE__, __LINE__)->
39 #else
40 #define __ gen->lir()->
41 #endif
42
43 void G1PreBarrierStub::emit_code(LIR_Assembler* ce) {
44 G1BarrierSetAssembler* bs = (G1BarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
45 bs->gen_pre_barrier_stub(ce, this);
46 }
47
48 void G1PostBarrierStub::emit_code(LIR_Assembler* ce) {
49 G1BarrierSetAssembler* bs = (G1BarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
138 }
139 new_val = new_val_reg;
140 }
141 assert(new_val->is_register(), "must be a register at this point");
142
143 if (addr->is_address()) {
144 LIR_Address* address = addr->as_address_ptr();
145 LIR_Opr ptr = gen->new_pointer_register();
146 if (!address->index()->is_valid() && address->disp() == 0) {
147 __ move(address->base(), ptr);
148 } else {
149 assert(address->disp() != max_jint, "lea doesn't support patched addresses!");
150 __ leal(addr, ptr);
151 }
152 addr = ptr;
153 }
154 assert(addr->is_register(), "must be a register at this point");
155
156 LIR_Opr xor_res = gen->new_pointer_register();
157 LIR_Opr xor_shift_res = gen->new_pointer_register();
158 #if INCLUDE_CDS
159 // we need to load the grain shift from the AOT Runtime
160 // Constants Area
161 LIR_Opr grain_shift_addr = LIR_OprFact::intptrConst(AOTRuntimeConstants::grain_shift_address());
162 LIR_Opr grain_shift_reg = gen->new_pointer_register();
163 LIR_Address* grain_shift_indirect = new LIR_Address(grain_shift_reg, 0, T_INT);
164 #ifdef X86
165 LIR_Opr grain_shift = gen->shiftCountOpr();
166 #else // X86
167 LIR_Opr grain_shift = gen->new_register(T_INT);
168 #endif // X86
169 #endif
170 if (two_operand_lir_form) {
171 __ move(addr, xor_res);
172 __ logical_xor(xor_res, new_val, xor_res);
173 #if INCLUDE_CDS
174 if (SCCache::is_on_for_write()) {
175 __ move(grain_shift_addr, grain_shift_reg);
176 __ move(xor_res, xor_shift_res);
177 __ move(grain_shift_indirect, grain_shift);
178 __ unsigned_shift_right(xor_shift_res,
179 grain_shift,
180 xor_shift_res,
181 LIR_Opr::illegalOpr());
182 } else
183 #endif
184 {
185 __ move(xor_res, xor_shift_res);
186 __ unsigned_shift_right(xor_shift_res,
187 LIR_OprFact::intConst(checked_cast<jint>(G1HeapRegion::LogOfHRGrainBytes)),
188 xor_shift_res,
189 LIR_Opr::illegalOpr());
190 }
191 } else {
192 __ logical_xor(addr, new_val, xor_res);
193 #if INCLUDE_CDS
194 if (SCCache::is_on_for_write()) {
195 __ move(grain_shift_addr, grain_shift_reg);
196 __ move(grain_shift_indirect, grain_shift);
197 __ unsigned_shift_right(xor_res,
198 grain_shift,
199 xor_shift_res,
200 LIR_Opr::illegalOpr());
201 } else
202 #endif
203 {
204 __ unsigned_shift_right(xor_res,
205 LIR_OprFact::intConst(checked_cast<jint>(G1HeapRegion::LogOfHRGrainBytes)),
206 xor_shift_res,
207 LIR_Opr::illegalOpr());
208 }
209 }
210
211 __ cmp(lir_cond_notEqual, xor_shift_res, LIR_OprFact::intptrConst(NULL_WORD));
212
213 CodeStub* slow = new G1PostBarrierStub(addr, new_val);
214 __ branch(lir_cond_notEqual, slow);
215 __ branch_destination(slow->continuation());
216 }
217
218 void G1BarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result) {
219 DecoratorSet decorators = access.decorators();
220 bool is_weak = (decorators & ON_WEAK_OOP_REF) != 0;
221 bool is_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
222 bool is_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0;
223 LIRGenerator *gen = access.gen();
224
225 BarrierSetC1::load_at_resolved(access, result);
226
227 if (access.is_oop() && (is_weak || is_phantom || is_anonymous)) {
228 // Register the value in the referent field with the pre-barrier
|