Merge "Build rule for dexdump regression test on host."
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc
index 7ca03cf..c50246d 100644
--- a/compiler/dex/quick/mir_to_lir.cc
+++ b/compiler/dex/quick/mir_to_lir.cc
@@ -193,7 +193,8 @@
   }
 
   if (!reg_arg.Valid()) {
-    LoadBaseDisp(TargetPtrReg(kSp), offset, rl_dest.reg, rl_dest.wide ? k64 : k32, kNotVolatile);
+    OpSize op_size = rl_dest.wide ? k64 : (rl_dest.ref ? kReference : k32);
+    LoadBaseDisp(TargetPtrReg(kSp), offset, rl_dest.reg, op_size, kNotVolatile);
   } else {
     if (rl_dest.wide) {
       OpRegCopyWide(rl_dest.reg, reg_arg);
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index a9a95d3..f64e801 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -1477,9 +1477,8 @@
     source = HeapOperand(obj, offset);
   } else {
     Register temp = temps.AcquireSameSizeAs(obj);
-    Register index_reg = RegisterFrom(index, Primitive::kPrimInt);
-    __ Add(temp, obj, Operand(index_reg, LSL, Primitive::ComponentSizeShift(type)));
-    source = HeapOperand(temp, offset);
+    __ Add(temp, obj, offset);
+    source = HeapOperand(temp, XRegisterFrom(index), LSL, Primitive::ComponentSizeShift(type));
   }
 
   codegen_->Load(type, OutputCPURegister(instruction), source);
@@ -1562,9 +1561,11 @@
         destination = HeapOperand(obj, offset);
       } else {
         Register temp = temps.AcquireSameSizeAs(obj);
-        Register index_reg = InputRegisterAt(instruction, 1);
-        __ Add(temp, obj, Operand(index_reg, LSL, Primitive::ComponentSizeShift(value_type)));
-        destination = HeapOperand(temp, offset);
+        __ Add(temp, obj, offset);
+        destination = HeapOperand(temp,
+                                  XRegisterFrom(index),
+                                  LSL,
+                                  Primitive::ComponentSizeShift(value_type));
       }
 
       codegen_->Store(value_type, source, destination);
diff --git a/compiler/optimizing/common_arm64.h b/compiler/optimizing/common_arm64.h
index 246fff9..f545475 100644
--- a/compiler/optimizing/common_arm64.h
+++ b/compiler/optimizing/common_arm64.h
@@ -151,6 +151,15 @@
   return vixl::MemOperand(base.X(), offset);
 }
 
+static inline vixl::MemOperand HeapOperand(const vixl::Register& base,
+                                           const vixl::Register& regoffset,
+                                           vixl::Shift shift = vixl::LSL,
+                                           unsigned shift_amount = 0) {
+  // A heap reference must be 32bit, so fit in a W register.
+  DCHECK(base.IsW());
+  return vixl::MemOperand(base.X(), regoffset, shift, shift_amount);
+}
+
 static inline vixl::MemOperand HeapOperand(const vixl::Register& base, Offset offset) {
   return HeapOperand(base, offset.SizeValue());
 }
diff --git a/compiler/utils/arm/assembler_thumb2.cc b/compiler/utils/arm/assembler_thumb2.cc
index 2dde014..88b2f2c 100644
--- a/compiler/utils/arm/assembler_thumb2.cc
+++ b/compiler/utils/arm/assembler_thumb2.cc
@@ -975,6 +975,7 @@
 }
 
 void Thumb2Assembler::b(Label* label, Condition cond) {
+  DCHECK_EQ(next_condition_, AL);
   EmitBranch(cond, label, false, false);
 }
 
diff --git a/dex2oat/Android.mk b/dex2oat/Android.mk
index d27ee3e..2c90623 100644
--- a/dex2oat/Android.mk
+++ b/dex2oat/Android.mk
@@ -14,6 +14,15 @@
 # limitations under the License.
 #
 
