OSDN Git Service

Changed dvmDexCacheStatus to check for odex file first.
[android-x86/dalvik.git] / vm / JarFile.cpp
index 0288fef..4425224 100644 (file)
@@ -73,7 +73,7 @@ static int openAlternateSuffix(const char *fileName, const char *suffix,
         *pCachedName = buf;
         return fd;
     }
-    LOGV("Couldn't open %s: %s\n", buf, strerror(errno));
+    ALOGV("Couldn't open %s: %s", buf, strerror(errno));
 bail:
     free(buf);
     return -1;
@@ -82,6 +82,8 @@ bail:
 /*
  * Checks the dependencies of the dex cache file corresponding
  * to the jar file at the absolute path "fileName".
+ *
+ * Note: This should parallel the logic of dvmJarFileOpen.
  */
 DexCacheStatus dvmDexCacheStatus(const char *fileName)
 {
@@ -99,71 +101,70 @@ DexCacheStatus dvmDexCacheStatus(const char *fileName)
         return DEX_CACHE_OK;
     }
 
-    //TODO: match dvmJarFileOpen()'s logic.  Not super-important
-    //      (the odex-first logic is only necessary for dexpreopt)
-    //      but it would be nice to be consistent.
-
     /* Try to find the dex file inside of the archive.
      */
     if (dexZipOpenArchive(fileName, &archive) != 0) {
         return DEX_CACHE_BAD_ARCHIVE;
     }
