Merge "Fix run-test for arm." into ics-mr1-plus-art
diff --git a/src/mark_sweep.cc b/src/mark_sweep.cc
index b80d1f6..72b9ddb 100644
--- a/src/mark_sweep.cc
+++ b/src/mark_sweep.cc
@@ -581,7 +581,7 @@
 
   // Unless we are in the zygote or required to clear soft references
   // with white references, preserve some white referents.
-  if (clear_soft) {
+  if (!clear_soft && !Runtime::Current()->IsZygote()) {
     PreserveSomeSoftReferences(soft_references);
   }
 
diff --git a/src/runtime.cc b/src/runtime.cc
index 2dfbefd..784a3f6 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -606,14 +606,6 @@
   VLOG(startup) << "Runtime::StartDaemonThreads exiting";
 }
 
-bool Runtime::IsShuttingDown() const {
-  return shutting_down_;
-}
-
-bool Runtime::IsStarted() const {
-  return started_;
-}
-
 bool Runtime::Init(const Options& raw_options, bool ignore_unrecognized) {
   CHECK_EQ(sysconf(_SC_PAGE_SIZE), kPageSize);
 
@@ -787,10 +779,6 @@
   Thread::Current()->GetStats()->Clear(kinds >> 16);
 }
 
-RuntimeStats* Runtime::GetStats() {
-  return &stats_;
-}
-
 int32_t Runtime::GetStat(int kind) {
   RuntimeStats* stats;
   if (kind < (1<<16)) {
@@ -871,15 +859,6 @@
   }
 }
 
-bool Runtime::HasJniDlsymLookupStub() const {
-  return jni_stub_array_ != NULL;
-}
-
-ByteArray* Runtime::GetJniDlsymLookupStub() const {
-  CHECK(jni_stub_array_ != NULL);
-  return jni_stub_array_;
-}
-
 void Runtime::SetJniDlsymLookupStub(ByteArray* jni_stub_array) {
   CHECK(jni_stub_array != NULL)  << " jni_stub_array=" << jni_stub_array;
   CHECK(jni_stub_array_ == NULL || jni_stub_array_ == jni_stub_array)
@@ -887,42 +866,12 @@
   jni_stub_array_ = jni_stub_array;
 }
 
-bool Runtime::HasAbstractMethodErrorStubArray() const {
-  return abstract_method_error_stub_array_ != NULL;
-}
-
-ByteArray* Runtime::GetAbstractMethodErrorStubArray() const {
-  CHECK(abstract_method_error_stub_array_ != NULL);
-  return abstract_method_error_stub_array_;
-}
-
 void Runtime::SetAbstractMethodErrorStubArray(ByteArray* abstract_method_error_stub_array) {
   CHECK(abstract_method_error_stub_array != NULL);
   CHECK(abstract_method_error_stub_array_ == NULL || abstract_method_error_stub_array_ == abstract_method_error_stub_array);
   abstract_method_error_stub_array_ = abstract_method_error_stub_array;
 }
 
-
-Runtime::TrampolineType Runtime::GetTrampolineType(Method* method) {
-  if (method == NULL) {
-    return Runtime::kUnknownMethod;
-  } else if (method->IsStatic()) {
-    return Runtime::kStaticMethod;
-  } else {
-    return Runtime::kUnknownMethod;
-  }
-}
-
-bool Runtime::HasResolutionStubArray(TrampolineType type) const {
-  return resolution_stub_array_[type] != NULL;
-}
-
-ByteArray* Runtime::GetResolutionStubArray(TrampolineType type) const {
-  CHECK(HasResolutionStubArray(type));
-  DCHECK_LT(static_cast<int>(type), static_cast<int>(kLastTrampolineMethodType));
-  return resolution_stub_array_[type];
-}
-
 void Runtime::SetResolutionStubArray(ByteArray* resolution_stub_array, TrampolineType type) {
   CHECK(resolution_stub_array != NULL);
   CHECK(!HasResolutionStubArray(type) || resolution_stub_array_[type] == resolution_stub_array);
@@ -941,20 +890,6 @@
   return method.get();
 }
 
