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 "code/aotCodeCache.hpp"
27 #include "gc/g1/g1BarrierSet.hpp"
28 #include "gc/g1/g1BarrierSetAssembler.hpp"
29 #include "gc/g1/g1BarrierSetRuntime.hpp"
30 #include "gc/g1/g1CardTable.hpp"
31 #include "gc/g1/g1HeapRegion.hpp"
32 #include "gc/g1/g1ThreadLocalData.hpp"
33 #include "interpreter/interp_masm.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;
396 generate_pre_barrier_slow_path(masm, obj, pre_val, thread, tmp, *stub->continuation());
397
398 generate_c2_barrier_runtime_call(masm, stub, pre_val, CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_pre_entry));
399 __ jmp(*stub->continuation());
400 }
401
402 void G1BarrierSetAssembler::g1_write_barrier_post_c2(MacroAssembler* masm,
403 Register store_addr,
404 Register new_val,
405 Register tmp,
406 bool new_val_may_be_null) {
407 generate_post_barrier(masm, store_addr, new_val, tmp, new_val_may_be_null);
408 }
409
410 #endif // COMPILER2
411
412 void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
413 Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) {
414 bool in_heap = (decorators & IN_HEAP) != 0;
415 bool as_normal = (decorators & AS_NORMAL) != 0;
416
417 bool needs_pre_barrier = as_normal;
418 bool needs_post_barrier = val != noreg && in_heap;
419
420 // flatten object address if needed
421 // We do it regardless of precise because we need the registers
422 if (dst.index() == noreg && dst.disp() == 0) {
423 if (dst.base() != tmp1) {
424 __ movptr(tmp1, dst.base());
425 }
426 } else {
427 __ lea(tmp1, dst);
428 }
429
430 if (needs_pre_barrier) {
431 g1_write_barrier_pre(masm /*masm*/,
432 tmp1 /* obj */,
433 tmp2 /* pre_val */,
434 tmp3 /* tmp */,
435 val != noreg /* tosca_live */,
436 false /* expand_call */);
437 }
|
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 "code/aotCodeCache.hpp"
27 #include "gc/g1/g1BarrierSet.hpp"
28 #include "gc/g1/g1BarrierSetAssembler.hpp"
29 #include "gc/g1/g1BarrierSetRuntime.hpp"
30 #include "gc/g1/g1CardTable.hpp"
31 #include "gc/g1/g1HeapRegion.hpp"
32 #include "gc/g1/g1ThreadLocalData.hpp"
33 #include "interpreter/interp_masm.hpp"
34 #include "runtime/arguments.hpp"
35 #include "runtime/sharedRuntime.hpp"
36 #include "utilities/debug.hpp"
37 #include "utilities/macros.hpp"
38 #ifdef COMPILER1
39 #include "c1/c1_LIRAssembler.hpp"
40 #include "c1/c1_MacroAssembler.hpp"
41 #include "gc/g1/c1/g1BarrierSetC1.hpp"
42 #endif // COMPILER1
43 #ifdef COMPILER2
44 #include "gc/g1/c2/g1BarrierSetC2.hpp"
45 #endif // COMPILER2
46
47 #define __ masm->
48
49 void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
50 Register addr, Register count) {
51 bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
52
53 if (!dest_uninitialized) {
54 Register thread = r15_thread;
397 generate_pre_barrier_slow_path(masm, obj, pre_val, thread, tmp, *stub->continuation());
398
399 generate_c2_barrier_runtime_call(masm, stub, pre_val, CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_pre_entry));
400 __ jmp(*stub->continuation());
401 }
402
403 void G1BarrierSetAssembler::g1_write_barrier_post_c2(MacroAssembler* masm,
404 Register store_addr,
405 Register new_val,
406 Register tmp,
407 bool new_val_may_be_null) {
408 generate_post_barrier(masm, store_addr, new_val, tmp, new_val_may_be_null);
409 }
410
411 #endif // COMPILER2
412
413 void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
414 Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) {
415 bool in_heap = (decorators & IN_HEAP) != 0;
416 bool as_normal = (decorators & AS_NORMAL) != 0;
417 bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
418
419 bool needs_pre_barrier = as_normal && !dest_uninitialized;
420 bool needs_post_barrier = val != noreg && in_heap;
421
422 // flatten object address if needed
423 // We do it regardless of precise because we need the registers
424 if (dst.index() == noreg && dst.disp() == 0) {
425 if (dst.base() != tmp1) {
426 __ movptr(tmp1, dst.base());
427 }
428 } else {
429 __ lea(tmp1, dst);
430 }
431
432 if (needs_pre_barrier) {
433 g1_write_barrier_pre(masm /*masm*/,
434 tmp1 /* obj */,
435 tmp2 /* pre_val */,
436 tmp3 /* tmp */,
437 val != noreg /* tosca_live */,
438 false /* expand_call */);
439 }
|