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