/*
 * Copyright (C) 2010 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.
 */

/*
 * Liveness analysis for Dalvik bytecode.
 */
#include "Dalvik.h"
#include "analysis/Liveness.h"
#include "analysis/CodeVerify.h"

static bool processInstruction(VerifierData* vdata, u4 curIdx,
    BitVector* workBits);
static bool markDebugLocals(VerifierData* vdata);
static void dumpLiveState(const VerifierData* vdata, u4 curIdx,
    const BitVector* workBits);


/*
 * Create a table of instruction widths that indicate the width of the
 * *previous* instruction.  The values are copied from the width table
 * in "vdata", not derived from the instruction stream.
 *
 * Caller must free the return value.
 */
static InstructionWidth* createBackwardWidthTable(VerifierData* vdata)
{
    InstructionWidth* widths;

    widths = (InstructionWidth*)
            calloc(vdata->insnsSize, sizeof(InstructionWidth));
    if (widths == NULL)
        return NULL;

    u4 insnWidth = 0;
    for (u4 idx = 0; idx < vdata->insnsSize; ) {
        widths[idx] = insnWidth;
        insnWidth = dvmInsnGetWidth(vdata->insnFlags, idx);
        idx += insnWidth;
    }

    return widths;
}

/*
 * Compute the "liveness" of every register at all GC points.
 */
