Wed, 27 Aug 2014 08:19:12 -0400
8046598: Scalable Native memory tracking development
Summary: Enhance scalability of native memory tracking
Reviewed-by: coleenp, ctornqvi, gtriantafill
fzhinkin@6997 | 1 | /* |
fzhinkin@6997 | 2 | * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. |
fzhinkin@6997 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
fzhinkin@6997 | 4 | * |
fzhinkin@6997 | 5 | * This code is free software; you can redistribute it and/or modify it |
fzhinkin@6997 | 6 | * under the terms of the GNU General Public License version 2 only, as |
fzhinkin@6997 | 7 | * published by the Free Software Foundation. |
fzhinkin@6997 | 8 | * |
fzhinkin@6997 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
fzhinkin@6997 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
fzhinkin@6997 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
fzhinkin@6997 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
fzhinkin@6997 | 13 | * accompanied this code). |
fzhinkin@6997 | 14 | * |
fzhinkin@6997 | 15 | * You should have received a copy of the GNU General Public License version |
fzhinkin@6997 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
fzhinkin@6997 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
fzhinkin@6997 | 18 | * |
fzhinkin@6997 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
fzhinkin@6997 | 20 | * or visit www.oracle.com if you need additional information or have any |
fzhinkin@6997 | 21 | * questions. |
fzhinkin@6997 | 22 | */ |
fzhinkin@6997 | 23 | |
fzhinkin@6997 | 24 | import java.lang.reflect.Constructor; |
fzhinkin@6997 | 25 | import java.lang.reflect.Method; |
fzhinkin@6997 | 26 | |
fzhinkin@6997 | 27 | import jdk.internal.org.objectweb.asm.ClassWriter; |
fzhinkin@6997 | 28 | import jdk.internal.org.objectweb.asm.Label; |
fzhinkin@6997 | 29 | import jdk.internal.org.objectweb.asm.MethodVisitor; |
fzhinkin@6997 | 30 | import static jdk.internal.org.objectweb.asm.Opcodes.*; |
fzhinkin@6997 | 31 | |
fzhinkin@6997 | 32 | /** |
fzhinkin@6997 | 33 | * @test |
fzhinkin@6997 | 34 | * @bug 8051344 |
fzhinkin@6997 | 35 | * @summary Force OSR compilation with non-empty stack at the OSR entry point. |
fzhinkin@6997 | 36 | * @compile -XDignore.symbol.file TestOSRWithNonEmptyStack.java |
fzhinkin@6997 | 37 | * @run main/othervm -XX:CompileOnly=TestCase.test TestOSRWithNonEmptyStack |
fzhinkin@6997 | 38 | */ |
fzhinkin@6997 | 39 | public class TestOSRWithNonEmptyStack extends ClassLoader { |
fzhinkin@6997 | 40 | private static final int CLASS_FILE_VERSION = 52; |
fzhinkin@6997 | 41 | private static final String CLASS_NAME = "TestCase"; |
fzhinkin@6997 | 42 | private static final String METHOD_NAME = "test"; |
fzhinkin@6997 | 43 | private static final int ITERATIONS = 1_000_000; |
fzhinkin@6997 | 44 | |
fzhinkin@6997 | 45 | private static byte[] generateTestClass() { |
fzhinkin@6997 | 46 | ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); |
fzhinkin@6997 | 47 | |
fzhinkin@6997 | 48 | cw.visit(TestOSRWithNonEmptyStack.CLASS_FILE_VERSION, ACC_PUBLIC, |
fzhinkin@6997 | 49 | TestOSRWithNonEmptyStack.CLASS_NAME, null, "java/lang/Object", |
fzhinkin@6997 | 50 | null); |
fzhinkin@6997 | 51 | |
fzhinkin@6997 | 52 | TestOSRWithNonEmptyStack.generateConstructor(cw); |
fzhinkin@6997 | 53 | TestOSRWithNonEmptyStack.generateTestMethod(cw); |
fzhinkin@6997 | 54 | |
fzhinkin@6997 | 55 | cw.visitEnd(); |
fzhinkin@6997 | 56 | return cw.toByteArray(); |
fzhinkin@6997 | 57 | } |
fzhinkin@6997 | 58 | |
fzhinkin@6997 | 59 | private static void generateConstructor(ClassWriter classWriter) { |
fzhinkin@6997 | 60 | MethodVisitor mv = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", |
fzhinkin@6997 | 61 | null, null); |
fzhinkin@6997 | 62 | |
fzhinkin@6997 | 63 | mv.visitCode(); |
fzhinkin@6997 | 64 | |
fzhinkin@6997 | 65 | mv.visitVarInsn(ALOAD, 0); |
fzhinkin@6997 | 66 | mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", |
fzhinkin@6997 | 67 | false); |
fzhinkin@6997 | 68 | mv.visitInsn(RETURN); |
fzhinkin@6997 | 69 | |
fzhinkin@6997 | 70 | mv.visitMaxs(0, 0); |
fzhinkin@6997 | 71 | mv.visitEnd(); |
fzhinkin@6997 | 72 | } |
fzhinkin@6997 | 73 | |
fzhinkin@6997 | 74 | private static void generateTestMethod(ClassWriter classWriter) { |
fzhinkin@6997 | 75 | MethodVisitor mv = classWriter.visitMethod(ACC_PUBLIC, |
fzhinkin@6997 | 76 | TestOSRWithNonEmptyStack.METHOD_NAME, "()V", null, null); |
fzhinkin@6997 | 77 | Label osrEntryPoint = new Label(); |
fzhinkin@6997 | 78 | |
fzhinkin@6997 | 79 | mv.visitCode(); |
fzhinkin@6997 | 80 | // Push 'this' into stack before OSR entry point to bail out compilation |
fzhinkin@6997 | 81 | mv.visitVarInsn(ALOAD, 0); |
fzhinkin@6997 | 82 | // Setup loop counter |
fzhinkin@6997 | 83 | mv.visitInsn(ICONST_0); |
fzhinkin@6997 | 84 | mv.visitVarInsn(ISTORE, 1); |
fzhinkin@6997 | 85 | // Begin loop |
fzhinkin@6997 | 86 | mv.visitLabel(osrEntryPoint); |
fzhinkin@6997 | 87 | // Increment loop counter |
fzhinkin@6997 | 88 | mv.visitVarInsn(ILOAD, 1); |
fzhinkin@6997 | 89 | mv.visitInsn(ICONST_1); |
fzhinkin@6997 | 90 | mv.visitInsn(IADD); |
fzhinkin@6997 | 91 | // Duplicate it for loop condition check |
fzhinkin@6997 | 92 | mv.visitInsn(DUP); |
fzhinkin@6997 | 93 | mv.visitVarInsn(ISTORE, 1); |
fzhinkin@6997 | 94 | // Check loop condition |
fzhinkin@6997 | 95 | mv.visitLdcInsn(TestOSRWithNonEmptyStack.ITERATIONS); |
fzhinkin@6997 | 96 | mv.visitJumpInsn(IF_ICMPLT, osrEntryPoint); |
fzhinkin@6997 | 97 | // Pop 'this'. |
fzhinkin@6997 | 98 | mv.visitInsn(POP); |
fzhinkin@6997 | 99 | mv.visitInsn(RETURN); |
fzhinkin@6997 | 100 | |
fzhinkin@6997 | 101 | mv.visitMaxs(0, 0); |
fzhinkin@6997 | 102 | mv.visitEnd(); |
fzhinkin@6997 | 103 | } |
fzhinkin@6997 | 104 | |
fzhinkin@6997 | 105 | private void run() { |
fzhinkin@6997 | 106 | byte[] bytecode = TestOSRWithNonEmptyStack.generateTestClass(); |
fzhinkin@6997 | 107 | |
fzhinkin@6997 | 108 | try { |
fzhinkin@6997 | 109 | Class klass = defineClass(TestOSRWithNonEmptyStack.CLASS_NAME, |
fzhinkin@6997 | 110 | bytecode, 0, bytecode.length); |
fzhinkin@6997 | 111 | |
fzhinkin@6997 | 112 | Constructor ctor = klass.getConstructor(); |
fzhinkin@6997 | 113 | Method method = klass.getDeclaredMethod( |
fzhinkin@6997 | 114 | TestOSRWithNonEmptyStack.METHOD_NAME); |
fzhinkin@6997 | 115 | |
fzhinkin@6997 | 116 | Object testCase = ctor.newInstance(); |
fzhinkin@6997 | 117 | method.invoke(testCase); |
fzhinkin@6997 | 118 | } catch (Exception e) { |
fzhinkin@6997 | 119 | throw new RuntimeException( |
fzhinkin@6997 | 120 | "Test bug: generated class should be valid.", e); |
fzhinkin@6997 | 121 | } |
fzhinkin@6997 | 122 | } |
fzhinkin@6997 | 123 | |
fzhinkin@6997 | 124 | public static void main(String args[]) { |
fzhinkin@6997 | 125 | new TestOSRWithNonEmptyStack().run(); |
fzhinkin@6997 | 126 | } |
fzhinkin@6997 | 127 | } |