1 /*
2 * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
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 "asm/macroAssembler.inline.hpp"
26 #include "gc/g1/g1BarrierSet.hpp"
27 #include "gc/g1/g1BarrierSetAssembler.hpp"
28 #include "gc/g1/g1BarrierSetRuntime.hpp"
29 #include "gc/g1/g1CardTable.hpp"
30 #include "gc/g1/g1HeapRegion.hpp"
31 #include "gc/g1/g1ThreadLocalData.hpp"
32 #include "interpreter/interp_masm.hpp"
33 #include "runtime/sharedRuntime.hpp"
34 #include "utilities/debug.hpp"
35 #include "utilities/macros.hpp"
36 #ifdef COMPILER1
37 #include "c1/c1_LIRAssembler.hpp"
38 #include "c1/c1_MacroAssembler.hpp"
39 #include "gc/g1/c1/g1BarrierSetC1.hpp"
40 #endif // COMPILER1
41 #ifdef COMPILER2
42 #include "gc/g1/c2/g1BarrierSetC2.hpp"
43 #endif // COMPILER2
44
45 #define __ masm->
46
47 void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
48 Register addr, Register count) {
49 bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
50
51 if (!dest_uninitialized) {
52 Register thread = r15_thread;
363 generate_pre_barrier_slow_path(masm, obj, pre_val, thread, tmp, *stub->continuation());
364
365 generate_c2_barrier_runtime_call(masm, stub, pre_val, CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_pre_entry));
366 __ jmp(*stub->continuation());
367 }
368
369 void G1BarrierSetAssembler::g1_write_barrier_post_c2(MacroAssembler* masm,
370 Register store_addr,
371 Register new_val,
372 Register tmp,
373 bool new_val_may_be_null) {
374 generate_post_barrier(masm, store_addr, new_val, tmp, new_val_may_be_null);
375 }
376
377 #endif // COMPILER2
378
379 void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
380 Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) {
381 bool in_heap = (decorators & IN_HEAP) != 0;
382 bool as_normal = (decorators & AS_NORMAL) != 0;
383
384 bool needs_pre_barrier = as_normal;
385 bool needs_post_barrier = val != noreg && in_heap;
386
387 // flatten object address if needed
388 // We do it regardless of precise because we need the registers
389 if (dst.index() == noreg && dst.disp() == 0) {
390 if (dst.base() != tmp1) {
391 __ movptr(tmp1, dst.base());
392 }
393 } else {
394 __ lea(tmp1, dst);
395 }
396
397 if (needs_pre_barrier) {
398 g1_write_barrier_pre(masm /*masm*/,
399 tmp1 /* obj */,
400 tmp2 /* pre_val */,
401 tmp3 /* tmp */,
402 val != noreg /* tosca_live */,
403 false /* expand_call */);
404 }
|
1 /*
2 * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
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 "asm/macroAssembler.inline.hpp"
26 #include "gc/g1/g1BarrierSet.hpp"
27 #include "gc/g1/g1BarrierSetAssembler.hpp"
28 #include "gc/g1/g1BarrierSetRuntime.hpp"
29 #include "gc/g1/g1CardTable.hpp"
30 #include "gc/g1/g1HeapRegion.hpp"
31 #include "gc/g1/g1ThreadLocalData.hpp"
32 #include "interpreter/interp_masm.hpp"
33 #include "runtime/arguments.hpp"
34 #include "runtime/sharedRuntime.hpp"
35 #include "utilities/debug.hpp"
36 #include "utilities/macros.hpp"
37 #ifdef COMPILER1
38 #include "c1/c1_LIRAssembler.hpp"
39 #include "c1/c1_MacroAssembler.hpp"
40 #include "gc/g1/c1/g1BarrierSetC1.hpp"
41 #endif // COMPILER1
42 #ifdef COMPILER2
43 #include "gc/g1/c2/g1BarrierSetC2.hpp"
44 #endif // COMPILER2
45
46 #define __ masm->
47
48 void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
49 Register addr, Register count) {
50 bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
51
52 if (!dest_uninitialized) {
53 Register thread = r15_thread;
364 generate_pre_barrier_slow_path(masm, obj, pre_val, thread, tmp, *stub->continuation());
365
366 generate_c2_barrier_runtime_call(masm, stub, pre_val, CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_pre_entry));
367 __ jmp(*stub->continuation());
368 }
369
370 void G1BarrierSetAssembler::g1_write_barrier_post_c2(MacroAssembler* masm,
371 Register store_addr,
372 Register new_val,
373 Register tmp,
374 bool new_val_may_be_null) {
375 generate_post_barrier(masm, store_addr, new_val, tmp, new_val_may_be_null);
376 }
377
378 #endif // COMPILER2
379
380 void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
381 Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) {
382 bool in_heap = (decorators & IN_HEAP) != 0;
383 bool as_normal = (decorators & AS_NORMAL) != 0;
384 bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
385
386 bool needs_pre_barrier = as_normal && !dest_uninitialized;
387 bool needs_post_barrier = val != noreg && in_heap;
388
389 // flatten object address if needed
390 // We do it regardless of precise because we need the registers
391 if (dst.index() == noreg && dst.disp() == 0) {
392 if (dst.base() != tmp1) {
393 __ movptr(tmp1, dst.base());
394 }
395 } else {
396 __ lea(tmp1, dst);
397 }
398
399 if (needs_pre_barrier) {
400 g1_write_barrier_pre(masm /*masm*/,
401 tmp1 /* obj */,
402 tmp2 /* pre_val */,
403 tmp3 /* tmp */,
404 val != noreg /* tosca_live */,
405 false /* expand_call */);
406 }
|