/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.dx.dex.cf;

import com.android.dx.dex.code.DalvCode;
import com.android.dx.rop.code.RopMethod;

import java.io.PrintStream;

/**
 * Static methods and variables for collecting statistics on generated
 * code.
 */
public final class CodeStatistics {
    /** set to {@code true} to enable development-time debugging code */
    private static final boolean DEBUG = false;

    /**
     * running sum of the number of registers added/removed in
     * SSA form by the optimizer
     */
    public static int runningDeltaRegisters = 0;

    /**
     * running sum of the number of insns added/removed in
     * SSA form by the optimizer
     */
    public static int runningDeltaInsns = 0;

    /** running sum of the total number of Rop insns processed */
    public static int runningTotalInsns = 0;

    /**
     * running sum of the number of dex-form registers added/removed in
     * SSA form by the optimizer. Only valid if args.statistics is true.
     */
    public static int dexRunningDeltaRegisters = 0;

    /**
     * running sum of the number of dex-form insns (actually code
     * units) added/removed in SSA form by the optimizer. Only valid
     * if args.statistics is true.
     */
    public static int dexRunningDeltaInsns = 0;

    /**
     * running sum of the total number of dex insns (actually code
     * units) processed
     */
    public static int dexRunningTotalInsns = 0;

    /** running sum of original class bytecode bytes */
    public static int runningOriginalBytes = 0;

    /**
     * This class is uninstantiable.
     */
    private CodeStatistics() {
        // This space intentionally left blank.
    }

    /**
     * Updates the number of original bytecode bytes processed.
     *
     * @param count {@code >= 0;} the number of bytes to add
     */
    public static void updateOriginalByteCount(int count) {
        runningOriginalBytes += count;
    }

    /**
     * Updates the dex statistics.
     *
     * @param nonOptCode non-optimized code block
     * @param code optimized code block
     */
    public static void updateDexStatistics(DalvCode nonOptCode,
            DalvCode code) {
        if (DEBUG) {
            System.err.println("dex insns (old/new) "
                    + nonOptCode.getInsns().codeSize()
                    + "/" + code.getInsns().codeSize()
                    + " regs (o/n) "
                    + nonOptCode.getInsns().getRegistersSize()
                    + "/" + code.getInsns().getRegistersSize()
            );
        }

        dexRunningDeltaInsns
            += (code.getInsns().codeSize()
                - nonOptCode.getInsns().codeSize());

        dexRunningDeltaRegisters
            += (code.getInsns().getRegistersSize()
                - nonOptCode.getInsns().getRegistersSize());

        dexRunningTotalInsns += code.getInsns().codeSize();
    }

    /**
     * Updates the ROP statistics.
     *
     * @param nonOptRmeth non-optimized method
     * @param rmeth optimized method
     */
    public static void updateRopStatistics(RopMethod nonOptRmeth,
            RopMethod rmeth) {
        int oldCountInsns
                = nonOptRmeth.getBlocks().getEffectiveInstructionCount();
        int oldCountRegs = nonOptRmeth.getBlocks().getRegCount();

        if (DEBUG) {
            System.err.println("insns (old/new): "
                    + oldCountInsns + "/"
                    + rmeth.getBlocks().getEffectiveInstructionCount()
                    + " regs (o/n):" + oldCountRegs
                    + "/"  +  rmeth.getBlocks().getRegCount());
        }

        int newCountInsns
                = rmeth.getBlocks().getEffectiveInstructionCount();

        runningDeltaInsns
            += (newCountInsns - oldCountInsns);

        runningDeltaRegisters
            += (rmeth.getBlocks().getRegCount() - oldCountRegs);

        runningTotalInsns += newCountInsns;
    }

    /**
     * Prints out the collected statistics.
     *
     * @param out {@code non-null;} where to output to
     */
    public static void dumpStatistics(PrintStream out) {
        out.printf("Optimizer Delta Rop Insns: %d total: %d "
                + "(%.2f%%) Delta Registers: %d\n",
                runningDeltaInsns,
                runningTotalInsns,
                (100.0 * (((float) runningDeltaInsns)
                        / (runningTotalInsns + Math.abs(runningDeltaInsns)))),
                runningDeltaRegisters);

        out.printf("Optimizer Delta Dex Insns: Insns: %d total: %d "
                + "(%.2f%%) Delta Registers: %d\n",
                dexRunningDeltaInsns,
                dexRunningTotalInsns,
                (100.0 * (((float) dexRunningDeltaInsns)
                        / (dexRunningTotalInsns
                                + Math.abs(dexRunningDeltaInsns)))),
                dexRunningDeltaRegisters);

        out.printf("Original bytecode byte count: %d\n",
                runningOriginalBytes);
    }
}
