< prev index next >

src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp

Print this page

  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   }
< prev index next >