bool dvmComputeLiveness(VerifierData* vdata)
{
    const InsnFlags* insnFlags = vdata->insnFlags;
    InstructionWidth* backwardWidth;
    VfyBasicBlock* startGuess = NULL;
    BitVector* workBits;
    bool result = false;

    bool verbose = false; //= dvmWantVerboseVerification(vdata->method);
    if (verbose) {
        const Method* meth = vdata->method;
        ALOGI("Computing liveness for %s.%s:%s",
            meth->clazz->descriptor, meth->name, meth->shorty);
    }

    assert(vdata->registerLines != NULL);

    backwardWidth = createBackwardWidthTable(vdata);
    if (backwardWidth == NULL)
        goto bail;

    /*
     * Allocate space for intra-block work set.  Does not include space
     * for method result "registers", which aren't visible to the GC.
     * (They would be made live by move-result and then die on the
     * instruction immediately before it.)
     */
    workBits = dvmAllocBitVector(vdata->insnRegCount, false);
    if (workBits == NULL)
        goto bail;

    /*
     * We continue until all blocks have been visited, and no block
     * requires further attention ("visited" is set and "changed" is
     * clear).
     *
     * TODO: consider creating a "dense" array of basic blocks to make
     * the walking faster.
     */
    for (int iter = 0;;) {
        VfyBasicBlock* workBlock = NULL;

        if (iter++ > 100000) {
            LOG_VFY_METH(vdata->method, "oh dear");
            dvmAbort();
        }

        /*
         * If a block is marked "changed", we stop and handle it.  If it
         * just hasn't been visited yet, we remember it but keep searching
         * for one that has been changed.
         *
         * The thought here is that this is more likely to let us work
         * from end to start, which reduces the amount of re-evaluation
         * required (both by using "changed" as a work list, and by picking
         * un-visited blocks from the tail end of the method).
         */
        if (startGuess != NULL) {
            assert(startGuess->changed);
            workBlock = startGuess;
        } else {
            for (u4 idx = 0; idx < vdata->insnsSize; idx++) {
                VfyBasicBlock* block = vdata->basicBlocks[idx];
                if (block == NULL)
                    continue;

                if (block->changed) {
                    workBlock = block;
                    break;
                } else if (!block->visited) {
                    workBlock = block;
                }
            }
        }

        if (workBlock == NULL) {
            /* all done */
            break;
        }

        assert(workBlock->changed || !workBlock->visited);
        startGuess = NULL;

        /*
         * Load work bits.  These represent the liveness of registers
         * after the last instruction in the block has finished executing.
         */
        assert(workBlock->liveRegs != NULL);
        dvmCopyBitVector(workBits, workBlock->liveRegs);
        if (verbose) {
            ALOGI("Loaded work bits from last=0x%04x", workBlock->lastAddr);
            dumpLiveState(vdata, 0xfffd, workBlock->liveRegs);
            dumpLiveState(vdata, 0xffff, workBits);
        }

        /*
         * Process a single basic block.
         *
         * If this instruction is a GC point, we want to save the result
         * in the RegisterLine.
         *
         * We don't break basic blocks on every GC point -- in particular,
         * instructions that might throw but have no "try" block don't
         * end a basic block -- so there could be more than one GC point
         * in a given basic block.
         *
         * We could change this, but it turns out to be not all that useful.
         * At first glance it appears that we could share the liveness bit
         * vector between the basic block struct and the register line,
         * but the basic block needs to reflect the state *after* the
         * instruction has finished, while the GC points need to describe
         * the state before the instruction starts.
         */
        u4 curIdx = workBlock->lastAddr;
        while (true) {
            if (!processInstruction(vdata, curIdx, workBits))
                goto bail;

            if (verbose) {
                dumpLiveState(vdata, curIdx + 0x8000, workBits);
            }

            if (dvmInsnIsGcPoint(insnFlags, curIdx)) {
                BitVector* lineBits = vdata->registerLines[curIdx].liveRegs;
                if (lineBits == NULL) {
                    lineBits = vdata->registerLines[curIdx].liveRegs =
                        dvmAllocBitVector(vdata->insnRegCount, false);
                }
                dvmCopyBitVector(lineBits, workBits);
            }

            if (curIdx == workBlock->firstAddr)
                break;
            assert(curIdx >= backwardWidth[curIdx]);
            curIdx -= backwardWidth[curIdx];
        }

        workBlock->visited = true;
        workBlock->changed = false;

        if (verbose) {
            dumpLiveState(vdata, curIdx, workBits);
        }

        /*
         * Merge changes to all predecessors.  If the new bits don't match
         * the old bits, set the "changed" flag.
         */
        PointerSet* preds = workBlock->predecessors;
        size_t numPreds = dvmPointerSetGetCount(preds);
        unsigned int predIdx;

        for (predIdx = 0; predIdx < numPreds; predIdx++) {
            VfyBasicBlock* pred =
                    (VfyBasicBlock*) dvmPointerSetGetEntry(preds, predIdx);

            pred->changed = dvmCheckMergeBitVectors(pred->liveRegs, workBits);
            if (verbose) {
                ALOGI("merging cur=%04x into pred last=%04x (ch=%d)",
                    curIdx, pred->lastAddr, pred->changed);
                dumpLiveState(vdata, 0xfffa, pred->liveRegs);
                dumpLiveState(vdata, 0xfffb, workBits);
            }

            /*
             * We want to set the "changed" flag on unvisited predecessors
             * as a way of guiding the verifier through basic blocks in
             * a reasonable order.  We can't count on variable liveness
             * changing, so we force "changed" to true even if it hasn't.
             */
            if (!pred->visited)
                pred->changed = true;

            /*
             * Keep track of one of the changed blocks so we can start
             * there instead of having to scan through the list.
             */
            if (pred->changed)
                startGuess = pred;
        }
    }

#ifndef NDEBUG
    /*
     * Sanity check: verify that all GC point register lines have a
     * liveness bit vector allocated.  Also, we're not expecting non-GC
     * points to have them.
     */
    u4 checkIdx;
    for (checkIdx = 0; checkIdx < vdata->insnsSize; ) {
        if (dvmInsnIsGcPoint(insnFlags, checkIdx)) {
            if (vdata->registerLines[checkIdx].liveRegs == NULL) {
                LOG_VFY_METH(vdata->method,
                    "GLITCH: no liveRegs for GC point 0x%04x", checkIdx);
                dvmAbort();
            }
        } else if (vdata->registerLines[checkIdx].liveRegs != NULL) {
            LOG_VFY_METH(vdata->method,
                "GLITCH: liveRegs for non-GC point 0x%04x", checkIdx);
            dvmAbort();
        }
        u4 insnWidth = dvmInsnGetWidth(insnFlags, checkIdx);
        checkIdx += insnWidth;
    }
#endif

    /*
     * Factor in the debug info, if any.
     */
    if (!markDebugLocals(vdata))
        goto bail;

    result = true;

bail:
    free(backwardWidth);
    return result;
}


