/* * Induce verification on all classes loaded from this DEX file as part * of pre-verification and optimization. This is never called from a * normally running VM. * * Returns "true" when all classes have been processed. */ bool dvmVerifyAllClasses(DexFile* pDexFile) { u4 count = pDexFile->pHeader->classDefsSize; u4 idx; assert(gDvm.optimizing); if (gDvm.classVerifyMode == VERIFY_MODE_NONE) { LOGV("+++ verification is disabled, skipping all classes\n"); return true; } if (gDvm.classVerifyMode == VERIFY_MODE_REMOTE && gDvm.optimizingBootstrapClass) { LOGV("+++ verification disabled for bootstrap classes\n"); return true; } for (idx = 0; idx < count; idx++) { const DexClassDef* pClassDef; const char* classDescriptor; ClassObject* clazz; pClassDef = dexGetClassDef(pDexFile, idx); classDescriptor = dexStringByTypeIdx(pDexFile, pClassDef->classIdx); /* all classes are loaded into the bootstrap class loader */ clazz = dvmLookupClass(classDescriptor, NULL, false); if (clazz != NULL) { if (clazz->pDvmDex->pDexFile != pDexFile) { LOGD("DexOpt: not verifying '%s': multiple definitions\n", classDescriptor); } else { if (dvmVerifyClass(clazz, VERIFY_DEFAULT)) { assert((clazz->accessFlags & JAVA_FLAGS_MASK) == pClassDef->accessFlags); ((DexClassDef*)pClassDef)->accessFlags |= CLASS_ISPREVERIFIED; } /* keep going even if one fails */ } } else { LOGV("DexOpt: +++ not verifying '%s'\n", classDescriptor); } } return true; }
/* * Verify and/or optimize a specific class. */ static void verifyAndOptimizeClass(DexFile* pDexFile, ClassObject* clazz, const DexClassDef* pClassDef, bool doVerify, bool doOpt) { const char* classDescriptor; bool verified = false; classDescriptor = dexStringByTypeIdx(pDexFile, pClassDef->classIdx); /* * First, try to verify it. */ if (doVerify) { if (clazz->pDvmDex->pDexFile != pDexFile) { LOGD("DexOpt: not verifying '%s': multiple definitions\n", classDescriptor); } else { if (dvmVerifyClass(clazz)) { /* * Set the "is preverified" flag in the DexClassDef. We * do it here, rather than in the ClassObject structure, * because the DexClassDef is part of the odex file. */ assert((clazz->accessFlags & JAVA_FLAGS_MASK) == pClassDef->accessFlags); ((DexClassDef*)pClassDef)->accessFlags |= CLASS_ISPREVERIFIED; verified = true; } else { // TODO: log when in verbose mode LOGV("DexOpt: '%s' failed verification\n", classDescriptor); } } } if (doOpt) { if (!verified && gDvm.dexOptMode == OPTIMIZE_MODE_VERIFIED) { LOGV("DexOpt: not optimizing '%s': not verified\n", classDescriptor); } else { dvmOptimizeClass(clazz, false); /* set the flag whether or not we actually changed anything */ ((DexClassDef*)pClassDef)->accessFlags |= CLASS_ISOPTIMIZED; } } }