* 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.
*/
* 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);