/*
 * Add a register to the LIVE set.
 */
static inline void GEN(BitVector* workBits, u4 regIndex)
{
    dvmSetBit(workBits, regIndex);
}

/*
 * Add a register pair to the LIVE set.
 */
static inline void GENW(BitVector* workBits, u4 regIndex)
{
    dvmSetBit(workBits, regIndex);
    dvmSetBit(workBits, regIndex+1);
}

/*
 * Remove a register from the LIVE set.
 */
static inline void KILL(BitVector* workBits, u4 regIndex)
{
    dvmClearBit(workBits, regIndex);
}

/*
 * Remove a register pair from the LIVE set.
 */
static inline void KILLW(BitVector* workBits, u4 regIndex)
{
    dvmClearBit(workBits, regIndex);
    dvmClearBit(workBits, regIndex+1);
}

/*
 * Process a single instruction.
 *
 * Returns "false" if something goes fatally wrong.
 */
static bool processInstruction(VerifierData* vdata, u4 insnIdx,
    BitVector* workBits)
{
    const Method* meth = vdata->method;
    const u2* insns = meth->insns + insnIdx;
    DecodedInstruction decInsn;

    dexDecodeInstruction(insns, &decInsn);

    /*
     * Add registers to the "GEN" or "KILL" sets.  We want to do KILL
     * before GEN to handle cases where the source and destination
     * register is the same.
     */
    switch (decInsn.opcode) {
    case OP_NOP:
    case OP_RETURN_VOID:
    case OP_GOTO:
    case OP_GOTO_16:
    case OP_GOTO_32:
        /* no registers are used */
        break;

    case OP_RETURN:
    case OP_RETURN_OBJECT:
    case OP_MONITOR_ENTER:
    case OP_MONITOR_EXIT:
    case OP_CHECK_CAST:
    case OP_THROW:
    case OP_PACKED_SWITCH:
    case OP_SPARSE_SWITCH:
    case OP_FILL_ARRAY_DATA:
    case OP_IF_EQZ:
    case OP_IF_NEZ:
    case OP_IF_LTZ:
    case OP_IF_GEZ:
    case OP_IF_GTZ:
    case OP_IF_LEZ:
    case OP_SPUT:
    case OP_SPUT_BOOLEAN:
    case OP_SPUT_BYTE:
    case OP_SPUT_CHAR:
    case OP_SPUT_SHORT:
    case OP_SPUT_OBJECT:
        /* action <- vA */
        GEN(workBits, decInsn.vA);
        break;

    case OP_RETURN_WIDE:
    case OP_SPUT_WIDE:
        /* action <- vA(wide) */
        GENW(workBits, decInsn.vA);
        break;

    case OP_IF_EQ:
    case OP_IF_NE:
    case OP_IF_LT:
    case OP_IF_GE:
    case OP_IF_GT:
    case OP_IF_LE:
    case OP_IPUT:
    case OP_IPUT_BOOLEAN:
    case OP_IPUT_BYTE:
    case OP_IPUT_CHAR:
    case OP_IPUT_SHORT:
    case OP_IPUT_OBJECT:
        /* action <- vA, vB */
        GEN(workBits, decInsn.vA);
        GEN(workBits, decInsn.vB);
        break;

    case OP_IPUT_WIDE:
        /* action <- vA(wide), vB */
        GENW(workBits, decInsn.vA);
        GEN(workBits, decInsn.vB);
        break;

    case OP_APUT:
    case OP_APUT_BOOLEAN:
    case OP_APUT_BYTE:
    case OP_APUT_CHAR:
    case OP_APUT_SHORT:
    case OP_APUT_OBJECT:
        /* action <- vA, vB, vC */
        GEN(workBits, decInsn.vA);
        GEN(workBits, decInsn.vB);
        GEN(workBits, decInsn.vC);
        break;

    case OP_APUT_WIDE:
        /* action <- vA(wide), vB, vC */
        GENW(workBits, decInsn.vA);
        GEN(workBits, decInsn.vB);
        GEN(workBits, decInsn.vC);
        break;

    case OP_FILLED_NEW_ARRAY:
    case OP_INVOKE_VIRTUAL:
    case OP_INVOKE_SUPER:
    case OP_INVOKE_DIRECT:
    case OP_INVOKE_STATIC:
    case OP_INVOKE_INTERFACE:
        /* action <- vararg */
        {
            unsigned int idx;
            for (idx = 0; idx < decInsn.vA; idx++) {
                GEN(workBits, decInsn.arg[idx]);
            }
        }
        break;

    case OP_FILLED_NEW_ARRAY_RANGE:
    case OP_INVOKE_VIRTUAL_RANGE:
    case OP_INVOKE_SUPER_RANGE:
    case OP_INVOKE_DIRECT_RANGE:
    case OP_INVOKE_STATIC_RANGE:
    case OP_INVOKE_INTERFACE_RANGE:
        /* action <- vararg/range */
        {
            unsigned int idx;
            for (idx = 0; idx < decInsn.vA; idx++) {
                GEN(workBits, decInsn.vC + idx);
            }
        }
        break;

    case OP_MOVE_RESULT:
    case OP_MOVE_RESULT_WIDE:
    case OP_MOVE_RESULT_OBJECT:
    case OP_MOVE_EXCEPTION:
    case OP_CONST_4:
    case OP_CONST_16:
    case OP_CONST:
    case OP_CONST_HIGH16:
    case OP_CONST_STRING:
    case OP_CONST_STRING_JUMBO:
    case OP_CONST_CLASS:
    case OP_NEW_INSTANCE:
    case OP_SGET:
    case OP_SGET_BOOLEAN:
    case OP_SGET_BYTE:
    case OP_SGET_CHAR:
    case OP_SGET_SHORT:
    case OP_SGET_OBJECT:
        /* vA <- value */
        KILL(workBits, decInsn.vA);
        break;

    case OP_CONST_WIDE_16:
    case OP_CONST_WIDE_32:
    case OP_CONST_WIDE:
    case OP_CONST_WIDE_HIGH16:
    case OP_SGET_WIDE:
        /* vA(wide) <- value */
        KILLW(workBits, decInsn.vA);
        break;

    case OP_MOVE:
    case OP_MOVE_FROM16:
    case OP_MOVE_16:
    case OP_MOVE_OBJECT:
    case OP_MOVE_OBJECT_FROM16:
    case OP_MOVE_OBJECT_16:
    case OP_INSTANCE_OF:
    case OP_ARRAY_LENGTH:
    case OP_NEW_ARRAY:
    case OP_IGET:
    case OP_IGET_BOOLEAN:
    case OP_IGET_BYTE:
    case OP_IGET_CHAR:
    case OP_IGET_SHORT:
    case OP_IGET_OBJECT:
    case OP_NEG_INT:
    case OP_NOT_INT:
    case OP_NEG_FLOAT:
    case OP_INT_TO_FLOAT:
    case OP_FLOAT_TO_INT:
    case OP_INT_TO_BYTE:
    case OP_INT_TO_CHAR:
    case OP_INT_TO_SHORT:
    case OP_ADD_INT_LIT16:
    case OP_RSUB_INT:
    case OP_MUL_INT_LIT16:
    case OP_DIV_INT_LIT16:
    case OP_REM_INT_LIT16:
    case OP_AND_INT_LIT16:
    case OP_OR_INT_LIT16:
    case OP_XOR_INT_LIT16:
    case OP_ADD_INT_LIT8:
    case OP_RSUB_INT_LIT8:
    case OP_MUL_INT_LIT8:
    case OP_DIV_INT_LIT8:
    case OP_REM_INT_LIT8:
    case OP_SHL_INT_LIT8:
    case OP_SHR_INT_LIT8:
    case OP_USHR_INT_LIT8:
    case OP_AND_INT_LIT8:
    case OP_OR_INT_LIT8:
    case OP_XOR_INT_LIT8:
        /* vA <- vB */
        KILL(workBits, decInsn.vA);
        GEN(workBits, decInsn.vB);
        break;

    case OP_IGET_WIDE:
    case OP_INT_TO_LONG:
    case OP_INT_TO_DOUBLE:
    case OP_FLOAT_TO_LONG:
    case OP_FLOAT_TO_DOUBLE:
        /* vA(wide) <- vB */
        KILLW(workBits, decInsn.vA);
        GEN(workBits, decInsn.vB);
        break;

    case OP_LONG_TO_INT:
    case OP_LONG_TO_FLOAT:
    case OP_DOUBLE_TO_INT:
    case OP_DOUBLE_TO_FLOAT:
        /* vA <- vB(wide) */
        KILL(workBits, decInsn.vA);
        GENW(workBits, decInsn.vB);
        break;

    case OP_MOVE_WIDE:
    case OP_MOVE_WIDE_FROM16:
    case OP_MOVE_WIDE_16:
    case OP_NEG_LONG:
    case OP_NOT_LONG:
    case OP_NEG_DOUBLE:
    case OP_LONG_TO_DOUBLE:
    case OP_DOUBLE_TO_LONG:
        /* vA(wide) <- vB(wide) */
        KILLW(workBits, decInsn.vA);
        GENW(workBits, decInsn.vB);
        break;

    case OP_CMPL_FLOAT:
    case OP_CMPG_FLOAT:
    case OP_AGET:
    case OP_AGET_BOOLEAN:
    case OP_AGET_BYTE:
    case OP_AGET_CHAR:
    case OP_AGET_SHORT:
    case OP_AGET_OBJECT:
    case OP_ADD_INT:
    case OP_SUB_INT:
    case OP_MUL_INT:
    case OP_REM_INT:
    case OP_DIV_INT:
    case OP_AND_INT:
    case OP_OR_INT:
    case OP_XOR_INT:
    case OP_SHL_INT:
    case OP_SHR_INT:
    case OP_USHR_INT:
    case OP_ADD_FLOAT:
    case OP_SUB_FLOAT:
    case OP_MUL_FLOAT:
    case OP_DIV_FLOAT:
    case OP_REM_FLOAT:
        /* vA <- vB, vC */
        KILL(workBits, decInsn.vA);
        GEN(workBits, decInsn.vB);
        GEN(workBits, decInsn.vC);
        break;

    case OP_AGET_WIDE:
        /* vA(wide) <- vB, vC */
        KILLW(workBits, decInsn.vA);
        GEN(workBits, decInsn.vB);
        GEN(workBits, decInsn.vC);
        break;

    case OP_CMPL_DOUBLE:
    case OP_CMPG_DOUBLE:
    case OP_CMP_LONG:
        /* vA <- vB(wide), vC(wide) */
        KILL(workBits, decInsn.vA);
        GENW(workBits, decInsn.vB);
        GENW(workBits, decInsn.vC);
        break;

    case OP_SHL_LONG:
    case OP_SHR_LONG:
    case OP_USHR_LONG:
        /* vA(wide) <- vB(wide), vC */
        KILLW(workBits, decInsn.vA);
        GENW(workBits, decInsn.vB);
        GEN(workBits, decInsn.vC);
        break;

    case OP_ADD_LONG:
    case OP_SUB_LONG:
    case OP_MUL_LONG:
    case OP_DIV_LONG:
    case OP_REM_LONG:
    case OP_AND_LONG:
    case OP_OR_LONG:
    case OP_XOR_LONG:
    case OP_ADD_DOUBLE:
    case OP_SUB_DOUBLE:
    case OP_MUL_DOUBLE:
    case OP_DIV_DOUBLE:
    case OP_REM_DOUBLE:
        /* vA(wide) <- vB(wide), vC(wide) */
        KILLW(workBits, decInsn.vA);
        GENW(workBits, decInsn.vB);
        GENW(workBits, decInsn.vC);
        break;

    case OP_ADD_INT_2ADDR:
    case OP_SUB_INT_2ADDR:
    case OP_MUL_INT_2ADDR:
    case OP_REM_INT_2ADDR:
    case OP_SHL_INT_2ADDR:
    case OP_SHR_INT_2ADDR:
    case OP_USHR_INT_2ADDR:
    case OP_AND_INT_2ADDR:
    case OP_OR_INT_2ADDR:
    case OP_XOR_INT_2ADDR:
    case OP_DIV_INT_2ADDR:
        /* vA <- vA, vB */
        /* KILL(workBits, decInsn.vA); */
        GEN(workBits, decInsn.vA);
        GEN(workBits, decInsn.vB);
        break;

    case OP_SHL_LONG_2ADDR:
    case OP_SHR_LONG_2ADDR:
    case OP_USHR_LONG_2ADDR:
        /* vA(wide) <- vA(wide), vB */
        /* KILLW(workBits, decInsn.vA); */
        GENW(workBits, decInsn.vA);
        GEN(workBits, decInsn.vB);
        break;

    case OP_ADD_LONG_2ADDR:
    case OP_SUB_LONG_2ADDR:
    case OP_MUL_LONG_2ADDR:
    case OP_DIV_LONG_2ADDR:
    case OP_REM_LONG_2ADDR:
    case OP_AND_LONG_2ADDR:
    case OP_OR_LONG_2ADDR:
    case OP_XOR_LONG_2ADDR:
    case OP_ADD_FLOAT_2ADDR:
    case OP_SUB_FLOAT_2ADDR:
    case OP_MUL_FLOAT_2ADDR:
    case OP_DIV_FLOAT_2ADDR:
    case OP_REM_FLOAT_2ADDR:
    case OP_ADD_DOUBLE_2ADDR:
    case OP_SUB_DOUBLE_2ADDR:
    case OP_MUL_DOUBLE_2ADDR:
    case OP_DIV_DOUBLE_2ADDR:
    case OP_REM_DOUBLE_2ADDR:
        /* vA(wide) <- vA(wide), vB(wide) */
        /* KILLW(workBits, decInsn.vA); */
        GENW(workBits, decInsn.vA);
        GENW(workBits, decInsn.vB);
        break;

    /* we will only see this if liveness analysis is done after general vfy */
    case OP_THROW_VERIFICATION_ERROR:
        /* no registers used */
        break;

    /* quickened instructions, not expected to appear */
    case OP_EXECUTE_INLINE:
    case OP_EXECUTE_INLINE_RANGE:
    case OP_IGET_QUICK:
    case OP_IGET_WIDE_QUICK:
    case OP_IGET_OBJECT_QUICK:
    case OP_IPUT_QUICK:
    case OP_IPUT_WIDE_QUICK:
    case OP_IPUT_OBJECT_QUICK:
    case OP_INVOKE_VIRTUAL_QUICK:
    case OP_INVOKE_VIRTUAL_QUICK_RANGE:
    case OP_INVOKE_SUPER_QUICK:
    case OP_INVOKE_SUPER_QUICK_RANGE:
        /* fall through to failure */

    /* correctness fixes, not expected to appear */
    case OP_INVOKE_OBJECT_INIT_RANGE:
    case OP_RETURN_VOID_BARRIER:
    case OP_SPUT_VOLATILE:
    case OP_SPUT_OBJECT_VOLATILE:
    case OP_SPUT_WIDE_VOLATILE:
    case OP_IPUT_VOLATILE:
    case OP_IPUT_OBJECT_VOLATILE:
    case OP_IPUT_WIDE_VOLATILE:
    case OP_SGET_VOLATILE:
    case OP_SGET_OBJECT_VOLATILE:
    case OP_SGET_WIDE_VOLATILE:
    case OP_IGET_VOLATILE:
    case OP_IGET_OBJECT_VOLATILE:
    case OP_IGET_WIDE_VOLATILE:
        /* fall through to failure */

    /* these should never appear during verification */
    case OP_UNUSED_3E:
    case OP_UNUSED_3F:
    case OP_UNUSED_40:
    case OP_UNUSED_41:
    case OP_UNUSED_42:
    case OP_UNUSED_43:
    case OP_UNUSED_73:
    case OP_UNUSED_79:
    case OP_UNUSED_7A:
    case OP_BREAKPOINT:
    case OP_UNUSED_FF:
        return false;
    }

    return true;
}

