< prev index next >

src/hotspot/cpu/x86/gc/g1/g1_x86_64.ad

Print this page
@@ -1,7 +1,7 @@
  //
- // Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
+ // Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
  // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  //
  // This code is free software; you can redistribute it and/or modify it
  // under the terms of the GNU General Public License version 2 only, as
  // published by the Free Software Foundation.

@@ -97,10 +97,122 @@
                         $tmp3$$Register /* tmp1 */);
    %}
    ins_pipe(ialu_mem_reg);
  %}
  
+ // TODO 8350865 (same applies to g1StoreLSpecialTwoOops)
+ // - Do no set/overwrite barrier data here, also handle G1C2BarrierPostNotNull
+ instruct g1StoreLSpecialOneOopOff0(memory mem, rRegL src, immI_0 off, rRegP tmp1, rRegP tmp2, rRegP tmp3, rFlagsReg cr)
+ %{
+   predicate(UseG1GC);
+   match(Set mem (StoreLSpecial mem (Binary src off)));
+   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
+   format %{ "movq    $mem, $src\t# g1StoreLSpecialOneOopOff0" %}
+   ins_encode %{
+     ((MachNode*)this)->set_barrier_data(G1C2BarrierPre | G1C2BarrierPost);
+ 
+     __ lea($tmp1$$Register, $mem$$Address);
+     write_barrier_pre(masm, this,
+                       $tmp1$$Register /* obj */,
+                       $tmp2$$Register /* pre_val */,
+                       $tmp3$$Register /* tmp */,
+                       RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
+ 
+     __ movq(Address($tmp1$$Register, 0), $src$$Register);
+ 
+     // Extract the narrow oop field value
+     __ movl($tmp2$$Register, $src$$Register);
+     __ decode_heap_oop($tmp2$$Register);
+     write_barrier_post(masm, this,
+                        $tmp1$$Register /* store_addr */,
+                        $tmp2$$Register /* new_val */,
+                        $tmp3$$Register /* tmp1 */);
+   %}
+   ins_pipe(ialu_mem_reg);
+ %}
+ 
+ instruct g1StoreLSpecialOneOopOff4(memory mem, rRegL src, immI_4 off, rRegP tmp1, rRegP tmp2, rRegP tmp3, rFlagsReg cr)
+ %{
+   predicate(UseG1GC);
+   match(Set mem (StoreLSpecial mem (Binary src off)));
+   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
+   format %{ "movq    $mem, $src\t# g1StoreLSpecialOneOopOff4" %}
+   ins_encode %{
+     ((MachNode*)this)->set_barrier_data(G1C2BarrierPre | G1C2BarrierPost);
+ 
+     // Adjust address to point to narrow oop
+     Address dst = $mem$$Address;
+     __ lea($tmp1$$Register, dst.plus_disp(4));
+     write_barrier_pre(masm, this,
+                       $tmp1$$Register /* obj */,
+                       $tmp2$$Register /* pre_val */,
+                       $tmp3$$Register /* tmp */,
+                       RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
+ 
+     // The address of the oop is the address of the store plus the offset of the oop
+     __ movq(Address($tmp1$$Register, -4), $src$$Register);
+ 
+     // Shift long value to extract the narrow oop field value
+     __ movq($tmp2$$Register, $src$$Register);
+     __ shrq($tmp2$$Register, 32);
+     __ decode_heap_oop($tmp2$$Register);
+     write_barrier_post(masm, this,
+                        $tmp1$$Register /* store_addr */,
+                        $src$$Register /* new_val */,
+                        $tmp3$$Register /* tmp1 */);
+   %}
+   ins_pipe(ialu_mem_reg);
+ %}
+ 
+ instruct g1StoreLSpecialTwoOops(memory mem, rRegL src, rRegP tmp1, rRegP tmp2, rRegP tmp3, rFlagsReg cr)
+ %{
+   predicate(UseG1GC);
+   match(Set mem (StoreLSpecial mem src));
+   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
+   format %{ "movq    $mem, $src\t# g1StoreLSpecialTwoOops" %}
+   ins_encode %{
+     ((MachNode*)this)->set_barrier_data(G1C2BarrierPre | G1C2BarrierPost);
+ 
+     __ lea($tmp1$$Register, $mem$$Address);
+     write_barrier_pre(masm, this,
+                       $tmp1$$Register /* obj */,
+                       $tmp2$$Register /* pre_val */,
+                       $tmp3$$Register /* tmp */,
+                       RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
+     // Adjust address to point to the second narrow oop in the long value
+     __ addq($tmp1$$Register, 4);
+     write_barrier_pre(masm, this,
+                       $tmp1$$Register /* obj */,
+                       $tmp2$$Register /* pre_val */,
+                       $tmp3$$Register /* tmp */,
+                       RegSet::of($tmp1$$Register, $src$$Register) /* preserve */);
+ 
+     // The address of the second oop is the address of the store plus the offset of the second oop
+     __ movq(Address($tmp1$$Register, -4), $src$$Register);
+ 
+     // Do the post-barrier of the second oop first since we have its address in tmp1
+     __ movq($tmp2$$Register, $src$$Register);
+     __ shrq($tmp2$$Register, 32);
+     __ decode_heap_oop($tmp2$$Register);
+     write_barrier_post(masm, this,
+                        $tmp1$$Register /* store_addr */,
+                        $tmp2$$Register /* new_val */,
+                        $tmp3$$Register /* tmp1 */);
+ 
+     // Retrieve the address of the first narrow oop
+     __ addq($tmp1$$Register, -4);
+     // Extract the first narrow oop
+     __ movl($tmp2$$Register, $src$$Register);
+     __ decode_heap_oop($tmp2$$Register);
+     write_barrier_post(masm, this,
+                        $tmp1$$Register /* store_addr */,
+                        $tmp2$$Register /* new_val */,
+                        $tmp3$$Register /* tmp1 */);
+   %}
+   ins_pipe(ialu_mem_reg);
+ %}
+ 
  instruct g1StoreN(memory mem, rRegN src, rRegP tmp1, rRegP tmp2, rRegP tmp3, rFlagsReg cr)
  %{
    predicate(UseG1GC && n->as_Store()->barrier_data() != 0);
    match(Set mem (StoreN mem src));
    effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
< prev index next >