1 /*
  2  * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
  3  * Copyright (c) 2019, Twitter, Inc.
  4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5  *
  6  * This code is free software; you can redistribute it and/or modify it
  7  * under the terms of the GNU General Public License version 2 only, as
  8  * published by the Free Software Foundation.
  9  *
 10  * This code is distributed in the hope that it will be useful, but WITHOUT
 11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 13  * version 2 for more details (a copy is included in the LICENSE file that
 14  * accompanied this code).
 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  *
 24  */
 25 
 26 package gc.metaspace;
 27 
 28 import jdk.test.lib.Platform;
 29 import jdk.test.lib.process.ProcessTools;
 30 import jdk.test.lib.process.OutputAnalyzer;
 31 import java.util.ArrayList;
 32 import java.util.List;
 33 
 34 /* @test TestSizeTransitionsSerial
 35  * @requires vm.gc.Serial
 36  * @summary Tests that the metaspace size transition logging is done correctly.
 37  * @library /test/lib
 38  * @run driver gc.metaspace.TestSizeTransitions -XX:+UseSerialGC
 39  */
 40 
 41 /* @test TestSizeTransitionsParallel
 42  * @requires vm.gc.Parallel
 43  * @summary Tests that the metaspace size transition logging is done correctly.
 44  * @library /test/lib
 45  * @run driver gc.metaspace.TestSizeTransitions -XX:+UseParallelGC
 46  */
 47 
 48 /* @test TestSizeTransitionsG1
 49  * @requires vm.gc.G1
 50  * @summary Tests that the metaspace size transition logging is done correctly.
 51  * @library /test/lib
 52  * @run driver gc.metaspace.TestSizeTransitions -XX:+UseG1GC
 53  */
 54 
 55 public class TestSizeTransitions {
 56   public static class Run {
 57     public static void main(String... args) throws Exception {
 58       System.out.println("Run started.");
 59 
 60       // easiest way to generate a metaspace transition is to ask for a full GC
 61       System.gc();
 62 
 63       System.out.println("Run finished.");
 64     }
 65   }
 66 
 67   // matches the log tags
 68   //   e.g., [0.043s][info][gc]
 69   private static final String LOG_TAGS_REGEX = "(\\[.*\\])+ ";
 70 
 71   // matches a size transition
 72   //   e.g., 177K(4864K)->177K(4864K)
 73   private static final String SIZE_TRANSITION_REGEX = "\\d+K\\(\\d+K\\)->\\d+K\\(\\d+K\\)";
 74 
 75   // matches -coops metaspace size transitions
 76   private static final String NO_COMPRESSED_KLASS_POINTERS_REGEX =
 77     String.format("^%s.* Metaspace: %s$",
 78                   LOG_TAGS_REGEX,
 79                   SIZE_TRANSITION_REGEX);
 80 
 81   // matches +coops metaspace size transitions
 82   private static final String COMPRESSED_KLASS_POINTERS_REGEX =
 83     String.format("^%s.* Metaspace: %s NonClass: %s Class: %s$",
 84                   LOG_TAGS_REGEX,
 85                   SIZE_TRANSITION_REGEX,
 86                   SIZE_TRANSITION_REGEX,
 87                   SIZE_TRANSITION_REGEX);
 88 
 89   public static void main(String... args) throws Exception {
 90     // args: <gc-arg>
 91     if (args.length != 1) {
 92       throw new RuntimeException("wrong number of args: " + args.length);
 93     }
 94 
 95     final boolean hasCompressedKlassPointers = Platform.is64bit();
 96     final String gcArg = args[0];
 97 
 98     List<String> jvmArgs = new ArrayList<>();
 99     jvmArgs.add(gcArg);
100     jvmArgs.add("-Xmx256m");
101     jvmArgs.add("-Xlog:gc,gc+metaspace=info");
102     jvmArgs.add(TestSizeTransitions.Run.class.getName());
103 
104     System.out.println("JVM args:");
105     for (String a : jvmArgs) {
106       System.out.println("  " + a);
107     }
108 
109     final ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(jvmArgs);
110     final OutputAnalyzer output = new OutputAnalyzer(pb.start());
111     System.out.println(output.getStdout());
112     output.shouldHaveExitValue(0);
113 
114     if (hasCompressedKlassPointers) {
115       output.stdoutShouldMatch(COMPRESSED_KLASS_POINTERS_REGEX);
116       output.stdoutShouldNotMatch(NO_COMPRESSED_KLASS_POINTERS_REGEX);
117     } else {
118       output.stdoutShouldMatch(NO_COMPRESSED_KLASS_POINTERS_REGEX);
119       output.stdoutShouldNotMatch(COMPRESSED_KLASS_POINTERS_REGEX);
120     }
121   }
122 }