Add oat file generation and tests to build

- Currently builds boot.oat for host and target
  and target oat files for art tests.
- Added cross compilation support via --strip-prefix option to dex2oat
- Reduced output to prevent build log spam (Compiler::verbose_)
- Added image roots for recovering important pointers on image load
- Redid JNI stub creation and made the stub array an image root
- Fixed JNI stub test by making JNI stub array executable
- Fixed JNI UnregisterNative to having it reinstall the JNI stub
- Fixed ARM JNI stub to generate PIC code (with irogers)
- Fixed JniCompiler to generate PIC code (with irogers)
- Fixed FindNativeMethod to handle recursive calls
- Finished checkFieldType to use Object::InstanceOf
- Fixed thread unsafe access to ClassLinker::{dex_files_,dex_caches_}
- Added ResolvedMethod variant for use with Method* for context
- Fixed ImageWriter to call FixupMethod
- Fixed ImageWriter to rewrite JNI stub references
- Improved error reporting on lack of ANDROID_DATA dir or art-cache dir
- Fixed Runtime::Start to InitLibraries before creating thread peer
- Implemented Space::IsCondemned to skip spaces loaded from images
- Implemented artFindInterfaceMethodInCache,
  allowing interface invocation from managed code

Change-Id: I603e97fa0ac44508ae05a2e47c1cdb4481678d7b
diff --git a/src/dex2oat.cc b/src/dex2oat.cc
index 64e0aaa..304c7d2 100644
--- a/src/dex2oat.cc
+++ b/src/dex2oat.cc
@@ -46,14 +46,20 @@
           "  --method may be used to limit compilation to a subset of methods.\n"
           "      Example: --method=Ljava/lang/Object;<init>()V\n"
           "\n");
+  fprintf(stderr,
+          "  --strip-prefix may be used to strip a path prefix from dex file names in the\n"
+          "       the generated image to match the target file system layout.\n"
+          "      Example: --strip-prefix=out/target/product/crespo\n"
+          "\n");
   exit(EXIT_FAILURE);
 }
 
 static void OpenDexFiles(std::vector<const char*>& dex_filenames,
-                         std::vector<const DexFile*>& dex_files) {
+                         std::vector<const DexFile*>& dex_files,
+                         const std::string& strip_location_prefix) {
   for (size_t i = 0; i < dex_filenames.size(); i++) {
     const char* dex_filename = dex_filenames[i];
-    const DexFile* dex_file = DexFile::Open(dex_filename);
+    const DexFile* dex_file = DexFile::Open(dex_filename, strip_location_prefix);
     if (dex_file == NULL) {
       fprintf(stderr, "could not open .dex from file %s\n", dex_filename);
       exit(EXIT_FAILURE);
@@ -78,6 +84,8 @@
   std::string boot_image_option;
   std::vector<const char*> boot_dex_filenames;
   uintptr_t image_base = 0;
+  std::string strip_location_prefix;
+
   for (int i = 0; i < argc; i++) {
     const StringPiece option(argv[i]);
     if (option.starts_with("--dex-file=")) {
@@ -101,6 +109,8 @@
       boot_image_option += boot_image_filename;
     } else if (option.starts_with("--boot-dex-file=")) {
       boot_dex_filenames.push_back(option.substr(strlen("--boot-dex-file=")).data());
+    } else if (option.starts_with("--strip-prefix=")) {
+      strip_location_prefix = option.substr(strlen("--strip-prefix=")).data();
     } else {
       fprintf(stderr, "unknown argument %s\n", option.data());
       usage();
@@ -125,10 +135,10 @@
   }
 
   std::vector<const DexFile*> dex_files;
-  OpenDexFiles(dex_filenames, dex_files);
+  OpenDexFiles(dex_filenames, dex_files, strip_location_prefix);
 
   std::vector<const DexFile*> boot_dex_files;
-  OpenDexFiles(boot_dex_filenames, boot_dex_files);
+  OpenDexFiles(boot_dex_filenames, boot_dex_files, strip_location_prefix);
 
   Runtime::Options options;
   if (boot_image_option.empty()) {
@@ -162,6 +172,11 @@
     class_loader = PathClassLoader::Alloc(dex_files);
   }
 
+  // if we loaded an existing image, we will reuse its stub array.
+  if (!runtime->HasJniStubArray()) {
+    runtime->SetJniStubArray(JniCompiler::CreateJniStub(kThumb2));
+  }
+
   Compiler compiler(kThumb2);
   if (method_names.empty()) {
     compiler.CompileAll(class_loader);