Merge "app_process: Forward -cp/-classpath to ART."
am: 4a4a8f1555

Change-Id: If7773d6bae3f4f13aa7f0c883b1c20319d85c747
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index 18ad43e..d5580ac 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -188,6 +188,16 @@
         LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));
     }
 
+    if (!LOG_NDEBUG) {
+      String8 argv_String;
+      for (int i = 0; i < argc; ++i) {
+        argv_String.append("\"");
+        argv_String.append(argv[i]);
+        argv_String.append("\" ");
+      }
+      ALOGV("app_process main with argv: %s", argv_String.string());
+    }
+
     AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
     // Process command line arguments
     // ignore argv[0]
@@ -216,9 +226,31 @@
     //
     // Note that we must copy argument string values since we will rewrite the
     // entire argument block when we apply the nice name to argv0.
+    //
+    // As an exception to the above rule, anything in "spaced commands"
+    // goes to the vm even though it has a space in it.
+    const char* spaced_commands[] = { "-cp", "-classpath" };
+    // Allow "spaced commands" to be succeeded by exactly 1 argument (regardless of -s).
+    bool known_command = false;
 
     int i;
     for (i = 0; i < argc; i++) {
+        if (known_command == true) {
+          runtime.addOption(strdup(argv[i]));
+          ALOGV("app_process main add known option '%s'", argv[i]);
+          known_command = false;
+          continue;
+        }
+
+        for (int j = 0;
+             j < static_cast<int>(sizeof(spaced_commands) / sizeof(spaced_commands[0]));
+             ++j) {
+          if (strcmp(argv[i], spaced_commands[j]) == 0) {
+            known_command = true;
+            ALOGV("app_process main found known command '%s'", argv[i]);
+          }
+        }
+
         if (argv[i][0] != '-') {
             break;
         }
@@ -226,7 +258,9 @@
             ++i; // Skip --.
             break;
         }
+
         runtime.addOption(strdup(argv[i]));
+        ALOGV("app_process main add option '%s'", argv[i]);
     }
 
     // Parse runtime arguments.  Stop at first unrecognized option.
@@ -266,6 +300,18 @@
         // copies of them before we overwrite them with the process name.
         args.add(application ? String8("application") : String8("tool"));
         runtime.setClassNameAndArgs(className, argc - i, argv + i);
+
+        if (!LOG_NDEBUG) {
+          String8 restOfArgs;
+          char* const* argv_new = argv + i;
+          int argc_new = argc - i;
+          for (int k = 0; k < argc_new; ++k) {
+            restOfArgs.append("\"");
+            restOfArgs.append(argv_new[k]);
+            restOfArgs.append("\" ");
+          }
+          ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());
+        }
     } else {
         // We're in zygote mode.
         maybeCreateDalvikCache();
diff --git a/core/tests/benchmarks/README b/core/tests/benchmarks/README
index 0a41bcc..e4d2dce 100644
--- a/core/tests/benchmarks/README
+++ b/core/tests/benchmarks/README
@@ -5,4 +5,21 @@
 http://code.google.com/p/caliper/
 http://code.google.com/p/vogar/
 
-$ vogar --benchmark path/to/Benchmark.java
+-------------------------
+
+Quick Command Line Reference:
+
+# Build vogar and dependencies.
+$> mmma -j32 external/vogar
+
+# First make sure art has permissions to dalvik-cache, otherwise it will run slower with interpreter.
+$> adb root
+
+# Run vogar in benchmark mode, telling it to use app_process (not dalvikvm which is default)
+# Otherwise you will likely crash with UnsatisfiedLinkError despite having correct JNI code.
+
+$> vogar --mode app_process --benchmark path/to/Benchmark.java
+
+# Sometimes your benchmarks might time out, if so increase the timeout:
+# (--timeout goes to vogar, and --time-limit goes to caliper)
+$> vogar --timeout 1000 --mode app_process --benchmark path/to/Benchmark -- --time-limit 9999s