Merge "ART: Changes to try-catch in GraphBuilder"
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc
index 0a1e2e3..4b67884 100644
--- a/compiler/common_compiler_test.cc
+++ b/compiler/common_compiler_test.cc
@@ -182,13 +182,11 @@
       }
     }
 
-    // TODO: make selectable
-    Compiler::Kind compiler_kind = Compiler::kQuick;
     timer_.reset(new CumulativeLogger("Compilation times"));
     compiler_driver_.reset(new CompilerDriver(compiler_options_.get(),
                                               verification_results_.get(),
                                               method_inliner_map_.get(),
-                                              compiler_kind, instruction_set,
+                                              compiler_kind_, instruction_set,
                                               instruction_set_features_.get(),
                                               true,
                                               GetImageClasses(),
@@ -211,6 +209,14 @@
                                               CompilerCallbacks::CallbackMode::kCompileApp));
 }
 
+Compiler::Kind CommonCompilerTest::GetCompilerKind() const {
+  return compiler_kind_;
+}
+
+void CommonCompilerTest::SetCompilerKind(Compiler::Kind compiler_kind) {
+  compiler_kind_ = compiler_kind;
+}
+
 void CommonCompilerTest::TearDown() {
   timer_.reset();
   compiler_driver_.reset();
diff --git a/compiler/common_compiler_test.h b/compiler/common_compiler_test.h
index 769319b..b828fcf 100644
--- a/compiler/common_compiler_test.h
+++ b/compiler/common_compiler_test.h
@@ -22,6 +22,7 @@
 #include <vector>
 
 #include "common_runtime_test.h"
+#include "compiler.h"
 #include "oat_file.h"
 
 namespace art {
@@ -55,7 +56,10 @@
  protected:
   virtual void SetUp();
 
-  virtual void SetUpRuntimeOptions(RuntimeOptions *options);
+  virtual void SetUpRuntimeOptions(RuntimeOptions* options);
+
+  Compiler::Kind GetCompilerKind() const;
+  void SetCompilerKind(Compiler::Kind compiler_kind);
 
   // Get the set of image classes given to the compiler-driver in SetUp. Note: the compiler
   // driver assumes ownership of the set, so the test should properly release the set.
@@ -88,6 +92,7 @@
 
   void UnreserveImageSpace();
 
+  Compiler::Kind compiler_kind_ = kUseOptimizingCompiler ? Compiler::kOptimizing : Compiler::kQuick;
   std::unique_ptr<CompilerOptions> compiler_options_;
   std::unique_ptr<VerificationResults> verification_results_;
   std::unique_ptr<DexFileToMethodInlinerMap> method_inliner_map_;
@@ -103,6 +108,13 @@
   std::list<std::vector<uint8_t>> header_code_and_maps_chunks_;
 };
 
+// TODO: When non-PIC works with all compilers in use, get rid of this.
+#define TEST_DISABLED_FOR_NON_PIC_COMPILING_WITH_OPTIMIZING() \
+  if (GetCompilerKind() == Compiler::kOptimizing) { \
+    printf("WARNING: TEST DISABLED FOR NON-PIC COMPILING WITH OPTIMIZING\n"); \
+    return; \
+  }
+
 }  // namespace art
 
 #endif  // ART_COMPILER_COMMON_COMPILER_TEST_H_
