/*
 * 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.lang.reflect.Constructor;
import java.lang.reflect.Method;

import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Label;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import static jdk.internal.org.objectweb.asm.Opcodes.*;

/**
 * @test
 * @bug 8051344
 * @summary Force OSR compilation with non-empty stack at the OSR entry point.
 * @compile -XDignore.symbol.file TestOSRWithNonEmptyStack.java
 * @run main/othervm -XX:CompileOnly=TestCase.test TestOSRWithNonEmptyStack
 */
public class TestOSRWithNonEmptyStack extends ClassLoader {
    private static final int CLASS_FILE_VERSION = 52;
    private static final String CLASS_NAME = "TestCase";
    private static final String METHOD_NAME = "test";
    private static final int ITERATIONS = 1_000_000;

    private static byte[] generateTestClass() {
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);

        cw.visit(TestOSRWithNonEmptyStack.CLASS_FILE_VERSION, ACC_PUBLIC,
                TestOSRWithNonEmptyStack.CLASS_NAME, null, "java/lang/Object",
                null);

        TestOSRWithNonEmptyStack.generateConstructor(cw);
        TestOSRWithNonEmptyStack.generateTestMethod(cw);

        cw.visitEnd();
        return cw.toByteArray();
    }

    private static void generateConstructor(ClassWriter classWriter) {
        MethodVisitor mv = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V",
                null, null);

        mv.visitCode();

        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V",
                false);
        mv.visitInsn(RETURN);

        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    private static void generateTestMethod(ClassWriter classWriter) {
        MethodVisitor mv = classWriter.visitMethod(ACC_PUBLIC,
                TestOSRWithNonEmptyStack.METHOD_NAME, "()V", null, null);
        Label osrEntryPoint = new Label();

        mv.visitCode();
        // Push 'this' into stack before OSR entry point to bail out compilation
        mv.visitVarInsn(ALOAD, 0);
        // Setup loop counter
        mv.visitInsn(ICONST_0);
        mv.visitVarInsn(ISTORE, 1);
        // Begin loop
        mv.visitLabel(osrEntryPoint);
        // Increment loop counter
        mv.visitVarInsn(ILOAD, 1);
        mv.visitInsn(ICONST_1);
        mv.visitInsn(IADD);
        // Duplicate it for loop condition check
        mv.visitInsn(DUP);
        mv.visitVarInsn(ISTORE, 1);
        // Check loop condition
        mv.visitLdcInsn(TestOSRWithNonEmptyStack.ITERATIONS);
        mv.visitJumpInsn(IF_ICMPLT, osrEntryPoint);
        // Pop 'this'.
        mv.visitInsn(POP);
        mv.visitInsn(RETURN);

        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    private void run() {
        byte[] bytecode = TestOSRWithNonEmptyStack.generateTestClass();

        try {
            Class klass = defineClass(TestOSRWithNonEmptyStack.CLASS_NAME,
                    bytecode, 0, bytecode.length);

            Constructor ctor = klass.getConstructor();
            Method method = klass.getDeclaredMethod(
                    TestOSRWithNonEmptyStack.METHOD_NAME);

            Object testCase = ctor.newInstance();
            method.invoke(testCase);
        } catch (Exception e) {
            throw new RuntimeException(
                    "Test bug: generated class should be valid.", e);
        }
    }

    public static void main(String args[]) {
        new TestOSRWithNonEmptyStack().run();
    }
}
