Merge "Add --runtime-arg to command line tools."
diff --git a/cmdline/cmdline.h b/cmdline/cmdline.h
index 95ab123..81a2179 100644
--- a/cmdline/cmdline.h
+++ b/cmdline/cmdline.h
@@ -85,7 +85,9 @@
   }
 }
 
-static Runtime* StartRuntime(const char* boot_image_location, InstructionSet instruction_set) {
+static Runtime* StartRuntime(const char* boot_image_location,
+                             InstructionSet instruction_set,
+                             const std::vector<const char*>& runtime_args) {
   CHECK(boot_image_location != nullptr);
 
   RuntimeOptions options;
@@ -101,13 +103,19 @@
     std::string boot_image_option;
     boot_image_option += "-Ximage:";
     boot_image_option += boot_image_location;
-    options.push_back(std::make_pair(boot_image_option.c_str(), nullptr));
+    options.push_back(std::make_pair(boot_image_option, nullptr));
   }
 
   // Instruction set.
   options.push_back(
       std::make_pair("imageinstructionset",
                      reinterpret_cast<const void*>(GetInstructionSetString(instruction_set))));
+
+  // Explicit runtime args.
+  for (const char* runtime_arg : runtime_args) {
+    options.push_back(std::make_pair(runtime_arg, nullptr));
+  }
+
   // None of the command line tools need sig chain. If this changes we'll need
   // to upgrade this option to a proper parameter.
   options.push_back(std::make_pair("-Xno-sig-chain", nullptr));
@@ -154,6 +162,14 @@
           PrintUsage();
           return false;
         }
+      } else if (option == "--runtime-arg") {
+        if (i + 1 == argc) {
+          fprintf(stderr, "Missing argument for --runtime-arg\n");
+          PrintUsage();
+          return false;
+        }
+        ++i;
+        runtime_args_.push_back(argv[i]);
       } else if (option.starts_with("--output=")) {
         output_name_ = option.substr(strlen("--output=")).ToString();
         const char* filename = output_name_.c_str();
@@ -209,6 +225,12 @@
         "      Default: %s\n"
         "\n",
         GetInstructionSetString(kRuntimeISA));
+    usage +=
+        "  --runtime-arg <argument> used to specify various arguments for the runtime\n"
+        "      such as initial heap size, maximum heap size, and verbose output.\n"
+        "      Use a separate --runtime-arg switch for each argument.\n"
+        "      Example: --runtime-arg -Xms256m\n"
+        "\n";
     usage +=  // Optional.
         "  --output=<file> may be used to send the output to a file.\n"
         "      Example: --output=/tmp/oatdump.txt\n"
@@ -221,6 +243,8 @@
   const char* boot_image_location_ = nullptr;
   // Specified by --instruction-set.
   InstructionSet instruction_set_ = InstructionSet::kNone;
+  // Runtime arguments specified by --runtime-arg.
+  std::vector<const char*> runtime_args_;
   // Specified by --output.
   std::ostream* os_ = &std::cout;
   std::unique_ptr<std::ofstream> out_;  // If something besides cout is used
@@ -383,7 +407,7 @@
   Runtime* CreateRuntime(CmdlineArgs* args) {
     CHECK(args != nullptr);
 
-    return StartRuntime(args->boot_image_location_, args->instruction_set_);
+    return StartRuntime(args->boot_image_location_, args->instruction_set_, args_->runtime_args_);
   }
 };
 }  // namespace art
diff --git a/dexoptanalyzer/dexoptanalyzer.cc b/dexoptanalyzer/dexoptanalyzer.cc
index 2b97fb4..acf0f94 100644
--- a/dexoptanalyzer/dexoptanalyzer.cc
+++ b/dexoptanalyzer/dexoptanalyzer.cc
@@ -97,6 +97,11 @@
   UsageError("       oat file is up to date. Defaults to $ANDROID_ROOT/framework/boot.art.");
   UsageError("       Example: --image=/system/framework/boot.art");
   UsageError("");
+  UsageError("  --runtime-arg <argument>: used to specify various arguments for the runtime,");
+  UsageError("      such as initial heap size, maximum heap size, and verbose output.");
+  UsageError("      Use a separate --runtime-arg switch for each argument.");
+  UsageError("      Example: --runtime-arg -Xms256m");
+  UsageError("");
   UsageError("  --android-data=<directory>: optional, the directory which should be used as");
   UsageError("       android-data. By default ANDROID_DATA env variable is used.");
   UsageError("");
@@ -168,6 +173,12 @@
         }
       } else if (option.starts_with("--image=")) {
         image_ = option.substr(strlen("--image=")).ToString();
+      } else if (option == "--runtime-arg") {
+        if (i + 1 == argc) {
+          Usage("Missing argument for --runtime-arg\n");
+        }
+        ++i;
+        runtime_args_.push_back(argv[i]);
       } else if (option.starts_with("--android-data=")) {
         // Overwrite android-data if needed (oat file assistant relies on a valid directory to
         // compute dalvik-cache folder). This is mostly used in tests.
@@ -218,10 +229,14 @@
     RuntimeOptions options;
     // The image could be custom, so make sure we explicitly pass it.
     std::string img = "-Ximage:" + image_;
-    options.push_back(std::make_pair(img.c_str(), nullptr));
+    options.push_back(std::make_pair(img, nullptr));
     // The instruction set of the image should match the instruction set we will test.
     const void* isa_opt = reinterpret_cast<const void*>(GetInstructionSetString(isa_));
     options.push_back(std::make_pair("imageinstructionset", isa_opt));
+    // Explicit runtime args.
+    for (const char* runtime_arg : runtime_args_) {
+      options.push_back(std::make_pair(runtime_arg, nullptr));
+    }
      // Disable libsigchain. We don't don't need it to evaluate DexOptNeeded status.
     options.push_back(std::make_pair("-Xno-sig-chain", nullptr));
     // Pretend we are a compiler so that we can re-use the same infrastructure to load a different
@@ -289,6 +304,7 @@
   bool assume_profile_changed_;
   bool downgrade_;
   std::string image_;
+  std::vector<const char*> runtime_args_;
   int oat_fd_ = -1;
   int vdex_fd_ = -1;
   // File descriptor corresponding to apk, dex_file, or zip.