11/*
2- * Copyright (c) 2004, 2021 , Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 2004, 2022 , 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
4040 * PhantomRefence for NonbranchyTree and Referent calsses does not refer to
4141 * arrays, but to instances of the classes.
4242 * After that a thread performs next checks for the reference:
43- * 1. The reference is in queue after GC is provoked with
44- * Algorithms.eatMemory() method (a single thread eats the memory).
43+ * 1. The reference is in queue after GC is provoked with WB.fullGC()
4544 * 2. reference.get() returns null.
4645 * 3. queue.poll() returns the reference that was created.
4746 * 4. queue.poll() again returns null.
4847 * 5. If the checked type is class (Referent), then it must be finalized,
4948 * since the reference is already enqueued.
50- * 6. reference.clear() does not throw any exception.
5149 * The test extends ThreadedGCTest and implements GarbageProducerAware and
5250 * MemoryStrategyAware interfaces. The corresponding javadoc documentation
5351 * for additional test configuration.
5452 *
5553 * @library /vmTestbase
5654 * /test/lib
57- * @run main/othervm gc.gctests.PhantomReference.phantom001.phantom001 -ms low
55+ * @build jdk.test.whitebox.WhiteBox
56+ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
57+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.gctests.PhantomReference.phantom001.phantom001
5858 */
5959
6060package gc .gctests .PhantomReference .phantom001 ;
6161
6262import java .lang .ref .*;
6363import java .time .LocalTime ;
64+
65+ import jdk .test .whitebox .WhiteBox ;
6466import nsk .share .gc .*;
65- import nsk .share .gc .gp .*;
6667import nsk .share .gc .gp .string .InternedStringProducer ;
6768import nsk .share .gc .gp .string .RandomStringProducer ;
6869
69- public class phantom001 extends ThreadedGCTest implements GarbageProducerAware , MemoryStrategyAware {
70+ public class phantom001 extends ThreadedGCTest {
7071
71- private GarbageProducer garbageProducer ;
72- private MemoryStrategy memoryStrategy ;
7372 private InternedStringProducer internedStringProducer = new InternedStringProducer (new RandomStringProducer (10 ));
7473 // Total number of types to test
7574 final static int TYPES_COUNT = 12 ;
@@ -81,20 +80,12 @@ protected Runnable createRunnable(int i) {
8180 return new Test ();
8281 }
8382
84- public void setGarbageProducer (GarbageProducer garbageProducer ) {
85- this .garbageProducer = garbageProducer ;
86- }
87-
88- public void setMemoryStrategy (MemoryStrategy memoryStrategy ) {
89- this .memoryStrategy = memoryStrategy ;
90- }
91-
9283 public static void main (String [] args ) {
9384 GC .runTest (new phantom001 (), args );
9485 }
9586
9687 // The class implements the logic of the testcase
97- class Test implements Runnable , OOMStress {
88+ class Test implements Runnable {
9889
9990 int iteration ;
10091 private volatile boolean finalized ;
@@ -124,131 +115,120 @@ private boolean shouldTerminate() {
124115 return !getExecutionController ().continueExecution ();
125116 }
126117
127- private void eatMemory (int initialFactor ) {
128- GarbageUtils .eatMemory (getExecutionController (),
129- garbageProducer ,
130- initialFactor , 10 , 0 );
131- }
132-
133118 public void run () {
134- try {
135- int code = iteration % TYPES_COUNT ;
136- info ("start code " + code );
137- ReferenceQueue queue = new ReferenceQueue ();
138- PhantomReference reference ;
139- String type ;
140- // Define a specific type for each thread to test
141- switch (code ) {
142- case 0 :
143- reference = new PhantomReference (new byte [SIZE ], queue );
144- type = "byte" ;
145- break ;
146- case 1 :
147- reference = new PhantomReference (new short [SIZE ], queue );
148- type = "short" ;
149- break ;
150- case 2 :
151- reference = new PhantomReference (new int [SIZE ], queue );
152- type = "int" ;
153- break ;
154- case 3 :
155- reference = new PhantomReference (new long [SIZE ], queue );
156- type = "long" ;
157- break ;
158- case 4 :
159- reference = new PhantomReference (new char [SIZE ], queue );
160- type = "char" ;
161- break ;
162- case 5 :
163- reference = new PhantomReference (new boolean [SIZE ], queue );
164- type = "boolean" ;
165- break ;
166- case 6 :
167- reference = new PhantomReference (new double [SIZE ], queue );
168- type = "double" ;
169- break ;
170- case 7 :
171- reference = new PhantomReference (new float [SIZE ], queue );
172- type = "float" ;
173- break ;
174- case 8 :
175- reference = new PhantomReference (new Object [SIZE ], queue );
176- type = "Object" ;
177- break ;
178- case 9 :
179- reference = new PhantomReference (new NonbranchyTree (SIZE , 0.3f , SIZE ),
180- queue );
181- type = "NonbranchyTree" ;
182- break ;
183- case 10 :
184- reference = new PhantomReference (internedStringProducer .create (SIZE ), queue );
185- type = "InternedString" ;
186- break ;
187- default :
188- reference = new PhantomReference (new Referent (), queue );
189- type = "class" ;
190- }
191-
192- int initialFactor = memoryStrategy .equals (MemoryStrategy .HIGH ) ? 1 : (memoryStrategy .equals (MemoryStrategy .LOW ) ? 10 : 2 );
193119
194- // If referent is finalizable, provoke GCs and wait for finalization.
195- if (type .equals ("class" )) {
196- progress ("Waiting for finalization: " + type );
197- for (int checks = 0 ; !finalized && !shouldTerminate (); ++checks ) {
198- // There are scenarios where one eatMemory() isn't enough,
199- // but 10 iterations really ought to be sufficient.
200- if (checks > 10 ) {
201- fail ("Waiting for finalization: " + type );
202- return ;
203- }
204- eatMemory (initialFactor );
205- // Give some time for finalizer to run.
206- try {
207- Thread .sleep (100 );
208- } catch (InterruptedException e ) {}
209- }
210- }
120+ int code = iteration % TYPES_COUNT ;
121+ info ("start code " + code );
122+ ReferenceQueue queue = new ReferenceQueue ();
123+ PhantomReference reference ;
124+ String type ;
125+ // Define a specific type for each thread to test
126+ switch (code ) {
127+ case 0 :
128+ reference = new PhantomReference (new byte [SIZE ], queue );
129+ type = "byte" ;
130+ break ;
131+ case 1 :
132+ reference = new PhantomReference (new short [SIZE ], queue );
133+ type = "short" ;
134+ break ;
135+ case 2 :
136+ reference = new PhantomReference (new int [SIZE ], queue );
137+ type = "int" ;
138+ break ;
139+ case 3 :
140+ reference = new PhantomReference (new long [SIZE ], queue );
141+ type = "long" ;
142+ break ;
143+ case 4 :
144+ reference = new PhantomReference (new char [SIZE ], queue );
145+ type = "char" ;
146+ break ;
147+ case 5 :
148+ reference = new PhantomReference (new boolean [SIZE ], queue );
149+ type = "boolean" ;
150+ break ;
151+ case 6 :
152+ reference = new PhantomReference (new double [SIZE ], queue );
153+ type = "double" ;
154+ break ;
155+ case 7 :
156+ reference = new PhantomReference (new float [SIZE ], queue );
157+ type = "float" ;
158+ break ;
159+ case 8 :
160+ reference = new PhantomReference (new Object [SIZE ], queue );
161+ type = "Object" ;
162+ break ;
163+ case 9 :
164+ reference = new PhantomReference (new NonbranchyTree (SIZE , 0.3f , SIZE ),
165+ queue );
166+ type = "NonbranchyTree" ;
167+ break ;
168+ case 10 :
169+ reference = new PhantomReference (internedStringProducer .create (SIZE ), queue );
170+ type = "InternedString" ;
171+ break ;
172+ default :
173+ reference = new PhantomReference (new Referent (), queue );
174+ type = "class" ;
175+ }
211176
212- // Provoke GCs and wait for reference to be enqueued .
213- progress ( "Waiting for enqueue: " + type );
214- Reference polled = queue . poll ( );
215- for (int checks = 0 ; polled == null && !shouldTerminate (); ++checks ) {
216- // There are scenarios where one eatMemory () isn't enough,
177+ // If referent is finalizable, provoke GCs and wait for finalization .
178+ if ( type . equals ( "class" )) {
179+ progress ( "Waiting for finalization: " + type );
180+ for (int checks = 0 ; ! finalized && !shouldTerminate (); ++checks ) {
181+ // There are scenarios where one WB.fillGC () isn't enough,
217182 // but 10 iterations really ought to be sufficient.
218183 if (checks > 10 ) {
219- fail ("Waiting for enqueue : " + type );
184+ fail ("Waiting for finalization : " + type );
220185 return ;
221186 }
222- eatMemory ( initialFactor );
223- // Give some time for reference to be enqueued .
187+ WhiteBox . getWhiteBox (). fullGC ( );
188+ // Give some time for finalizer to run .
224189 try {
225- polled = queue . remove ( 100 );
190+ Thread . sleep ( checks * 100 );
226191 } catch (InterruptedException e ) {}
227192 }
193+ }
228194
229- if (polled == null && shouldTerminate ()) {
230- info ("Terminated: " + type );
195+ // Provoke GCs and wait for reference to be enqueued.
196+ progress ("Waiting for enqueue: " + type );
197+ Reference polled = queue .poll ();
198+ for (int checks = 0 ; polled == null && !shouldTerminate (); ++checks ) {
199+ // There are scenarios where one WB.fillGC() isn't enough,
200+ // but 10 iterations really ought to be sufficient.
201+ if (checks > 10 ) {
202+ fail ("Waiting for enqueue: " + type );
231203 return ;
232204 }
205+ WhiteBox .getWhiteBox ().fullGC ();
206+ // Give some time for reference to be enqueued.
207+ try {
208+ polled = queue .remove (checks * 100 );
209+ } catch (InterruptedException e ) {}
210+ }
233211
234- // The polled reference must be equal to the one enqueued to
235- // the queue
236- if (polled != reference ) {
237- fail ("The original reference is not equal to polled reference." );
238- return ;
239- }
212+ if (polled == null && shouldTerminate ()) {
213+ info ("Terminated: " + type );
214+ return ;
215+ }
240216
241- // queue.poll() once again must return null now, since there is
242- // only one reference in the queue
243- if (queue .poll () != null ) {
244- fail ("There are more than one reference in the queue." );
245- return ;
246- }
247- progress ("Finished: " + type );
248- } catch (OutOfMemoryError e ) {
249- } finally {
250- iteration ++;
217+ // The polled reference must be equal to the one enqueued to
218+ // the queue
219+ if (polled != reference ) {
220+ fail ("The original reference is not equal to polled reference." );
221+ return ;
222+ }
223+
224+ // queue.poll() once again must return null now, since there is
225+ // only one reference in the queue
226+ if (queue .poll () != null ) {
227+ fail ("There are more than one reference in the queue." );
228+ return ;
251229 }
230+ progress ("Finished: " + type );
231+ iteration ++;
252232 }
253233
254234 class Referent {
0 commit comments