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