< prev index next >

test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegions.java

Print this page

 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 package gc.g1;
 25 
 26 /*
 27  * @test TestEagerReclaimHumongousRegions
 28  * @bug 8051973
 29  * @summary Test to make sure that eager reclaim of humongous objects correctly works.
 30  * @requires vm.gc.G1
 31  * @requires vm.debug
 32  * @library /test/lib /testlibrary /
 33  * @modules java.base/jdk.internal.misc
 34  *          java.management

 35  * @build jdk.test.whitebox.WhiteBox
 36  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 37  * @run main/othervm -XX:+UnlockDiagnosticVMOptions -Xbootclasspath/a:. -XX:+WhiteBoxAPI gc.g1.TestEagerReclaimHumongousRegions
 38  */
 39 
 40 import java.util.ArrayList;
 41 import java.util.List;
 42 import java.util.regex.Matcher;
 43 import java.util.regex.MatchResult;
 44 import java.util.regex.Pattern;
 45 
 46 import jdk.test.lib.Asserts;
 47 import jdk.test.lib.process.OutputAnalyzer;
 48 import jdk.test.lib.process.ProcessTools;
 49 import jdk.test.whitebox.WhiteBox;
 50 
 51 public class TestEagerReclaimHumongousRegions {
 52     private static final WhiteBox WB = WhiteBox.getWhiteBox();
 53 
 54     enum ObjectType { TYPE_ARRAY, OBJ_ARRAY }
 55     enum ReferencePolicy { KEEP, DROP }
 56     enum AllocationTiming { BEFORE_MARK_START, AFTER_MARK_START}
 57 
 58     enum ExpectedState {
 59         MARKED_CANDIDATE_RECLAIMED(true, true, true),
 60         MARKED_CANDIDATE_NOT_RECLAIMED(true, true, false),
 61         MARKED_NOTCANDIDATE_NOTRECLAIMED(true, false, false),
 62         NOTMARKED_CANDIDATE_RECLAIMED(false, true, true),
 63         NOTMARKED_CANDIDATE_NOTRECLAIMED(false, true, false),
 64         NOTMARKED_NOTCANDIDATE_NOTRECLAIMED(false, false, false);
 65 
 66         final boolean marked;
 67         final boolean candidate;
 68         final boolean reclaimed;
 69 
 70         ExpectedState(boolean marked, boolean candidate, boolean reclaimed) {
 71             this.marked = marked;
 72             this.candidate = candidate;
 73             this.reclaimed = reclaimed;
 74         }
 75     }
 76 
 77     /**
 78      * Run the helper VM, passing configuration arguments, simulating an application allocating some kind of humongous object at a
 79      * point during the induced concurrent mark, and executing a young gc.
 80      *
 81      * @param type Whether the allocated humongous object should be a typeArray, or an objArray.
 82      * @param refPolicy Drop the reference to the allocated object after reaching the given phase or keep.
 83      * @param timing Allocate the humongous objects before or after reaching the given phase.
 84      * @param phase The phase during concurrent mark to reach before triggering a young garbage collection.
 85      * @return Returns the stdout of the VM.
 86      */
 87     private static String runHelperVM(List<String> args, ObjectType type, ReferencePolicy refPolicy, AllocationTiming timing, String phase) throws Exception {
 88 
 89         boolean useTypeArray = (type == ObjectType.TYPE_ARRAY);
 90         boolean keepReference = (refPolicy == ReferencePolicy.KEEP);
 91         boolean allocateAfter = (timing == AllocationTiming.AFTER_MARK_START);
 92 
 93         args.add(TestEagerReclaimHumongousRegionsClearMarkBitsRunner.class.getName());
 94         args.add(String.valueOf(useTypeArray));
 95         args.add(String.valueOf(keepReference));
 96         args.add(String.valueOf(allocateAfter));
 97         args.add(phase);
 98 
 99         OutputAnalyzer output = ProcessTools.executeLimitedTestJava(args);








100 
101         String log = output.getStdout();
102         System.out.println(log);
103         output.shouldHaveExitValue(0);
104         return log;
105     }
106 
107     private static List<String> testArgs() throws Exception {
108         return List.of("-XX:+UseG1GC",
109                        "-Xmx20M",
110                        "-Xms20m",
111                        "-XX:+UnlockDiagnosticVMOptions",
112                        "-XX:+VerifyBeforeGC",
113                        "-XX:+VerifyAfterGC",
114                        "-XX:+VerifyDuringGC",
115                        "-XX:+G1VerifyBitmaps",
116                        "-Xbootclasspath/a:.",
117                        "-Xlog:gc=debug,gc+humongous=debug",
118                        "-XX:+UnlockDiagnosticVMOptions",
119                        "-XX:+WhiteBoxAPI");

137           found.add(matcher.toMatchResult());
138         }
139 
140         Asserts.assertTrue(found.size() == 1 || found.size() == 2, "Unexpected number of log messages " + found.size());
141 
142         if (found.size() == 2) {
143           Asserts.assertTrue(timing == AllocationTiming.BEFORE_MARK_START, "Should only have two messages if allocating the object before mark start");
144           MatchResult mr = found.removeFirst();
145           Asserts.assertTrue(mr.group(1).equals(boolToInt(false)), "Should not be marked before mark start " + mr.group());
146           Asserts.assertTrue(mr.group(2).equals(boolToInt(true)), "Should be candidate before mark start " + mr.group());
147         }
148 
149         MatchResult mr = found.removeFirst();
150         Asserts.assertTrue(mr.group(1).equals(boolToInt(expected.marked)), "Expected that region was " + (expected.marked ? "" : "not ") + " marked but is " + mr.group());
151         Asserts.assertTrue(mr.group(2).equals(boolToInt(expected.candidate)), "Expected that region was " + (expected.candidate ? "" : "not ") + " candidate but is " + mr.group());
152 
153         boolean reclaimed = Pattern.compile("Reclaimed humongous region .*").matcher(log).find();
154         Asserts.assertTrue(expected.reclaimed == reclaimed, "Wrong log output reclaiming humongous region");
155     }
156 
157     private static void runTest(ObjectType type,
158                                 ReferencePolicy refPolicy,
159                                 AllocationTiming timing,
160                                 String phase,
161                                 ExpectedState expected) throws Exception {
162         List<String> vmArgs = testArgs();
163 
164         ArrayList<String> args = new ArrayList(vmArgs);
165         String log = runHelperVM(args, type, refPolicy, timing, phase);
166         verifyLog(log, timing, expected);
167 
168         ArrayList<String> jfrArgs = new ArrayList(vmArgs);
169         jfrArgs.addLast("-XX:StartFlightRecording=settings=profile");
170         String jfrLog = runHelperVM(jfrArgs, type, refPolicy, timing, phase);
171         verifyLog(jfrLog, timing, expected);
172     }
173 
174     public static void main(String[] args) throws Exception {
175         System.out.println("Tests checking eager reclaim for when the object is allocated before mark start.");
176         runTest(ObjectType.TYPE_ARRAY, ReferencePolicy.DROP, AllocationTiming.BEFORE_MARK_START, WB.BEFORE_MARKING_COMPLETED, ExpectedState.MARKED_CANDIDATE_RECLAIMED);
177         runTest(ObjectType.TYPE_ARRAY, ReferencePolicy.DROP, AllocationTiming.BEFORE_MARK_START, WB.G1_BEFORE_REBUILD_COMPLETED, ExpectedState.MARKED_CANDIDATE_RECLAIMED);
178         runTest(ObjectType.TYPE_ARRAY, ReferencePolicy.DROP, AllocationTiming.BEFORE_MARK_START, WB.G1_BEFORE_CLEANUP_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_RECLAIMED);
179 
180         runTest(ObjectType.TYPE_ARRAY, ReferencePolicy.KEEP, AllocationTiming.BEFORE_MARK_START, WB.BEFORE_MARKING_COMPLETED, ExpectedState.MARKED_CANDIDATE_NOT_RECLAIMED);
181         runTest(ObjectType.TYPE_ARRAY, ReferencePolicy.KEEP, AllocationTiming.BEFORE_MARK_START, WB.G1_BEFORE_REBUILD_COMPLETED, ExpectedState.MARKED_CANDIDATE_NOT_RECLAIMED);
182         runTest(ObjectType.TYPE_ARRAY, ReferencePolicy.KEEP, AllocationTiming.BEFORE_MARK_START, WB.G1_BEFORE_CLEANUP_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_NOTRECLAIMED);
183 
184         runTest(ObjectType.OBJ_ARRAY, ReferencePolicy.DROP, AllocationTiming.BEFORE_MARK_START, WB.BEFORE_MARKING_COMPLETED, ExpectedState.MARKED_NOTCANDIDATE_NOTRECLAIMED);
185         runTest(ObjectType.OBJ_ARRAY, ReferencePolicy.DROP, AllocationTiming.BEFORE_MARK_START, WB.G1_BEFORE_REBUILD_COMPLETED, ExpectedState.MARKED_CANDIDATE_RECLAIMED);
186         runTest(ObjectType.OBJ_ARRAY, ReferencePolicy.DROP, AllocationTiming.BEFORE_MARK_START, WB.G1_BEFORE_CLEANUP_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_RECLAIMED);


187 
188         runTest(ObjectType.OBJ_ARRAY, ReferencePolicy.KEEP, AllocationTiming.BEFORE_MARK_START, WB.BEFORE_MARKING_COMPLETED, ExpectedState.MARKED_NOTCANDIDATE_NOTRECLAIMED);
189         runTest(ObjectType.OBJ_ARRAY, ReferencePolicy.KEEP, AllocationTiming.BEFORE_MARK_START, WB.G1_BEFORE_REBUILD_COMPLETED, ExpectedState.MARKED_CANDIDATE_NOT_RECLAIMED);
190         runTest(ObjectType.OBJ_ARRAY, ReferencePolicy.KEEP, AllocationTiming.BEFORE_MARK_START, WB.G1_BEFORE_CLEANUP_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_NOTRECLAIMED);

191 
192         System.out.println("Tests checking eager reclaim for when the object is allocated after mark start.");
193         // These must not be marked (as they were allocated after mark start), and they are always candidates. Reclamation depends on whether there is a reference.
194         runTest(ObjectType.TYPE_ARRAY, ReferencePolicy.DROP, AllocationTiming.AFTER_MARK_START, WB.BEFORE_MARKING_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_RECLAIMED);
195         runTest(ObjectType.TYPE_ARRAY, ReferencePolicy.DROP, AllocationTiming.AFTER_MARK_START, WB.G1_BEFORE_REBUILD_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_RECLAIMED);
196         runTest(ObjectType.TYPE_ARRAY, ReferencePolicy.DROP, AllocationTiming.AFTER_MARK_START, WB.G1_BEFORE_CLEANUP_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_RECLAIMED);
197 
198         runTest(ObjectType.TYPE_ARRAY, ReferencePolicy.KEEP, AllocationTiming.AFTER_MARK_START, WB.BEFORE_MARKING_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_NOTRECLAIMED);
199         runTest(ObjectType.TYPE_ARRAY, ReferencePolicy.KEEP, AllocationTiming.AFTER_MARK_START, WB.G1_BEFORE_REBUILD_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_NOTRECLAIMED);
200         runTest(ObjectType.TYPE_ARRAY, ReferencePolicy.KEEP, AllocationTiming.AFTER_MARK_START, WB.G1_BEFORE_CLEANUP_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_NOTRECLAIMED);
201 
202         runTest(ObjectType.OBJ_ARRAY, ReferencePolicy.DROP, AllocationTiming.AFTER_MARK_START, WB.BEFORE_MARKING_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_RECLAIMED);
203         runTest(ObjectType.OBJ_ARRAY, ReferencePolicy.DROP, AllocationTiming.AFTER_MARK_START, WB.G1_BEFORE_REBUILD_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_RECLAIMED);
204         runTest(ObjectType.OBJ_ARRAY, ReferencePolicy.DROP, AllocationTiming.AFTER_MARK_START, WB.G1_BEFORE_CLEANUP_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_RECLAIMED);


205 
206         runTest(ObjectType.OBJ_ARRAY, ReferencePolicy.KEEP, AllocationTiming.AFTER_MARK_START, WB.BEFORE_MARKING_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_NOTRECLAIMED);
207         runTest(ObjectType.OBJ_ARRAY, ReferencePolicy.KEEP, AllocationTiming.AFTER_MARK_START, WB.G1_BEFORE_REBUILD_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_NOTRECLAIMED);
208         runTest(ObjectType.OBJ_ARRAY, ReferencePolicy.KEEP, AllocationTiming.AFTER_MARK_START, WB.G1_BEFORE_CLEANUP_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_NOTRECLAIMED);







209     }
210 }
211 
212 class TestEagerReclaimHumongousRegionsClearMarkBitsRunner {










213     private static final WhiteBox WB = WhiteBox.getWhiteBox();
214     private static final int SIZE = 1024 * 1024;
215 
216     private static Object allocateHumongousObj(boolean useTypeArray) {
217         if (useTypeArray) {
218             return new int[SIZE];
219         } else {
220             return new Object[SIZE];


221         }
222     }
223 
224     public static void main(String[] args) throws Exception {
225         if (args.length != 4) {
226             throw new Exception("Invalid number of arguments " + args.length);
227         }
228         boolean useTypeArray = Boolean.parseBoolean(args[0]);
229         boolean keepReference = Boolean.parseBoolean(args[1]);
230         boolean allocateAfter = Boolean.parseBoolean(args[2]);
231         String phase = args[3];
232 
233         System.out.println("useTypeArray: " + useTypeArray + " keepReference: " + keepReference + " allocateAfter " + allocateAfter + " phase: " + phase);
234         WB.fullGC();
235 
236         Object largeObj = null; // Allocated humongous object.
237         if (!allocateAfter) {
238           largeObj = allocateHumongousObj(useTypeArray);
239         }
240 
241         WB.concurrentGCAcquireControl();
242         WB.concurrentGCRunTo(phase);
243 
244         System.out.println("Phase " + phase + " reached");
245 
246         if (allocateAfter) {
247           largeObj = allocateHumongousObj(useTypeArray);
248         }
249 
250         if (!keepReference) {
251           largeObj = null;
252         }
253         WB.youngGC(); // May reclaim the humongous object.
254 
255         WB.concurrentGCRunToIdle();
256 
257         System.out.println("Large object at " + largeObj); // Keepalive.
258     }
259 }

 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 package gc.g1;
 25 
 26 /*
 27  * @test TestEagerReclaimHumongousRegions
 28  * @bug 8051973
 29  * @summary Test to make sure that eager reclaim of humongous objects correctly works.
 30  * @requires vm.gc.G1
 31  * @requires vm.debug
 32  * @library /test/lib /testlibrary /
 33  * @modules java.base/jdk.internal.misc
 34  *          java.management
 35  * @enablePreview
 36  * @build jdk.test.whitebox.WhiteBox
 37  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 38  * @run main/othervm -XX:+UnlockDiagnosticVMOptions -Xbootclasspath/a:. -XX:+WhiteBoxAPI --enable-preview gc.g1.TestEagerReclaimHumongousRegions
 39  */
 40 
 41 import java.util.ArrayList;
 42 import java.util.List;
 43 import java.util.regex.Matcher;
 44 import java.util.regex.MatchResult;
 45 import java.util.regex.Pattern;
 46 
 47 import jdk.test.lib.Asserts;
 48 import jdk.test.lib.process.OutputAnalyzer;
 49 import jdk.test.lib.process.ProcessTools;
 50 import jdk.test.whitebox.WhiteBox;
 51 
 52 public class TestEagerReclaimHumongousRegions {
 53     private static final WhiteBox WB = WhiteBox.getWhiteBox();
 54 
 55     enum ArrayType { TYPE_ARRAY, OBJ_ARRAY, FLAT_TYPE_ARRAY, FLAT_OBJ_ARRAY }
 56     enum ReferencePolicy { KEEP, DROP }
 57     enum AllocationTiming { BEFORE_MARK_START, AFTER_MARK_START}
 58 
 59     enum ExpectedState {
 60         MARKED_CANDIDATE_RECLAIMED(true, true, true),
 61         MARKED_CANDIDATE_NOT_RECLAIMED(true, true, false),
 62         MARKED_NOTCANDIDATE_NOTRECLAIMED(true, false, false),
 63         NOTMARKED_CANDIDATE_RECLAIMED(false, true, true),
 64         NOTMARKED_CANDIDATE_NOTRECLAIMED(false, true, false),
 65         NOTMARKED_NOTCANDIDATE_NOTRECLAIMED(false, false, false);
 66 
 67         final boolean marked;
 68         final boolean candidate;
 69         final boolean reclaimed;
 70 
 71         ExpectedState(boolean marked, boolean candidate, boolean reclaimed) {
 72             this.marked = marked;
 73             this.candidate = candidate;
 74             this.reclaimed = reclaimed;
 75         }
 76     }
 77 
 78     /**
 79      * Run the helper VM, passing configuration arguments, simulating an application allocating some kind of humongous object at a
 80      * point during the induced concurrent mark, and executing a young gc.
 81      *
 82      * @param type Whether the allocated humongous object should be a typeArray, or an objArray.
 83      * @param refPolicy Drop the reference to the allocated object after reaching the given phase or keep.
 84      * @param timing Allocate the humongous objects before or after reaching the given phase.
 85      * @param phase The phase during concurrent mark to reach before triggering a young garbage collection.
 86      * @return Returns the stdout of the VM.
 87      */
 88     private static String runHelperVM(List<String> args, ArrayType type, ReferencePolicy refPolicy, AllocationTiming timing, String phase) throws Exception {
 89 
 90         int arrayKind = type.ordinal();
 91         boolean keepReference = (refPolicy == ReferencePolicy.KEEP);
 92         boolean allocateAfter = (timing == AllocationTiming.AFTER_MARK_START);
 93 
 94         OutputAnalyzer output = ProcessTools.executeLimitedTestJava("-XX:+UseG1GC",
 95                                                                     "-Xmx20M",
 96                                                                     "-Xms20M",
 97                                                                     "-XX:+UnlockDiagnosticVMOptions",
 98                                                                     "-XX:+VerifyAfterGC",
 99                                                                     "-Xbootclasspath/a:.",
100                                                                     "-Xlog:gc=debug,gc+humongous=debug",
101                                                                     "-XX:+UnlockDiagnosticVMOptions",
102                                                                     "-XX:+WhiteBoxAPI",
103                                                                     "--enable-preview",
104                                                                     TestEagerReclaimHumongousRegionsClearMarkBitsRunner.class.getName(),
105                                                                     String.valueOf(arrayKind),
106                                                                     String.valueOf(keepReference),
107                                                                     String.valueOf(allocateAfter),
108                                                                     phase);
109 
110         String log = output.getStdout();
111         System.out.println(log);
112         output.shouldHaveExitValue(0);
113         return log;
114     }
115 
116     private static List<String> testArgs() throws Exception {
117         return List.of("-XX:+UseG1GC",
118                        "-Xmx20M",
119                        "-Xms20m",
120                        "-XX:+UnlockDiagnosticVMOptions",
121                        "-XX:+VerifyBeforeGC",
122                        "-XX:+VerifyAfterGC",
123                        "-XX:+VerifyDuringGC",
124                        "-XX:+G1VerifyBitmaps",
125                        "-Xbootclasspath/a:.",
126                        "-Xlog:gc=debug,gc+humongous=debug",
127                        "-XX:+UnlockDiagnosticVMOptions",
128                        "-XX:+WhiteBoxAPI");

146           found.add(matcher.toMatchResult());
147         }
148 
149         Asserts.assertTrue(found.size() == 1 || found.size() == 2, "Unexpected number of log messages " + found.size());
150 
151         if (found.size() == 2) {
152           Asserts.assertTrue(timing == AllocationTiming.BEFORE_MARK_START, "Should only have two messages if allocating the object before mark start");
153           MatchResult mr = found.removeFirst();
154           Asserts.assertTrue(mr.group(1).equals(boolToInt(false)), "Should not be marked before mark start " + mr.group());
155           Asserts.assertTrue(mr.group(2).equals(boolToInt(true)), "Should be candidate before mark start " + mr.group());
156         }
157 
158         MatchResult mr = found.removeFirst();
159         Asserts.assertTrue(mr.group(1).equals(boolToInt(expected.marked)), "Expected that region was " + (expected.marked ? "" : "not ") + " marked but is " + mr.group());
160         Asserts.assertTrue(mr.group(2).equals(boolToInt(expected.candidate)), "Expected that region was " + (expected.candidate ? "" : "not ") + " candidate but is " + mr.group());
161 
162         boolean reclaimed = Pattern.compile("Reclaimed humongous region .*").matcher(log).find();
163         Asserts.assertTrue(expected.reclaimed == reclaimed, "Wrong log output reclaiming humongous region");
164     }
165 
166     private static void runTest(ArrayType type,
167                                 ReferencePolicy refPolicy,
168                                 AllocationTiming timing,
169                                 String phase,
170                                 ExpectedState expected) throws Exception {
171         List<String> vmArgs = testArgs();
172 
173         ArrayList<String> args = new ArrayList(vmArgs);
174         String log = runHelperVM(args, type, refPolicy, timing, phase);
175         verifyLog(log, timing, expected);
176 
177         ArrayList<String> jfrArgs = new ArrayList(vmArgs);
178         jfrArgs.addLast("-XX:StartFlightRecording=settings=profile");
179         String jfrLog = runHelperVM(jfrArgs, type, refPolicy, timing, phase);
180         verifyLog(jfrLog, timing, expected);
181     }
182 
183     private static void runTestNoRefsFor(ArrayType ot) throws Exception {
184         System.out.println("Tests checking eager reclaim for when the object of type " + ot + " is allocated before mark start.");
185         runTest(ot, ReferencePolicy.DROP, AllocationTiming.BEFORE_MARK_START, WB.BEFORE_MARKING_COMPLETED, ExpectedState.MARKED_CANDIDATE_RECLAIMED);
186         runTest(ot, ReferencePolicy.DROP, AllocationTiming.BEFORE_MARK_START, WB.G1_BEFORE_REBUILD_COMPLETED, ExpectedState.MARKED_CANDIDATE_RECLAIMED);
187         runTest(ot, ReferencePolicy.DROP, AllocationTiming.BEFORE_MARK_START, WB.G1_BEFORE_CLEANUP_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_RECLAIMED);
188 
189         runTest(ot, ReferencePolicy.KEEP, AllocationTiming.BEFORE_MARK_START, WB.BEFORE_MARKING_COMPLETED, ExpectedState.MARKED_CANDIDATE_NOT_RECLAIMED);
190         runTest(ot, ReferencePolicy.KEEP, AllocationTiming.BEFORE_MARK_START, WB.G1_BEFORE_REBUILD_COMPLETED, ExpectedState.MARKED_CANDIDATE_NOT_RECLAIMED);
191         runTest(ot, ReferencePolicy.KEEP, AllocationTiming.BEFORE_MARK_START, WB.G1_BEFORE_CLEANUP_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_NOTRECLAIMED);
192 
193         System.out.println("Tests checking eager reclaim for when the object of type " + ot + " is allocated after mark start.");
194         // These must not be marked (as they were allocated after mark start), and they are always candidates. Reclamation depends on whether there is a reference.
195         runTest(ot, ReferencePolicy.DROP, AllocationTiming.AFTER_MARK_START, WB.BEFORE_MARKING_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_RECLAIMED);
196         runTest(ot, ReferencePolicy.DROP, AllocationTiming.AFTER_MARK_START, WB.G1_BEFORE_REBUILD_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_RECLAIMED);
197         runTest(ot, ReferencePolicy.DROP, AllocationTiming.AFTER_MARK_START, WB.G1_BEFORE_CLEANUP_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_RECLAIMED);
198 
199         runTest(ot, ReferencePolicy.KEEP, AllocationTiming.AFTER_MARK_START, WB.BEFORE_MARKING_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_NOTRECLAIMED);
200         runTest(ot, ReferencePolicy.KEEP, AllocationTiming.AFTER_MARK_START, WB.G1_BEFORE_REBUILD_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_NOTRECLAIMED);
201         runTest(ot, ReferencePolicy.KEEP, AllocationTiming.AFTER_MARK_START, WB.G1_BEFORE_CLEANUP_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_NOTRECLAIMED);
202     }
203 
204     private static void runTestWithRefsFor(ArrayType ot) throws Exception {
205         System.out.println("Tests checking eager reclaim for when the object of type " + ot + " is allocated before mark start.");
206         runTest(ot, ReferencePolicy.DROP, AllocationTiming.BEFORE_MARK_START, WB.BEFORE_MARKING_COMPLETED, ExpectedState.MARKED_NOTCANDIDATE_NOTRECLAIMED);
207         runTest(ot, ReferencePolicy.DROP, AllocationTiming.BEFORE_MARK_START, WB.G1_BEFORE_REBUILD_COMPLETED, ExpectedState.MARKED_CANDIDATE_RECLAIMED);
208         runTest(ot, ReferencePolicy.DROP, AllocationTiming.BEFORE_MARK_START, WB.G1_BEFORE_CLEANUP_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_RECLAIMED);
209 
210         runTest(ot, ReferencePolicy.KEEP, AllocationTiming.BEFORE_MARK_START, WB.BEFORE_MARKING_COMPLETED, ExpectedState.MARKED_NOTCANDIDATE_NOTRECLAIMED);
211         runTest(ot, ReferencePolicy.KEEP, AllocationTiming.BEFORE_MARK_START, WB.G1_BEFORE_REBUILD_COMPLETED, ExpectedState.MARKED_CANDIDATE_NOT_RECLAIMED);
212         runTest(ot, ReferencePolicy.KEEP, AllocationTiming.BEFORE_MARK_START, WB.G1_BEFORE_CLEANUP_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_NOTRECLAIMED);
213 
214         System.out.println("Tests checking eager reclaim for when the object of type " + ot + " is allocated after mark start.");
215         // These must not be marked (as they were allocated after mark start), and they are always candidates. Reclamation depends on whether there is a reference.
216         runTest(ot, ReferencePolicy.DROP, AllocationTiming.AFTER_MARK_START, WB.BEFORE_MARKING_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_RECLAIMED);
217         runTest(ot, ReferencePolicy.DROP, AllocationTiming.AFTER_MARK_START, WB.G1_BEFORE_REBUILD_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_RECLAIMED);
218         runTest(ot, ReferencePolicy.DROP, AllocationTiming.AFTER_MARK_START, WB.G1_BEFORE_CLEANUP_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_RECLAIMED);
219 
220         runTest(ot, ReferencePolicy.KEEP, AllocationTiming.AFTER_MARK_START, WB.BEFORE_MARKING_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_NOTRECLAIMED);
221         runTest(ot, ReferencePolicy.KEEP, AllocationTiming.AFTER_MARK_START, WB.G1_BEFORE_REBUILD_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_NOTRECLAIMED);
222         runTest(ot, ReferencePolicy.KEEP, AllocationTiming.AFTER_MARK_START, WB.G1_BEFORE_CLEANUP_COMPLETED, ExpectedState.NOTMARKED_CANDIDATE_NOTRECLAIMED);
223     }
224 
225     public static void main(String[] args) throws Exception {
226         runTestNoRefsFor(ArrayType.TYPE_ARRAY);
227         runTestWithRefsFor(ArrayType.OBJ_ARRAY);
228         runTestNoRefsFor(ArrayType.FLAT_TYPE_ARRAY);
229         runTestWithRefsFor(ArrayType.FLAT_OBJ_ARRAY);
230     }
231 }
232 
233 class TestEagerReclaimHumongousRegionsClearMarkBitsRunner {
234     value class RefValue {
235         Object o;
236         RefValue() { o = null; }
237     }
238 
239     value class IntValue {
240         int i;
241         IntValue() { i = 0; }
242     }
243 
244     private static final WhiteBox WB = WhiteBox.getWhiteBox();
245     private static final int SIZE = 1024 * 1024;
246 
247     private static Object allocateHumongousObj(int type) {
248         switch (type) {
249           case 0: return new int[SIZE];
250           case 1: return new Object[SIZE];
251           case 2: return new IntValue[SIZE];
252           case 3: return new RefValue[SIZE];
253           default: throw new RuntimeException("Unknown object type " + type);
254         }
255     }
256 
257     public static void main(String[] args) throws Exception {
258         if (args.length != 4) {
259             throw new Exception("Invalid number of arguments " + args.length);
260         }
261         int arrayType = Integer.parseInt(args[0]);
262         boolean keepReference = Boolean.parseBoolean(args[1]);
263         boolean allocateAfter = Boolean.parseBoolean(args[2]);
264         String phase = args[3];
265 
266         System.out.println("arrayType: " + arrayType + " keepReference: " + keepReference + " allocateAfter " + allocateAfter + " phase: " + phase);
267         WB.fullGC();
268 
269         Object largeObj = null; // Allocated humongous object.
270         if (!allocateAfter) {
271           largeObj = allocateHumongousObj(arrayType);
272         }
273 
274         WB.concurrentGCAcquireControl();
275         WB.concurrentGCRunTo(phase);
276 
277         System.out.println("Phase " + phase + " reached");
278 
279         if (allocateAfter) {
280           largeObj = allocateHumongousObj(arrayType);
281         }
282 
283         if (!keepReference) {
284           largeObj = null;
285         }
286         WB.youngGC(); // May reclaim the humongous object.
287 
288         WB.concurrentGCRunToIdle();
289 
290         System.out.println("Large object at " + largeObj); // Keepalive.
291     }
292 }
< prev index next >