hotspot/test/runtime/SharedArchiveFile/SpaceUtilizationCheck.java
changeset 46746 ea379ebb9447
parent 46417 1593c061e6af
child 46779 d80ca591ae48
equal deleted inserted replaced
46745:f7b9bb98bb72 46746:ea379ebb9447
    26  * @summary Check if the space utilization for shared spaces is adequate
    26  * @summary Check if the space utilization for shared spaces is adequate
    27  * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
    27  * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
    28  * @library /test/lib
    28  * @library /test/lib
    29  * @modules java.base/jdk.internal.misc
    29  * @modules java.base/jdk.internal.misc
    30  *          java.management
    30  *          java.management
    31  * @run main SpaceUtilizationCheck
    31  * @build sun.hotspot.WhiteBox
       
    32  * @run main ClassFileInstaller sun.hotspot.WhiteBox
       
    33  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
       
    34  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SpaceUtilizationCheck
    32  */
    35  */
    33 
    36 
    34 import jdk.test.lib.cds.CDSTestUtils;
    37 import jdk.test.lib.cds.CDSTestUtils;
    35 import jdk.test.lib.process.OutputAnalyzer;
    38 import jdk.test.lib.process.OutputAnalyzer;
       
    39 import sun.hotspot.WhiteBox;
    36 
    40 
    37 import java.util.regex.Pattern;
    41 import java.util.regex.Pattern;
    38 import java.util.regex.Matcher;
    42 import java.util.regex.Matcher;
    39 import java.util.ArrayList;
    43 import java.util.ArrayList;
       
    44 import java.util.Hashtable;
    40 import java.lang.Integer;
    45 import java.lang.Integer;
    41 
    46 
    42 public class SpaceUtilizationCheck {
    47 public class SpaceUtilizationCheck {
    43     // Minimum allowed utilization value (percent)
    48     // [1] Each region must have strictly less than
    44     // The goal is to have this number to be 50% for RO and RW regions
    49     //     WhiteBox.metaspaceReserveAlignment() bytes of unused space.
    45     // Once that feature is implemented, increase the MIN_UTILIZATION to 50
    50     // [2] There must be no gap between two consecutive regions.
    46     private static final int MIN_UTILIZATION = 30;
       
    47 
       
    48     // Only RO and RW regions are considered for this check, since they
       
    49     // currently account for the bulk of the shared space
       
    50     private static final int NUMBER_OF_CHECKED_SHARED_REGIONS = 2;
       
    51 
    51 
    52     public static void main(String[] args) throws Exception {
    52     public static void main(String[] args) throws Exception {
    53         OutputAnalyzer output = CDSTestUtils.createArchive();
    53         // (1) Default VM arguments
       
    54         test();
       
    55 
       
    56         // (2) Use the now deprecated VM arguments. They should have no effect.
       
    57         test("-XX:SharedReadWriteSize=128M",
       
    58              "-XX:SharedReadOnlySize=128M",
       
    59              "-XX:SharedMiscDataSize=128M",
       
    60              "-XX:SharedMiscCodeSize=128M");
       
    61     }
       
    62 
       
    63     static void test(String... extra_options) throws Exception {
       
    64         OutputAnalyzer output = CDSTestUtils.createArchive(extra_options);
    54         CDSTestUtils.checkDump(output);
    65         CDSTestUtils.checkDump(output);
       
    66         Pattern pattern = Pattern.compile("^(..) space: *([0-9]+).* out of *([0-9]+) bytes .* at 0x([0-9a0-f]+)");
       
    67         WhiteBox wb = WhiteBox.getWhiteBox();
       
    68         long reserve_alignment = wb.metaspaceReserveAlignment();
       
    69         System.out.println("Metaspace::reserve_alignment() = " + reserve_alignment);
    55 
    70 
    56         String stdout = output.getStdout();
    71         long last_region = -1;
    57         ArrayList<String> utilization = findUtilization(stdout);
    72         Hashtable<String,String> checked = new Hashtable<>();
    58 
    73         for (String line : output.getStdout().split("\n")) {
    59         if (utilization.size() != NUMBER_OF_CHECKED_SHARED_REGIONS )
    74             if (line.contains(" space:") && !line.contains("st space:")) {
    60             throw new RuntimeException("The output format of sharing summary has changed");
    75                 Matcher matcher = pattern.matcher(line);
    61 
    76                 if (matcher.find()) {
    62         for(String str : utilization) {
    77                     String name = matcher.group(1);
    63             int value = Integer.parseInt(str);
    78                     if (name.equals("s0") || name.equals("s1")) {
    64             if (value < MIN_UTILIZATION) {
    79                       // String regions are listed at the end and they may not be fully occupied.
    65                 System.out.println(stdout);
    80                       break;
    66                 throw new RuntimeException("Utilization for one of the regions" +
    81                     } else {
    67                     "is below a threshold of " + MIN_UTILIZATION + "%");
    82                       System.out.println("Checking " + name + " in : " + line);
       
    83                       checked.put(name, name);
       
    84                     }
       
    85                     long used = Long.parseLong(matcher.group(2));
       
    86                     long capacity = Long.parseLong(matcher.group(3));
       
    87                     long address = Long.parseLong(matcher.group(4), 16);
       
    88                     long unused = capacity - used;
       
    89                     if (unused < 0) {
       
    90                         throw new RuntimeException("Unused space (" + unused + ") less than 0");
       
    91                     }
       
    92                     if (unused > reserve_alignment) {
       
    93                         // [1] Check for unused space
       
    94                         throw new RuntimeException("Unused space (" + unused + ") must be smaller than Metaspace::reserve_alignment() (" +
       
    95                                                    reserve_alignment + ")");
       
    96                     }
       
    97                     if (last_region >= 0 && address != last_region) {
       
    98                         // [2] Check for no-gap
       
    99                         throw new RuntimeException("Region 0x" + address + " should have started at 0x" + Long.toString(last_region, 16));
       
   100                     }
       
   101                     last_region = address + capacity;
       
   102                 }
    68             }
   103             }
    69         }
   104         }
    70     }
   105         if (checked.size() != 5) {
    71 
   106           throw new RuntimeException("Must have 5 consecutive, fully utilized regions");
    72     public static ArrayList<String> findUtilization(String input) {
       
    73         ArrayList<String> regions = filterRegionsOfInterest(input.split("\n"));
       
    74         return filterByPattern(filterByPattern(regions, "bytes \\[.*% used\\]"), "\\d+");
       
    75     }
       
    76 
       
    77     private static ArrayList<String> filterByPattern(Iterable<String> input, String pattern) {
       
    78         ArrayList<String> result = new ArrayList<String>();
       
    79         for (String str : input) {
       
    80             Matcher matcher = Pattern.compile(pattern).matcher(str);
       
    81             if (matcher.find()) {
       
    82                 result.add(matcher.group());
       
    83             }
       
    84         }
   107         }
    85         return result;
       
    86     }
       
    87 
       
    88     private static ArrayList<String> filterRegionsOfInterest(String[] inputLines) {
       
    89         ArrayList<String> result = new ArrayList<String>();
       
    90         for (String str : inputLines) {
       
    91             if (str.contains("ro space:") || str.contains("rw space:")) {
       
    92                 result.add(str);
       
    93             }
       
    94         }
       
    95         return result;
       
    96     }
   108     }
    97 }
   109 }