AllocationCodeBlobTest.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/*
26 * @test AllocationCodeBlobTest
27 * @summary testing of WB::allocate/freeCodeBlob()
28 * @bug 8059624 8064669
29 * @library /testlibrary /test/lib /
30 * @modules java.base/jdk.internal.misc
31 *          java.management
32 * @build compiler.whitebox.AllocationCodeBlobTest
33 * @run driver ClassFileInstaller sun.hotspot.WhiteBox
34 *                                sun.hotspot.WhiteBox$WhiteBoxPermission
35 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
36 *                   -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,null::*
37 *                   -XX:-SegmentedCodeCache
38 *                   compiler.whitebox.AllocationCodeBlobTest
39 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
40 *                   -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,null::*
41 *                   -XX:+SegmentedCodeCache
42 *                   compiler.whitebox.AllocationCodeBlobTest
43 */
44
45package compiler.whitebox;
46
47import jdk.test.lib.Asserts;
48import jdk.test.lib.InfiniteLoop;
49import sun.hotspot.WhiteBox;
50import sun.hotspot.code.BlobType;
51
52import java.lang.management.MemoryPoolMXBean;
53import java.util.ArrayList;
54import java.util.EnumSet;
55
56public class AllocationCodeBlobTest {
57    private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
58    private static final long CODE_CACHE_SIZE
59            = WHITE_BOX.getUintxVMFlag("ReservedCodeCacheSize");
60    private static final int SIZE = 1;
61
62    public static void main(String[] args) {
63        // check that Sweeper handels dummy blobs correctly
64        Thread t = new Thread(
65                new InfiniteLoop(WHITE_BOX::forceNMethodSweep, 1L),
66                "ForcedSweeper");
67        t.setDaemon(true);
68        System.out.println("Starting " + t.getName());
69        t.start();
70
71        EnumSet<BlobType> blobTypes = BlobType.getAvailable();
72        for (BlobType type : blobTypes) {
73            new AllocationCodeBlobTest(type).test();
74        }
75
76        // check that deoptimization works well w/ dummy blobs
77        t = new Thread(
78                new InfiniteLoop(WHITE_BOX::deoptimizeAll, 1L),
79                "Deoptimize Thread");
80        t.setDaemon(true);
81        System.out.println("Starting " + t.getName());
82        t.start();
83
84        for (int i = 0; i < 10_000; ++i) {
85            for (BlobType type : blobTypes) {
86                long addr = WHITE_BOX.allocateCodeBlob(SIZE, type.id);
87            }
88        }
89
90    }
91
92    private final BlobType type;
93    private final MemoryPoolMXBean bean;
94    private AllocationCodeBlobTest(BlobType type) {
95        this.type = type;
96        bean = type.getMemoryPool();
97    }
98
99    private void test() {
100        System.out.printf("type %s%n", type);
101
102        // Measure the code cache usage after allocate/free.
103        long start = getUsage();
104        long addr1 = WHITE_BOX.allocateCodeBlob(SIZE, type.id);
105        long firstAllocation = getUsage();
106        WHITE_BOX.freeCodeBlob(addr1);
107        long firstFree = getUsage();
108        long addr2 = WHITE_BOX.allocateCodeBlob(SIZE, type.id);
109        long secondAllocation = getUsage();
110        WHITE_BOX.freeCodeBlob(addr2);
111
112        // The following code may trigger resolving of invokedynamic
113        // instructions and therefore method handle intrinsic creation
114        // in the code cache. Make sure this is executed after measuring
115        // the code cache usage.
116        Asserts.assertNE(0, addr1, "first allocation failed");
117        Asserts.assertNE(0, addr2, "second allocation failed");
118        Asserts.assertLTE(start + SIZE, firstAllocation,
119                "allocation should increase memory usage: "
120                + start + " + " + SIZE + " <= " + firstAllocation);
121        Asserts.assertLTE(firstFree, firstAllocation,
122                "free shouldn't increase memory usage: "
123                + firstFree + " <= " + firstAllocation);
124        Asserts.assertEQ(firstAllocation, secondAllocation);
125
126        System.out.println("allocating till possible...");
127        ArrayList<Long> blobs = new ArrayList<>();
128        int size = (int) (CODE_CACHE_SIZE >> 7);
129        while ((addr1 = WHITE_BOX.allocateCodeBlob(size, type.id)) != 0) {
130            blobs.add(addr1);
131        }
132        for (Long blob : blobs) {
133            WHITE_BOX.freeCodeBlob(blob);
134        }
135    }
136
137    private long getUsage() {
138        return bean.getUsage().getUsed();
139    }
140}
141