11/*
2- * Copyright (c) 2014, 2024 , Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 2014, 2025 , Oracle and/or its affiliates. All rights reserved.
33 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44 *
55 * This code is free software; you can redistribute it and/or modify it
2626import org .openjdk .jmh .annotations .BenchmarkMode ;
2727import org .openjdk .jmh .annotations .CompilerControl ;
2828import org .openjdk .jmh .annotations .Fork ;
29+ import org .openjdk .jmh .annotations .Level ;
2930import org .openjdk .jmh .annotations .Measurement ;
3031import org .openjdk .jmh .annotations .Mode ;
3132import org .openjdk .jmh .annotations .OutputTimeUnit ;
3233import org .openjdk .jmh .annotations .Scope ;
3334import org .openjdk .jmh .annotations .Setup ;
3435import org .openjdk .jmh .annotations .State ;
36+ import org .openjdk .jmh .annotations .TearDown ;
3537import org .openjdk .jmh .annotations .Warmup ;
3638
3739import java .util .Random ;
@@ -56,12 +58,18 @@ public abstract class WriteBarrier {
5658 private Object [] theArrayLarge ;
5759 private int [] indicesLarge ;
5860
61+ private Object [] youngArraySmall ;
62+ private Object [] youngArrayLarge ;
63+
5964 private Object nullRef ;
6065 private Object realRef ;
66+ private Object youngRef ;
6167
6268 // For field update tests
6369 public Referencer head = null ;
6470 public Referencer tail = null ;
71+ public Referencer youngHead = null ;
72+ public Referencer youngTail = null ;
6573
6674 // For random number generation
6775 private int m_w ;
@@ -81,7 +89,7 @@ void clear() {
8189 }
8290 }
8391
84- @ Setup
92+ @ Setup ( Level . Trial )
8593 public void setup () {
8694 theArraySmall = new Object [NUM_REFERENCES_SMALL ];
8795 indicesSmall = new int [NUM_REFERENCES_SMALL ];
@@ -114,6 +122,16 @@ public void setup() {
114122 System .gc ();
115123 }
116124
125+ @ Setup (Level .Iteration )
126+ public void setupIteration () {
127+ // Reallocate target objects each iteration to ensure they are in young gen.
128+ youngArraySmall = new Object [NUM_REFERENCES_SMALL ];
129+ youngArrayLarge = new Object [NUM_REFERENCES_LARGE ];
130+ youngRef = new Object ();
131+ this .youngHead = new Referencer ();
132+ this .youngTail = new Referencer ();
133+ }
134+
117135 private int get_random () {
118136 m_z = 36969 * (m_z & 65535 ) + (m_z >> 16 );
119137 m_w = 18000 * (m_w & 65535 ) + (m_w >> 16 );
@@ -133,6 +151,70 @@ public void testArrayWriteBarrierFastPathRealSmall() {
133151 }
134152 }
135153
154+ @ Benchmark
155+ @ CompilerControl (CompilerControl .Mode .DONT_INLINE )
156+ public void testArrayWriteBarrierFastPathOldToYoungSmall () {
157+ for (int i = 0 ; i < NUM_REFERENCES_SMALL ; i ++) {
158+ youngArraySmall [indicesSmall [NUM_REFERENCES_SMALL - i - 1 ]] = realRef ;
159+ }
160+ }
161+
162+ @ Benchmark
163+ @ CompilerControl (CompilerControl .Mode .DONT_INLINE )
164+ public void testArrayWriteBarrierFastPathYoungToOldSmall () {
165+ for (int i = 0 ; i < NUM_REFERENCES_SMALL ; i ++) {
166+ theArraySmall [indicesSmall [NUM_REFERENCES_SMALL - i - 1 ]] = youngRef ;
167+ }
168+ }
169+
170+ @ Benchmark
171+ @ CompilerControl (CompilerControl .Mode .DONT_INLINE )
172+ public void testArrayWriteBarrierFastPathYoungToYoungSmall () {
173+ for (int i = 0 ; i < NUM_REFERENCES_SMALL ; i ++) {
174+ youngArraySmall [indicesSmall [NUM_REFERENCES_SMALL - i - 1 ]] = youngRef ;
175+ }
176+ }
177+
178+ @ Benchmark
179+ @ CompilerControl (CompilerControl .Mode .DONT_INLINE )
180+ public void testArrayWriteBarrierFastPathNullYoungSmall () {
181+ for (int i = 0 ; i < NUM_REFERENCES_SMALL ; i ++) {
182+ youngArraySmall [indicesSmall [NUM_REFERENCES_SMALL - i - 1 ]] = nullRef ;
183+ }
184+ }
185+
186+ @ Benchmark
187+ @ CompilerControl (CompilerControl .Mode .DONT_INLINE )
188+ public void testArrayWriteBarrierFastPathOldToYoungLarge () {
189+ for (int i = 0 ; i < NUM_REFERENCES_LARGE ; i ++) {
190+ youngArrayLarge [indicesLarge [NUM_REFERENCES_LARGE - i - 1 ]] = realRef ;
191+ }
192+ }
193+
194+ @ Benchmark
195+ @ CompilerControl (CompilerControl .Mode .DONT_INLINE )
196+ public void testArrayWriteBarrierFastPathYoungToYoungLarge () {
197+ for (int i = 0 ; i < NUM_REFERENCES_LARGE ; i ++) {
198+ youngArrayLarge [indicesLarge [NUM_REFERENCES_LARGE - i - 1 ]] = youngRef ;
199+ }
200+ }
201+
202+ @ Benchmark
203+ @ CompilerControl (CompilerControl .Mode .DONT_INLINE )
204+ public void testArrayWriteBarrierFastPathNullYoungLarge () {
205+ for (int i = 0 ; i < NUM_REFERENCES_LARGE ; i ++) {
206+ youngArrayLarge [indicesLarge [NUM_REFERENCES_LARGE - i - 1 ]] = nullRef ;
207+ }
208+ }
209+
210+ @ Benchmark
211+ @ CompilerControl (CompilerControl .Mode .DONT_INLINE )
212+ public void testArrayWriteBarrierFastPathYoungToOldLarge () {
213+ for (int i = 0 ; i < NUM_REFERENCES_LARGE ; i ++) {
214+ theArrayLarge [indicesLarge [NUM_REFERENCES_LARGE - i - 1 ]] = youngRef ;
215+ }
216+ }
217+
136218 @ Benchmark
137219 @ CompilerControl (CompilerControl .Mode .DONT_INLINE )
138220 public void testArrayWriteBarrierFastPathNullSmall () {
@@ -166,6 +248,15 @@ public void testFieldWriteBarrierFastPath() {
166248 this .tail .clear ();
167249 }
168250
251+ @ Benchmark ()
252+ public void testFieldWriteBarrierFastPathYoungRef () {
253+ // Shuffle everything around
254+ this .tail .append (this .youngHead );
255+ this .head .clear ();
256+ this .head .append (this .youngTail );
257+ this .tail .clear ();
258+ }
259+
169260 // This run is useful to compare different GC barrier models without being
170261 // affected by C2 unrolling the main loop differently for each model.
171262 @ Fork (value = 3 , jvmArgs = {"-XX:LoopUnrollLimit=1" })
0 commit comments