OSDN Git Service

Emit return-void-barrier when appropriate.
[android-x86/dalvik.git] / vm / analysis / DexPrepare.c
index d9871c9..d361290 100644 (file)
@@ -51,8 +51,8 @@ static void verifyAndOptimizeClass(DexFile* pDexFile, ClassObject* clazz,
     const DexClassDef* pClassDef, bool doVerify, bool doOpt);
 static void updateChecksum(u1* addr, int len, DexHeader* pHeader);
 static int writeDependencies(int fd, u4 modWhen, u4 crc);
-static bool writeAuxData(int fd, const DexClassLookup* pClassLookup,\
-    const IndexMapSet* pIndexMapSet, const RegisterMapBuilder* pRegMapBuilder);
+static bool writeOptData(int fd, const DexClassLookup* pClassLookup,\
+    const RegisterMapBuilder* pRegMapBuilder);
 static bool computeFileChecksum(int fd, off_t start, size_t length, u4* pSum);
 
 
@@ -228,7 +228,8 @@ retry:
              * changes doing anything" purposes its best if we just make
              * everything crash when a DEX they're using gets updated.
              */
-            LOGD("Stale deps in cache file; removing and retrying\n");
+            LOGD("ODEX file is stale or bad; removing and retrying (%s)\n",
+                cacheFileName);
             if (ftruncate(fd, 0) != 0) {
                 LOGW("Warning: unable to truncate cache file '%s': %s\n",
                     cacheFileName, strerror(errno));
@@ -474,7 +475,6 @@ bool dvmContinueOptimization(int fd, off_t dexOffset, long dexLength,
     const char* fileName, u4 modWhen, u4 crc, bool isBootstrap)
 {
     DexClassLookup* pClassLookup = NULL;
-    IndexMapSet* pIndexMapSet = NULL;
     RegisterMapBuilder* pRegMapBuilder = NULL;
     u4 headerFlags = 0;
 
@@ -543,15 +543,6 @@ bool dvmContinueOptimization(int fd, off_t dexOffset, long dexLength,
                 success = false;
             } else {
                 /*
-                 * If configured to do so, scan the instructions, looking
-                 * for ways to reduce the size of the resolved-constant table.
-                 * This is done post-optimization, across the instructions
-                 * in all methods in all classes (even the ones that failed
-                 * to load).
-                 */
-                pIndexMapSet = dvmRewriteConstants(pDvmDex);
-
-                /*
                  * If configured to do so, generate register map output
                  * for all verified classes.  The register maps were
                  * generated during verification, and will now be serialized.
@@ -594,8 +585,8 @@ bool dvmContinueOptimization(int fd, off_t dexOffset, long dexLength,
     }
 
     /* get start offset, and adjust deps start for 64-bit alignment */
-    off_t depsOffset, auxOffset, endOffset, adjOffset;
-    int depsLength, auxLength;
+    off_t depsOffset, optOffset, endOffset, adjOffset;
+    int depsLength, optLength;
     u4 optChecksum;
 
     depsOffset = lseek(fd, 0, SEEK_END);
@@ -619,32 +610,32 @@ bool dvmContinueOptimization(int fd, off_t dexOffset, long dexLength,
         goto bail;
     }
 
-    /* compute deps length, then adjust aux start for 64-bit alignment */
-    auxOffset = lseek(fd, 0, SEEK_END);
-    depsLength = auxOffset - depsOffset;
+    /* compute deps length, then adjust opt start for 64-bit alignment */
+    optOffset = lseek(fd, 0, SEEK_END);
+    depsLength = optOffset - depsOffset;
 
-    adjOffset = (auxOffset + 7) & ~(0x07);
-    if (adjOffset != auxOffset) {
-        LOGV("Adjusting aux start from %d to %d\n",
-            (int) auxOffset, (int) adjOffset);
-        auxOffset = adjOffset;
-        lseek(fd, auxOffset, SEEK_SET);
+    adjOffset = (optOffset + 7) & ~(0x07);
+    if (adjOffset != optOffset) {
+        LOGV("Adjusting opt start from %d to %d\n",
+            (int) optOffset, (int) adjOffset);
+        optOffset = adjOffset;
+        lseek(fd, optOffset, SEEK_SET);
     }
 
     /*
-     * Append any auxillary pre-computed data structures.
+     * Append any optimized pre-computed data structures.
      */
-    if (!writeAuxData(fd, pClassLookup, pIndexMapSet, pRegMapBuilder)) {
-        LOGW("Failed writing aux data\n");
+    if (!writeOptData(fd, pClassLookup, pRegMapBuilder)) {
+        LOGW("Failed writing opt data\n");
         goto bail;
     }
 
     endOffset = lseek(fd, 0, SEEK_END);
-    auxLength = endOffset - auxOffset;
+    optLength = endOffset - optOffset;
 
-    /* compute checksum from start of deps to end of aux area */
+    /* compute checksum from start of deps to end of opt area */
     if (!computeFileChecksum(fd, depsOffset,
-            (auxOffset+auxLength) - depsOffset, &optChecksum))
+            (optOffset+optLength) - depsOffset, &optChecksum))
     {
         goto bail;
     }
@@ -661,12 +652,14 @@ bool dvmContinueOptimization(int fd, off_t dexOffset, long dexLength,
     optHdr.dexLength = (u4) dexLength;
     optHdr.depsOffset = (u4) depsOffset;
     optHdr.depsLength = (u4) depsLength;
-    optHdr.auxOffset = (u4) auxOffset;
-    optHdr.auxLength = (u4) auxLength;
+    optHdr.optOffset = (u4) optOffset;
+    optHdr.optLength = (u4) optLength;
 
     optHdr.flags = headerFlags;
     optHdr.checksum = optChecksum;
 
+    fsync(fd);      /* ensure previous writes go before header is written */
+
     lseek(fd, 0, SEEK_SET);
     if (sysWriteFully(fd, &optHdr, sizeof(optHdr), "DexOpt opt header") != 0)
         goto bail;
@@ -677,7 +670,6 @@ bool dvmContinueOptimization(int fd, off_t dexOffset, long dexLength,
     //dvmRegisterMapDumpStats();
 
 bail:
-    dvmFreeIndexMapSet(pIndexMapSet);
     dvmFreeRegisterMapBuilder(pRegMapBuilder);
     free(pClassLookup);
     return result;
@@ -933,30 +925,38 @@ static void verifyAndOptimizeClass(DexFile* pDexFile, ClassObject* clazz,
     const char* classDescriptor;
     bool verified = false;
 
+    if (clazz->pDvmDex->pDexFile != pDexFile) {
+        /*
+         * The current DEX file defined a class that is also present in the
+         * bootstrap class path.  The class loader favored the bootstrap
+         * version, which means that we have a pointer to a class that is
+         * (a) not the one we want to examine, and (b) mapped read-only,
+         * so we will seg fault if we try to rewrite instructions inside it.
+         */
+        LOGD("DexOpt: not verifying/optimizing '%s': multiple definitions\n",
+            clazz->descriptor);
+        return;
+    }
+
     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);
+        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 {
-            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);
-            }
+            // TODO: log when in verbose mode
+            LOGV("DexOpt: '%s' failed verification\n", classDescriptor);
         }
     }
 
@@ -1067,13 +1067,22 @@ bool dvmCheckOptHeaderAndDependencies(int fd, bool sourceAvail, u4 modWhen,
      * Read and do trivial verification on the opt header.  The header is
      * always in host byte order.
      */
-    if (read(fd, &optHdr, sizeof(optHdr)) != sizeof(optHdr)) {
+    actual = read(fd, &optHdr, sizeof(optHdr));
+    if (actual < 0) {
         LOGE("DexOpt: failed reading opt header: %s\n", strerror(errno));
         goto bail;
+    } else if (actual != sizeof(optHdr)) {
+        LOGE("DexOpt: failed reading opt header (got %d of %zd)\n",
+            (int) actual, sizeof(optHdr));
+        goto bail;
     }
 
     magic = optHdr.magic;
-    if (memcmp(magic, DEX_OPT_MAGIC, 4) != 0) {
+    if (memcmp(magic, DEX_MAGIC, 4) == 0) {
+        /* somebody probably pointed us at the wrong file */
+        LOGD("DexOpt: expected optimized DEX, found unoptimized\n");
+        goto bail;
+    } else if (memcmp(magic, DEX_OPT_MAGIC, 4) != 0) {
         /* not a DEX file, or previous attempt was interrupted */
         LOGD("DexOpt: incorrect opt magic number (0x%02x %02x %02x %02x)\n",
             magic[0], magic[1], magic[2], magic[3]);
@@ -1137,9 +1146,12 @@ bool dvmCheckOptHeaderAndDependencies(int fd, bool sourceAvail, u4 modWhen,
         goto bail;
     }
     actual = read(fd, depData, optHdr.depsLength);
-    if (actual != (ssize_t) optHdr.depsLength) {
-        LOGW("DexOpt: failed reading deps: %d of %d (err=%s)\n",
-            (int) actual, optHdr.depsLength, strerror(errno));
+    if (actual < 0) {
+        LOGW("DexOpt: failed reading deps: %s\n", strerror(errno));
+        goto bail;
+    } else if (actual != (ssize_t) optHdr.depsLength) {
+        LOGW("DexOpt: failed reading deps: got %d of %d\n",
+            (int) actual, optHdr.depsLength);
         goto bail;
     }
 
@@ -1319,13 +1331,13 @@ static bool writeChunk(int fd, u4 type, const void* data, size_t size)
     header.ts.type = type;
     header.ts.size = (u4) size;
     if (sysWriteFully(fd, &header, sizeof(header),
-            "DexOpt aux chunk header write") != 0)
+            "DexOpt opt chunk header write") != 0)
     {
         return false;
     }
 
     if (size > 0) {
-        if (sysWriteFully(fd, data, size, "DexOpt aux chunk write") != 0)
+        if (sysWriteFully(fd, data, size, "DexOpt opt chunk write") != 0)
             return false;
     }
 
@@ -1342,15 +1354,15 @@ static bool writeChunk(int fd, u4 type, const void* data, size_t size)
 }
 
 /*
- * Write aux data.
+ * Write opt data.
  *
  * We have different pieces, some of which may be optional.  To make the
  * most effective use of space, we use a "chunk" format, with a 4-byte
  * type and a 4-byte length.  We guarantee 64-bit alignment for the data,
  * so it can be used directly when the file is mapped for reading.
  */
-static bool writeAuxData(int fd, const DexClassLookup* pClassLookup,
-    const IndexMapSet* pIndexMapSet, const RegisterMapBuilder* pRegMapBuilder)
+static bool writeOptData(int fd, const DexClassLookup* pClassLookup,
+    const RegisterMapBuilder* pRegMapBuilder)
 {
     /* pre-computed class lookup hash table */
     if (!writeChunk(fd, (u4) kDexChunkClassLookup,
@@ -1359,15 +1371,6 @@ static bool writeAuxData(int fd, const DexClassLookup* pClassLookup,
         return false;
     }
 
-    /* remapped constants (optional) */
-    if (pIndexMapSet != NULL) {
-        if (!writeChunk(fd, pIndexMapSet->chunkType,
-                pIndexMapSet->chunkData, pIndexMapSet->chunkDataLen))
-        {
-            return false;
-        }
-    }
-
     /* register maps (optional) */
     if (pRegMapBuilder != NULL) {
         if (!writeChunk(fd, (u4) kDexChunkRegisterMaps,
@@ -1427,7 +1430,7 @@ static bool computeFileChecksum(int fd, off_t start, size_t length, u4* pSum)
 /*
  * Update the Adler-32 checksum stored in the DEX file.  This covers the
  * swapped and optimized DEX data, but does not include the opt header
- * or auxillary data.
+ * or optimized data.
  */
 static void updateChecksum(u1* addr, int len, DexHeader* pHeader)
 {