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