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 }
|