1/* 2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 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 24package gc.g1.humongousObjects; 25 26import jdk.test.lib.Asserts; 27import sun.hotspot.WhiteBox; 28 29import java.io.IOException; 30import java.net.URL; 31import java.net.URLClassLoader; 32import java.nio.file.Files; 33import java.nio.file.Path; 34import java.nio.file.Paths; 35 36/** 37 * @test gc.g1.humongousObjects.TestHumongousNonArrayAllocation 38 * @summary Checks that huge class' instances (ie with huge amount of fields) are allocated successfully 39 * @requires vm.gc.G1 40 * @requires vm.opt.G1HeapRegionSize == "null" | vm.opt.G1HeapRegionSize == "1M" 41 * @library /test/lib / 42 * @modules java.base/jdk.internal.misc 43 * @modules java.management 44 * @build sun.hotspot.WhiteBox 45 * @run driver ClassFileInstaller sun.hotspot.WhiteBox 46 * sun.hotspot.WhiteBox$WhiteBoxPermission 47 * 48 * @run main/othervm -Xms128M -Xmx128M -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. 49 * -XX:G1HeapRegionSize=1M 50 * gc.g1.humongousObjects.TestHumongousNonArrayAllocation LARGEST_NON_HUMONGOUS 51 * 52 * @run main/othervm -Xms128M -Xmx128M -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. 53 * -XX:G1HeapRegionSize=1M 54 * gc.g1.humongousObjects.TestHumongousNonArrayAllocation SMALLEST_HUMONGOUS 55 * 56 * @run main/othervm -Xms128M -Xmx128M -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. 57 * -XX:G1HeapRegionSize=1M 58 * gc.g1.humongousObjects.TestHumongousNonArrayAllocation ONE_REGION_HUMONGOUS 59 * 60 * @run main/othervm -Xms128M -Xmx128M -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. 61 * -XX:G1HeapRegionSize=1M 62 * gc.g1.humongousObjects.TestHumongousNonArrayAllocation TWO_REGION_HUMONGOUS 63 * 64 * @run main/othervm -Xms128M -Xmx128M -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. 65 * -XX:G1HeapRegionSize=1M 66 * gc.g1.humongousObjects.TestHumongousNonArrayAllocation MORE_THAN_TWO_REGION_HUMONGOUS 67 * 68 */ 69 70/** 71 * The test for objects which are instances of classes with a huge amount of fields. It's an alternative way to create 72 * a humongous object rather to allocate a long array. 73 * The size of a class object depends on the field declared in the class. So, the tests generates such classes to cover 74 * the following cases: 75 * largest non-humongous object (exactly half a region) 76 * smallest humongous object (half a region + sizeof(long)) 77 * humongous object that takes exactly one region 78 * humongous object that takes more than one region (region + sizeof(long)) 79 * humongous object that takes more than two regions (region * 2 + sizeof(long)) 80 * 81 */ 82public class TestHumongousNonArrayAllocation { 83 private static final WhiteBox WB = WhiteBox.getWhiteBox(); 84 private static final String CLASS_NAME_PREFIX = TestHumongousNonArrayAllocation.class.getSimpleName() + "_"; 85 86 public static void main(String[] args) throws ClassNotFoundException, InstantiationException, 87 IllegalAccessException, IOException { 88 89 if (args.length != 1) { 90 throw new Error("Test Bug: Expected class name wasn't provided as command line argument"); 91 } 92 G1SampleClass sampleClass = G1SampleClass.valueOf(args[0]); 93 94 Path wrkDir = Files.createTempDirectory(Paths.get(""), CLASS_NAME_PREFIX); 95 URL[] url = {wrkDir.toUri().toURL()}; 96 URLClassLoader urlLoader = new URLClassLoader(url); 97 98 Object sampleObject; 99 try { 100 sampleObject = sampleClass.getCls(urlLoader, wrkDir, CLASS_NAME_PREFIX).newInstance(); 101 } catch (Throwable throwable) { 102 throw new AssertionError("Test Bug: Cannot create object of provided class", throwable); 103 } 104 105 boolean isHumongous = WB.g1IsHumongous(sampleObject); 106 boolean shouldBeHumongous = (sampleClass.expectedInstanceSize() > (WB.g1RegionSize() / 2)); 107 108 // Sanity check 109 Asserts.assertEquals(WB.getObjectSize(sampleObject), sampleClass.expectedInstanceSize(), 110 String.format("Test Bug: Object of class %s is expected to take %d bytes but it takes %d.", 111 sampleClass.name(), sampleClass.expectedInstanceSize(), WB.getObjectSize(sampleObject))); 112 113 // Test check 114 Asserts.assertEquals(isHumongous, shouldBeHumongous, 115 String.format("Object of class %s is expected to be %shumongous but it is not", 116 sampleClass.name(), (shouldBeHumongous ? "" : "non-"))); 117 } 118 119} 120