Merge "Use temp register in Unsafe Get/Put intrisics for displaced offset."
diff --git a/Android.mk b/Android.mk
index 5325abd..6139cb9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -435,6 +435,18 @@
 	adb shell setprop persist.sys.dalvik.vm.lib.1 libart.so
 	adb shell start
 
+.PHONY: use-art-verify-none
+use-art-verify-none:
+	adb root && sleep 3
+	adb shell stop
+	adb shell rm $(ART_DALVIK_CACHE_DIR)/*.dex
+	adb shell rm $(ART_DALVIK_CACHE_DIR)/*.oat
+	adb shell rm $(ART_DALVIK_CACHE_DIR)/*.art
+	adb shell setprop dalvik.vm.dex2oat-flags "--compiler-filter=verify-none"
+	adb shell setprop dalvik.vm.image-dex2oat-flags "--compiler-filter=verify-none"
+	adb shell setprop persist.sys.dalvik.vm.lib.1 libart.so
+	adb shell start
+
 ########################################################################
 
 endif # !art_dont_bother
diff --git a/build/Android.executable.mk b/build/Android.executable.mk
index 88ca47e..27d687c 100644
--- a/build/Android.executable.mk
+++ b/build/Android.executable.mk
@@ -30,6 +30,7 @@
 # $(4): extra include directories
 # $(5): target or host
 # $(6): ndebug or debug
+# $(7): value for LOCAL_MULTILIB (empty means default)
 define build-art-executable
   ifneq ($(5),target)
     ifneq ($(5),host)
@@ -48,6 +49,7 @@
   art_c_includes := $(4)
   art_target_or_host := $(5)
   art_ndebug_or_debug := $(6)
+  art_multilib := $(7)
 
   include $(CLEAR_VARS)
   ifeq ($$(art_target_or_host),target)
@@ -98,6 +100,7 @@
 
   ifeq ($$(art_target_or_host),target)
     LOCAL_MODULE_TARGET_ARCH := $(ART_SUPPORTED_ARCH)
+    LOCAL_MULTILIB := $$(art_multilib)
   endif
 
   ifeq ($$(art_target_or_host),target)
diff --git a/compiler/common_compiler_test.h b/compiler/common_compiler_test.h
index 6aa85d4..9a21da0 100644
--- a/compiler/common_compiler_test.h
+++ b/compiler/common_compiler_test.h
@@ -291,7 +291,7 @@
 
       // Take the default set of instruction features from the build.
       InstructionSetFeatures instruction_set_features =
-          ParseFeatureList(STRINGIFY(ART_DEFAULT_INSTRUCTION_SET_FEATURES));
+          ParseFeatureList(Runtime::GetDefaultInstructionSetFeatures());
 
 #if defined(__arm__)
       instruction_set = kThumb2;
diff --git a/compiler/dex/frontend.cc b/compiler/dex/frontend.cc
index 3f122de..cc616f6 100644
--- a/compiler/dex/frontend.cc
+++ b/compiler/dex/frontend.cc
@@ -145,9 +145,7 @@
     return NULL;
   }
 
-  const CompilerOptions& compiler_options = driver.GetCompilerOptions();
-  CompilerOptions::CompilerFilter compiler_filter = compiler_options.GetCompilerFilter();
-  if (compiler_filter == CompilerOptions::kInterpretOnly) {
+  if (!driver.GetCompilerOptions().IsCompilationEnabled()) {
     return nullptr;
   }
 
@@ -230,10 +228,8 @@
                               class_loader, dex_file);
 
   cu.NewTimingSplit("MIROpt:CheckFilters");
-  if (compiler_filter != CompilerOptions::kInterpretOnly) {
-    if (cu.mir_graph->SkipCompilation()) {
-      return NULL;
-    }
+  if (cu.mir_graph->SkipCompilation()) {
+    return NULL;
   }
 
   /* Create the pass driver and launch it */
diff --git a/compiler/dex/mir_analysis.cc b/compiler/dex/mir_analysis.cc
index b96c40d..200795e 100644
--- a/compiler/dex/mir_analysis.cc
+++ b/compiler/dex/mir_analysis.cc
@@ -1013,7 +1013,7 @@
     return true;
   }
 