diff --git a/compiler/dex/quick/gen_loadstore.cc b/compiler/dex/quick/gen_loadstore.cc
index aa95e77..3f89001 100644
--- a/compiler/dex/quick/gen_loadstore.cc
+++ b/compiler/dex/quick/gen_loadstore.cc
@@ -107,7 +107,9 @@
 }
 
 RegLocation Mir2Lir::LoadValue(RegLocation rl_src, RegisterClass op_kind) {
-  DCHECK(!rl_src.ref || op_kind == kRefReg);
+  // If op_kind isn't a reference, rl_src should not be marked as a reference either
+  // unless we've seen type conflicts (i.e. register promotion is disabled).
+  DCHECK(op_kind == kRefReg || (!rl_src.ref || (cu_->disable_opt & (1u << kPromoteRegs)) != 0u));
   rl_src = UpdateLoc(rl_src);
   if (rl_src.location == kLocPhysReg) {
     if (!RegClassMatches(op_kind, rl_src.reg)) {
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index f737007..2d7ceae 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -668,7 +668,7 @@
   bool dedupe_enabled_;
   bool dump_stats_;
   const bool dump_passes_;
-  const std::string& dump_cfg_file_name_;
+  const std::string dump_cfg_file_name_;
 
   CumulativeLogger* const timings_logger_;
 
diff --git a/compiler/image_test.cc b/compiler/image_test.cc
index 772cc80..7e31a7a 100644
--- a/compiler/image_test.cc
+++ b/compiler/image_test.cc
@@ -45,6 +45,7 @@
 };
 
 TEST_F(ImageTest, WriteRead) {
+  TEST_DISABLED_FOR_NON_PIC_COMPILING_WITH_OPTIMIZING();
   // Create a generic location tmp file, to be the base of the .art and .oat temporary files.
   ScratchFile location;
   ScratchFile image_location(location, ".art");
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index ff9373a..39c316f 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -1030,9 +1030,8 @@
     if (!cond->IsCondition() || cond->AsCondition()->NeedsMaterialization()) {
       // Condition has been materialized, compare the output to 0
       DCHECK(instruction->GetLocations()->InAt(0).IsRegister());
-      __ cmp(instruction->GetLocations()->InAt(0).AsRegister<Register>(),
-             ShifterOperand(0));
-      __ b(true_target, NE);
+      __ CompareAndBranchIfNonZero(instruction->GetLocations()->InAt(0).AsRegister<Register>(),
+                                   true_target);
     } else {
       // Condition has not been materialized, use its inputs as the
       // comparison and its condition as the branch condition.
@@ -2591,8 +2590,7 @@
   switch (instruction->GetType()) {
     case Primitive::kPrimInt: {
       if (value.IsRegister()) {
-        __ cmp(value.AsRegister<Register>(), ShifterOperand(0));
-        __ b(slow_path->GetEntryLabel(), EQ);
+        __ CompareAndBranchIfZero(value.AsRegister<Register>(), slow_path->GetEntryLabel());
       } else {
         DCHECK(value.IsConstant()) << value;
         if (value.GetConstant()->AsIntConstant()->GetValue() == 0) {
@@ -3011,8 +3009,7 @@
   __ ldrexd(temp1, temp2, addr);
   codegen_->MaybeRecordImplicitNullCheck(instruction);
   __ strexd(temp1, value_lo, value_hi, addr);
-  __ cmp(temp1, ShifterOperand(0));
-  __ b(&fail, NE);
+  __ CompareAndBranchIfNonZero(temp1, &fail);
 }
 
 void LocationsBuilderARM::HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info) {
@@ -3328,8 +3325,7 @@
   LocationSummary* locations = instruction->GetLocations();
   Location obj = locations->InAt(0);
 
-  __ cmp(obj.AsRegister<Register>(), ShifterOperand(0));
-  __ b(slow_path->GetEntryLabel(), EQ);
+  __ CompareAndBranchIfZero(obj.AsRegister<Register>(), slow_path->GetEntryLabel());
 }
 
 void InstructionCodeGeneratorARM::VisitNullCheck(HNullCheck* instruction) {
@@ -3746,13 +3742,11 @@
 
   __ LoadFromOffset(
       kLoadUnsignedHalfword, IP, TR, Thread::ThreadFlagsOffset<kArmWordSize>().Int32Value());
-  __ cmp(IP, ShifterOperand(0));
-  // TODO: Figure out the branch offsets and use cbz/cbnz.
   if (successor == nullptr) {
-    __ b(slow_path->GetEntryLabel(), NE);
+    __ CompareAndBranchIfNonZero(IP, slow_path->GetEntryLabel());
     __ Bind(slow_path->GetReturnLabel());
   } else {
-    __ b(codegen_->GetLabelOf(successor), EQ);
+    __ CompareAndBranchIfZero(IP, codegen_->GetLabelOf(successor));
     __ b(slow_path->GetEntryLabel());
   }
 }
@@ -4004,8 +3998,7 @@
     SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathARM(
         cls, cls, cls->GetDexPc(), cls->MustGenerateClinitCheck());
     codegen_->AddSlowPath(slow_path);
-    __ cmp(out, ShifterOperand(0));
-    __ b(slow_path->GetEntryLabel(), EQ);
+    __ CompareAndBranchIfZero(out, slow_path->GetEntryLabel());
     if (cls->MustGenerateClinitCheck()) {
       GenerateClassInitializationCheck(slow_path, out);
     } else {
@@ -4061,8 +4054,7 @@
       kLoadWord, out, current_method, ArtMethod::DeclaringClassOffset().Int32Value());
   __ LoadFromOffset(kLoadWord, out, out, mirror::Class::DexCacheStringsOffset().Int32Value());
   __ LoadFromOffset(kLoadWord, out, out, CodeGenerator::GetCacheOffset(load->GetStringIndex()));
-  __ cmp(out, ShifterOperand(0));
-  __ b(slow_path->GetEntryLabel(), EQ);
+  __ CompareAndBranchIfZero(out, slow_path->GetEntryLabel());
   __ Bind(slow_path->GetExitLabel());
 }
 
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 6c82fe9..931d751 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -3856,7 +3856,7 @@
           } else {
             DCHECK(value.IsConstant()) << value;
             __ movl(Address(obj, offset),
-                    Immediate(value.GetConstant()->AsIntConstant()->GetValue()));
+                    Immediate(CodeGenerator::GetInt32ValueOf(value.GetConstant())));
           }
         } else {
           DCHECK(index.IsRegister()) << index;
@@ -3866,7 +3866,7 @@
           } else {
             DCHECK(value.IsConstant()) << value;
             __ movl(Address(obj, index.AsRegister<Register>(), TIMES_4, data_offset),
-                    Immediate(value.GetConstant()->AsIntConstant()->GetValue()));
+                    Immediate(CodeGenerator::GetInt32ValueOf(value.GetConstant())));
           }
         }
         codegen_->MaybeRecordImplicitNullCheck(instruction);
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 22f5d96..afffbe2 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -3337,7 +3337,7 @@
     case Primitive::kPrimNot: {
       if (value.IsConstant()) {
         int32_t v = CodeGenerator::GetInt32ValueOf(value.GetConstant());
-        __ movw(Address(base, offset), Immediate(v));
+        __ movl(Address(base, offset), Immediate(v));
       } else {
         __ movl(Address(base, offset), value.AsRegister<CpuRegister>());
       }
diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc
index 5cb9772..f8c93cb 100644
--- a/compiler/optimizing/graph_visualizer.cc
+++ b/compiler/optimizing/graph_visualizer.cc
@@ -152,7 +152,7 @@
 /**
  * HGraph visitor to generate a file suitable for the c1visualizer tool and IRHydra.
  */
-class HGraphVisualizerPrinter : public HGraphVisitor {
+class HGraphVisualizerPrinter : public HGraphDelegateVisitor {
  public:
   HGraphVisualizerPrinter(HGraph* graph,
                           std::ostream& output,
@@ -160,7 +160,7 @@
                           bool is_after_pass,
                           const CodeGenerator& codegen,
                           const DisassemblyInformation* disasm_info = nullptr)
-      : HGraphVisitor(graph),
+      : HGraphDelegateVisitor(graph),
         output_(output),
         pass_name_(pass_name),
         is_after_pass_(is_after_pass),
@@ -372,8 +372,14 @@
         << instance_of->MustDoNullCheck() << std::noboolalpha;
   }
 
-  void VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) OVERRIDE {
+  void VisitInvoke(HInvoke* invoke) OVERRIDE {
     StartAttributeStream("dex_file_index") << invoke->GetDexMethodIndex();
+    StartAttributeStream("method_name")
+        << PrettyMethod(invoke->GetDexMethodIndex(), GetGraph()->GetDexFile());
+  }
+
+  void VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) OVERRIDE {
+    VisitInvoke(invoke);
     StartAttributeStream("recursive") << std::boolalpha
                                       << invoke->IsRecursive()
                                       << std::noboolalpha;
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index e375f7b..62f90c2 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -398,6 +398,10 @@
     }
   }
 