/*
 * This is a dexDecodeDebugInfo callback, used by markDebugLocals().
 */
static void markLocalsCb(void* ctxt, u2 reg, u4 startAddress, u4 endAddress,
    const char* name, const char* descriptor, const char* signature)
{
    VerifierData* vdata = (VerifierData*) ctxt;
    bool verbose = dvmWantVerboseVerification(vdata->method);

    if (verbose) {
        ALOGI("%04x-%04x %2d (%s %s)",
            startAddress, endAddress, reg, name, descriptor);
    }

    bool wide = (descriptor[0] == 'D' || descriptor[0] == 'J');
    assert(reg <= vdata->insnRegCount + (wide ? 1 : 0));

    /*
     * Set the bit in all GC point instructions in the range
     * [startAddress, endAddress).
     */
    unsigned int idx;
    for (idx = startAddress; idx < endAddress; idx++) {
        BitVector* liveRegs = vdata->registerLines[idx].liveRegs;
        if (liveRegs != NULL) {
            if (wide) {
                GENW(liveRegs, reg);
            } else {
                GEN(liveRegs, reg);
            }
        }
    }
}

/*
 * Mark all debugger-visible locals as live.
 *
 * The "locals" table describes the positions of the various locals in the
 * stack frame based on the current execution address.  If the debugger
 * wants to display one, it issues a request by "slot number".  We need
 * to ensure that references in stack slots that might be queried by the
 * debugger aren't GCed.
 *
 * (If the GC had some way to mark the slot as invalid we wouldn't have
 * to do this.  We could also have the debugger interface check the
 * register map and simply refuse to return a "dead" value, but that's
 * potentially confusing since the referred-to object might actually be
 * alive, and being able to see it without having to hunt around for a
 * "live" stack frame is useful.)
 */
