/*
 * 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.
 *
 */

/**
 * @test
 * @bug 8031320
 * @summary Verify that if we use RTMDeopt, then deoptimization
 *          caused by reason other then rtm_state_change will reset
 *          method's RTM state. And if we don't use RTMDeopt, then
 *          RTM state remain the same after such deoptimization.
 * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
 * @build TestRTMAfterNonRTMDeopt
 * @run main ClassFileInstaller sun.hotspot.WhiteBox
 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
 *                   -XX:+WhiteBoxAPI TestRTMAfterNonRTMDeopt
 */

import java.util.List;
import com.oracle.java.testlibrary.*;
import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
import rtm.*;
import rtm.predicate.SupportedCPU;
import rtm.predicate.SupportedVM;
import sun.misc.Unsafe;

/**
 * To verify that with +UseRTMDeopt method's RTM state will be
 * changed to ProfileRTM on deoptimization unrelated to
 * rtm_state_change following sequence of events is used:
 * <pre>
 *
 *     rtm state ^
 *               |
 *       UseRTM  |      ******|     ******
 *               |            |
 *   ProfileRTM  |******|     |*****|
 *               |      |     |     |
 *              0-------|-----|-----|---------------------&gt; time
 *                      |     |     \ force abort
 *                      |     |
 *                      |     \ force deoptimization
 *                      |
 *                      \ force xabort
 * </pre>
 * When xabort is forced by native method call method should
 * change it's state to UseRTM, because we use RTMAbortRatio=100
 * and low RTMLockingThreshold, so at this point actual abort
 * ratio will be below 100% and there should be enough lock
 * attempts to recompile method without RTM profiling.
 */
public class TestRTMAfterNonRTMDeopt extends CommandLineOptionTest {
    private static final int ABORT_THRESHOLD = 1000;
    private static final String RANGE_CHECK = "range_check";

    private TestRTMAfterNonRTMDeopt() {
        super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
    }

    @Override
    protected void runTestCases() throws Throwable {
        verifyRTMAfterDeopt(false, false);
        verifyRTMAfterDeopt(true, false);

        verifyRTMAfterDeopt(false, true);
        verifyRTMAfterDeopt(true, true);
    }

    private void verifyRTMAfterDeopt(boolean useStackLock,
            boolean useRTMDeopt) throws Throwable {
        CompilableTest test = new Test();
        String logFile = String.format("rtm_%s_stack_lock_%s_deopt.xml",
                (useStackLock ? "use" : "no"), (useRTMDeopt ? "use" : "no"));

        OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
                logFile,
                test,
                "-XX:CompileThreshold=1",
                CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
                        useStackLock),
                CommandLineOptionTest.prepareBooleanFlag("UseRTMDeopt",
                        useRTMDeopt),
                "-XX:RTMAbortRatio=100",
                CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
                        TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD),
                CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
                        TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD / 2L),
                "-XX:RTMTotalCountIncrRate=1",
                "-XX:+PrintPreciseRTMLockingStatistics",
                Test.class.getName(),
                Boolean.toString(!useStackLock)
        );

        outputAnalyzer.shouldHaveExitValue(0);

        int traps = RTMTestBase.firedRTMStateChangeTraps(logFile);

        if (useRTMDeopt) {
            Asserts.assertEQ(traps, 2, "Two uncommon traps with "
                    + "reason rtm_state_change should be fired.");
        } else {
            Asserts.assertEQ(traps, 0, "No uncommon traps with "
                    + "reason rtm_state_change should be fired.");
        }

        int rangeCheckTraps = RTMTestBase.firedUncommonTraps(logFile,
                TestRTMAfterNonRTMDeopt.RANGE_CHECK);

        Asserts.assertEQ(rangeCheckTraps, 1,
                "One range_check uncommon trap should be fired.");

        List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
                test.getMethodWithLockName(), outputAnalyzer.getOutput());

        int expectedStatEntries = (useRTMDeopt ? 4 : 2);

        Asserts.assertEQ(statistics.size(), expectedStatEntries,
                String.format("VM output should contain %d RTM locking "
                        + "statistics entries.", expectedStatEntries));
    }

    public static class Test implements CompilableTest {
        // Following field have to be static in order to avoid escape analysis.
        @SuppressWarnings("UnsuedDeclaration")
        private static int field = 0;
        private static final int ITERATIONS = 10000;
        private static final int RANGE_CHECK_AT = ITERATIONS / 2;
        private static final Unsafe UNSAFE = Utils.getUnsafe();
        private final Object monitor = new Object();

        @Override
        public String getMethodWithLockName() {
            return this.getClass().getName() + "::forceAbort";
        }

        @Override
        public String[] getMethodsToCompileNames() {
            return new String[] { getMethodWithLockName() };
        }

        public void forceAbort(int a[], boolean abort) {
            try {
                synchronized(monitor) {
                    a[0]++;
                    if (abort) {
                        Test.field = Test.UNSAFE.addressSize();
                    }
                }
            } catch (Throwable t) {
                // suppress any throwables
            }
        }

        /**
         * Usage:
         * Test &lt;inflate monitor&gt;
         */
        public static void main(String args[]) throws Throwable {
            Test t = new Test();

            boolean shouldBeInflated = Boolean.valueOf(args[0]);
            if (shouldBeInflated) {
                AbortProvoker.inflateMonitor(t.monitor);
            }

            int tmp[] = new int[1];

            for (int i = 0; i < Test.ITERATIONS; i++ ) {
                AbortProvoker.verifyMonitorState(t.monitor, shouldBeInflated);
                if (i == Test.RANGE_CHECK_AT) {
                    t.forceAbort(new int[0], false);
                } else {
                    boolean isThreshold
                            = (i == TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD);
                    boolean isThresholdPlusRange
                            = (i == TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD
                            + Test.RANGE_CHECK_AT);
                    t.forceAbort(tmp, isThreshold || isThresholdPlusRange);
                }
            }
        }
    }

    public static void main(String args[]) throws Throwable {
        new TestRTMAfterNonRTMDeopt().test();
    }
}

