19fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden/*
29fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * Copyright (C) 2010 The Android Open Source Project
39fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden *
49fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * Licensed under the Apache License, Version 2.0 (the "License");
59fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * you may not use this file except in compliance with the License.
69fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * You may obtain a copy of the License at
79fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden *
89fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden *      http://www.apache.org/licenses/LICENSE-2.0
99fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden *
109fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * Unless required by applicable law or agreed to in writing, software
119fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * distributed under the License is distributed on an "AS IS" BASIS,
129fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * See the License for the specific language governing permissions and
149fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * limitations under the License.
159fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden */
169fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
179fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden/*
18dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden * Liveness analysis for Dalvik bytecode.
199fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden */
209fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden#include "Dalvik.h"
21e9224fbea5e7aaa120847aac9d1fe9f38cad9222Andy McFadden#include "analysis/Liveness.h"
229fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden#include "analysis/CodeVerify.h"
239fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
249fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenstatic bool processInstruction(VerifierData* vdata, u4 curIdx,
259fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    BitVector* workBits);
26dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFaddenstatic bool markDebugLocals(VerifierData* vdata);
279fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenstatic void dumpLiveState(const VerifierData* vdata, u4 curIdx,
289fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    const BitVector* workBits);
299fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
309fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
319fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden/*
329fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * Create a table of instruction widths that indicate the width of the
339fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * *previous* instruction.  The values are copied from the width table
349fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * in "vdata", not derived from the instruction stream.
359fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden *
369fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * Caller must free the return value.
379fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden */
389fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenstatic InstructionWidth* createBackwardWidthTable(VerifierData* vdata)
399fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden{
409fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    InstructionWidth* widths;
419fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
429fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    widths = (InstructionWidth*)
439fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            calloc(vdata->insnsSize, sizeof(InstructionWidth));
449fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    if (widths == NULL)
459fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        return NULL;
469fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
479fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    u4 insnWidth = 0;
481813ab265f691e93401c7307c0b34247842ab35eCarl Shapiro    for (u4 idx = 0; idx < vdata->insnsSize; ) {
499fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        widths[idx] = insnWidth;
509fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        insnWidth = dvmInsnGetWidth(vdata->insnFlags, idx);
519fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        idx += insnWidth;
529fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    }
539fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
549fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    return widths;
559fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden}
569fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
579fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden/*
589fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * Compute the "liveness" of every register at all GC points.
599fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden */
609fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenbool dvmComputeLiveness(VerifierData* vdata)
619fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden{
629fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    const InsnFlags* insnFlags = vdata->insnFlags;
639fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    InstructionWidth* backwardWidth;
649fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    VfyBasicBlock* startGuess = NULL;
659fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    BitVector* workBits;
669fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    bool result = false;
679fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
689fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    bool verbose = false; //= dvmWantVerboseVerification(vdata->method);
699fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    if (verbose) {
709fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        const Method* meth = vdata->method;
714308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block        ALOGI("Computing liveness for %s.%s:%s",
729fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            meth->clazz->descriptor, meth->name, meth->shorty);
739fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    }
749fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
759fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    assert(vdata->registerLines != NULL);
769fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
779fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    backwardWidth = createBackwardWidthTable(vdata);
789fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    if (backwardWidth == NULL)
799fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        goto bail;
809fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
819fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    /*
829fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     * Allocate space for intra-block work set.  Does not include space
839fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     * for method result "registers", which aren't visible to the GC.
849fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     * (They would be made live by move-result and then die on the
859fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     * instruction immediately before it.)
869fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     */
879fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    workBits = dvmAllocBitVector(vdata->insnRegCount, false);
889fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    if (workBits == NULL)
899fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        goto bail;
909fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
919fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    /*
929fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     * We continue until all blocks have been visited, and no block
939fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     * requires further attention ("visited" is set and "changed" is
949fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     * clear).
959fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     *
969fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     * TODO: consider creating a "dense" array of basic blocks to make
979fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     * the walking faster.
989fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     */
991813ab265f691e93401c7307c0b34247842ab35eCarl Shapiro    for (int iter = 0;;) {
1009fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        VfyBasicBlock* workBlock = NULL;
1019fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
1029fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        if (iter++ > 100000) {
1039fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            LOG_VFY_METH(vdata->method, "oh dear");
1049fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            dvmAbort();
1059fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        }
1069fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
1079fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /*
1089fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * If a block is marked "changed", we stop and handle it.  If it
1099fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * just hasn't been visited yet, we remember it but keep searching
1109fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * for one that has been changed.
1119fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         *
1129fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * The thought here is that this is more likely to let us work
1139fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * from end to start, which reduces the amount of re-evaluation
1149fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * required (both by using "changed" as a work list, and by picking
1159fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * un-visited blocks from the tail end of the method).
1169fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         */
1179fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        if (startGuess != NULL) {
1189fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            assert(startGuess->changed);
1199fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            workBlock = startGuess;
1209fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        } else {
1211813ab265f691e93401c7307c0b34247842ab35eCarl Shapiro            for (u4 idx = 0; idx < vdata->insnsSize; idx++) {
1229fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                VfyBasicBlock* block = vdata->basicBlocks[idx];
1239fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                if (block == NULL)
1249fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                    continue;
1259fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
1269fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                if (block->changed) {
1279fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                    workBlock = block;
1289fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                    break;
1299fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                } else if (!block->visited) {
1309fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                    workBlock = block;
1319fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                }
1329fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            }
1339fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        }
1349fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
1359fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        if (workBlock == NULL) {
1369fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            /* all done */
1379fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            break;
1389fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        }
1399fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
1409fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        assert(workBlock->changed || !workBlock->visited);
1419fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        startGuess = NULL;
1429fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
1439fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /*
1449fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * Load work bits.  These represent the liveness of registers
1459fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * after the last instruction in the block has finished executing.
1469fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         */
1479fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        assert(workBlock->liveRegs != NULL);
1489fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        dvmCopyBitVector(workBits, workBlock->liveRegs);
1499fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        if (verbose) {
1504308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block            ALOGI("Loaded work bits from last=0x%04x", workBlock->lastAddr);
1519fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            dumpLiveState(vdata, 0xfffd, workBlock->liveRegs);
1529fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            dumpLiveState(vdata, 0xffff, workBits);
1539fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        }
1549fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
1559fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /*
1569fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * Process a single basic block.
1579fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         *
1589fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * If this instruction is a GC point, we want to save the result
1599fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * in the RegisterLine.
1609fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         *
1619fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * We don't break basic blocks on every GC point -- in particular,
1629fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * instructions that might throw but have no "try" block don't
1639fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * end a basic block -- so there could be more than one GC point
1649fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * in a given basic block.
1659fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         *
1669fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * We could change this, but it turns out to be not all that useful.
1679fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * At first glance it appears that we could share the liveness bit
1689fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * vector between the basic block struct and the register line,
1699fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * but the basic block needs to reflect the state *after* the
1709fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * instruction has finished, while the GC points need to describe
1719fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * the state before the instruction starts.
1729fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         */
1739fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        u4 curIdx = workBlock->lastAddr;
1749fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        while (true) {
1759fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            if (!processInstruction(vdata, curIdx, workBits))
1769fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                goto bail;
1779fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
1789fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            if (verbose) {
1799fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                dumpLiveState(vdata, curIdx + 0x8000, workBits);
1809fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            }
1819fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
1829fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            if (dvmInsnIsGcPoint(insnFlags, curIdx)) {
1839fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                BitVector* lineBits = vdata->registerLines[curIdx].liveRegs;
1849fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                if (lineBits == NULL) {
1859fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                    lineBits = vdata->registerLines[curIdx].liveRegs =
1869fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                        dvmAllocBitVector(vdata->insnRegCount, false);
1879fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                }
1889fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                dvmCopyBitVector(lineBits, workBits);
1899fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            }
1909fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
1919fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            if (curIdx == workBlock->firstAddr)
1929fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                break;
1939fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            assert(curIdx >= backwardWidth[curIdx]);
1949fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            curIdx -= backwardWidth[curIdx];
1959fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        }
1969fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
1979fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        workBlock->visited = true;
1989fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        workBlock->changed = false;
1999fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
2009fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        if (verbose) {
2019fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            dumpLiveState(vdata, curIdx, workBits);
2029fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        }
2039fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
2049fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /*
2059fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * Merge changes to all predecessors.  If the new bits don't match
2069fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         * the old bits, set the "changed" flag.
2079fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden         */
2089fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        PointerSet* preds = workBlock->predecessors;
2099fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        size_t numPreds = dvmPointerSetGetCount(preds);
2109fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        unsigned int predIdx;
2119fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
2129fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        for (predIdx = 0; predIdx < numPreds; predIdx++) {
2139fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            VfyBasicBlock* pred =
2149fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                    (VfyBasicBlock*) dvmPointerSetGetEntry(preds, predIdx);
2159fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
2169fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            pred->changed = dvmCheckMergeBitVectors(pred->liveRegs, workBits);
2179fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            if (verbose) {
2184308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block                ALOGI("merging cur=%04x into pred last=%04x (ch=%d)",
2199fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                    curIdx, pred->lastAddr, pred->changed);
2209fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                dumpLiveState(vdata, 0xfffa, pred->liveRegs);
2219fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                dumpLiveState(vdata, 0xfffb, workBits);
2229fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            }
2239fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
2249fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            /*
2259fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden             * We want to set the "changed" flag on unvisited predecessors
2269fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden             * as a way of guiding the verifier through basic blocks in
2279fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden             * a reasonable order.  We can't count on variable liveness
2289fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden             * changing, so we force "changed" to true even if it hasn't.
2299fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden             */
2309fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            if (!pred->visited)
2319fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                pred->changed = true;
2329fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
2339fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            /*
2349fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden             * Keep track of one of the changed blocks so we can start
2359fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden             * there instead of having to scan through the list.
2369fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden             */
2379fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            if (pred->changed)
2389fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                startGuess = pred;
2399fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        }
2409fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    }
2419fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
2429fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden#ifndef NDEBUG
2439fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    /*
2449fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     * Sanity check: verify that all GC point register lines have a
2459fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     * liveness bit vector allocated.  Also, we're not expecting non-GC
2469fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     * points to have them.
2479fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     */
2489fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    u4 checkIdx;
2499fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    for (checkIdx = 0; checkIdx < vdata->insnsSize; ) {
2509fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        if (dvmInsnIsGcPoint(insnFlags, checkIdx)) {
2519fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            if (vdata->registerLines[checkIdx].liveRegs == NULL) {
2529fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                LOG_VFY_METH(vdata->method,
2536f3c21fb026d9489e5046416bcd5a84fa8e4615bDan Bornstein                    "GLITCH: no liveRegs for GC point 0x%04x", checkIdx);
2549fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                dvmAbort();
2559fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            }
2569fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        } else if (vdata->registerLines[checkIdx].liveRegs != NULL) {
2579fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            LOG_VFY_METH(vdata->method,
2586f3c21fb026d9489e5046416bcd5a84fa8e4615bDan Bornstein                "GLITCH: liveRegs for non-GC point 0x%04x", checkIdx);
2599fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            dvmAbort();
2609fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        }
2619fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        u4 insnWidth = dvmInsnGetWidth(insnFlags, checkIdx);
2629fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        checkIdx += insnWidth;
2639fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    }
2649fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden#endif
2659fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
266dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden    /*
267dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden     * Factor in the debug info, if any.
268dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden     */
269dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden    if (!markDebugLocals(vdata))
270dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden        goto bail;
271dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden
2729fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    result = true;
2739fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
2749fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenbail:
2759fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    free(backwardWidth);
2769fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    return result;
2779fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden}
2789fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
2799fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
2809fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden/*
2819fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * Add a register to the LIVE set.
2829fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden */
2839fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenstatic inline void GEN(BitVector* workBits, u4 regIndex)
2849fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden{
2859fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    dvmSetBit(workBits, regIndex);
2869fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden}
2879fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
2889fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden/*
2899fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * Add a register pair to the LIVE set.
2909fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden */
2919fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenstatic inline void GENW(BitVector* workBits, u4 regIndex)
2929fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden{
2939fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    dvmSetBit(workBits, regIndex);
2949fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    dvmSetBit(workBits, regIndex+1);
2959fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden}
2969fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
2979fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden/*
2989fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * Remove a register from the LIVE set.
2999fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden */
3009fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenstatic inline void KILL(BitVector* workBits, u4 regIndex)
3019fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden{
3029fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    dvmClearBit(workBits, regIndex);
3039fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden}
3049fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
3059fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden/*
3069fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * Remove a register pair from the LIVE set.
3079fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden */
3089fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenstatic inline void KILLW(BitVector* workBits, u4 regIndex)
3099fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden{
3109fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    dvmClearBit(workBits, regIndex);
3119fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    dvmClearBit(workBits, regIndex+1);
3129fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden}
3139fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
3149fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden/*
3159fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * Process a single instruction.
3169fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden *
3179fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * Returns "false" if something goes fatally wrong.
3189fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden */
3199fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenstatic bool processInstruction(VerifierData* vdata, u4 insnIdx,
3209fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    BitVector* workBits)
3219fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden{
3229fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    const Method* meth = vdata->method;
3239fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    const u2* insns = meth->insns + insnIdx;
3249fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    DecodedInstruction decInsn;
3259fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
3269fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    dexDecodeInstruction(insns, &decInsn);
3279fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
3289fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    /*
3299fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     * Add registers to the "GEN" or "KILL" sets.  We want to do KILL
3309fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     * before GEN to handle cases where the source and destination
3319fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     * register is the same.
3329fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden     */
3339fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    switch (decInsn.opcode) {
3349fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_NOP:
3359fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_RETURN_VOID:
3369fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_GOTO:
3379fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_GOTO_16:
3389fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_GOTO_32:
3399fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* no registers are used */
3409fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
3419fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
3429fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_RETURN:
3439fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_RETURN_OBJECT:
3449fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MONITOR_ENTER:
3459fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MONITOR_EXIT:
3469fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_CHECK_CAST:
3479fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_THROW:
3489fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_PACKED_SWITCH:
3499fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SPARSE_SWITCH:
3509fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_FILL_ARRAY_DATA:
3519fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IF_EQZ:
3529fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IF_NEZ:
3539fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IF_LTZ:
3549fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IF_GEZ:
3559fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IF_GTZ:
3569fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IF_LEZ:
3579fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SPUT:
3589fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SPUT_BOOLEAN:
3599fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SPUT_BYTE:
3609fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SPUT_CHAR:
3619fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SPUT_SHORT:
3629fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SPUT_OBJECT:
3639fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* action <- vA */
3649fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vA);
3659fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
3669fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
3679fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_RETURN_WIDE:
3689fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SPUT_WIDE:
3699fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* action <- vA(wide) */
3709fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GENW(workBits, decInsn.vA);
3719fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
3729fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
3739fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IF_EQ:
3749fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IF_NE:
3759fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IF_LT:
3769fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IF_GE:
3779fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IF_GT:
3789fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IF_LE:
3799fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IPUT:
3809fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IPUT_BOOLEAN:
3819fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IPUT_BYTE:
3829fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IPUT_CHAR:
3839fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IPUT_SHORT:
3849fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IPUT_OBJECT:
3859fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* action <- vA, vB */
3869fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vA);
3879fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vB);
3889fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
3899fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
3909fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IPUT_WIDE:
3919fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* action <- vA(wide), vB */
3929fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GENW(workBits, decInsn.vA);
3939fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vB);
3949fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
3959fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
3969fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_APUT:
3979fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_APUT_BOOLEAN:
3989fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_APUT_BYTE:
3999fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_APUT_CHAR:
4009fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_APUT_SHORT:
4019fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_APUT_OBJECT:
4029fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* action <- vA, vB, vC */
4039fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vA);
4049fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vB);
4059fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vC);
4069fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
4079fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
4089fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_APUT_WIDE:
4099fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* action <- vA(wide), vB, vC */
4109fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GENW(workBits, decInsn.vA);
4119fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vB);
4129fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vC);
4139fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
4149fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
4159fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_FILLED_NEW_ARRAY:
4169fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INVOKE_VIRTUAL:
4179fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INVOKE_SUPER:
4189fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INVOKE_DIRECT:
4199fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INVOKE_STATIC:
4209fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INVOKE_INTERFACE:
4219fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* action <- vararg */
4229fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        {
4239fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            unsigned int idx;
4249fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            for (idx = 0; idx < decInsn.vA; idx++) {
4259fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                GEN(workBits, decInsn.arg[idx]);
4269fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            }
4279fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        }
4289fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
4299fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
4309fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_FILLED_NEW_ARRAY_RANGE:
4319fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INVOKE_VIRTUAL_RANGE:
4329fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INVOKE_SUPER_RANGE:
4339fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INVOKE_DIRECT_RANGE:
4349fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INVOKE_STATIC_RANGE:
4359fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INVOKE_INTERFACE_RANGE:
4369fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* action <- vararg/range */
4379fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        {
4389fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            unsigned int idx;
4399fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            for (idx = 0; idx < decInsn.vA; idx++) {
4409fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden                GEN(workBits, decInsn.vC + idx);
4419fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden            }
4429fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        }
4439fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
4449fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
4459fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MOVE_RESULT:
4469fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MOVE_RESULT_WIDE:
4479fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MOVE_RESULT_OBJECT:
4489fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MOVE_EXCEPTION:
4499fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_CONST_4:
4509fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_CONST_16:
4519fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_CONST:
4529fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_CONST_HIGH16:
4539fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_CONST_STRING:
4549fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_CONST_STRING_JUMBO:
4559fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_CONST_CLASS:
4569fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_NEW_INSTANCE:
4579fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SGET:
4589fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SGET_BOOLEAN:
4599fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SGET_BYTE:
4609fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SGET_CHAR:
4619fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SGET_SHORT:
4629fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SGET_OBJECT:
4639fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* vA <- value */
4649fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        KILL(workBits, decInsn.vA);
4659fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
4669fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
4679fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_CONST_WIDE_16:
4689fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_CONST_WIDE_32:
4699fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_CONST_WIDE:
4709fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_CONST_WIDE_HIGH16:
4719fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SGET_WIDE:
4729fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* vA(wide) <- value */
4739fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        KILLW(workBits, decInsn.vA);
4749fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
4759fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
4769fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MOVE:
4779fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MOVE_FROM16:
4789fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MOVE_16:
4799fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MOVE_OBJECT:
4809fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MOVE_OBJECT_FROM16:
4819fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MOVE_OBJECT_16:
4829fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INSTANCE_OF:
4839fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_ARRAY_LENGTH:
4849fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_NEW_ARRAY:
4859fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IGET:
4869fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IGET_BOOLEAN:
4879fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IGET_BYTE:
4889fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IGET_CHAR:
4899fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IGET_SHORT:
4909fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IGET_OBJECT:
4919fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_NEG_INT:
4929fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_NOT_INT:
4939fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_NEG_FLOAT:
4949fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INT_TO_FLOAT:
4959fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_FLOAT_TO_INT:
4969fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INT_TO_BYTE:
4979fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INT_TO_CHAR:
4989fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INT_TO_SHORT:
4999fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_ADD_INT_LIT16:
5009fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_RSUB_INT:
5019fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MUL_INT_LIT16:
5029fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_DIV_INT_LIT16:
5039fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_REM_INT_LIT16:
5049fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_AND_INT_LIT16:
5059fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_OR_INT_LIT16:
5069fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_XOR_INT_LIT16:
5079fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_ADD_INT_LIT8:
5089fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_RSUB_INT_LIT8:
5099fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MUL_INT_LIT8:
5109fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_DIV_INT_LIT8:
5119fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_REM_INT_LIT8:
5129fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SHL_INT_LIT8:
5139fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SHR_INT_LIT8:
5149fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_USHR_INT_LIT8:
5159fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_AND_INT_LIT8:
5169fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_OR_INT_LIT8:
5179fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_XOR_INT_LIT8:
5189fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* vA <- vB */
5199fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        KILL(workBits, decInsn.vA);
5209fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vB);
5219fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
5229fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
5239fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IGET_WIDE:
5249fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INT_TO_LONG:
5259fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INT_TO_DOUBLE:
5269fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_FLOAT_TO_LONG:
5279fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_FLOAT_TO_DOUBLE:
5289fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* vA(wide) <- vB */
5299fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        KILLW(workBits, decInsn.vA);
5309fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vB);
5319fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
5329fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
5339fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_LONG_TO_INT:
5349fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_LONG_TO_FLOAT:
5359fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_DOUBLE_TO_INT:
5369fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_DOUBLE_TO_FLOAT:
5379fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* vA <- vB(wide) */
5389fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        KILL(workBits, decInsn.vA);
5399fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GENW(workBits, decInsn.vB);
5409fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
5419fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
5429fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MOVE_WIDE:
5439fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MOVE_WIDE_FROM16:
5449fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MOVE_WIDE_16:
5459fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_NEG_LONG:
5469fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_NOT_LONG:
5479fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_NEG_DOUBLE:
5489fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_LONG_TO_DOUBLE:
5499fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_DOUBLE_TO_LONG:
5509fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* vA(wide) <- vB(wide) */
5519fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        KILLW(workBits, decInsn.vA);
5529fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GENW(workBits, decInsn.vB);
5539fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
5549fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
5559fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_CMPL_FLOAT:
5569fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_CMPG_FLOAT:
5579fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_AGET:
5589fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_AGET_BOOLEAN:
5599fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_AGET_BYTE:
5609fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_AGET_CHAR:
5619fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_AGET_SHORT:
5629fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_AGET_OBJECT:
5639fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_ADD_INT:
5649fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SUB_INT:
5659fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MUL_INT:
5669fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_REM_INT:
5679fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_DIV_INT:
5689fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_AND_INT:
5699fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_OR_INT:
5709fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_XOR_INT:
5719fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SHL_INT:
5729fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SHR_INT:
5739fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_USHR_INT:
5749fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_ADD_FLOAT:
5759fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SUB_FLOAT:
5769fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MUL_FLOAT:
5779fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_DIV_FLOAT:
5789fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_REM_FLOAT:
5799fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* vA <- vB, vC */
5809fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        KILL(workBits, decInsn.vA);
5819fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vB);
5829fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vC);
5839fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
5849fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
5859fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_AGET_WIDE:
5869fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* vA(wide) <- vB, vC */
5879fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        KILLW(workBits, decInsn.vA);
5889fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vB);
5899fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vC);
5909fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
5919fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
5929fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_CMPL_DOUBLE:
5939fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_CMPG_DOUBLE:
5949fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_CMP_LONG:
5959fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* vA <- vB(wide), vC(wide) */
5969fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        KILL(workBits, decInsn.vA);
5979fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GENW(workBits, decInsn.vB);
5989fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GENW(workBits, decInsn.vC);
5999fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
6009fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
6019fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SHL_LONG:
6029fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SHR_LONG:
6039fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_USHR_LONG:
6049fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* vA(wide) <- vB(wide), vC */
6059fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        KILLW(workBits, decInsn.vA);
6069fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GENW(workBits, decInsn.vB);
6079fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vC);
6089fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
6099fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
6109fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_ADD_LONG:
6119fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SUB_LONG:
6129fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MUL_LONG:
6139fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_DIV_LONG:
6149fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_REM_LONG:
6159fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_AND_LONG:
6169fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_OR_LONG:
6179fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_XOR_LONG:
6189fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_ADD_DOUBLE:
6199fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SUB_DOUBLE:
6209fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MUL_DOUBLE:
6219fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_DIV_DOUBLE:
6229fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_REM_DOUBLE:
6239fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* vA(wide) <- vB(wide), vC(wide) */
6249fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        KILLW(workBits, decInsn.vA);
6259fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GENW(workBits, decInsn.vB);
6269fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GENW(workBits, decInsn.vC);
6279fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
6289fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
6299fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_ADD_INT_2ADDR:
6309fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SUB_INT_2ADDR:
6319fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MUL_INT_2ADDR:
6329fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_REM_INT_2ADDR:
6339fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SHL_INT_2ADDR:
6349fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SHR_INT_2ADDR:
6359fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_USHR_INT_2ADDR:
6369fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_AND_INT_2ADDR:
6379fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_OR_INT_2ADDR:
6389fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_XOR_INT_2ADDR:
6399fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_DIV_INT_2ADDR:
6409fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* vA <- vA, vB */
6419fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* KILL(workBits, decInsn.vA); */
6429fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vA);
6439fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vB);
6449fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
6459fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
6469fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SHL_LONG_2ADDR:
6479fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SHR_LONG_2ADDR:
6489fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_USHR_LONG_2ADDR:
6499fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* vA(wide) <- vA(wide), vB */
6509fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* KILLW(workBits, decInsn.vA); */
6519fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GENW(workBits, decInsn.vA);
6529fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GEN(workBits, decInsn.vB);
6539fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
6549fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
6559fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_ADD_LONG_2ADDR:
6569fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SUB_LONG_2ADDR:
6579fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MUL_LONG_2ADDR:
6589fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_DIV_LONG_2ADDR:
6599fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_REM_LONG_2ADDR:
6609fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_AND_LONG_2ADDR:
6619fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_OR_LONG_2ADDR:
6629fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_XOR_LONG_2ADDR:
6639fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_ADD_FLOAT_2ADDR:
6649fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SUB_FLOAT_2ADDR:
6659fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MUL_FLOAT_2ADDR:
6669fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_DIV_FLOAT_2ADDR:
6679fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_REM_FLOAT_2ADDR:
6689fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_ADD_DOUBLE_2ADDR:
6699fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_SUB_DOUBLE_2ADDR:
6709fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_MUL_DOUBLE_2ADDR:
6719fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_DIV_DOUBLE_2ADDR:
6729fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_REM_DOUBLE_2ADDR:
6739fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* vA(wide) <- vA(wide), vB(wide) */
6749fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* KILLW(workBits, decInsn.vA); */
6759fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GENW(workBits, decInsn.vA);
6769fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        GENW(workBits, decInsn.vB);
6779fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
6789fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
6799fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    /* we will only see this if liveness analysis is done after general vfy */
6809fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_THROW_VERIFICATION_ERROR:
6819fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        /* no registers used */
6829fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        break;
6839fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
6849fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    /* quickened instructions, not expected to appear */
6859fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_EXECUTE_INLINE:
6869fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_EXECUTE_INLINE_RANGE:
6879fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IGET_QUICK:
6889fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IGET_WIDE_QUICK:
6899fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IGET_OBJECT_QUICK:
6909fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IPUT_QUICK:
6919fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IPUT_WIDE_QUICK:
6929fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_IPUT_OBJECT_QUICK:
6939fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INVOKE_VIRTUAL_QUICK:
6949fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INVOKE_VIRTUAL_QUICK_RANGE:
6959fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INVOKE_SUPER_QUICK:
6969fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_INVOKE_SUPER_QUICK_RANGE:
697f4ef26d994b4e735d88b97d0f3f37046ba0f6793Andy McFadden        /* fall through to failure */
698f4ef26d994b4e735d88b97d0f3f37046ba0f6793Andy McFadden
699f4ef26d994b4e735d88b97d0f3f37046ba0f6793Andy McFadden    /* correctness fixes, not expected to appear */
700f4ef26d994b4e735d88b97d0f3f37046ba0f6793Andy McFadden    case OP_INVOKE_OBJECT_INIT_RANGE:
7019fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_RETURN_VOID_BARRIER:
702f4ef26d994b4e735d88b97d0f3f37046ba0f6793Andy McFadden    case OP_SPUT_VOLATILE:
703f4ef26d994b4e735d88b97d0f3f37046ba0f6793Andy McFadden    case OP_SPUT_OBJECT_VOLATILE:
704f4ef26d994b4e735d88b97d0f3f37046ba0f6793Andy McFadden    case OP_SPUT_WIDE_VOLATILE:
705f4ef26d994b4e735d88b97d0f3f37046ba0f6793Andy McFadden    case OP_IPUT_VOLATILE:
706f4ef26d994b4e735d88b97d0f3f37046ba0f6793Andy McFadden    case OP_IPUT_OBJECT_VOLATILE:
707f4ef26d994b4e735d88b97d0f3f37046ba0f6793Andy McFadden    case OP_IPUT_WIDE_VOLATILE:
708f4ef26d994b4e735d88b97d0f3f37046ba0f6793Andy McFadden    case OP_SGET_VOLATILE:
709f4ef26d994b4e735d88b97d0f3f37046ba0f6793Andy McFadden    case OP_SGET_OBJECT_VOLATILE:
710f4ef26d994b4e735d88b97d0f3f37046ba0f6793Andy McFadden    case OP_SGET_WIDE_VOLATILE:
711f4ef26d994b4e735d88b97d0f3f37046ba0f6793Andy McFadden    case OP_IGET_VOLATILE:
712f4ef26d994b4e735d88b97d0f3f37046ba0f6793Andy McFadden    case OP_IGET_OBJECT_VOLATILE:
713f4ef26d994b4e735d88b97d0f3f37046ba0f6793Andy McFadden    case OP_IGET_WIDE_VOLATILE:
714f4ef26d994b4e735d88b97d0f3f37046ba0f6793Andy McFadden        /* fall through to failure */
7159fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
7169fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    /* these should never appear during verification */
7179fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_UNUSED_3E:
7189fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_UNUSED_3F:
7199fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_UNUSED_40:
7209fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_UNUSED_41:
7219fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_UNUSED_42:
7229fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_UNUSED_43:
7239fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_UNUSED_73:
7249fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_UNUSED_79:
7259fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_UNUSED_7A:
7269fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    case OP_BREAKPOINT:
727ab35b50311951feea3782151dd5422ee944685c2Elliott Hughes    case OP_UNUSED_FF:
7289fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        return false;
7299fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    }
7309fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
7319fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    return true;
7329fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden}
7339fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
734dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden/*
735dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden * This is a dexDecodeDebugInfo callback, used by markDebugLocals().
736dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden */
737dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFaddenstatic void markLocalsCb(void* ctxt, u2 reg, u4 startAddress, u4 endAddress,
738dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden    const char* name, const char* descriptor, const char* signature)
739dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden{
740dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden    VerifierData* vdata = (VerifierData*) ctxt;
741dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden    bool verbose = dvmWantVerboseVerification(vdata->method);
742dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden
743dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden    if (verbose) {
7444308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block        ALOGI("%04x-%04x %2d (%s %s)",
745dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden            startAddress, endAddress, reg, name, descriptor);
746dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden    }
747dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden
748dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden    bool wide = (descriptor[0] == 'D' || descriptor[0] == 'J');
749dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden    assert(reg <= vdata->insnRegCount + (wide ? 1 : 0));
750dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden
751dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden    /*
752dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden     * Set the bit in all GC point instructions in the range
753dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden     * [startAddress, endAddress).
754dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden     */
755dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden    unsigned int idx;
756dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden    for (idx = startAddress; idx < endAddress; idx++) {
757dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden        BitVector* liveRegs = vdata->registerLines[idx].liveRegs;
758dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden        if (liveRegs != NULL) {
759dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden            if (wide) {
760dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden                GENW(liveRegs, reg);
761dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden            } else {
762dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden                GEN(liveRegs, reg);
763dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden            }
764dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden        }
765dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden    }
766dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden}
767dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden
768dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden/*
769dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden * Mark all debugger-visible locals as live.
770dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden *
771dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden * The "locals" table describes the positions of the various locals in the
772dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden * stack frame based on the current execution address.  If the debugger
773dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden * wants to display one, it issues a request by "slot number".  We need
774dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden * to ensure that references in stack slots that might be queried by the
775dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden * debugger aren't GCed.
776dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden *
777dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden * (If the GC had some way to mark the slot as invalid we wouldn't have
778dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden * to do this.  We could also have the debugger interface check the
779dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden * register map and simply refuse to return a "dead" value, but that's
780dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden * potentially confusing since the referred-to object might actually be
781dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden * alive, and being able to see it without having to hunt around for a
782dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden * "live" stack frame is useful.)
783dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden */
784dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFaddenstatic bool markDebugLocals(VerifierData* vdata)
785dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden{
786dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden    const Method* meth = vdata->method;
787dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden
788dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden    dexDecodeDebugInfo(meth->clazz->pDvmDex->pDexFile, dvmGetMethodCode(meth),
789dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden        meth->clazz->descriptor, meth->prototype.protoIdx, meth->accessFlags,
790dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden        NULL, markLocalsCb, vdata);
791dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden
792dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden    return true;
793dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden}
794dce27e5a9bed6db6a032343fcfb36ef9ccb3e34eAndy McFadden
7959fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
7969fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden/*
7979fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * Dump the liveness bits to the log.
7989fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden *
7999fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden * "curIdx" is for display only.
8009fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden */
8019fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFaddenstatic void dumpLiveState(const VerifierData* vdata, u4 curIdx,
8029fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    const BitVector* workBits)
8039fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden{
8049fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    u4 insnRegCount = vdata->insnRegCount;
8059fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    size_t regCharSize = insnRegCount + (insnRegCount-1)/4 + 2 +1;
8069fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    char regChars[regCharSize +1];
8079fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    unsigned int idx;
8089fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
8099fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    memset(regChars, ' ', regCharSize);
8109fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    regChars[0] = '[';
8119fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    if (insnRegCount == 0)
8129fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        regChars[1] = ']';
8139fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    else
8149fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        regChars[1 + (insnRegCount-1) + (insnRegCount-1)/4 +1] = ']';
8159fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    regChars[regCharSize] = '\0';
8169fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
8179fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    for (idx = 0; idx < insnRegCount; idx++) {
8189fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        char ch = dvmIsBitSet(workBits, idx) ? '+' : '-';
8199fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden        regChars[1 + idx + (idx/4)] = ch;
8209fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden    }
8219fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden
8224308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block    ALOGI("0x%04x %s", curIdx, regChars);
8239fd527f3258381b33365cb18fd37c7864e2bbb40Andy McFadden}
824