-  if (compiler_filter == CompilerOptions::kInterpretOnly || compiler_filter == CompilerOptions::kProfiled) {
+  if (!compiler_options.IsCompilationEnabled() || compiler_filter == CompilerOptions::kProfiled) {
     return true;
   }
 
diff --git a/compiler/dex/quick/arm/target_arm.cc b/compiler/dex/quick/arm/target_arm.cc
index 5ebe0a3..5e9a8b0 100644
--- a/compiler/dex/quick/arm/target_arm.cc
+++ b/compiler/dex/quick/arm/target_arm.cc
@@ -559,10 +559,13 @@
       (arena_->Alloc(num_fp_regs * sizeof(*reg_pool_->FPRegs), kArenaAllocRegAlloc));
   CompilerInitPool(reg_pool_->core_regs, core_regs, reg_pool_->num_core_regs);
   CompilerInitPool(reg_pool_->FPRegs, FpRegs, reg_pool_->num_fp_regs);
+
   // Keep special registers from being allocated
+  // Don't reserve the r4 if we are doing implicit suspend checks.
+  bool no_suspend = NO_SUSPEND || !Runtime::Current()->ExplicitSuspendChecks();
   for (int i = 0; i < num_reserved; i++) {
-    if (NO_SUSPEND && (ReservedRegs[i] == rARM_SUSPEND)) {
-      // To measure cost of suspend check
+    if (no_suspend && (ReservedRegs[i] == rARM_SUSPEND)) {
+      // Don't reserve the suspend register.
       continue;
     }
     MarkInUse(ReservedRegs[i]);
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index c10dd84..a120d05 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -598,6 +598,11 @@
                                 ThreadPool* thread_pool, TimingLogger* timings) {
   LoadImageClasses(timings);
 
+  if (!compiler_options_->IsVerificationEnabled()) {
+    VLOG(compiler) << "Verify none mode specified, skipping pre-compilation";
+    return;
+  }
+
   Resolve(class_loader, dex_files, thread_pool, timings);
 
   Verify(class_loader, dex_files, thread_pool, timings);
@@ -1872,7 +1877,7 @@
 
   if ((access_flags & kAccNative) != 0) {
     // Are we interpreting only and have support for generic JNI down calls?
-    if ((compiler_options_->GetCompilerFilter() == CompilerOptions::kInterpretOnly) &&
+    if (!compiler_options_->IsCompilationEnabled() &&
         (instruction_set_ == kX86_64 || instruction_set_ == kArm64)) {
       // Leaving this empty will trigger the generic JNI version
     } else {
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index 0cca1e9..20c6bc8 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -22,7 +22,8 @@
 class CompilerOptions {
  public:
   enum CompilerFilter {
-    kInterpretOnly,       // Compile nothing.
+    kVerifyNone,          // Skip verification and compile nothing except JNI stubs.
+    kInterpretOnly,       // Compile nothing except JNI stubs.
     kProfiled,            // Compile based on profile.
     kSpace,               // Maximize space savings.
     kBalanced,            // Try to get the best performance return on compilation investment.
@@ -86,6 +87,15 @@
     compiler_filter_ = compiler_filter;
   }
 
+  bool IsCompilationEnabled() const {
+    return ((compiler_filter_ != CompilerOptions::kVerifyNone) &&
+            (compiler_filter_ != CompilerOptions::kInterpretOnly));
+  }
+
+  bool IsVerificationEnabled() const {
+    return (compiler_filter_ != CompilerOptions::kVerifyNone);
+  }
+
   size_t GetHugeMethodThreshold() const {
     return huge_method_threshold_;
   }
diff --git a/dex2oat/Android.mk b/dex2oat/Android.mk
index 6cd0538..038f0a7 100644
--- a/dex2oat/Android.mk
+++ b/dex2oat/Android.mk
@@ -22,10 +22,10 @@
 	dex2oat.cc
 
 ifeq ($(ART_BUILD_TARGET_NDEBUG),true)
-  $(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),libcutils libart-compiler,art/compiler,target,ndebug))
+  $(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),libcutils libart-compiler,art/compiler,target,ndebug,32))
 endif
 ifeq ($(ART_BUILD_TARGET_DEBUG),true)
-  $(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),libcutils libartd-compiler,art/compiler,target,debug))
+  $(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),libcutils libartd-compiler,art/compiler,target,debug,32))
 endif
 
 ifeq ($(WITH_HOST_DALVIK),true)
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 72effde..f665f5c 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -153,8 +153,8 @@
   UsageError("      Example: --compiler-backend=Portable");
   UsageError("      Default: Quick");
   UsageError("");
-  UsageError("  --compiler-filter=(interpret-only|space|balanced|speed|everything): select");
-  UsageError("      compiler filter.");
+  UsageError("  --compiler-filter=(verify-none|interpret-only|space|balanced|speed|everything):");
+  UsageError("      select compiler filter.");
   UsageError("      Example: --compiler-filter=everything");
 #if ART_SMALL_MODE
   UsageError("      Default: interpret-only");
@@ -189,7 +189,8 @@
   UsageError("");
   UsageError("  --num-dex-methods=<method-count>: threshold size for a small dex file for");
   UsageError("      compiler filter tuning. If the input has fewer than this many methods");
-  UsageError("      and the filter is not interpret-only, overrides the filter to use speed");
+  UsageError("      and the filter is not interpret-only or verify-none, overrides the");
+  UsageError("      filter to use speed");
   UsageError("      Example: --num-dex-method=%d", CompilerOptions::kDefaultNumDexMethodsThreshold);
   UsageError("      Default: %d", CompilerOptions::kDefaultNumDexMethodsThreshold);
   UsageError("");
@@ -201,8 +202,8 @@
   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("  --profile-file=<filename>: specify profiler output file to use for compilation.");