-bool Runtime::HasResolutionMethod() const {
-  return resolution_method_ != NULL;
-}
-
-// Returns a special method that calls into a trampoline for runtime method resolution
-Method* Runtime::GetResolutionMethod() const {
-  CHECK(HasResolutionMethod());
-  return resolution_method_;
-}
-
-void Runtime::SetResolutionMethod(Method* method) {
-  resolution_method_ = method;
-}
-
 Method* Runtime::CreateCalleeSaveMethod(InstructionSet instruction_set, CalleeSaveType type) {
   Class* method_class = Method::GetMethodClass();
   SirtRef<Method> method(down_cast<Method*>(method_class->AllocObject()));
@@ -1003,16 +938,6 @@
   return method.get();
 }
 
-bool Runtime::HasCalleeSaveMethod(CalleeSaveType type) const {
-  return callee_save_method_[type] != NULL;
-}
-
-// Returns a special method that describes all callee saves being spilled to the stack.
-Method* Runtime::GetCalleeSaveMethod(CalleeSaveType type) const {
-  CHECK(HasCalleeSaveMethod(type));
-  return callee_save_method_[type];
-}
-
 void Runtime::SetCalleeSaveMethod(Method* method, CalleeSaveType type) {
   DCHECK_LT(static_cast<int>(type), static_cast<int>(kLastCalleeSaveType));
   callee_save_method_[type] = method;
@@ -1029,15 +954,6 @@
   tracer_ = NULL;
 }
 