+  if (value->IsNullConstant()) {
+    instruction->ClearNeedsTypeCheck();
+  }
+
   if (!value->CanBeNull()) {
     instruction->ClearValueCanBeNull();
   }
diff --git a/compiler/optimizing/locations.cc b/compiler/optimizing/locations.cc
index 42aba04..d14dfc1 100644
--- a/compiler/optimizing/locations.cc
+++ b/compiler/optimizing/locations.cc
@@ -51,16 +51,17 @@
 }
 
 Location Location::RegisterOrInt32LongConstant(HInstruction* instruction) {
-  if (!instruction->IsConstant() || !instruction->AsConstant()->IsLongConstant()) {
+  if (instruction->IsIntConstant() || instruction->IsNullConstant()) {
+    return Location::ConstantLocation(instruction->AsConstant());
+  } else if (instruction->IsLongConstant()) {
+    // Does the long constant fit in a 32 bit int?
+    int64_t value = instruction->AsLongConstant()->GetValue();
+    return IsInt<32>(value)
+        ? Location::ConstantLocation(instruction->AsConstant())
+        : Location::RequiresRegister();
+  } else {
     return Location::RequiresRegister();
   }
-
-  // Does the long constant fit in a 32 bit int?
-  int64_t value = instruction->AsConstant()->AsLongConstant()->GetValue();
-
-  return IsInt<32>(value)
-      ? Location::ConstantLocation(instruction->AsConstant())
-      : Location::RequiresRegister();
 }
 
 Location Location::ByteRegisterOrConstant(int reg, HInstruction* instruction) {
diff --git a/compiler/utils/arm/assembler_thumb2.cc b/compiler/utils/arm/assembler_thumb2.cc
index f9e1ac6..2dde014 100644
--- a/compiler/utils/arm/assembler_thumb2.cc
+++ b/compiler/utils/arm/assembler_thumb2.cc
@@ -3341,7 +3341,7 @@
 
 
 void Thumb2Assembler::CompareAndBranchIfZero(Register r, Label* label) {
-  if (CanRelocateBranches() && IsLowRegister(r)) {
+  if (CanRelocateBranches() && IsLowRegister(r) && !label->IsBound()) {
     cbz(r, label);
   } else {
     cmp(r, ShifterOperand(0));
@@ -3351,7 +3351,7 @@
 
 
 void Thumb2Assembler::CompareAndBranchIfNonZero(Register r, Label* label) {
-  if (CanRelocateBranches() && IsLowRegister(r)) {
+  if (CanRelocateBranches() && IsLowRegister(r) && !label->IsBound()) {
     cbnz(r, label);
   } else {
     cmp(r, ShifterOperand(0));
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 7a23746..74d5c0c 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -1038,6 +1038,10 @@
   bool OpenFile() {
     bool create_file = !oat_unstripped_.empty();  // as opposed to using open file descriptor
     if (create_file) {
+      // We're supposed to create this file. If the file already exists, it may be in use currently.
+      // We must not change the content of that file, then. So unlink it first.
+      unlink(oat_unstripped_.c_str());
+
       oat_file_.reset(OS::CreateEmptyFile(oat_unstripped_.c_str()));
       if (oat_location_.empty()) {
         oat_location_ = oat_filename_;
diff --git a/runtime/Android.mk b/runtime/Android.mk
index 5ed6955..19079cb 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -478,7 +478,7 @@
     # For liblog, atrace, properties, ashmem, set_sched_policy and socket_peer_is_trusted.
     LOCAL_SHARED_LIBRARIES += libcutils
   else # host
-    LOCAL_SHARED_LIBRARIES += libziparchive-host
+    LOCAL_SHARED_LIBRARIES += libziparchive-host libz-host
     # For ashmem_create_region.
     LOCAL_SHARED_LIBRARIES += libcutils
   endif
diff --git a/runtime/java_vm_ext.cc b/runtime/java_vm_ext.cc
index eb9c32d..f1deacf 100644
--- a/runtime/java_vm_ext.cc
+++ b/runtime/java_vm_ext.cc
@@ -132,6 +132,8 @@
   }
 
   void* FindSymbol(const std::string& symbol_name) {
+    CHECK(!NeedsNativeBridge());
+
     return dlsym(handle_, symbol_name.c_str());
   }
 
@@ -234,9 +236,6 @@
           fn = library->FindSymbol(jni_long_name);
         }
       }
-      if (fn == nullptr) {
-        fn = library->FindSymbol(jni_long_name);
-      }
       if (fn != nullptr) {
         VLOG(jni) << "[Found native code for " << PrettyMethod(m)
                   << " in \"" << library->GetPath() << "\"]";
diff --git a/test/036-finalizer/src/Main.java b/test/036-finalizer/src/Main.java
index e3cf4ee..8c7c27d 100644
--- a/test/036-finalizer/src/Main.java
+++ b/test/036-finalizer/src/Main.java
@@ -34,31 +34,10 @@
     }
 
     public static WeakReference<FinalizerTest> makeRef() {
-        /*
-         * Make ft in another thread, so there is no danger of
-         * a conservative reference leaking onto the main thread's
-         * stack.
-         */
-
-        final List<WeakReference<FinalizerTest>> wimp =
-                new ArrayList<WeakReference<FinalizerTest>>();
-        Thread t = new Thread() {
-                public void run() {
-                    FinalizerTest ft = new FinalizerTest("wahoo");
-                    wimp.add(new WeakReference<FinalizerTest>(ft));
-                    ft = null;
-                }
-            };
-
-        t.start();
-
-        try {
-            t.join();
-        } catch (InterruptedException ie) {
-            throw new RuntimeException(ie);
-        }
-
-        return wimp.get(0);
+        FinalizerTest ft = new FinalizerTest("wahoo");
+        WeakReference<FinalizerTest> ref = new WeakReference<FinalizerTest>(ft);
+        ft = null;
+        return ref;
     }
 
     public static String wimpString(final WeakReference<FinalizerTest> wimp) {
@@ -91,10 +70,12 @@
 
     public static void main(String[] args) {
         WeakReference<FinalizerTest> wimp = makeRef();
+        FinalizerTest keepLive = wimp.get();
 
         System.out.println("wimp: " + wimpString(wimp));
 
         /* this will try to collect and finalize ft */
+        keepLive = null;
         System.out.println("gc");
         Runtime.getRuntime().gc();
 
diff --git a/test/099-vmdebug/src/Main.java b/test/099-vmdebug/src/Main.java
index a8db069..add2ff6 100644
--- a/test/099-vmdebug/src/Main.java
+++ b/test/099-vmdebug/src/Main.java
@@ -20,6 +20,9 @@
 import java.util.Map;
 
 public class Main {
+    private static final String TEMP_FILE_NAME_PREFIX = "test";
+    private static final String TEMP_FILE_NAME_SUFFIX = ".trace";
+
     public static void main(String[] args) throws Exception {
         String name = System.getProperty("java.vm.name");
         if (!"Dalvik".equals(name)) {
@@ -32,21 +35,31 @@
 
     private static File createTempFile() throws Exception {
         try {
-            return  File.createTempFile("test", ".trace");
+            return  File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
         } catch (IOException e) {
             System.setProperty("java.io.tmpdir", "/data/local/tmp");
             try {
-                return File.createTempFile("test", ".trace");
+                return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
             } catch (IOException e2) {
                 System.setProperty("java.io.tmpdir", "/sdcard");
-                return File.createTempFile("test", ".trace");
+                return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
             }
         }
     }
 
     private static void testMethodTracing() throws Exception {
-        File tempFile = createTempFile();
-        tempFile.deleteOnExit();
+        File tempFile = null;
+        try {
+            tempFile = createTempFile();
+            testMethodTracingToFile(tempFile);
+        } finally {
+            if (tempFile != null) {
+                tempFile.delete();
+            }
+        }
+    }
+
+    private static void testMethodTracingToFile(File tempFile) throws Exception {
         String tempFileName = tempFile.getPath();
 
         if (VMDebug.getMethodTracingMode() != 0) {
diff --git a/test/521-checker-array-set-null/expected.txt b/test/521-checker-array-set-null/expected.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/521-checker-array-set-null/expected.txt
diff --git a/test/521-checker-array-set-null/info.txt b/test/521-checker-array-set-null/info.txt
new file mode 100644
index 0000000..ec2ba35
--- /dev/null
+++ b/test/521-checker-array-set-null/info.txt
@@ -0,0 +1,2 @@
+Checker test for optimizing that checks whether our
+optimizations to remove type checks on array set operations work.
diff --git a/test/521-checker-array-set-null/src/Main.java b/test/521-checker-array-set-null/src/Main.java
new file mode 100644
index 0000000..74bb73f
--- /dev/null
+++ b/test/521-checker-array-set-null/src/Main.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+public class Main {
+  public static void main(String[] args) {
+    testWithNull(new Object[2]);
+    testWithUnknown(new Object[2], new Object());
+    testWithSame(new Object[2]);
+  }
+
+  /// CHECK-START: void Main.testWithNull(java.lang.Object[]) disassembly (after)
+  /// CHECK-NOT:      pAputObject
+  public static void testWithNull(Object[] o) {
+    o[0] = null;
+  }
+
+  /// CHECK-START: void Main.testWithUnknown(java.lang.Object[], java.lang.Object) disassembly (after)
+  /// CHECK:          pAputObject
+  public static void testWithUnknown(Object[] o, Object obj) {
+    o[0] = obj;
+  }
+
+  /// CHECK-START: void Main.testWithSame(java.lang.Object[]) disassembly (after)
+  /// CHECK-NOT:      pAputObject
+  public static void testWithSame(Object[] o) {
+    o[0] = o[1];
+  }
+}
diff --git a/test/521-regression-integer-field-set/expected.txt b/test/521-regression-integer-field-set/expected.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/521-regression-integer-field-set/expected.txt
diff --git a/test/521-regression-integer-field-set/info.txt b/test/521-regression-integer-field-set/info.txt
new file mode 100644
index 0000000..62f7e3d
--- /dev/null
+++ b/test/521-regression-integer-field-set/info.txt
@@ -0,0 +1,3 @@
+Regression test for Optimizing's x86-64 code generator, where moving a
+32-bit immediate (integer or reference) into a field used to generate
+a `movw` instruction instead of a `movl` instruction.
diff --git a/test/521-regression-integer-field-set/src/Main.java b/test/521-regression-integer-field-set/src/Main.java
new file mode 100644
index 0000000..9924e09
--- /dev/null
+++ b/test/521-regression-integer-field-set/src/Main.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+class Main {
+  public static void assertIntEquals(int expected, int result) {
+    if (expected != result) {
+      throw new Error("Expected: " + expected + ", found: " + result);
+    }
+  }
+
+  public static void main(String[] args) {
+    Main m = new Main();
+
+    m.$noinline$SetInstanceField();
+    assertIntEquals(123456, m.i);
+
+    $noinline$SetStaticField();
+    assertIntEquals(456789, s);
+  }
+
+  private static boolean doThrow = false;
+
+  private void $noinline$SetInstanceField() {
+    if (doThrow) {
+      // Try defeating inlining.
+      throw new Error();
+    }
+
+    // Set a value than does not fit in a 16-bit (signed) integer.
+    i = 123456;
+  }
+
+  private static void $noinline$SetStaticField() {
+    if (doThrow) {
+      // Try defeating inlining.
+      throw new Error();
+    }
+
+    // Set a value than does not fit in a 16-bit (signed) integer.
+    s = 456789;
+  }
+
+  private int i = 0;
+  private static int s = 0;
+}
diff --git a/test/802-deoptimization/src/DeoptimizationController.java b/test/802-deoptimization/src/DeoptimizationController.java
index c926669..d6e662d 100644
--- a/test/802-deoptimization/src/DeoptimizationController.java
+++ b/test/802-deoptimization/src/DeoptimizationController.java
@@ -22,24 +22,27 @@
  * Controls deoptimization using dalvik.system.VMDebug class.
  */
 public class DeoptimizationController {
+  private static final String TEMP_FILE_NAME_PREFIX = "test";
+  private static final String TEMP_FILE_NAME_SUFFIX = ".trace";
+
   private static File createTempFile() throws Exception {
     try {
-      return  File.createTempFile("test", ".trace");
+      return  File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
     } catch (IOException e) {
       System.setProperty("java.io.tmpdir", "/data/local/tmp");
       try {
-        return File.createTempFile("test", ".trace");
+        return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
       } catch (IOException e2) {
         System.setProperty("java.io.tmpdir", "/sdcard");
-        return File.createTempFile("test", ".trace");
+        return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX);
       }
     }
   }
 
   public static void startDeoptimization() {
+    File tempFile = null;
     try {
-      File tempFile = createTempFile();
-      tempFile.deleteOnExit();
+      tempFile = createTempFile();
       String tempFileName = tempFile.getPath();
 
       VMDebug.startMethodTracing(tempFileName, 0, 0, false, 1000);
@@ -48,6 +51,10 @@
       }
     } catch (Exception exc) {
       exc.printStackTrace(System.err);
+    } finally {
+      if (tempFile != null) {
+        tempFile.delete();
+      }
     }
   }
 
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 6c2ce62..5b5c368 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -233,7 +233,10 @@
 TEST_ART_BROKEN_NO_RELOCATE_TESTS :=
 
 # Tests that are broken with GC stress.
-TEST_ART_BROKEN_GCSTRESS_RUN_TESTS :=
+# 137-cfi needs to unwind a second forked process. We're using a primitive sleep to wait till we
+# hope the second process got into the expected state. The slowness of gcstress makes this bad.
+TEST_ART_BROKEN_GCSTRESS_RUN_TESTS := \
+  137-cfi
 
 ifneq (,$(filter gcstress,$(GC_TYPES)))
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \
diff --git a/test/run-test b/test/run-test
index 995d30f..ffa25eb 100755
--- a/test/run-test
+++ b/test/run-test
@@ -308,7 +308,7 @@
   run_args="${run_args} --runtime-option -Xgc:preverify_rosalloc --runtime-option -Xgc:postverify_rosalloc"
 fi
 if [ "$gc_stress" = "true" ]; then
-  run_args="${run_args} --runtime-option -Xgc:SS --runtime-option -Xms2m --runtime-option -Xmx2m"
+  run_args="${run_args} --runtime-option -Xgc:SS,gcstress --runtime-option -Xms2m --runtime-option -Xmx16m"
 fi
 if [ "$trace" = "true" ]; then
     run_args="${run_args} --runtime-option -Xmethod-trace --runtime-option -Xmethod-trace-file-size:2000000"
diff --git a/tools/symbolize.sh b/tools/symbolize.sh
index 0168e7d..7365a9b 100755
--- a/tools/symbolize.sh
+++ b/tools/symbolize.sh
@@ -37,30 +37,23 @@
       exit 0
     fi
   fi
-  adb pull /data/dalvik-cache/$1/$2 /tmp || exit 1
-  mkdir -p $OUT/symbols/data/dalvik-cache/$1
-  oatdump --symbolize=/tmp/$2 --output=$OUT/symbols/data/dalvik-cache/$1/$2
+  adb pull $1/$2 /tmp || exit 1
+  mkdir -p $OUT/symbols/$1
+  oatdump --symbolize=/tmp/$2 --output=$OUT/symbols/$1/$2
 }
 
-# adb shell ls seems to output in DOS format (CRLF), which messes up scripting
-function adbls() {
-  adb shell ls $@ | sed 's/\r$//'
+# adb shell find seems to output in DOS format (CRLF), which messes up scripting
+function adbshellstrip() {
+  adb shell $@ | sed 's/\r$//'
 }
 
-# Check for all ISA directories on device.
+# Search in all of /data on device.
 function all() {
-  DIRS=$(adbls /data/dalvik-cache/)
-  for DIR in $DIRS ; do
-    case $DIR in
-      arm|arm64|mips|mips64|x86|x86_64)
-        FILES=$(adbls /data/dalvik-cache/$DIR/*.oat /data/dalvik-cache/$DIR/*.dex)
-        for FILE in $FILES ; do
-          # Cannot use basename as the file doesn't exist.
-          NAME=$(echo $FILE | sed -e 's/.*\///')
-          one $DIR $NAME
-        done
-        ;;
-    esac
+  FILES=$(adbshellstrip find /data -name "'*.oat'" -o -name "'*.dex'" -o -name "'*.odex'")
+  for FILE in $FILES ; do
+    DIR=$(dirname $FILE)
+    NAME=$(basename $FILE)
+    one $DIR $NAME
   done
 }