Correct dexopt for uniprocessors.

The SMP flag was defaulting to "true" for dexopt, even on uniprocessors.
With this change the VM now has three choices: dexopt for SMP, dexopt
for uniprocessor, or dexopt for current system.  The last is used for
just-in-time dexopt (used by -eng and -userdebug builds on bootstrap DEX
files) and installd dexopt (used for apps on all builds).

The dexopt used by the build system during -user builds will either be
explicitly SMP or explicitly uniprocessor, since "current system" has
no meaning when you're cross-dexopting.

Also, unified the dexopt control flags into a single enum.

Change-Id: I02e22d53ccde2e8603cac8090ca3aae59f792f70
diff --git a/dexopt/OptMain.c b/dexopt/OptMain.c
index fbb7947..b8e5889 100644
--- a/dexopt/OptMain.c
+++ b/dexopt/OptMain.c
@@ -160,9 +160,13 @@
             dexoptFlags |= DEXOPT_GEN_REGISTER_MAPS;
         }
 
-        opc = strstr(dexoptFlagStr, "u=y");     /* uniprocessor target */
+        opc = strstr(dexoptFlagStr, "u=");      /* uniprocessor target */
         if (opc != NULL) {
-            dexoptFlags |= DEXOPT_UNIPROCESSOR;
+            switch (*(opc+2)) {
+            case 'y':   dexoptFlags |= DEXOPT_UNIPROCESSOR;     break;
+            case 'n':   dexoptFlags |= DEXOPT_SMP;              break;
+            default:                                            break;
+            }
         }
     }
 
@@ -350,6 +354,13 @@
     const char* outName = argv[3];
     const char* dexoptFlags = argv[4];
 
+    if (strstr(dexoptFlags, "u=y") == NULL &&
+        strstr(dexoptFlags, "u=n") == NULL)
+    {
+        fprintf(stderr, "Either 'u=y' or 'u=n' must be specified\n");
+        goto bail;
+    }
+
     zipFd = open(zipName, O_RDONLY);
     if (zipFd < 0) {
         perror(argv[0]);
@@ -483,7 +494,6 @@
     bool onlyOptVerifiedDex = false;
     DexClassVerifyMode verifyMode;
     DexOptimizerMode dexOptMode;
-    int dexoptFlags = 0;
 
     /* ugh -- upgrade these to a bit field if they get any more complex */
     if ((flags & DEXOPT_VERIFY_ENABLED) != 0) {
@@ -502,13 +512,8 @@
     } else {
         dexOptMode = OPTIMIZE_MODE_NONE;
     }
-    if ((flags & DEXOPT_GEN_REGISTER_MAP) != 0) {
-        dexoptFlags |= DEXOPT_GEN_REGISTER_MAPS;
-    }
 
-    if (dvmPrepForDexOpt(bootClassPath, dexOptMode, verifyMode,
-            dexoptFlags) != 0)
-    {
+    if (dvmPrepForDexOpt(bootClassPath, dexOptMode, verifyMode, flags) != 0) {
         LOGE("VM init failed\n");
         goto bail;
     }
diff --git a/libdex/OptInvocation.h b/libdex/OptInvocation.h
index d9708ca..0352eb4 100644
--- a/libdex/OptInvocation.h
+++ b/libdex/OptInvocation.h
@@ -13,20 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 /*
  * Utility functions related to "dexopt".
  */
 #ifndef _LIBDEX_OPTINVOCATION
 #define _LIBDEX_OPTINVOCATION
 
-#include <stdint.h>
-#include <unistd.h>
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-
 /*
  * Utility routines, used by the VM.
  */
@@ -34,15 +31,6 @@
     const char* subFileName);
 int dexOptCreateEmptyHeader(int fd);
 
-/* some flags that get passed through to "dexopt" command */
-#define DEXOPT_OPT_ENABLED      (1)
-#define DEXOPT_OPT_ALL          (1 << 1)
-#define DEXOPT_VERIFY_ENABLED   (1 << 2)
-#define DEXOPT_VERIFY_ALL       (1 << 3)
-#define DEXOPT_IS_BOOTSTRAP     (1 << 4)
-#define DEXOPT_GEN_REGISTER_MAP (1 << 5)
-
-
 #ifdef __cplusplus
 };
 #endif
diff --git a/vm/Init.c b/vm/Init.c
index f93d2c8..aa6b98a 100644
--- a/vm/Init.c
+++ b/vm/Init.c
@@ -1568,7 +1568,14 @@
     gDvm.dexOptMode = dexOptMode;
     gDvm.classVerifyMode = verifyMode;
     gDvm.generateRegisterMaps = (dexoptFlags & DEXOPT_GEN_REGISTER_MAPS) != 0;
-    gDvm.dexOptForSmp = (dexoptFlags & DEXOPT_UNIPROCESSOR) == 0;
+    if (dexoptFlags & DEXOPT_SMP) {
+        assert((dexoptFlags & DEXOPT_UNIPROCESSOR) == 0);
+        gDvm.dexOptForSmp = true;
+    } else if (dexoptFlags & DEXOPT_UNIPROCESSOR) {
+        gDvm.dexOptForSmp = false;
+    } else {
+        gDvm.dexOptForSmp = (ANDROID_SMP != 0);
+    }
 
     /*
      * Initialize the heap, some basic thread control mutexes, and
diff --git a/vm/analysis/DexPrepare.c b/vm/analysis/DexPrepare.c
index 99aeabe..7a9f283 100644
--- a/vm/analysis/DexPrepare.c
+++ b/vm/analysis/DexPrepare.c
@@ -398,7 +398,7 @@
         if (isBootstrap)
             flags |= DEXOPT_IS_BOOTSTRAP;
         if (gDvm.generateRegisterMaps)
-            flags |= DEXOPT_GEN_REGISTER_MAP;
+            flags |= DEXOPT_GEN_REGISTER_MAPS;
         sprintf(values[9], "%d", flags);
         argv[curArg++] = values[9];
 
diff --git a/vm/analysis/DexPrepare.h b/vm/analysis/DexPrepare.h
index c014055..bfa5fb5 100644
--- a/vm/analysis/DexPrepare.h
+++ b/vm/analysis/DexPrepare.h
@@ -33,8 +33,14 @@
 
 /* some additional bit flags for dexopt */
 enum DexoptFlags {
-    DEXOPT_GEN_REGISTER_MAPS = 1, /* generate register maps during verify */
-    DEXOPT_UNIPROCESSOR = 1 << 1, /* assume a uniprocessor target */
+    DEXOPT_OPT_ENABLED       = 1,       /* optimizations enabled? */
+    DEXOPT_OPT_ALL           = 1 << 1,  /* optimize when verify fails? */
+    DEXOPT_VERIFY_ENABLED    = 1 << 2,  /* verification enabled? */
+    DEXOPT_VERIFY_ALL        = 1 << 3,  /* verify bootstrap classes? */
+    DEXOPT_IS_BOOTSTRAP      = 1 << 4,  /* is dex in bootstrap class path? */
+    DEXOPT_GEN_REGISTER_MAPS = 1 << 5,  /* generate register maps during vfy */
+    DEXOPT_UNIPROCESSOR      = 1 << 6,  /* specify uniprocessor target */
+    DEXOPT_SMP               = 1 << 7   /* specify SMP target */
 };
 
 /*