+  UsageError("");
+  UsageError("  --profile-file=<filename>: specify profiler output file to use for compilation.");
   UsageError("");
   UsageError("  --print-pass-names: print a list of pass names");
   UsageError("");
@@ -740,7 +741,7 @@
 
   // Take the default set of instruction features from the build.
   InstructionSetFeatures instruction_set_features =
-      ParseFeatureList(STRINGIFY(ART_DEFAULT_INSTRUCTION_SET_FEATURES));
+      ParseFeatureList(Runtime::GetDefaultInstructionSetFeatures());
 
 #if defined(__arm__)
   InstructionSet instruction_set = kThumb2;
@@ -1037,7 +1038,9 @@
   }
   CHECK(compiler_filter_string != nullptr);
   CompilerOptions::CompilerFilter compiler_filter = CompilerOptions::kDefaultCompilerFilter;
-  if (strcmp(compiler_filter_string, "interpret-only") == 0) {
+  if (strcmp(compiler_filter_string, "verify-none") == 0) {
+    compiler_filter = CompilerOptions::kVerifyNone;
+  } else if (strcmp(compiler_filter_string, "interpret-only") == 0) {
     compiler_filter = CompilerOptions::kInterpretOnly;
   } else if (strcmp(compiler_filter_string, "space") == 0) {
     compiler_filter = CompilerOptions::kSpace;
@@ -1208,10 +1211,10 @@
   }
 
   /*
-   * If we're not in interpret-only mode, go ahead and compile small applications. Don't
-   * bother to check if we're doing the image.
+   * If we're not in interpret-only or verify-none mode, go ahead and compile small applications.
+   * Don't bother to check if we're doing the image.
    */
-  if (!image && (compiler_options.GetCompilerFilter() != CompilerOptions::kInterpretOnly)) {
+  if (!image && compiler_options.IsCompilationEnabled()) {
     size_t num_methods = 0;
     for (size_t i = 0; i != dex_files.size(); ++i) {
       const DexFile* dex_file = dex_files[i];
diff --git a/runtime/Android.mk b/runtime/Android.mk
index 697d1a3..cf7f895 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -73,6 +73,7 @@
 	hprof/hprof.cc \
 	image.cc \
 	indirect_reference_table.cc \
+	instruction_set.cc \
 	instrumentation.cc \
 	intern_table.cc \
 	interpreter/interpreter.cc \
@@ -436,6 +437,11 @@
   endif
 
   ifeq ($$(art_target_or_host),target)
+    ifneq ($$(art_ndebug_or_debug),debug)
+      # Leave the symbols in the shared library so that stack unwinders can
+      # produce meaningful name resolution.
+      LOCAL_STRIP_MODULE := keep_symbols
+    endif
     include $(BUILD_SHARED_LIBRARY)
   else # host
     include $(BUILD_HOST_SHARED_LIBRARY)
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 3957493..6c5406e 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -567,40 +567,16 @@
   argv.push_back("--runtime-arg");
   argv.push_back(Runtime::Current()->GetClassPathString());
 
-  argv.push_back("--runtime-arg");
-  std::string checkstr = "-implicit-checks";
+  Runtime::Current()->AddCurrentRuntimeFeaturesAsDex2OatArguments(&argv);
 
-  int nchecks = 0;
-  char checksep = ':';
-
-  if (!Runtime::Current()->ExplicitNullChecks()) {
-    checkstr += checksep;
-    checksep = ',';
-    checkstr += "null";
-    ++nchecks;
+  if (!Runtime::Current()->IsVerificationEnabled()) {
+    argv.push_back("--compiler-filter=verify-none");
   }
-  if (!Runtime::Current()->ExplicitSuspendChecks()) {
-    checkstr += checksep;
-    checksep = ',';
-    checkstr += "suspend";
-    ++nchecks;
-  }
-
-  if (!Runtime::Current()->ExplicitStackOverflowChecks()) {
-    checkstr += checksep;
-    checksep = ',';
-    checkstr += "stack";
-    ++nchecks;
-  }
-
-  if (nchecks == 0) {
-    checkstr += ":none";
-  }
-  argv.push_back(checkstr);
 
   if (!kIsTargetBuild) {
     argv.push_back("--host");
   }
+
   argv.push_back(boot_image_option);
   argv.push_back(dex_file_option);
   argv.push_back(oat_fd_option);
@@ -2561,6 +2537,12 @@
     klass->SetStatus(mirror::Class::kStatusVerifyingAtRuntime, self);
   }
 
+  // Skip verification if disabled.
+  if (!Runtime::Current()->IsVerificationEnabled()) {
+    klass->SetStatus(mirror::Class::kStatusVerified, self);
+    return;
+  }
+
   // Verify super class.
   SirtRef<mirror::Class> super(self, klass->GetSuperClass());
   if (super.get() != NULL) {
diff --git a/runtime/gc/accounting/space_bitmap-inl.h b/runtime/gc/accounting/space_bitmap-inl.h
index d6d1b3e..0fbd27c 100644
--- a/runtime/gc/accounting/space_bitmap-inl.h
+++ b/runtime/gc/accounting/space_bitmap-inl.h
@@ -29,10 +29,10 @@
   DCHECK_GE(addr, heap_begin_);
   const uintptr_t offset = addr - heap_begin_;
   const size_t index = OffsetToIndex(offset);
-  const word mask = OffsetToMask(offset);
-  word* const address = &bitmap_begin_[index];
+  const uword mask = OffsetToMask(offset);
+  uword* const address = &bitmap_begin_[index];
   DCHECK_LT(index, bitmap_size_ / kWordSize) << " bitmap_size_ = " << bitmap_size_;
-  word old_word;
+  uword old_word;
   do {
     old_word = *address;
     // Fast path: The bit is already set.
@@ -58,74 +58,79 @@
 void SpaceBitmap::VisitMarkedRange(uintptr_t visit_begin, uintptr_t visit_end,
                                    const Visitor& visitor) const {
   DCHECK_LT(visit_begin, visit_end);
-#ifdef __LP64__
-  // TODO: make the optimized code below work in the 64bit case.
-  for (uintptr_t i = visit_begin; i < visit_end; i += kAlignment) {
-    mirror::Object* obj = reinterpret_cast<mirror::Object*>(i);
-    if (Test(obj)) {
-      visitor(obj);
-    }
-  }
-#else
-  const size_t bit_index_start = (visit_begin - heap_begin_) / kAlignment;
-  const size_t bit_index_end = (visit_end - heap_begin_ - 1) / kAlignment;
+  DCHECK_LE(heap_begin_, visit_begin);
+  DCHECK_LE(visit_end, HeapLimit());
 
-  size_t word_start = bit_index_start / kBitsPerWord;
-  size_t word_end = bit_index_end / kBitsPerWord;
-  DCHECK_LT(word_end * kWordSize, Size());
+  const uintptr_t offset_start = visit_begin - heap_begin_;
+  const uintptr_t offset_end = visit_end - heap_begin_;
 
-  // Trim off left_bits of left bits.
-  size_t edge_word = bitmap_begin_[word_start];
+  const uintptr_t index_start = OffsetToIndex(offset_start);
+  const uintptr_t index_end = OffsetToIndex(offset_end);
 
-  // Handle bits on the left first as a special case
-  size_t left_bits = bit_index_start & (kBitsPerWord - 1);
-  if (left_bits != 0) {
-    edge_word &= (1 << (kBitsPerWord - left_bits)) - 1;
-  }
+  const size_t bit_start = (offset_start / kAlignment) % kBitsPerWord;
+  const size_t bit_end = (offset_end / kAlignment) % kBitsPerWord;
 
-  // If word_start == word_end then handle this case at the same place we handle the right edge.
-  if (edge_word != 0 && word_start < word_end) {
-    uintptr_t ptr_base = IndexToOffset(word_start) + heap_begin_;
-    do {
-      const size_t shift = CLZ(edge_word);
-      mirror::Object* obj = reinterpret_cast<mirror::Object*>(ptr_base + shift * kAlignment);
-      visitor(obj);
-      edge_word ^= static_cast<size_t>(kWordHighBitMask) >> shift;
-    } while (edge_word != 0);
-  }
-  word_start++;
+  // Index(begin)  ...    Index(end)
+  // [xxxxx???][........][????yyyy]
+  //      ^                   ^
+  //      |                   #---- Bit of visit_end
+  //      #---- Bit of visit_begin
+  //
 
-  for (size_t i = word_start; i < word_end; i++) {
-    size_t w = bitmap_begin_[i];
-    if (w != 0) {
-      uintptr_t ptr_base = IndexToOffset(i) + heap_begin_;
+  // Left edge.
+  uword left_edge = bitmap_begin_[index_start];
+  // Mark of lower bits that are not in range.
+  left_edge &= ~((static_cast<uword>(1) << bit_start) - 1);
+
+  // Right edge. Either unique, or left_edge.
+  uword right_edge;
+
+  if (index_start < index_end) {
+    // Left edge != right edge.
+
+    // Traverse left edge.
+    if (left_edge != 0) {
+      const uintptr_t ptr_base = IndexToOffset(index_start) + heap_begin_;
       do {
-        const size_t shift = CLZ(w);
+        const size_t shift = CTZ(left_edge);
         mirror::Object* obj = reinterpret_cast<mirror::Object*>(ptr_base + shift * kAlignment);
         visitor(obj);
-        w ^= static_cast<size_t>(kWordHighBitMask) >> shift;
-      } while (w != 0);
+        left_edge ^= (static_cast<uword>(1)) << shift;
+      } while (left_edge != 0);
     }
+
+    // Traverse the middle, full part.
+    for (size_t i = index_start + 1; i < index_end; ++i) {
+      uword w = bitmap_begin_[i];
+      if (w != 0) {
+        const uintptr_t ptr_base = IndexToOffset(i) + heap_begin_;
+        do {
+          const size_t shift = CTZ(w);
+          mirror::Object* obj = reinterpret_cast<mirror::Object*>(ptr_base + shift * kAlignment);
+          visitor(obj);
+          w ^= (static_cast<uword>(1)) << shift;
+        } while (w != 0);
+      }
+    }
+
+    // Right edge is unique.
+    right_edge = bitmap_begin_[index_end];
+  } else {
+    // Right edge = left edge.
+    right_edge = left_edge;
   }
 
-  // Handle the right edge, and also the left edge if both edges are on the same word.
-  size_t right_bits = bit_index_end & (kBitsPerWord - 1);
-
-  // If word_start == word_end then we need to use the word which we removed the left bits.
-  if (word_start <= word_end) {
-    edge_word = bitmap_begin_[word_end];
+  // Right edge handling.
+  right_edge &= ((static_cast<uword>(1) << bit_end) - 1) | (static_cast<uword>(1) << bit_end);
+  if (right_edge != 0) {
+    const uintptr_t ptr_base = IndexToOffset(index_end) + heap_begin_;
+    do {
+      const size_t shift = CTZ(right_edge);
+      mirror::Object* obj = reinterpret_cast<mirror::Object*>(ptr_base + shift * kAlignment);
+      visitor(obj);
+      right_edge ^= (static_cast<uword>(1)) << shift;
+    } while (right_edge != 0);
   }
-
-  // Bits that we trim off the right.
-  edge_word &= ~((static_cast<size_t>(kWordHighBitMask) >> right_bits) - 1);
-  uintptr_t ptr_base = IndexToOffset(word_end) + heap_begin_;
-  while (edge_word != 0) {
-    const size_t shift = CLZ(edge_word);
-    mirror::Object* obj = reinterpret_cast<mirror::Object*>(ptr_base + shift * kAlignment);
-    visitor(obj);
-    edge_word ^= static_cast<size_t>(kWordHighBitMask) >> shift;
-  }
-#endif
 }
 
 inline bool SpaceBitmap::Modify(const mirror::Object* obj, bool do_set) {
@@ -133,10 +138,10 @@
   DCHECK_GE(addr, heap_begin_);
   const uintptr_t offset = addr - heap_begin_;
   const size_t index = OffsetToIndex(offset);
-  const word mask = OffsetToMask(offset);
+  const uword mask = OffsetToMask(offset);
   DCHECK_LT(index, bitmap_size_ / kWordSize) << " bitmap_size_ = " << bitmap_size_;
-  word* address = &bitmap_begin_[index];
-  word old_word = *address;
+  uword* address = &bitmap_begin_[index];
+  uword old_word = *address;
   if (do_set) {
     *address = old_word | mask;
   } else {
diff --git a/runtime/gc/accounting/space_bitmap.cc b/runtime/gc/accounting/space_bitmap.cc
index ad4ff1b..1957c21 100644
--- a/runtime/gc/accounting/space_bitmap.cc
+++ b/runtime/gc/accounting/space_bitmap.cc
@@ -53,7 +53,7 @@
 SpaceBitmap* SpaceBitmap::CreateFromMemMap(const std::string& name, MemMap* mem_map,
                                            byte* heap_begin, size_t heap_capacity) {
   CHECK(mem_map != nullptr);
-  word* bitmap_begin = reinterpret_cast<word*>(mem_map->Begin());
+  uword* bitmap_begin = reinterpret_cast<uword*>(mem_map->Begin());
   size_t bitmap_size = OffsetToIndex(RoundUp(heap_capacity, kAlignment * kBitsPerWord)) * kWordSize;
   return new SpaceBitmap(name, mem_map, bitmap_begin, bitmap_size, heap_begin);
 }
@@ -107,16 +107,16 @@
   CHECK(callback != NULL);
 
   uintptr_t end = OffsetToIndex(HeapLimit() - heap_begin_ - 1);
-  word* bitmap_begin = bitmap_begin_;
+  uword* bitmap_begin = bitmap_begin_;
   for (uintptr_t i = 0; i <= end; ++i) {
-    word w = bitmap_begin[i];
+    uword w = bitmap_begin[i];
     if (w != 0) {
       uintptr_t ptr_base = IndexToOffset(i) + heap_begin_;
       do {
-        const size_t shift = CLZ(w);
+        const size_t shift = CTZ(w);
         mirror::Object* obj = reinterpret_cast<mirror::Object*>(ptr_base + shift * kAlignment);
         (*callback)(obj, arg);
-        w ^= static_cast<size_t>(kWordHighBitMask) >> shift;
+        w ^= (static_cast<uword>(1)) << shift;
       } while (w != 0);
     }
   }
@@ -150,15 +150,15 @@
   size_t start = OffsetToIndex(sweep_begin - live_bitmap.heap_begin_);
   size_t end = OffsetToIndex(sweep_end - live_bitmap.heap_begin_ - 1);
   CHECK_LT(end, live_bitmap.Size() / kWordSize);
-  word* live = live_bitmap.bitmap_begin_;
-  word* mark = mark_bitmap.bitmap_begin_;
+  uword* live = live_bitmap.bitmap_begin_;
+  uword* mark = mark_bitmap.bitmap_begin_;
   for (size_t i = start; i <= end; i++) {
-    word garbage = live[i] & ~mark[i];
+    uword garbage = live[i] & ~mark[i];
     if (UNLIKELY(garbage != 0)) {
       uintptr_t ptr_base = IndexToOffset(i) + live_bitmap.heap_begin_;
       do {
-        const size_t shift = CLZ(garbage);
-        garbage ^= static_cast<size_t>(kWordHighBitMask) >> shift;
+        const size_t shift = CTZ(garbage);
+        garbage ^= (static_cast<uword>(1)) << shift;
         *pb++ = reinterpret_cast<mirror::Object*>(ptr_base + shift * kAlignment);
       } while (garbage != 0);
       // Make sure that there are always enough slots available for an
@@ -254,14 +254,15 @@
   CHECK(callback != NULL);
   uintptr_t end = Size() / kWordSize;
   for (uintptr_t i = 0; i < end; ++i) {
-    word w = bitmap_begin_[i];
+    // Need uint for unsigned shift.
+    uword w = bitmap_begin_[i];
     if (UNLIKELY(w != 0)) {
       uintptr_t ptr_base = IndexToOffset(i) + heap_begin_;
       while (w != 0) {
-        const size_t shift = CLZ(w);
+        const size_t shift = CTZ(w);
         mirror::Object* obj = reinterpret_cast<mirror::Object*>(ptr_base + shift * kAlignment);
         WalkFieldsInOrder(visited.get(), callback, obj, arg);
-        w ^= static_cast<size_t>(kWordHighBitMask) >> shift;
+        w ^= (static_cast<uword>(1)) << shift;
       }
     }
   }
diff --git a/runtime/gc/accounting/space_bitmap.h b/runtime/gc/accounting/space_bitmap.h
index 5fd2bce..aa24b03 100644
--- a/runtime/gc/accounting/space_bitmap.h
+++ b/runtime/gc/accounting/space_bitmap.h
@@ -70,9 +70,9 @@
     return static_cast<uintptr_t>(index * kAlignment * kBitsPerWord);
   }
 
-  // Pack the bits in backwards so they come out in address order when using CLZ.
-  static word OffsetToMask(uintptr_t offset) {
-    return static_cast<uintptr_t>(kWordHighBitMask) >> ((offset / kAlignment) % kBitsPerWord);
+  // Bits are packed in the obvious way.
+  static uword OffsetToMask(uintptr_t offset) {
+    return (static_cast<size_t>(1)) << ((offset / kAlignment) % kBitsPerWord);
   }
 
   inline bool Set(const mirror::Object* obj) {
@@ -140,7 +140,7 @@
   void CopyFrom(SpaceBitmap* source_bitmap);
 
   // Starting address of our internal storage.
-  word* Begin() {
+  uword* Begin() {
     return bitmap_begin_;
   }
 
@@ -181,7 +181,7 @@
  private:
   // TODO: heap_end_ is initialized so that the heap bitmap is empty, this doesn't require the -1,
   // however, we document that this is expected on heap_end_
-  SpaceBitmap(const std::string& name, MemMap* mem_map, word* bitmap_begin, size_t bitmap_size,
+  SpaceBitmap(const std::string& name, MemMap* mem_map, uword* bitmap_begin, size_t bitmap_size,
               const void* heap_begin)
       : mem_map_(mem_map), bitmap_begin_(bitmap_begin), bitmap_size_(bitmap_size),
         heap_begin_(reinterpret_cast<uintptr_t>(heap_begin)),
@@ -193,7 +193,7 @@
   UniquePtr<MemMap> mem_map_;
 
   // This bitmap itself, word sized for efficiency in scanning.
-  word* const bitmap_begin_;
+  uword* const bitmap_begin_;
 
   // Size of this bitmap.
   size_t bitmap_size_;
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 9a2815a..faa539f 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -67,36 +67,6 @@
   arg_vector.push_back("--runtime-arg");
   arg_vector.push_back("-Xmx64m");
 
-  arg_vector.push_back("--runtime-arg");
-  std::string checkstr = "-implicit-checks";
-  int nchecks = 0;
-  char checksep = ':';
-
-  if (!Runtime::Current()->ExplicitNullChecks()) {
-    checkstr += checksep;
-    checksep = ',';
-    checkstr += "null";
-    ++nchecks;
-  }
-  if (!Runtime::Current()->ExplicitSuspendChecks()) {
-    checkstr += checksep;
-    checksep = ',';
-    checkstr += "suspend";
-    ++nchecks;
-  }
-
-  if (!Runtime::Current()->ExplicitStackOverflowChecks()) {
-    checkstr += checksep;
-    checksep = ',';
-    checkstr += "stack";
-    ++nchecks;
-  }
-
-  if (nchecks == 0) {
-    checkstr += ":none";
-  }
-
-  arg_vector.push_back(checkstr);
 
   for (size_t i = 0; i < boot_class_path.size(); i++) {
     arg_vector.push_back(std::string("--dex-file=") + boot_class_path[i]);
@@ -108,6 +78,8 @@
   oat_file_option_string += "oat";
   arg_vector.push_back(oat_file_option_string);
 
+  Runtime::Current()->AddCurrentRuntimeFeaturesAsDex2OatArguments(&arg_vector);
+
   arg_vector.push_back(StringPrintf("--base=0x%x", ART_BASE_ADDRESS));
 
   if (kIsTargetBuild) {
diff --git a/runtime/instruction_set.cc b/runtime/instruction_set.cc
new file mode 100644
index 0000000..c964629
--- /dev/null
+++ b/runtime/instruction_set.cc
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "instruction_set.h"
+
+namespace art {
+
+std::string InstructionSetFeatures::GetFeatureString() const {
+  std::string result;
+  if ((mask_ & kHwDiv) != 0) {
+    result += "div";
+  }
+  if (result.size() == 0) {
+    result = "none";
+  }
+  return result;
+}
+
+}  // namespace art
diff --git a/runtime/instruction_set.h b/runtime/instruction_set.h
index cbc9912..c5a4ec8 100644
--- a/runtime/instruction_set.h
+++ b/runtime/instruction_set.h
@@ -33,6 +33,7 @@
   kX86_64,
   kMips
 };
+std::ostream& operator<<(std::ostream& os, const InstructionSet& rhs);
 
 enum InstructionFeatures {
   kHwDiv = 1                  // Supports hardware divide.
@@ -44,6 +45,8 @@
   InstructionSetFeatures() : mask_(0) {}
   explicit InstructionSetFeatures(uint32_t mask) : mask_(mask) {}
 
+  static InstructionSetFeatures GuessInstructionSetFeatures();
+
   bool HasDivideInstruction() const {
       return (mask_ & kHwDiv) != 0;
   }
@@ -52,20 +55,7 @@
     mask_ = (mask_ & ~kHwDiv) | (v ? kHwDiv : 0);
   }
 
-  std::string GetFeatureString() const {
-    std::string result;
-    if ((mask_ & kHwDiv) != 0) {
-      result += "div";
-    }
-    if (result.size() == 0) {
-      result = "none";
-    }
-    return result;
-  }
-
-  uint32_t get_mask() const {
-    return mask_;
-  }
+  std::string GetFeatureString() const;
 
   // Other features in here.
 
@@ -81,8 +71,6 @@
   uint32_t mask_;
 };
 
-std::ostream& operator<<(std::ostream& os, const InstructionSet& rhs);
-
 }  // namespace art
 
 #endif  // ART_RUNTIME_INSTRUCTION_SET_H_
diff --git a/runtime/oat.cc b/runtime/oat.cc
index f970789..246e090 100644
--- a/runtime/oat.cc
+++ b/runtime/oat.cc
@@ -22,7 +22,7 @@
 namespace art {
 
 const uint8_t OatHeader::kOatMagic[] = { 'o', 'a', 't', '\n' };
-const uint8_t OatHeader::kOatVersion[] = { '0', '1', '9', '\0' };
+const uint8_t OatHeader::kOatVersion[] = { '0', '2', '0', '\0' };
 
 OatHeader::OatHeader() {
   memset(this, 0, sizeof(*this));
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index e2086f1..08a674f 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -196,6 +196,8 @@
   profile_backoff_coefficient_ = 2.0;
   profile_clock_source_ = kDefaultProfilerClockSource;
 
+  verify_ = true;
+
   // Default to explicit checks.  Switch off with -implicit-checks:.
   // or setprop dalvik.vm.implicit_checks check1,check2,...
 #ifdef HAVE_ANDROID_OS
@@ -569,6 +571,16 @@
         return false;
       }
       image_compiler_options_.push_back(options[i].first);
+    } else if (StartsWith(option, "-Xverify:")) {
+      std::string verify_mode = option.substr(strlen("-Xverify:"));
+      if (verify_mode == "none") {
+        verify_ = false;
+      } else if (verify_mode == "remote" || verify_mode == "all") {
+        verify_ = true;
+      } else {
+        Usage("Unknown -Xverify option %s", verify_mode.c_str());
+        return false;
+      }
     } else if (StartsWith(option, "-ea:") ||
                StartsWith(option, "-da:") ||
                StartsWith(option, "-enableassertions:") ||
@@ -578,7 +590,6 @@
                (option == "-dsa") ||
                (option == "-enablesystemassertions") ||
                (option == "-disablesystemassertions") ||
-               StartsWith(option, "-Xverify:") ||
                (option == "-Xrs") ||
                StartsWith(option, "-Xint:") ||
                StartsWith(option, "-Xdexopt:") ||
diff --git a/runtime/parsed_options.h b/runtime/parsed_options.h
index d6516a8..416bc78 100644
--- a/runtime/parsed_options.h
+++ b/runtime/parsed_options.h
@@ -80,6 +80,7 @@
   uint32_t profile_interval_us_;
   double profile_backoff_coefficient_;
   ProfilerClockSource profile_clock_source_;
+  bool verify_;
 
   static constexpr uint32_t kExplicitNullCheck = 1;
   static constexpr uint32_t kExplicitSuspendCheck = 2;
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index a830018..1b3c996 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -79,6 +79,8 @@
 namespace art {
 
 static constexpr bool kEnableJavaStackTraceHandler = true;
+const char* Runtime::kDefaultInstructionSetFeatures =
+    STRINGIFY(ART_DEFAULT_INSTRUCTION_SET_FEATURES);
 Runtime* Runtime::instance_ = NULL;
 
 Runtime::Runtime()
@@ -130,7 +132,8 @@
       preinitialization_transaction_(nullptr),
       null_pointer_handler_(nullptr),
       suspend_handler_(nullptr),
-      stack_overflow_handler_(nullptr) {
+      stack_overflow_handler_(nullptr),
+      verify_(false) {
   for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
     callee_save_methods_[i] = nullptr;
   }
@@ -519,6 +522,7 @@
   thread_list_ = new ThreadList;
   intern_table_ = new InternTable;
 
+  verify_ = options->verify_;
 
   if (options->interpreter_only_) {
     GetInstrumentation()->ForceInterpretOnly();
@@ -1216,6 +1220,59 @@
   fault_message_ = message;
 }
 
+void Runtime::AddCurrentRuntimeFeaturesAsDex2OatArguments(std::vector<std::string>* argv)
+    const {
+  argv->push_back("--runtime-arg");
+  std::string checkstr = "-implicit-checks";
+
+  int nchecks = 0;
+  char checksep = ':';
+
+  if (!ExplicitNullChecks()) {
+    checkstr += checksep;
+    checksep = ',';
+    checkstr += "null";
+    ++nchecks;
+  }
+  if (!ExplicitSuspendChecks()) {
+    checkstr += checksep;
+    checksep = ',';
+    checkstr += "suspend";
+    ++nchecks;
+  }
+
+  if (!ExplicitStackOverflowChecks()) {
+    checkstr += checksep;
+    checksep = ',';
+    checkstr += "stack";
+    ++nchecks;
+  }
+
+  if (nchecks == 0) {
+    checkstr += ":none";
+  }
+  argv->push_back(checkstr);
+
+  // Make the dex2oat instruction set match that of the launching runtime. If we have multiple
+  // architecture support, dex2oat may be compiled as a different instruction-set than that
+  // currently being executed.
+#if defined(__arm__)
+  argv->push_back("--instruction-set=arm");
+#elif defined(__aarch64__)
+  argv->push_back("--instruction-set=arm64");
+#elif defined(__i386__)
+  argv->push_back("--instruction-set=x86");
+#elif defined(__x86_64__)
+  argv->push_back("--instruction-set=x86_64");
+#elif defined(__mips__)
+  argv->push_back("--instruction-set=mips");
+#endif
+
+  std::string features("--instruction-set-features=");
+  features += GetDefaultInstructionSetFeatures();
+  argv->push_back(features);
+}
+
 void Runtime::UpdateProfilerState(int state) {
   LOG(DEBUG) << "Profiler state updated to " << state;
 }
diff --git a/runtime/runtime.h b/runtime/runtime.h
index ed60d4d..7b3e04c 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -407,6 +407,8 @@
     return fault_message_;
   }
 
+  void AddCurrentRuntimeFeaturesAsDex2OatArguments(std::vector<std::string>* arg_vector) const;
+
   bool ExplicitNullChecks() const {
     return null_pointer_handler_ == nullptr;
   }
@@ -419,10 +421,18 @@
     return stack_overflow_handler_ == nullptr;
   }
 
+  bool IsVerificationEnabled() const {
+    return verify_;
+  }
+
   bool RunningOnValgrind() const {
     return running_on_valgrind_;
   }
 
+  static const char* GetDefaultInstructionSetFeatures() {
+    return kDefaultInstructionSetFeatures;
+  }
+
  private:
   static void InitPlatformSignalHandlers();
 
@@ -439,15 +449,15 @@
   void StartDaemonThreads();
   void StartSignalCatcher();
 
-  // NOTE: these must match the gc::ProcessState values as they come directly
-  // from the framework.
-  static constexpr int kProfileForground = 0;
-  static constexpr int kProfileBackgrouud = 1;
-
-
   // A pointer to the active runtime or NULL.
   static Runtime* instance_;
 
+  static const char* kDefaultInstructionSetFeatures;
+
+  // NOTE: these must match the gc::ProcessState values as they come directly from the framework.
+  static constexpr int kProfileForground = 0;
+  static constexpr int kProfileBackgrouud = 1;
+
   mirror::ArtMethod* callee_save_methods_[kLastCalleeSaveType];
   mirror::Throwable* pre_allocated_OutOfMemoryError_;
   mirror::ArtMethod* resolution_method_;
@@ -557,6 +567,9 @@
   SuspensionHandler* suspend_handler_;
   StackOverflowHandler* stack_overflow_handler_;
 
+  // If false, verification is disabled. True by default.
+  bool verify_;
+
   DISALLOW_COPY_AND_ASSIGN(Runtime);
 };