Path: blob/master/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassPointers.java
40943 views
/*1* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 802492726* @summary Testing address of compressed class pointer space as best as possible.27* @requires vm.bits == 64 & !vm.graal.enabled28* @library /test/lib29* @modules java.base/jdk.internal.misc30* java.management31* @run driver CompressedClassPointers32*/3334import jdk.test.lib.Platform;35import jdk.test.lib.process.ProcessTools;36import jdk.test.lib.process.OutputAnalyzer;37import jtreg.SkippedException;3839public class CompressedClassPointers {4041static final String logging_option = "-Xlog:gc+metaspace=trace,cds=trace";4243// Returns true if we are to test the narrow klass base; we only do this on44// platforms where we can be reasonably shure that we get reproducable placement).45static boolean testNarrowKlassBase() {46if (Platform.isWindows()) {47return false;48}49return true;5051}5253// CDS off, small heap, ccs size default (1G)54// A small heap should allow us to place the ccs within the lower 32G and thus allow zero based encoding.55public static void smallHeapTest() throws Exception {56ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(57"-XX:+UnlockDiagnosticVMOptions",58"-XX:SharedBaseAddress=8g",59"-Xmx128m",60logging_option,61"-Xshare:off",62"-XX:+VerifyBeforeGC", "-version");63OutputAnalyzer output = new OutputAnalyzer(pb.start());64if (testNarrowKlassBase()) {65output.shouldContain("Narrow klass base: 0x0000000000000000");66}67output.shouldHaveExitValue(0);68}6970// CDS off, small heap, ccs size explicitely set to 1G71// A small heap should allow us to place the ccs within the lower 32G and thus allow zero based encoding.72public static void smallHeapTestWith1G() throws Exception {73ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(74"-XX:+UnlockDiagnosticVMOptions",75"-XX:CompressedClassSpaceSize=1g",76"-Xmx128m",77logging_option,78"-Xshare:off",79"-XX:+VerifyBeforeGC", "-version");80OutputAnalyzer output = new OutputAnalyzer(pb.start());81if (testNarrowKlassBase()) {82output.shouldContain("Narrow klass base: 0x0000000000000000, Narrow klass shift: 3");83}84output.shouldHaveExitValue(0);85}8687// CDS off, a very large heap, ccs size left to 1G default.88// We expect the ccs to be mapped somewhere far beyond the heap, such that it is not possible89// to use zero based encoding.90public static void largeHeapTest() throws Exception {91ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(92"-XX:+UnlockDiagnosticVMOptions",93"-XX:+UnlockExperimentalVMOptions",94"-Xmx30g",95logging_option,96"-Xshare:off",97"-XX:+VerifyBeforeGC", "-version");98OutputAnalyzer output = new OutputAnalyzer(pb.start());99if (testNarrowKlassBase() && !Platform.isPPC() && !Platform.isOSX()) {100// PPC: in most cases the heap cannot be placed below 32g so there101// is room for ccs and narrow klass base will be 0x0. Exception:102// Linux 4.1.42 or earlier (see ELF_ET_DYN_BASE in JDK-8244847).103// For simplicity we exclude PPC.104// OSX: similar.105output.shouldNotContain("Narrow klass base: 0x0000000000000000");106output.shouldContain("Narrow klass shift: 0");107}108output.shouldHaveExitValue(0);109}110111// Settings as in largeHeapTest() except for max heap size. We make max heap112// size even larger such that it cannot fit into lower 32G but not too large113// for compressed oops.114// We expect a zerobased ccs.115public static void largeHeapAbove32GTest() throws Exception {116ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(117"-XX:+UnlockDiagnosticVMOptions",118"-XX:+UnlockExperimentalVMOptions",119"-Xmx31g",120logging_option,121"-Xshare:off",122"-XX:+VerifyBeforeGC", "-version");123OutputAnalyzer output = new OutputAnalyzer(pb.start());124if (testNarrowKlassBase()) {125if (!(Platform.isAArch64() && Platform.isOSX())) { // see JDK-8262895126output.shouldContain("Narrow klass base: 0x0000000000000000");127if (!Platform.isAArch64() && !Platform.isOSX()) {128output.shouldContain("Narrow klass shift: 0");129}130}131}132output.shouldHaveExitValue(0);133}134135// Using large paged heap, metaspace uses small pages.136public static void largePagesForHeapTest() throws Exception {137ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(138"-XX:+UnlockDiagnosticVMOptions",139"-Xmx128m",140"-XX:+UseLargePages",141logging_option,142"-XX:+VerifyBeforeGC", "-version");143OutputAnalyzer output = new OutputAnalyzer(pb.start());144if (testNarrowKlassBase()) {145output.shouldContain("Narrow klass base:");146}147output.shouldHaveExitValue(0);148}149150public static void heapBaseMinAddressTest() throws Exception {151ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(152"-XX:HeapBaseMinAddress=1m",153"-Xlog:gc+heap+coops=debug",154"-version");155OutputAnalyzer output = new OutputAnalyzer(pb.start());156output.shouldContain("HeapBaseMinAddress must be at least");157output.shouldHaveExitValue(0);158}159160public static void sharingTest() throws Exception {161// Test small heaps162ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(163"-XX:+UnlockDiagnosticVMOptions",164"-XX:SharedArchiveFile=./CompressedClassPointers.jsa",165"-Xmx128m",166"-XX:SharedBaseAddress=8g",167"-XX:+VerifyBeforeGC",168"-Xshare:dump",169"-Xlog:cds,gc+heap+coops=debug");170OutputAnalyzer output = new OutputAnalyzer(pb.start());171if (output.firstMatch("Shared spaces are not supported in this VM") != null) {172return;173}174try {175output.shouldContain("Loading classes to share");176output.shouldHaveExitValue(0);177178pb = ProcessTools.createJavaProcessBuilder(179"-XX:+UnlockDiagnosticVMOptions",180"-XX:SharedArchiveFile=./CompressedClassPointers.jsa",181"-Xmx128m",182"-XX:SharedBaseAddress=8g",183"-Xlog:gc+heap+coops=debug",184"-Xshare:on",185"-version");186output = new OutputAnalyzer(pb.start());187output.shouldContain("sharing");188output.shouldHaveExitValue(0);189190} catch (RuntimeException e) {191output.shouldContain("Unable to use shared archive");192output.shouldHaveExitValue(1);193}194}195196public static void smallHeapTestNoCoop() throws Exception {197ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(198"-XX:-UseCompressedOops",199"-XX:+UseCompressedClassPointers",200"-XX:+UnlockDiagnosticVMOptions",201"-XX:SharedBaseAddress=8g",202"-Xmx128m",203"-Xlog:gc+metaspace=trace",204"-Xshare:off",205"-Xlog:cds=trace",206"-XX:+VerifyBeforeGC", "-version");207OutputAnalyzer output = new OutputAnalyzer(pb.start());208output.shouldContain("Narrow klass base: 0x0000000000000000");209output.shouldHaveExitValue(0);210}211212public static void smallHeapTestWith1GNoCoop() throws Exception {213ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(214"-XX:-UseCompressedOops",215"-XX:+UseCompressedClassPointers",216"-XX:+UnlockDiagnosticVMOptions",217"-XX:CompressedClassSpaceSize=1g",218"-Xmx128m",219"-Xlog:gc+metaspace=trace",220"-Xshare:off",221"-Xlog:cds=trace",222"-XX:+VerifyBeforeGC", "-version");223OutputAnalyzer output = new OutputAnalyzer(pb.start());224output.shouldContain("Narrow klass base: 0x0000000000000000");225if (!Platform.isAArch64()) {226// Currently relax this test for Aarch64.227output.shouldContain("Narrow klass shift: 0");228}229output.shouldHaveExitValue(0);230}231232public static void largeHeapTestNoCoop() throws Exception {233ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(234"-XX:-UseCompressedOops",235"-XX:+UseCompressedClassPointers",236"-XX:+UnlockDiagnosticVMOptions",237"-XX:+UnlockExperimentalVMOptions",238"-Xmx30g",239"-Xlog:gc+metaspace=trace",240"-Xshare:off",241"-Xlog:cds=trace",242"-XX:+VerifyBeforeGC", "-version");243OutputAnalyzer output = new OutputAnalyzer(pb.start());244output.shouldContain("Narrow klass base: 0x0000000000000000");245if (!Platform.isAArch64()) {246// Currently relax this test for Aarch64.247output.shouldContain("Narrow klass shift: 0");248}249output.shouldHaveExitValue(0);250}251252public static void largePagesTestNoCoop() throws Exception {253ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(254"-XX:-UseCompressedOops",255"-XX:+UseCompressedClassPointers",256"-XX:+UnlockDiagnosticVMOptions",257"-Xmx128m",258"-XX:+UseLargePages",259"-Xlog:gc+metaspace=trace",260"-XX:+VerifyBeforeGC", "-version");261OutputAnalyzer output = new OutputAnalyzer(pb.start());262output.shouldContain("Narrow klass base:");263output.shouldHaveExitValue(0);264}265266public static void heapBaseMinAddressTestNoCoop() throws Exception {267ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(268"-XX:-UseCompressedOops",269"-XX:+UseCompressedClassPointers",270"-XX:HeapBaseMinAddress=1m",271"-Xlog:gc+heap+coops=debug",272"-version");273OutputAnalyzer output = new OutputAnalyzer(pb.start());274output.shouldContain("HeapBaseMinAddress must be at least");275output.shouldHaveExitValue(0);276}277278public static void sharingTestNoCoop() throws Exception {279// Test small heaps280ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(281"-XX:-UseCompressedOops",282"-XX:+UseCompressedClassPointers",283"-XX:+UnlockDiagnosticVMOptions",284"-XX:SharedArchiveFile=./CompressedClassPointers.jsa",285"-Xmx128m",286"-XX:SharedBaseAddress=8g",287"-XX:+VerifyBeforeGC",288"-Xshare:dump",289"-Xlog:cds,gc+heap+coops=debug");290OutputAnalyzer output = new OutputAnalyzer(pb.start());291if (output.firstMatch("Shared spaces are not supported in this VM") != null) {292return;293}294try {295output.shouldContain("Loading classes to share");296output.shouldHaveExitValue(0);297298pb = ProcessTools.createJavaProcessBuilder(299"-XX:-UseCompressedOops",300"-XX:+UseCompressedClassPointers",301"-XX:+UnlockDiagnosticVMOptions",302"-XX:SharedArchiveFile=./CompressedClassPointers.jsa",303"-Xmx128m",304"-XX:SharedBaseAddress=8g",305"-Xlog:gc+heap+coops=debug",306"-Xshare:on",307"-version");308output = new OutputAnalyzer(pb.start());309output.shouldContain("sharing");310output.shouldHaveExitValue(0);311312} catch (RuntimeException e) {313output.shouldContain("Unable to use shared archive");314output.shouldHaveExitValue(1);315}316}317318public static void main(String[] args) throws Exception {319smallHeapTest();320smallHeapTestWith1G();321largeHeapTest();322largeHeapAbove32GTest();323largePagesForHeapTest();324heapBaseMinAddressTest();325sharingTest();326327if (!Platform.isOSX()) {328// Testing compressed class pointers without compressed oops.329// This is only possible if the platform supports it. Notably,330// on macOS, when compressed oops is disabled and the heap is331// given an arbitrary address, that address occasionally collides332// with where we would ideally have placed the compressed class333// space. Therefore, macOS is omitted for now.334smallHeapTestNoCoop();335smallHeapTestWith1GNoCoop();336largeHeapTestNoCoop();337largePagesTestNoCoop();338heapBaseMinAddressTestNoCoop();339sharingTestNoCoop();340}341}342}343344345