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 gc.testlibrary.Helpers;
27import jdk.test.lib.Asserts;
28import sun.hotspot.WhiteBox;
29
30/**
31 * @test TestHumongousThreshold
32 * @summary Checks that objects larger than half a region are allocated as humongous
33 * @requires vm.gc.G1
34 * @library /test/lib /
35 * @modules java.base/jdk.internal.misc
36 * @modules java.management
37 * @build sun.hotspot.WhiteBox
38 * @run driver ClassFileInstaller sun.hotspot.WhiteBox
39 *                                sun.hotspot.WhiteBox$WhiteBoxPermission
40 *
41 * @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
42 * -XX:G1HeapRegionSize=1M
43 * gc.g1.humongousObjects.TestHumongousThreshold
44 *
45 * @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
46 * -XX:G1HeapRegionSize=2M
47 * gc.g1.humongousObjects.TestHumongousThreshold
48 *
49 * @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
50 * -XX:G1HeapRegionSize=4M
51 * gc.g1.humongousObjects.TestHumongousThreshold
52 *
53 * @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
54 * -XX:G1HeapRegionSize=8M
55 * gc.g1.humongousObjects.TestHumongousThreshold
56 *
57 * @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
58 * -Xms128M -XX:G1HeapRegionSize=16M
59 * gc.g1.humongousObjects.TestHumongousThreshold
60 *
61 * @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
62 * -Xms200M -XX:G1HeapRegionSize=32M
63 * gc.g1.humongousObjects.TestHumongousThreshold
64 *
65 */
66
67public class TestHumongousThreshold {
68    private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
69    private static final int REGION_SIZE = WHITE_BOX.g1RegionSize();
70    private static final int MAX_CONTINUOUS_SIZE_CHECK = 129;
71    private static final int NON_HUMONGOUS_STEPS = 10;
72
73    /**
74     * The method allocates byte[] with specified size and checks that:
75     * 1. byte[] is allocated as we specified in expectedHumongous.
76     * 2. byte[] is allocated as humongous if its size is large than a half of region and non-humongous otherwise.
77     * It uses WB to obtain the size of created byte[]. Only objects larger than half of region are expected
78     * to be humongous.
79     *
80     * @param arraySize size of allocation
81     * @param expectedHumongous expected humongous/non-humongous allocation
82     * @return allocated byte array
83     */
84
85    private static void allocateAndCheck(int arraySize, boolean expectedHumongous) {
86        byte[] storage = new byte[arraySize];
87        long objectSize = WHITE_BOX.getObjectSize(storage);
88        boolean shouldBeHumongous = objectSize > (REGION_SIZE / 2);
89
90        Asserts.assertEquals(expectedHumongous, shouldBeHumongous, "Despite we expected this object to be "
91                + (expectedHumongous ? "humongous" : "non-humongous") + " it appeared otherwise when we checked "
92                + "object size - likely test bug; Allocation size = " + arraySize + "; Object size = " + objectSize
93                + "; region size = " + REGION_SIZE);
94
95        Asserts.assertEquals(WHITE_BOX.g1IsHumongous(storage), shouldBeHumongous,
96                "Object should be allocated as " + (shouldBeHumongous ? "humongous"
97                        : "non-humongous") + " but it wasn't; Allocation size = " + arraySize + "; Object size = "
98                        + objectSize + "; region size = " + REGION_SIZE);
99    }
100
101    public static void main(String[] args) {
102        int byteArrayMemoryOverhead = Helpers.detectByteArrayAllocationOverhead();
103
104        // Largest non-humongous byte[]
105        int maxByteArrayNonHumongousSize = (REGION_SIZE / 2) - byteArrayMemoryOverhead;
106
107        // Increment for non-humongous testing
108        int nonHumongousStep = maxByteArrayNonHumongousSize / NON_HUMONGOUS_STEPS;
109
110        // Maximum byte[] that takes one region
111        int maxByteArrayOneRegionSize = REGION_SIZE - byteArrayMemoryOverhead;
112
113        // Sizes in regions
114        // i,e, 1.0f means one region, 1.5f means one and half region etc
115        float[] humongousFactors = {0.8f, 1.0f, 1.2f, 1.5f, 1.7f, 2.0f, 2.5f};
116
117        // Some diagnostic output
118        System.out.format("%s started%n", TestHumongousThreshold.class.getName());
119        System.out.format("Actual G1 region size %d%n", REGION_SIZE);
120        System.out.format("byte[] memory overhead %d%n", byteArrayMemoryOverhead);
121
122        // Non-humongous allocations
123        System.out.format("Doing non-humongous allocations%n");
124
125        // Testing allocations with byte[] with length from 0 to MAX_CONTINUOUS_SIZE_CHECK
126        System.out.format("Testing allocations with byte[] with length from 0 to %d%n", MAX_CONTINUOUS_SIZE_CHECK);
127        for (int i = 0; i < MAX_CONTINUOUS_SIZE_CHECK; ++i) {
128            allocateAndCheck(i, false);
129        }
130
131        // Testing allocations with byte[] with length from 0 to nonHumongousStep * NON_HUMONGOUS_STEPS
132        System.out.format("Testing allocations with byte[] with length from 0 to %d with step %d%n",
133                nonHumongousStep * NON_HUMONGOUS_STEPS, nonHumongousStep);
134        for (int i = 0; i < NON_HUMONGOUS_STEPS; ++i) {
135            allocateAndCheck(i * nonHumongousStep, false);
136        }
137
138        // Testing allocations with byte[] of maximum non-humongous length
139        System.out.format("Testing allocations with byte[] of maximum non-humongous length %d%n",
140                maxByteArrayNonHumongousSize);
141        allocateAndCheck(maxByteArrayNonHumongousSize, false);
142
143        // Humongous allocations
144        System.out.format("Doing humongous allocations%n");
145        // Testing with minimum humongous object
146        System.out.format("Testing with byte[] of minimum humongous object %d%n", maxByteArrayNonHumongousSize + 1);
147        allocateAndCheck(maxByteArrayNonHumongousSize + 1, true);
148
149        // Testing allocations with byte[] with length from (maxByteArrayNonHumongousSize + 1) to
150        // (maxByteArrayNonHumongousSize + 1 + MAX_CONTINUOUS_SIZE_CHECK)
151        System.out.format("Testing allocations with byte[] with length from %d to %d%n",
152                maxByteArrayNonHumongousSize + 1, maxByteArrayNonHumongousSize + 1 + MAX_CONTINUOUS_SIZE_CHECK);
153        for (int i = 0; i < MAX_CONTINUOUS_SIZE_CHECK; ++i) {
154            allocateAndCheck(maxByteArrayNonHumongousSize + 1 + i, true);
155        }
156
157        // Checking that large (more than a half of region size) objects are humongous
158        System.out.format("Checking that large (more than a half of region size) objects are humongous%n");
159        for (float factor : humongousFactors) {
160            allocateAndCheck((int) (maxByteArrayOneRegionSize * factor), true);
161        }
162    }
163}
164