--- old/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java 2014-11-18 16:09:28.168848883 +0300 +++ new/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java 2014-11-18 16:09:28.008848886 +0300 @@ -151,7 +151,9 @@ public native void freeCodeBlob(long addr); public native void forceNMethodSweep(); public native Object[] getCodeHeapEntries(int type); - + public native int getCompilationActivityMode(); + public native Object[] getCodeBlob(long addr); + // Intered strings public native boolean isInStringTable(String str); --- old/test/testlibrary/whitebox/sun/hotspot/code/BlobType.java 2014-11-18 16:09:28.140848884 +0300 +++ new/test/testlibrary/whitebox/sun/hotspot/code/BlobType.java 2014-11-18 16:09:27.964848887 +0300 @@ -36,7 +36,13 @@ // Execution level 2 and 3 (profiled) nmethods MethodProfiled(1, "CodeHeap 'profiled nmethods'"), // Non-nmethods like Buffers, Adapters and Runtime Stubs - NonNMethod(2, "CodeHeap 'non-nmethods'"), + NonNMethod(2, "CodeHeap 'non-nmethods'") { + @Override + public boolean allowTypeWhenOverflow(BlobType type) { + return super.allowTypeWhenOverflow(type) + || type == BlobType.MethodNonProfiled; + } + }, // All types (No code cache segmentation) All(3, "CodeCache"); @@ -57,6 +63,11 @@ } return null; } + + public boolean allowTypeWhenOverflow(BlobType type) { + return false; + } + public static EnumSet getAvailable() { WhiteBox whiteBox = WhiteBox.getWhiteBox(); if (!whiteBox.getBooleanVMFlag("SegmentedCodeCache")) { --- old/test/testlibrary/whitebox/sun/hotspot/code/CodeBlob.java 2014-11-18 16:09:28.180848883 +0300 +++ new/test/testlibrary/whitebox/sun/hotspot/code/CodeBlob.java 2014-11-18 16:09:27.980848887 +0300 @@ -39,6 +39,13 @@ } return result; } + public static CodeBlob getCodeBlob(long addr) { + Object[] obj = WB.getCodeBlob(addr); + if (obj == null) { + return null; + } + return new CodeBlob(obj); + } protected CodeBlob(Object[] obj) { assert obj.length == 3; name = (String) obj[0]; --- /dev/null 2014-10-31 14:00:36.452833932 +0300 +++ new/test/compiler/codecache/OverflowCodeCacheTest.java 2014-11-18 16:09:27.992848886 +0300 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +import java.util.EnumSet; +import java.util.ArrayList; + +import sun.hotspot.WhiteBox; +import sun.hotspot.code.BlobType; +import sun.hotspot.code.CodeBlob; +import com.oracle.java.testlibrary.Asserts; + +/* + * @test OverflowCodeCacheTest + * @bug 8059550 + * @library /testlibrary /testlibrary/whitebox + * @build OverflowCodeCacheTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,null::* + * -XX:-SegmentedCodeCache OverflowCodeCacheTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,null::* + * -XX:+SegmentedCodeCache OverflowCodeCacheTest + * @summary testing of code cache segments overflow + */ +public class OverflowCodeCacheTest { + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + private static final long CODE_CACHE_SIZE + = WHITE_BOX.getUintxVMFlag("ReservedCodeCacheSize"); + + public static void main(String[] args) { + EnumSet blobTypes = BlobType.getAvailable(); + for (BlobType type : blobTypes) { + new OverflowCodeCacheTest(type).test(); + } + } + + private final BlobType type; + private OverflowCodeCacheTest(BlobType type) { + this.type = type; + } + + private void test() { + System.out.printf("type %s%n", type); + System.out.println("allocating till possible..."); + ArrayList blobs = new ArrayList<>(); + try { + long addr; + int size = (int) (CODE_CACHE_SIZE >> 7); + while ((addr = WHITE_BOX.allocateCodeBlob(size, type.id)) != 0) { + blobs.add(addr); + + BlobType actualType = CodeBlob.getCodeBlob(addr).code_blob_type; + if (actualType != type) { + // check we got allowed overflow handling + Asserts.assertTrue(type.allowTypeWhenOverflow(actualType), + type + " doesn't allow using " + actualType + " when overflow"); + } + } + Asserts.assertNotEquals(WHITE_BOX.getCompilationActivityMode(), 1 /* run_compilation*/, + "Compilation must be disabled when CodeCache(CodeHeap) overflows"); + } finally { + for (Long blob : blobs) { + WHITE_BOX.freeCodeBlob(blob); + } + } + } + +} --- old/src/share/vm/compiler/compileBroker.hpp 2014-11-18 16:09:28.300848881 +0300 +++ new/src/share/vm/compiler/compileBroker.hpp 2014-11-18 16:09:28.064848885 +0300 @@ -418,6 +418,7 @@ shutdown_compilaton = 2 }; + static jint get_compilation_activity_mode() { return _should_compile_new_jobs; } static bool should_compile_new_jobs() { return UseCompiler && (_should_compile_new_jobs == run_compilation); } static bool set_should_compile_new_jobs(jint new_state) { // Return success if the current caller set it --- old/src/share/vm/prims/whitebox.cpp 2014-11-18 16:09:28.308848881 +0300 +++ new/src/share/vm/prims/whitebox.cpp 2014-11-18 16:09:28.124848884 +0300 @@ -944,6 +944,16 @@ return result; WB_END +WB_ENTRY(jint, WB_GetCompilationActivityMode(JNIEnv* env, jobject o)) + return CompileBroker::get_compilation_activity_mode(); +WB_END + +WB_ENTRY(jobjectArray, WB_GetCodeBlob(JNIEnv* env, jobject o, jlong addr)) + ThreadToNativeFromVM ttn(thread); + CodeBlobStub stub((CodeBlob*) addr); + return codeBlob2objectArray(thread, env, &stub); +WB_END + WB_ENTRY(jlong, WB_GetThreadStackSize(JNIEnv* env, jobject o)) return (jlong) Thread::current()->stack_size(); WB_END @@ -1194,6 +1204,9 @@ {CC"allocateCodeBlob", CC"(II)J", (void*)&WB_AllocateCodeBlob }, {CC"freeCodeBlob", CC"(J)V", (void*)&WB_FreeCodeBlob }, {CC"getCodeHeapEntries", CC"(I)[Ljava/lang/Object;",(void*)&WB_GetCodeHeapEntries }, + {CC"getCompilationActivityMode", + CC"()I", (void*)&WB_GetCompilationActivityMode}, + {CC"getCodeBlob", CC"(J)[Ljava/lang/Object;",(void*)&WB_GetCodeBlob }, {CC"getThreadStackSize", CC"()J", (void*)&WB_GetThreadStackSize }, {CC"getThreadRemainingStackSize", CC"()J", (void*)&WB_GetThreadRemainingStackSize }, };