Forward progress on verifier.
Promoted VerifierData to a more prominent role in passing state around.
This will (a) allow us to pass fewer explicit arguments around in the
core of the verifier, and (b) make it easier to maintain some fancier
data structures that we will need shortly.
Made use of dexGetInstrOrTableWidthAbs() in a couple of places where
we were still explicitly calculating the sizes of NOP data chunks.
Converted some things from int to size_t.
Change-Id: I206f588bf1fc116a9d1f50fb631a9af33479b291
diff --git a/vm/analysis/CodeVerify.c b/vm/analysis/CodeVerify.c
index 74f2f02..30670ec 100644
--- a/vm/analysis/CodeVerify.c
+++ b/vm/analysis/CodeVerify.c
@@ -123,9 +123,9 @@
VerifyError* pFailure);
static void verifyRegisterType(const RegType* insnRegs, const int insnRegCount,\
u4 vsrc, RegType checkType, VerifyError* pFailure);
-static bool doCodeVerification(Method* meth, InsnFlags* insnFlags,\
+static bool doCodeVerification(const Method* meth, InsnFlags* insnFlags,\
RegisterTable* regTable, UninitInstanceMap* uninitMap);
-static bool verifyInstruction(Method* meth, InsnFlags* insnFlags,\
+static bool verifyInstruction(const Method* meth, InsnFlags* insnFlags,\
RegisterTable* regTable, RegType* workRegs, int insnIdx,
UninitInstanceMap* uninitMap, int* pStartGuess);
static ClassObject* findCommonSuperclass(ClassObject* c1, ClassObject* c2);
@@ -2936,12 +2936,9 @@
* The verifier explicitly locks out breakpoint activity, so there should
* be no clashes with the debugger.
*
- * IMPORTANT: this may replace meth->insns with a pointer to a new copy of
- * the instructions.
- *
* Returns "true" on success.
*/
-static bool replaceFailingInstruction(Method* meth, InsnFlags* insnFlags,
+static bool replaceFailingInstruction(const Method* meth, InsnFlags* insnFlags,
int insnIdx, VerifyError failure)
{
VerifyErrorRefType refType;
@@ -3062,7 +3059,7 @@
* that the feature isn't disabled when verification is turned off. At
* some point we may need to revisit this choice.
*/
-static void replaceVolatileInstruction(Method* meth, InsnFlags* insnFlags,
+static void replaceVolatileInstruction(const Method* meth, InsnFlags* insnFlags,
int insnIdx)
{
u2* oldInsns = (u2*)meth->insns + insnIdx;
@@ -3102,11 +3099,11 @@
/*
* Entry point for the detailed code-flow analysis.
*/
-bool dvmVerifyCodeFlow(Method* meth, InsnFlags* insnFlags,
- UninitInstanceMap* uninitMap)
+bool dvmVerifyCodeFlow(VerifierData* vdata)
{
bool result = false;
- const int insnsSize = dvmGetMethodInsnsSize(meth);
+ const Method* meth = vdata->method;
+ const int insnsSize = vdata->insnsSize;
const bool generateRegisterMap = gDvm.generateRegisterMaps;
RegisterTable regTable;
@@ -3150,37 +3147,32 @@
* also going to create the register map, we need to retain the
* register lists for a larger set of addresses.
*/
- if (!initRegisterTable(meth, insnFlags, ®Table,
+ if (!initRegisterTable(meth, vdata->insnFlags, ®Table,
generateRegisterMap ? kTrackRegsGcPoints : kTrackRegsBranches))
goto bail;
+ vdata->addrRegs = NULL; /* don't set this until we need it */
+
/*
* Initialize the types of the registers that correspond to the
* method arguments. We can determine this from the method signature.
*/
- if (!setTypesFromSignature(meth, regTable.addrRegs[0], uninitMap))
+ if (!setTypesFromSignature(meth, regTable.addrRegs[0], vdata->uninitMap))
goto bail;
/*
* Run the verifier.
*/
- if (!doCodeVerification(meth, insnFlags, ®Table, uninitMap))
+ if (!doCodeVerification(meth, vdata->insnFlags, ®Table, vdata->uninitMap))
goto bail;
/*
* Generate a register map.
*/
if (generateRegisterMap) {
- RegisterMap* pMap;
- VerifierData vd;
+ vdata->addrRegs = regTable.addrRegs;
- vd.method = meth;
- vd.insnsSize = insnsSize;
- vd.insnRegCount = meth->registersSize;
- vd.insnFlags = insnFlags;
- vd.addrRegs = regTable.addrRegs;
-
- pMap = dvmGenerateRegisterMapV(&vd);
+ RegisterMap* pMap = dvmGenerateRegisterMapV(vdata);
if (pMap != NULL) {
/*
* Tuck it into the Method struct. It will either get used
@@ -3253,7 +3245,7 @@
* instruction if a register contains an uninitialized instance created
* by that same instrutcion.
*/
-static bool doCodeVerification(Method* meth, InsnFlags* insnFlags,
+static bool doCodeVerification(const Method* meth, InsnFlags* insnFlags,
RegisterTable* regTable, UninitInstanceMap* uninitMap)
{
const int insnsSize = dvmGetMethodInsnsSize(meth);
@@ -3487,7 +3479,7 @@
* This may alter meth->insns if we need to replace an instruction with
* throw-verification-error.
*/
-static bool verifyInstruction(Method* meth, InsnFlags* insnFlags,
+static bool verifyInstruction(const Method* meth, InsnFlags* insnFlags,
RegisterTable* regTable, RegType* workRegs, int insnIdx,
UninitInstanceMap* uninitMap, int* pStartGuess)
{
@@ -3506,13 +3498,12 @@
* and switch statements.
* (3) Exception handlers. Applies to any instruction that can
* throw an exception that is handled by an encompassing "try"
- * block. (We simplify this to be any instruction that can
- * throw any exception.)
+ * block.
*
* We can also return, in which case there is no successor instruction
* from this point.
*
- * The behavior can be determined from the InstrFlags.
+ * The behavior can be determined from the InstructionFlags.
*/
const DexFile* pDexFile = meth->clazz->pDvmDex->pDexFile;