-    entry = dexZipFindEntry(&archive, kDexInJarName);
-    if (entry != NULL) {
-        bool newFile = false;
-
-        /*
-         * See if there's an up-to-date copy of the optimized dex
-         * in the cache, but don't create one if there isn't.
-         */
-        LOGV("dvmDexCacheStatus: Checking cache for %s\n", fileName);
-        cachedName = dexOptGenerateCacheFileName(fileName, kDexInJarName);
-        if (cachedName == NULL)
-            return DEX_CACHE_BAD_ARCHIVE;
-
-        fd = dvmOpenCachedDexFile(fileName, cachedName,
-                dexGetZipEntryModTime(&archive, entry),
-                dexGetZipEntryCrc32(&archive, entry),
-                /*isBootstrap=*/false, &newFile, /*createIfMissing=*/false);
-        LOGV("dvmOpenCachedDexFile returned fd %d\n", fd);
-        if (fd < 0) {
-            result = DEX_CACHE_STALE;
-            goto bail;
-        }
 
-        /* dvmOpenCachedDexFile locks the file as a side-effect.
-         * Unlock and close it.
-         */
-        if (!dvmUnlockCachedDexFile(fd)) {
-            /* uh oh -- this process needs to exit or we'll wedge the system */
-            LOGE("Unable to unlock DEX file\n");
-            goto bail;
+    /* First, look for a ".odex" alongside the jar file.  It will
+     * have the same name/path except for the extension.
+     */
+    fd = openAlternateSuffix(fileName, "odex", O_RDONLY, &cachedName);
+    if (fd >= 0) {
+        ALOGV("Using alternate file (odex) for %s ...", fileName);
+        if (!dvmCheckOptHeaderAndDependencies(fd, false, 0, 0, true, true)) {
+            ALOGE("%s odex has stale dependencies", fileName);
+            free(cachedName);
+            cachedName = NULL;
+            close(fd);
+            fd = -1;
+            goto tryArchive;
+        } else {
+            ALOGV("%s odex has good dependencies", fileName);
         }
-
-        /* When createIfMissing is false, dvmOpenCachedDexFile() only
-         * returns a valid fd if the cache file is up-to-date.
-         */
     } else {
+
+tryArchive:
         /*
-         * There's no dex file in the jar file.  See if there's an
-         * optimized dex file living alongside the jar.
+         * Pre-created .odex absent or stale.  Look inside the jar for a
+         * "classes.dex".
          */
-        fd = openAlternateSuffix(fileName, "odex", O_RDONLY, &cachedName);
-        if (fd < 0) {
-            LOGI("Zip is good, but no %s inside, and no .odex "
-                    "file in the same directory\n", kDexInJarName);
-            result = DEX_CACHE_BAD_ARCHIVE;
-            goto bail;
-        }
+        if ((entry = dexZipFindEntry(&archive, kDexInJarName)) != NULL) {
+            bool newFile = false;
 
-        LOGV("Using alternate file (odex) for %s ...\n", fileName);
-        if (!dvmCheckOptHeaderAndDependencies(fd, false, 0, 0, true, true)) {
-            LOGE("%s odex has stale dependencies\n", fileName);
-            LOGE("odex source not available -- failing\n");
-            result = DEX_CACHE_STALE_ODEX;
-            goto bail;
+            /*
+             * See if there's an up-to-date copy of the optimized dex
+             * in the cache, but don't create one if there isn't.
+             */
+            ALOGV("dvmDexCacheStatus: Checking cache for %s", fileName);
+            cachedName = dexOptGenerateCacheFileName(fileName, kDexInJarName);
+            if (cachedName == NULL)
+                return DEX_CACHE_BAD_ARCHIVE;
+
+            fd = dvmOpenCachedDexFile(fileName, cachedName,
+                    dexGetZipEntryModTime(&archive, entry),
+                    dexGetZipEntryCrc32(&archive, entry),
+                    /*isBootstrap=*/false, &newFile, /*createIfMissing=*/false);
+            ALOGV("dvmOpenCachedDexFile returned fd %d", fd);
+            if (fd < 0) {
+                result = DEX_CACHE_STALE;
+                goto bail;
+            }
+
+            /* dvmOpenCachedDexFile locks the file as a side-effect.
+             * Unlock and close it.
+             */
+            if (!dvmUnlockCachedDexFile(fd)) {
+                /* uh oh -- this process needs to exit or we'll wedge the system */
+                ALOGE("Unable to unlock DEX file");
+                goto bail;
+            }
         } else {
-            LOGV("%s odex has good dependencies\n", fileName);
+            ALOGI("Zip is good, but no %s inside, and no .odex "
+                    "file in the same directory", kDexInJarName);
+            result = DEX_CACHE_BAD_ARCHIVE;
+            goto bail;
         }
     }
     result = DEX_CACHE_OK;
@@ -184,6 +185,8 @@ bail:
  *
  * If "isBootstrap" is not set, the optimizer/verifier regards this DEX as
  * being part of a different class loader.
+ *
+ * Note: This should parallel the logic of dvmDexCacheStatus.
  */
 int dvmJarFileOpen(const char* fileName, const char* odexOutputName,
     JarFile** ppJarFile, bool isBootstrap)
@@ -217,16 +220,16 @@ int dvmJarFileOpen(const char* fileName, const char* odexOutputName,
      */
     fd = openAlternateSuffix(fileName, "odex", O_RDONLY, &cachedName);
     if (fd >= 0) {
-        LOGV("Using alternate file (odex) for %s ...\n", fileName);
+        ALOGV("Using alternate file (odex) for %s ...", fileName);
         if (!dvmCheckOptHeaderAndDependencies(fd, false, 0, 0, true, true)) {
-            LOGE("%s odex has stale dependencies\n", fileName);
+            ALOGE("%s odex has stale dependencies", fileName);
             free(cachedName);
             cachedName = NULL;
             close(fd);
             fd = -1;
             goto tryArchive;
         } else {
-            LOGV("%s odex has good dependencies\n", fileName);
+            ALOGV("%s odex has good dependencies", fileName);
             //TODO: make sure that the .odex actually corresponds
             //      to the classes.dex inside the archive (if present).
             //      For typical use there will be no classes.dex.
@@ -262,14 +265,14 @@ tryArchive:
             } else {
                 cachedName = strdup(odexOutputName);
             }
-            LOGV("dvmJarFileOpen: Checking cache for %s (%s)\n",
+            ALOGV("dvmJarFileOpen: Checking cache for %s (%s)",
                 fileName, cachedName);
             fd = dvmOpenCachedDexFile(fileName, cachedName,
                     dexGetZipEntryModTime(&archive, entry),
                     dexGetZipEntryCrc32(&archive, entry),
                     isBootstrap, &newFile, /*createIfMissing=*/true);
             if (fd < 0) {
-                LOGI("Unable to open or create cache for %s (%s)\n",
+                ALOGI("Unable to open or create cache for %s (%s)",
                     fileName, cachedName);
                 goto bail;
             }
@@ -304,20 +307,20 @@ tryArchive:
                 }
 
                 if (!result) {
-                    LOGE("Unable to extract+optimize DEX from '%s'\n",
+                    ALOGE("Unable to extract+optimize DEX from '%s'",
                         fileName);
                     goto bail;
                 }
 
                 endWhen = dvmGetRelativeTimeUsec();
-                LOGD("DEX prep '%s': unzip in %dms, rewrite %dms\n",
+                ALOGD("DEX prep '%s': unzip in %dms, rewrite %dms",
                     fileName,
                     (int) (extractWhen - startWhen) / 1000,
                     (int) (endWhen - extractWhen) / 1000);
             }
         } else {
-            LOGI("Zip is good, but no %s inside, and no valid .odex "
-                    "file in the same directory\n", kDexInJarName);
+            ALOGI("Zip is good, but no %s inside, and no valid .odex "
+                    "file in the same directory", kDexInJarName);
             goto bail;
         }
     }
@@ -327,7 +330,7 @@ tryArchive:
      * doesn't have to be seeked anywhere in particular.
      */
     if (dvmDexFileOpenFromFd(fd, &pDvmDex) != 0) {
-        LOGI("Unable to map %s in %s\n", kDexInJarName, fileName);
+        ALOGI("Unable to map %s in %s", kDexInJarName, fileName);
         goto bail;
     }
 
@@ -335,13 +338,13 @@ tryArchive:
         /* unlock the fd */
         if (!dvmUnlockCachedDexFile(fd)) {
             /* uh oh -- this process needs to exit or we'll wedge the system */
-            LOGE("Unable to unlock DEX file\n");
+            ALOGE("Unable to unlock DEX file");
             goto bail;
         }
         locked = false;
     }
 
-    LOGV("Successfully opened '%s' in '%s'\n", kDexInJarName, fileName);
+    ALOGV("Successfully opened '%s' in '%s'", kDexInJarName, fileName);
 
     *ppJarFile = (JarFile*) calloc(1, sizeof(JarFile));
     (*ppJarFile)->archive = archive;