OSDN Git Service

Don't force optimizations during class init in dexopt.
authorAndy McFadden <fadden@android.com>
Fri, 22 Oct 2010 19:41:33 +0000 (12:41 -0700)
committerAndy McFadden <fadden@android.com>
Fri, 22 Oct 2010 19:41:33 +0000 (12:41 -0700)
Some "optimizations" are mandatory, notably those having to do with
access to volatile fields.  We get into an odd situation in dexopt
where we have to initialize and execute <clinit> in a few classes
(primarily Class and Object), but if optimizations are disabled we
don't want to write optimized instructions into the output DEX.

This modifies the class init code to skip the mandatory optimizations
if we're in dexopt.  Either the optimization will happen as a normal
part of dexopt operation, or it won't (in which case it'll be applied
when the class is first loaded in a normal VM).

Bug 3099161.

Change-Id: I11ee5affd5e3ac5a1e8583241acdf3c4de033a96

vm/Init.c
vm/oo/Class.c

index 0b96d3b..07b3ad8 100644 (file)
--- a/vm/Init.c
+++ b/vm/Init.c
@@ -1554,11 +1554,10 @@ static bool dvmInitJDWP(void)
  * of initialization and then returns with "initializing" still set.  (Used
  * by DexOpt command-line utility.)
  *
- * Attempting to use JNI or internal natives will fail.  It's best if
- * no bytecode gets executed, which means no <clinit>, which means no
- * exception-throwing.  We check the "initializing" flag anyway when
- * throwing an exception, so we can insert some code that avoids chucking
- * an exception when we're optimizing stuff.
+ * Attempting to use JNI or internal natives will fail.  It's best
+ * if no bytecode gets executed, which means no <clinit>, which means
+ * no exception-throwing.  (In practice we need to initialize Class and
+ * Object, and probably some exception classes.)
  *
  * Returns 0 on success.
  */
index 9de277f..c6b169f 100644 (file)
@@ -4308,8 +4308,17 @@ noverify:
      * We need to ensure that certain instructions, notably accesses to
      * volatile fields, are replaced before any code is executed.  This
      * must happen even if DEX optimizations are disabled.
+     *
+     * The only exception to this rule is that we don't want to do this
+     * during dexopt.  We don't generally initialize classes at all
+     * during dexopt, but because we're loading classes we need Class and
+     * Object (and possibly some Throwable stuff if a class isn't found).
+     * If optimizations are disabled, we don't want to output optimized
+     * instructions at this time.  This means we will be executing <clinit>
+     * code with un-fixed volatiles, but we're only doing it for a few
+     * system classes, and dexopt runs single-threaded.
      */
-    if (!IS_CLASS_FLAG_SET(clazz, CLASS_ISOPTIMIZED)) {
+    if (!IS_CLASS_FLAG_SET(clazz, CLASS_ISOPTIMIZED) && !gDvm.optimizing) {
         LOGV("+++ late optimize on %s (pv=%d)\n",
             clazz->descriptor, IS_CLASS_FLAG_SET(clazz, CLASS_ISPREVERIFIED));
         dvmOptimizeClass(clazz, true);