static bool markDebugLocals(VerifierData* vdata)
{
    const Method* meth = vdata->method;

    dexDecodeDebugInfo(meth->clazz->pDvmDex->pDexFile, dvmGetMethodCode(meth),
        meth->clazz->descriptor, meth->prototype.protoIdx, meth->accessFlags,
        NULL, markLocalsCb, vdata);

    return true;
}


/*
 * Dump the liveness bits to the log.
 *
 * "curIdx" is for display only.
 */
static void dumpLiveState(const VerifierData* vdata, u4 curIdx,
    const BitVector* workBits)
{
    u4 insnRegCount = vdata->insnRegCount;
    size_t regCharSize = insnRegCount + (insnRegCount-1)/4 + 2 +1;
    char regChars[regCharSize +1];
    unsigned int idx;

    memset(regChars, ' ', regCharSize);
    regChars[0] = '[';
    if (insnRegCount == 0)
        regChars[1] = ']';
    else
        regChars[1 + (insnRegCount-1) + (insnRegCount-1)/4 +1] = ']';
    regChars[regCharSize] = '\0';

    for (idx = 0; idx < insnRegCount; idx++) {
        char ch = dvmIsBitSet(workBits, idx) ? '+' : '-';
        regChars[1 + idx + (idx/4)] = ch;
    }

    ALOGI("0x%04x %s", curIdx, regChars);
}
