GetUsageTest.java revision 11707:ad7af1afda7a
1/*
2 * Copyright (c) 2014, 2015, 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
24/*
25 * @test GetUsageTest
26 * @summary testing of getUsage() for segmented code cache
27 * @modules java.base/jdk.internal.misc
28 *          java.management
29 * @library /testlibrary /test/lib /
30 *
31 * @build compiler.codecache.jmx.GetUsageTest
32 * @run driver ClassFileInstaller sun.hotspot.WhiteBox
33 *                                sun.hotspot.WhiteBox$WhiteBoxPermission
34 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
35 *     -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,null::*
36 *     -XX:-UseCodeCacheFlushing -XX:-MethodFlushing
37 *     -XX:+SegmentedCodeCache
38 *     compiler.codecache.jmx.GetUsageTest
39 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
40 *     -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,null::*
41 *     -XX:-UseCodeCacheFlushing -XX:-MethodFlushing
42 *     -XX:-SegmentedCodeCache
43 *     compiler.codecache.jmx.GetUsageTest
44 */
45
46package compiler.codecache.jmx;
47
48import jdk.test.lib.Asserts;
49import sun.hotspot.code.BlobType;
50
51import java.lang.management.MemoryPoolMXBean;
52import java.util.HashMap;
53import java.util.Map;
54
55public class GetUsageTest {
56
57    private final BlobType btype;
58    private final int allocateSize;
59
60    public GetUsageTest(BlobType btype, int allocSize) {
61        this.btype = btype;
62        this.allocateSize = allocSize;
63    }
64
65    public static void main(String[] args) throws Exception {
66        for (BlobType btype : BlobType.getAvailable()) {
67            for (int allocSize = 10; allocSize < 100000; allocSize *= 10) {
68                new GetUsageTest(btype, allocSize).runTest();
69            }
70        }
71    }
72
73    protected final Map<MemoryPoolMXBean, Long> getBeanUsages() {
74        Map<MemoryPoolMXBean, Long> beanUsages = new HashMap<>();
75        for (BlobType bt : BlobType.getAvailable()) {
76            beanUsages.put(bt.getMemoryPool(),
77                    bt.getMemoryPool().getUsage().getUsed());
78        }
79        return beanUsages;
80    }
81
82    protected void runTest() {
83        MemoryPoolMXBean[] predictableBeans = BlobType.getAvailable().stream()
84                .filter(CodeCacheUtils::isCodeHeapPredictable)
85                .map(BlobType::getMemoryPool)
86                .toArray(MemoryPoolMXBean[]::new);
87        Map<MemoryPoolMXBean, Long> initial = getBeanUsages();
88        long addr = 0;
89        try {
90            addr = CodeCacheUtils.WB.allocateCodeBlob(allocateSize, btype.id);
91            Map<MemoryPoolMXBean, Long> current = getBeanUsages();
92            long blockCount = Math.floorDiv(allocateSize
93                    + CodeCacheUtils.getHeaderSize(btype)
94                    + CodeCacheUtils.SEGMENT_SIZE - 1, CodeCacheUtils.SEGMENT_SIZE);
95            long usageUpperEstimate = Math.max(blockCount,
96                    CodeCacheUtils.MIN_BLOCK_LENGTH) * CodeCacheUtils.SEGMENT_SIZE;
97            for (MemoryPoolMXBean entry : predictableBeans) {
98                long diff = current.get(entry) - initial.get(entry);
99                if (entry.equals(btype.getMemoryPool())) {
100                    if (CodeCacheUtils.isCodeHeapPredictable(btype)) {
101                        Asserts.assertFalse(diff <= 0L || diff > usageUpperEstimate,
102                                String.format("Pool %s usage increase was reported "
103                                        + "unexpectedly as increased by %d using "
104                                        + "allocation size %d", entry.getName(),
105                                        diff, allocateSize));
106                    }
107                } else {
108                    CodeCacheUtils.assertEQorGTE(btype, diff, 0L,
109                            String.format("Pool %s usage changed unexpectedly while"
110                                    + " trying to increase: %s using allocation "
111                                    + "size %d", entry.getName(),
112                                    btype.getMemoryPool().getName(), allocateSize));
113                }
114            }
115        } finally {
116            if (addr != 0) {
117                CodeCacheUtils.WB.freeCodeBlob(addr);
118            }
119        }
120        System.out.printf("INFO: Scenario finished successfully for %s%n",
121                btype.getMemoryPool().getName());
122    }
123}
124