Merge "Remove bogus DCHECK."
diff --git a/runtime/dex_file_verifier.cc b/runtime/dex_file_verifier.cc
index 5fa58f7..90b8fdb 100644
--- a/runtime/dex_file_verifier.cc
+++ b/runtime/dex_file_verifier.cc
@@ -694,25 +694,52 @@
   std::unordered_set<uint32_t> direct_method_indexes;
 
   // These calls use the raw access flags to check whether the whole dex field is valid.
-
+  uint32_t prev_index = 0;
   for (; it.HasNextStaticField(); it.Next()) {
-    if (!CheckClassDataItemField(it.GetMemberIndex(), it.GetRawMemberAccessFlags(), true)) {
+    uint32_t curr_index = it.GetMemberIndex();
+    if (curr_index < prev_index) {
+      ErrorStringPrintf("out-of-order static field indexes %d and %d", prev_index, curr_index);
+      return false;
+    }
+    prev_index = curr_index;
+    if (!CheckClassDataItemField(curr_index, it.GetRawMemberAccessFlags(), true)) {
       return false;
     }
   }
+  prev_index = 0;
   for (; it.HasNextInstanceField(); it.Next()) {
-    if (!CheckClassDataItemField(it.GetMemberIndex(), it.GetRawMemberAccessFlags(), false)) {
+    uint32_t curr_index = it.GetMemberIndex();
+    if (curr_index < prev_index) {
+      ErrorStringPrintf("out-of-order instance field indexes %d and %d", prev_index, curr_index);
+      return false;
+    }
+    prev_index = curr_index;
+    if (!CheckClassDataItemField(curr_index, it.GetRawMemberAccessFlags(), false)) {
       return false;
     }
   }
+  prev_index = 0;
   for (; it.HasNextDirectMethod(); it.Next()) {
-    if (!CheckClassDataItemMethod(it.GetMemberIndex(), it.GetRawMemberAccessFlags(),
+    uint32_t curr_index = it.GetMemberIndex();
+    if (curr_index < prev_index) {
+      ErrorStringPrintf("out-of-order direct method indexes %d and %d", prev_index, curr_index);
+      return false;
+    }
+    prev_index = curr_index;
+    if (!CheckClassDataItemMethod(curr_index, it.GetRawMemberAccessFlags(),
         it.GetMethodCodeItemOffset(), direct_method_indexes, true)) {
       return false;
     }
   }
+  prev_index = 0;
   for (; it.HasNextVirtualMethod(); it.Next()) {
-    if (!CheckClassDataItemMethod(it.GetMemberIndex(), it.GetRawMemberAccessFlags(),
+    uint32_t curr_index = it.GetMemberIndex();
+    if (curr_index < prev_index) {
+      ErrorStringPrintf("out-of-order virtual method indexes %d and %d", prev_index, curr_index);
+      return false;
+    }
+    prev_index = curr_index;
+    if (!CheckClassDataItemMethod(curr_index, it.GetRawMemberAccessFlags(),
         it.GetMethodCodeItemOffset(), direct_method_indexes, false)) {
       return false;
     }
diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc
index f32d5a1..8ba6172 100644
--- a/runtime/hprof/hprof.cc
+++ b/runtime/hprof/hprof.cc
@@ -1255,15 +1255,16 @@
   size_t size_patch_offset = output_->Length();
   __ AddU4(0x77777777);
 
-  // Write the instance data;  fields for this class, followed by super class fields,
-  // and so on. Don't write the klass or monitor fields of Object.class.
-  mirror::Class* orig_klass = klass;
+  // What we will use for the string value if the object is a string.
+  mirror::Object* string_value = nullptr;
+
+  // Write the instance data;  fields for this class, followed by super class fields, and so on.
   do {
-    int ifieldCount = klass->NumInstanceFields();
-    for (int i = 0; i < ifieldCount; ++i) {
+    const size_t instance_fields = klass->NumInstanceFields();
+    for (size_t i = 0; i < instance_fields; ++i) {
       ArtField* f = klass->GetInstanceField(i);
       size_t size;
-      auto t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), &size);
+      HprofBasicType t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), &size);
       switch (t) {
       case hprof_basic_byte:
         __ AddU1(f->GetByte(obj));
@@ -1288,34 +1289,35 @@
         break;
       }
     }
+    // Add value field for String if necessary.
+    if (klass->IsStringClass()) {
+      mirror::String* s = obj->AsString();
+      if (s->GetLength() == 0) {
+        // If string is empty, use an object-aligned address within the string for the value.
+        string_value = reinterpret_cast<mirror::Object*>(
+            reinterpret_cast<uintptr_t>(s) + kObjectAlignment);
+      } else {
+        string_value = reinterpret_cast<mirror::Object*>(s->GetValue());
+      }
+      __ AddObjectId(string_value);
+    }
 
     klass = klass->GetSuperClass();
   } while (klass != nullptr);
 
+  // Patch the instance field length.
+  __ UpdateU4(size_patch_offset, output_->Length() - (size_patch_offset + 4));
+
   // Output native value character array for strings.
-  if (orig_klass->IsStringClass()) {
+  CHECK_EQ(obj->IsString(), string_value != nullptr);
+  if (string_value != nullptr) {
     mirror::String* s = obj->AsString();
-    mirror::Object* value;
-    if (s->GetLength() == 0) {
-      // If string is empty, use an object-aligned address within the string for the value.
-      value = reinterpret_cast<mirror::Object*>(reinterpret_cast<uintptr_t>(s) + kObjectAlignment);
-    } else {
-      value = reinterpret_cast<mirror::Object*>(s->GetValue());
-    }
-    __ AddObjectId(value);
-
-    // Patch the instance field length.
-    __ UpdateU4(size_patch_offset, output_->Length() - (size_patch_offset + 4));
-
     __ AddU1(HPROF_PRIMITIVE_ARRAY_DUMP);
-    __ AddObjectId(value);
+    __ AddObjectId(string_value);
     __ AddStackTraceSerialNumber(LookupStackTraceSerialNumber(obj));
     __ AddU4(s->GetLength());
     __ AddU1(hprof_basic_char);
     __ AddU2List(s->GetValue(), s->GetLength());
-  } else {
-    // Patch the instance field length.
-    __ UpdateU4(size_patch_offset, output_->Length() - (size_patch_offset + 4));
   }
 }
 
diff --git a/runtime/indenter.h b/runtime/indenter.h
index d055d4e..38b398d 100644
--- a/runtime/indenter.h
+++ b/runtime/indenter.h
@@ -27,45 +27,76 @@
 class Indenter : public std::streambuf {
  public:
   Indenter(std::streambuf* out, char text, size_t count)
-      : indent_next_(true), out_sbuf_(out), text_(text), count_(count) {}
+      : indent_next_(true), out_sbuf_(out),
+        text_{text, text, text, text, text, text, text, text},  // NOLINT(whitespace/braces)
+        count_(count) {}
 
  private:
-  int_type overflow(int_type c) {
+  std::streamsize xsputn(const char* s, std::streamsize n) OVERRIDE {
+    std::streamsize result = n;  // Aborts on failure.
+    const char* eol = static_cast<const char*>(memchr(s, '\n', n));
+    while (eol != nullptr) {
+      size_t to_write = eol + 1 - s;
+      Write(s, to_write);
+      s += to_write;
+      n -= to_write;
+      indent_next_ = true;
+      eol = static_cast<const char*>(memchr(s, '\n', n));
+    }
+    if (n != 0u) {
+      Write(s, n);
+    }
+    return result;
+  }
+
+  int_type overflow(int_type c) OVERRIDE {
     if (UNLIKELY(c == std::char_traits<char>::eof())) {
       out_sbuf_->pubsync();
       return c;
     }
-    if (indent_next_) {
-      for (size_t i = 0; i < count_; ++i) {
-        int_type r = out_sbuf_->sputc(text_);
-        if (UNLIKELY(r != text_)) {
-          out_sbuf_->pubsync();
-          r = out_sbuf_->sputc(text_);
-          CHECK_EQ(r, text_) << "Error writing to buffer. Disk full?";
-        }
-      }
-    }
+    char data[1] = { static_cast<char>(c) };
+    Write(data, 1u);
     indent_next_ = (c == '\n');
-    int_type r = out_sbuf_->sputc(c);
-    if (UNLIKELY(r != c)) {
-      out_sbuf_->pubsync();
-      r = out_sbuf_->sputc(c);
-      CHECK_EQ(r, c) << "Error writing to buffer. Disk full?";
-    }
-    return r;
+    return c;
   }
 
   int sync() {
     return out_sbuf_->pubsync();
   }
 
+  void Write(const char* s, std::streamsize n) {
+    if (indent_next_) {
+      size_t remaining = count_;
+      while (remaining != 0u) {
+        size_t to_write = std::min(remaining, sizeof(text_));
+        RawWrite(text_, to_write);
+        remaining -= to_write;
+      }
+      indent_next_ = false;
+    }
+    RawWrite(s, n);
+  }
+
+  void RawWrite(const char* s, std::streamsize n) {
+    size_t written = out_sbuf_->sputn(s, n);
+    s += written;
+    n -= written;
+    while (n != 0u) {
+      out_sbuf_->pubsync();
+      written = out_sbuf_->sputn(s, n);
+      CHECK_NE(written, 0u) << "Error writing to buffer. Disk full?";
+      s += written;
+      n -= written;
+    }
+  }
+
   bool indent_next_;
 
   // Buffer to write output to.
   std::streambuf* const out_sbuf_;
 
   // Text output as indent.
-  const char text_;
+  const char text_[8];
 
   // Number of times text is output.
   const size_t count_;
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index ddd1caa..5d685da 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -2402,9 +2402,9 @@
         StackHandleScope<1> hs(self_);
         mirror::Class* return_type_class = called_method->GetReturnType(can_load_classes_);
         if (return_type_class != nullptr) {
-          return_type = &reg_types_.FromClass(called_method->GetReturnTypeDescriptor(),
-                                              return_type_class,
-                                              return_type_class->CannotBeAssignedFromOtherTypes());
+          return_type = &FromClass(called_method->GetReturnTypeDescriptor(),
+                                   return_type_class,
+                                   return_type_class->CannotBeAssignedFromOtherTypes());
         } else {
           DCHECK(!can_load_classes_ || self_->IsExceptionPending());
           self_->ClearException();
@@ -2444,9 +2444,9 @@
         StackHandleScope<1> hs(self_);
         mirror::Class* return_type_class = called_method->GetReturnType(can_load_classes_);
         if (return_type_class != nullptr) {
-          return_type = &reg_types_.FromClass(return_type_descriptor,
-                                              return_type_class,
-                                              return_type_class->CannotBeAssignedFromOtherTypes());
+          return_type = &FromClass(return_type_descriptor,
+                                   return_type_class,
+                                   return_type_class->CannotBeAssignedFromOtherTypes());
         } else {
           DCHECK(!can_load_classes_ || self_->IsExceptionPending());
           self_->ClearException();
@@ -3195,7 +3195,7 @@
   const RegType& referrer = GetDeclaringClass();
   mirror::Class* klass = dex_cache_->GetResolvedType(class_idx);
   const RegType& result = klass != nullptr ?
-      reg_types_.FromClass(descriptor, klass, klass->CannotBeAssignedFromOtherTypes()) :
+      FromClass(descriptor, klass, klass->CannotBeAssignedFromOtherTypes()) :
       reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
   if (result.IsConflict()) {
     Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "accessing broken descriptor '" << descriptor
@@ -3414,8 +3414,8 @@
       if (res_method != nullptr && !res_method->IsMiranda()) {
         mirror::Class* klass = res_method->GetDeclaringClass();
         std::string temp;
-        res_method_class = &reg_types_.FromClass(klass->GetDescriptor(&temp), klass,
-                                                 klass->CannotBeAssignedFromOtherTypes());
+        res_method_class = &FromClass(klass->GetDescriptor(&temp), klass,
+                                      klass->CannotBeAssignedFromOtherTypes());
       } else {
         const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
         const uint16_t class_idx = dex_file_->GetMethodId(method_idx).class_idx_;
@@ -3672,8 +3672,7 @@
     mirror::Class* klass = res_method->GetDeclaringClass();
     std::string temp;
     const RegType& res_method_class =
-        reg_types_.FromClass(klass->GetDescriptor(&temp), klass,
-                             klass->CannotBeAssignedFromOtherTypes());
+        FromClass(klass->GetDescriptor(&temp), klass, klass->CannotBeAssignedFromOtherTypes());
     if (!res_method_class.IsAssignableFrom(actual_arg_type)) {
       Fail(actual_arg_type.IsUnresolvedTypes() ? VERIFY_ERROR_NO_CLASS :
           VERIFY_ERROR_BAD_CLASS_SOFT) << "'this' argument '" << actual_arg_type
@@ -3983,8 +3982,8 @@
   } else {
     mirror::Class* klass = field->GetDeclaringClass();
     const RegType& field_klass =
-        reg_types_.FromClass(dex_file_->GetFieldDeclaringClassDescriptor(field_id),
-                             klass, klass->CannotBeAssignedFromOtherTypes());
+        FromClass(dex_file_->GetFieldDeclaringClassDescriptor(field_id),
+                  klass, klass->CannotBeAssignedFromOtherTypes());
     if (obj_type.IsUninitializedTypes() &&
         (!IsConstructor() || GetDeclaringClass().Equals(obj_type) ||
             !field_klass.Equals(GetDeclaringClass()))) {
@@ -4034,8 +4033,8 @@
     mirror::Class* field_type_class =
         can_load_classes_ ? field->GetType<true>() : field->GetType<false>();
     if (field_type_class != nullptr) {
-      field_type = &reg_types_.FromClass(field->GetTypeDescriptor(), field_type_class,
-                                         field_type_class->CannotBeAssignedFromOtherTypes());
+      field_type = &FromClass(field->GetTypeDescriptor(), field_type_class,
+                              field_type_class->CannotBeAssignedFromOtherTypes());
     } else {
       DCHECK(!can_load_classes_ || self_->IsExceptionPending());
       self_->ClearException();
@@ -4146,8 +4145,8 @@
         field->GetType<false>();
 
     if (field_type_class != nullptr) {
-      field_type = &reg_types_.FromClass(field->GetTypeDescriptor(), field_type_class,
-                                         field_type_class->CannotBeAssignedFromOtherTypes());
+      field_type = &FromClass(field->GetTypeDescriptor(), field_type_class,
+                              field_type_class->CannotBeAssignedFromOtherTypes());
     } else {
       Thread* self = Thread::Current();
       DCHECK(!can_load_classes_ || self->IsExceptionPending());
@@ -4339,9 +4338,9 @@
     if (mirror_method_ != nullptr) {
       mirror::Class* return_type_class = mirror_method_->GetReturnType(can_load_classes_);
       if (return_type_class != nullptr) {
-        return_type_ = &reg_types_.FromClass(mirror_method_->GetReturnTypeDescriptor(),
-                                             return_type_class,
-                                             return_type_class->CannotBeAssignedFromOtherTypes());
+        return_type_ = &FromClass(mirror_method_->GetReturnTypeDescriptor(),
+                                  return_type_class,
+                                  return_type_class->CannotBeAssignedFromOtherTypes());
       } else {
         DCHECK(!can_load_classes_ || self_->IsExceptionPending());
         self_->ClearException();
@@ -4365,8 +4364,8 @@
         = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(method_id.class_idx_));
     if (mirror_method_ != nullptr) {
       mirror::Class* klass = mirror_method_->GetDeclaringClass();
-      declaring_class_ = &reg_types_.FromClass(descriptor, klass,
-                                               klass->CannotBeAssignedFromOtherTypes());
+      declaring_class_ = &FromClass(descriptor, klass,
+                                    klass->CannotBeAssignedFromOtherTypes());
     } else {
       declaring_class_ = &reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
     }
@@ -4466,5 +4465,17 @@
   reg_types_.VisitRoots(visitor, root_info);
 }
 
+const RegType& MethodVerifier::FromClass(const char* descriptor,
+                                         mirror::Class* klass,
+                                         bool precise) {
+  DCHECK(klass != nullptr);
+  if (precise && !klass->IsInstantiable() && !klass->IsPrimitive()) {
+    Fail(VerifyError::VERIFY_ERROR_NO_CLASS) << "Could not create precise reference for "
+        << "non-instantiable klass " << descriptor;
+    precise = false;
+  }
+  return reg_types_.FromClass(descriptor, klass, precise);
+}
+
 }  // namespace verifier
 }  // namespace art
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index 824daf6..994616f 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -670,6 +670,14 @@
   const RegType& DetermineCat1Constant(int32_t value, bool precise)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
+  // Try to create a register type from the given class. In case a precise type is requested, but
+  // the class is not instantiable, a soft error (of type NO_CLASS) will be enqueued and a
+  // non-precise reference will be returned.
+  // Note: we reuse NO_CLASS as this will throw an exception at runtime, when the failing class is
+  //       actually touched.
+  const RegType& FromClass(const char* descriptor, mirror::Class* klass, bool precise)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
   // The thread we're verifying on.
   Thread* const self_;
 
diff --git a/test/496-checker-inlining-and-class-loader/expected.txt b/test/496-checker-inlining-and-class-loader/expected.txt
index c6fcb51..312c28f 100644
--- a/test/496-checker-inlining-and-class-loader/expected.txt
+++ b/test/496-checker-inlining-and-class-loader/expected.txt
@@ -1,4 +1,4 @@
 Request for LoadedByMyClassLoader
-Request for Main
+Request for FirstSeenByMyClassLoader
 In between the two calls.
 In $noinline$bar
diff --git a/test/496-checker-inlining-and-class-loader/src/FirstSeenByMyClassLoader.java b/test/496-checker-inlining-and-class-loader/src/FirstSeenByMyClassLoader.java
new file mode 100644
index 0000000..e97b4e3
--- /dev/null
+++ b/test/496-checker-inlining-and-class-loader/src/FirstSeenByMyClassLoader.java
@@ -0,0 +1,26 @@
+/*
+ * 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 FirstSeenByMyClassLoader {
+  public static void $inline$bar() {
+  }
+
+  public static void $noinline$bar() {
+    try {
+      System.out.println("In $noinline$bar");
+    } catch (Throwable t) { /* Ignore */ }
+  }
+}
diff --git a/test/496-checker-inlining-and-class-loader/src/Main.java b/test/496-checker-inlining-and-class-loader/src/Main.java
index 4f23eec..39c031a 100644
--- a/test/496-checker-inlining-and-class-loader/src/Main.java
+++ b/test/496-checker-inlining-and-class-loader/src/Main.java
@@ -82,7 +82,7 @@
   /// CHECK-START: void LoadedByMyClassLoader.bar() inliner (after)
   /// CHECK:      LoadClass
   /// CHECK-NEXT: ClinitCheck
-                /* We inlined Main.$inline$bar */
+                /* We inlined FirstSeenByMyClassLoader.$inline$bar */
   /// CHECK-NEXT: LoadClass
   /// CHECK-NEXT: ClinitCheck
   /// CHECK-NEXT: StaticFieldGet
@@ -91,7 +91,7 @@
   /// CHECK-NEXT: InvokeVirtual
 
   /// CHECK-START: void LoadedByMyClassLoader.bar() register (before)
-                /* Load and initialize Main */
+                /* Load and initialize FirstSeenByMyClassLoader */
   /// CHECK:      LoadClass gen_clinit_check:true
                 /* Load and initialize System */
   /// CHECK-NEXT: LoadClass gen_clinit_check:true
@@ -100,9 +100,9 @@
   /// CHECK-NEXT: NullCheck
   /// CHECK-NEXT: InvokeVirtual
   public static void bar() {
-    Main.$inline$bar();
+    FirstSeenByMyClassLoader.$inline$bar();
     System.out.println("In between the two calls.");
-    Main.$noinline$bar();
+    FirstSeenByMyClassLoader.$noinline$bar();
   }
 }
 
@@ -113,13 +113,4 @@
     Method m = foo.getDeclaredMethod("bar");
     m.invoke(null);
   }
-
-  public static void $inline$bar() {
-  }
-
-  public static void $noinline$bar() {
-    try {
-      System.out.println("In $noinline$bar");
-    } catch (Throwable t) { /* Ignore */ }
-  }
 }
diff --git a/tools/run-libcore-tests.sh b/tools/run-libcore-tests.sh
index 1b8748b..e28de09 100755
--- a/tools/run-libcore-tests.sh
+++ b/tools/run-libcore-tests.sh
@@ -84,7 +84,7 @@
     # Increase the timeout, as vogar cannot set individual test
     # timeout when being asked to run packages, and some tests go above
     # the default timeout.
-    vogar_args="$vogar_args --timeout 180"
+    vogar_args="$vogar_args --timeout 240"
     shift
   elif [[ "$1" == "" ]]; then
     break