+# ASan slows down dex2oat by ~3.5x, which translates into extremely slow first
+# boot. Disabled to help speed up SANITIZE_TARGET mode.
+# The supported way of using SANITIZE_TARGET is by first running a normal build,
+# followed by a SANITIZE_TARGET=address build on top of it (in the same build
+# tree). By disabling this module in SANITIZE_TARGET build, we keep the regular,
+# uninstrumented version of it.
+# Bug: 22233158
+ifneq (address,$(strip $(SANITIZE_TARGET)))
+
 LOCAL_PATH := $(call my-dir)
 
 include art/build/Android.executable.mk
@@ -59,3 +68,5 @@
     $(eval $(call build-art-executable,dex2oat,$(DEX2OAT_SRC_FILES),libartd libartd-compiler libartd libziparchive-host libnativehelper libnativebridge libsigchain_dummy libvixld liblog libz libbacktrace libcutils libunwindbacktrace libutils libbase,art/compiler,host,debug,$(dex2oat_host_arch),static))
   endif
 endif
+
+endif
diff --git a/dexdump/Android.mk b/dexdump/Android.mk
index 9b534b9..c6b4d47 100755
--- a/dexdump/Android.mk
+++ b/dexdump/Android.mk
@@ -36,7 +36,6 @@
 LOCAL_MODULE := dexdump2
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
-LOCAL_32_BIT_ONLY := true
 include $(BUILD_EXECUTABLE)
 endif # !SDK_ONLY
 
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index b3801b3..cf4f822 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -1889,10 +1889,14 @@
         state->stats_.pc_mapping_table_bytes += pc_mapping_table_bytes;
       }
 
-      size_t vmap_table_bytes = state->ComputeOatSize(
-          method->GetVmapTable(image_pointer_size), &first_occurrence);
-      if (first_occurrence) {
-        state->stats_.vmap_table_bytes += vmap_table_bytes;
+      size_t vmap_table_bytes = 0u;
+      if (!method->IsOptimized(image_pointer_size)) {
+        // Method compiled with the optimizing compiler have no vmap table.
+        vmap_table_bytes = state->ComputeOatSize(
+            method->GetVmapTable(image_pointer_size), &first_occurrence);
+        if (first_occurrence) {
+          state->stats_.vmap_table_bytes += vmap_table_bytes;
+        }
       }
 
       const void* quick_oat_code_begin = state->GetQuickOatCodeBegin(method);
diff --git a/test/800-smali/expected.txt b/test/800-smali/expected.txt
index 7059b6b..fe68c5b 100644
--- a/test/800-smali/expected.txt
+++ b/test/800-smali/expected.txt
@@ -27,4 +27,5 @@
 b/21886894
 b/22080519
 b/21645819
+b/22244733
 Done!
diff --git a/test/800-smali/smali/b_22244733.smali b/test/800-smali/smali/b_22244733.smali
new file mode 100644
index 0000000..1b62ad92
--- /dev/null
+++ b/test/800-smali/smali/b_22244733.smali
@@ -0,0 +1,7 @@
+.class public LB22244733;
+.super Ljava/lang/Object;
+
+.method public static run(Ljava/lang/String;)Ljava/lang/String;
+.registers 2             # One local and one parameter.
+       return-object p0  # Simple return, use the special-method path in Quick.
+.end method
diff --git a/test/800-smali/src/Main.java b/test/800-smali/src/Main.java
index 30c1b14..61f0d7b 100644
--- a/test/800-smali/src/Main.java
+++ b/test/800-smali/src/Main.java
@@ -101,6 +101,8 @@
                 new NullPointerException(), null));
         testCases.add(new TestCase("b/21645819", "B21645819", "run", new Object[] { null },
                 null, null));
+        testCases.add(new TestCase("b/22244733", "B22244733", "run", new Object[] { "abc" },
+                null, "abc"));
     }
 
     public void runTests() {