-bool Runtime::IsMethodTracingActive() const {
-  return (tracer_ != NULL);
-}
-
-Trace* Runtime::GetTracer() const {
-  CHECK(IsMethodTracingActive());
-  return tracer_;
-}
-
 const std::vector<const DexFile*>& Runtime::GetCompileTimeClassPath(const ClassLoader* class_loader) {
   if (class_loader == NULL) {
     return GetClassLinker()->GetBootClassPath();
diff --git a/src/runtime.h b/src/runtime.h
index b682b67..55dab07 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -108,8 +108,13 @@
   // Starts a runtime, which may cause threads to be started and code to run.
   void Start();
 
-  bool IsShuttingDown() const;
-  bool IsStarted() const;
+  bool IsShuttingDown() const {
+    return shutting_down_;
+  }
+
+  bool IsStarted() const {
+    return started_;
+  }
 
   static Runtime* Current() {
     return instance_;
@@ -181,12 +186,26 @@
 
   void VisitRoots(Heap::RootVisitor* visitor, void* arg) const;
 
-  bool HasJniDlsymLookupStub() const;
-  ByteArray* GetJniDlsymLookupStub() const;
+  bool HasJniDlsymLookupStub() const {
+    return jni_stub_array_ != NULL;
+  }
+
+  ByteArray* GetJniDlsymLookupStub() const {
+    CHECK(HasJniDlsymLookupStub());
+    return jni_stub_array_;
+  }
+
   void SetJniDlsymLookupStub(ByteArray* jni_stub_array);
 
-  bool HasAbstractMethodErrorStubArray() const;
-  ByteArray* GetAbstractMethodErrorStubArray() const;
+  bool HasAbstractMethodErrorStubArray() const {
+    return abstract_method_error_stub_array_ != NULL;
+  }
+
+  ByteArray* GetAbstractMethodErrorStubArray() const {
+    CHECK(abstract_method_error_stub_array_ != NULL);
+    return abstract_method_error_stub_array_;
+  }
+
   void SetAbstractMethodErrorStubArray(ByteArray* abstract_method_error_stub_array);
 
   enum TrampolineType {
@@ -194,16 +213,34 @@
     kUnknownMethod,
     kLastTrampolineMethodType  // Value used for iteration
   };
-  static TrampolineType GetTrampolineType(Method* method);
-  bool HasResolutionStubArray(TrampolineType type) const;
-  ByteArray* GetResolutionStubArray(TrampolineType type) const;
+
+  bool HasResolutionStubArray(TrampolineType type) const {
+    return resolution_stub_array_[type] != NULL;
+  }
+
+  ByteArray* GetResolutionStubArray(TrampolineType type) const {
+    CHECK(HasResolutionStubArray(type));
+    DCHECK_LT(static_cast<int>(type), static_cast<int>(kLastTrampolineMethodType));
+    return resolution_stub_array_[type];
+  }
+
   void SetResolutionStubArray(ByteArray* resolution_stub_array, TrampolineType type);
 
-  // Returns a special method to trampoline into runtime resolution
+  // Returns a special method that calls into a trampoline for runtime method resolution
+  Method* GetResolutionMethod() const {
+    CHECK(HasResolutionMethod());
+    return resolution_method_;
+  }
+
+  bool HasResolutionMethod() const {
+    return resolution_method_ != NULL;
+  }
+
+  void SetResolutionMethod(Method* method) {
+    resolution_method_ = method;
+  }
+
   Method* CreateResolutionMethod();
-  bool HasResolutionMethod() const;
-  Method* GetResolutionMethod() const;
-  void SetResolutionMethod(Method* method);
 
   // Returns a special method that describes all callee saves being spilled to the stack.
   enum CalleeSaveType {
@@ -212,17 +249,28 @@
     kRefsAndArgs,
     kLastCalleeSaveType  // Value used for iteration
   };
-  Method* CreateCalleeSaveMethod(InstructionSet instruction_set, CalleeSaveType type);
-  bool HasCalleeSaveMethod(CalleeSaveType type) const;
-  Method* GetCalleeSaveMethod(CalleeSaveType type) const;
+
+  bool HasCalleeSaveMethod(CalleeSaveType type) const {
+    return callee_save_method_[type] != NULL;
+  }
+
+  Method* GetCalleeSaveMethod(CalleeSaveType type) const {
+    CHECK(HasCalleeSaveMethod(type));
+    return callee_save_method_[type];
+  }
+
   void SetCalleeSaveMethod(Method* method, CalleeSaveType type);
 
+  Method* CreateCalleeSaveMethod(InstructionSet instruction_set, CalleeSaveType type);
+
   Method* CreateRefOnlyCalleeSaveMethod(InstructionSet instruction_set);
   Method* CreateRefAndArgsCalleeSaveMethod(InstructionSet instruction_set);
 
   int32_t GetStat(int kind);
 
-  RuntimeStats* GetStats();
+  RuntimeStats* GetStats() {
+    return &stats_;
+  }
 
   bool HasStatsEnabled() const {
     return stats_enabled_;
@@ -236,12 +284,20 @@
 
   void EnableMethodTracing(Trace* tracer);
   void DisableMethodTracing();
-  bool IsMethodTracingActive() const;
-  Trace* GetTracer() const;
+
+  bool IsMethodTracingActive() const {
+    return tracer_ != NULL;
+  }
+
+  Trace* GetTracer() const {
+    CHECK(IsMethodTracingActive());
+    return tracer_;
+  }
 
   bool UseCompileTimeClassPath() const {
     return use_compile_time_class_path_;
   }
+
   const std::vector<const DexFile*>& GetCompileTimeClassPath(const ClassLoader* class_loader);
   void SetCompileTimeClassPath(const ClassLoader* class_loader, std::vector<const DexFile*>& class_path);
 
diff --git a/src/thread_list.cc b/src/thread_list.cc
index 45b7966..e8b412c 100644
--- a/src/thread_list.cc
+++ b/src/thread_list.cc
@@ -75,8 +75,10 @@
 #endif
   if (delta == -1 && thread->suspend_count_ <= 0) {
     // This is expected if you attach a thread during a GC.
-    if (!thread->IsStillStarting()) {
-      LOG(FATAL) << *thread << " suspend count already zero";
+    if (UNLIKELY(!thread->IsStillStarting())) {
+      std::ostringstream ss;
+      Runtime::Current()->GetThreadList()->DumpLocked(ss);
+      LOG(FATAL) << *thread << " suspend count already zero.\n" << ss.str();
     }
     return;
   }
diff --git a/src/verifier/method_verifier.cc b/src/verifier/method_verifier.cc
index 015f81c..c68d6f3 100644
--- a/src/verifier/method_verifier.cc
+++ b/src/verifier/method_verifier.cc
@@ -271,10 +271,10 @@
   if (success) {
     // Verification completed, however failures may be pending that didn't cause the verification
     // to hard fail.
+    CHECK(!verifier.have_pending_hard_failure_);
     if (verifier.failures_.size() != 0) {
       verifier.DumpFailures(LOG(INFO) << "Soft verification failures in "
                                       << PrettyMethod(method_idx, *dex_file) << "\n");
-      success = false;
     }
   } else {
     // Bad method data.
@@ -1858,7 +1858,19 @@
     case Instruction::INVOKE_DIRECT_RANGE: {
       bool is_range = (dec_insn.opcode == Instruction::INVOKE_DIRECT_RANGE);
       Method* called_method = VerifyInvocationArgs(dec_insn, METHOD_DIRECT, is_range, false);
-      if (called_method != NULL && called_method->IsConstructor()) {
+      const char* return_type_descriptor;
+      bool is_constructor;
+      if (called_method == NULL) {
+        uint32_t method_idx = dec_insn.vB;
+        const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
+        is_constructor = StringPiece(dex_file_->GetMethodName(method_id)) == "<init>";
+        uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
+        return_type_descriptor =  dex_file_->StringByTypeIdx(return_type_idx);
+      } else {
+        is_constructor = called_method->IsConstructor();
+        return_type_descriptor = MethodHelper(called_method).GetReturnTypeDescriptor();
+      }
+      if (is_constructor) {
         /*
          * Some additional checks when calling a constructor. We know from the invocation arg check
          * that the "this" argument is an instance of called_method->klass. Now we further restrict
@@ -1877,12 +1889,13 @@
         }
 
         /* must be in same class or in superclass */
-        const RegType& this_super_klass = this_type.GetSuperClass(&reg_types_);
-        if (this_super_klass.IsConflict()) {
+        // const RegType& this_super_klass = this_type.GetSuperClass(&reg_types_);
+        // TODO: re-enable constructor type verification
+        // if (this_super_klass.IsConflict()) {
           // Unknown super class, fail so we re-check at runtime.
-          Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "super class unknown for '" << this_type << "'";
-          break;
-        }
+          // Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "super class unknown for '" << this_type << "'";
+          // break;
+        // }
 
         /* arg must be an uninitialized reference */
         if (!this_type.IsUninitializedTypes()) {
@@ -1897,16 +1910,7 @@
          */
         work_line_->MarkRefsAsInitialized(this_type);
       }
-      const char* descriptor;
-      if (called_method == NULL) {
-        uint32_t method_idx = dec_insn.vB;
-        const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
-        uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
-        descriptor =  dex_file_->StringByTypeIdx(return_type_idx);
-      } else {
-        descriptor = MethodHelper(called_method).GetReturnTypeDescriptor();
-      }
-      const RegType& return_type = reg_types_.FromDescriptor(class_loader_, descriptor);
+      const RegType& return_type = reg_types_.FromDescriptor(class_loader_, return_type_descriptor);
       work_line_->SetResultRegisterType(return_type);
       just_set_result = true;
       break;
@@ -2562,7 +2566,7 @@
 }
 
 Method* MethodVerifier::VerifyInvocationArgs(const DecodedInstruction& dec_insn,
-                                          MethodType method_type, bool is_range, bool is_super) {
+                                             MethodType method_type, bool is_range, bool is_super) {
   // Resolve the method. This could be an abstract or concrete method depending on what sort of call
   // we're making.
   Method* res_method = ResolveMethodAndCheckAccess(dec_insn.vB, method_type);