Merge "Change intern table to unordered set."
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 7ba0d92..0746e0c 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2015,10 +2015,18 @@
   if (descriptor[0] == '[') {
     return CreateArrayClass(self, descriptor, class_loader);
   } else if (class_loader.Get() == nullptr) {
+    // The boot class loader, search the boot class path.
     ClassPathEntry pair = FindInClassPath(descriptor, boot_class_path_);
     if (pair.second != nullptr) {
       StackHandleScope<1> hs(self);
       return DefineClass(descriptor, NullHandle<mirror::ClassLoader>(), *pair.first, *pair.second);
+    } else {
+      // The boot class loader is searched ahead of the application class loader, failures are
+      // expected and will be wrapped in a ClassNotFoundException. Use the pre-allocated error to
+      // trigger the chaining with a proper stack trace.
+      mirror::Throwable* pre_allocated = Runtime::Current()->GetPreAllocatedNoClassDefFoundError();
+      self->SetException(ThrowLocation(), pre_allocated);
+      return nullptr;
     }
   } else if (Runtime::Current()->UseCompileTimeClassPath()) {
     // First try with the bootstrap class loader.
@@ -2028,7 +2036,8 @@
         return EnsureResolved(self, descriptor, klass);
       }
     }
-    // If the lookup failed search the boot class path. We don't perform a recursive call to avoid a NoClassDefFoundError being allocated.
+    // If the lookup failed search the boot class path. We don't perform a recursive call to avoid
+    // a NoClassDefFoundError being allocated.
     ClassPathEntry pair = FindInClassPath(descriptor, boot_class_path_);
     if (pair.second != nullptr) {
       StackHandleScope<1> hs(self);
@@ -2057,6 +2066,7 @@
       ScopedLocalRef<jobject> class_name_object(soa.Env(),
                                                 soa.Env()->NewStringUTF(class_name_string.c_str()));
       if (class_name_object.get() == nullptr) {
+        DCHECK(self->IsExceptionPending());  // OOME.
         return nullptr;
       }
       CHECK(class_loader_object.get() != nullptr);
@@ -2070,7 +2080,7 @@
     } else if (result.get() == nullptr) {
       // broken loader - throw NPE to be compatible with Dalvik
       ThrowNullPointerException(nullptr, StringPrintf("ClassLoader.loadClass returned null for %s",
-                                                   class_name_string.c_str()).c_str());
+                                                      class_name_string.c_str()).c_str());
       return nullptr;
     } else {
       // success, return mirror::Class*
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index bb6b1c8..064a85d 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -85,7 +85,7 @@
   mirror::Class* FindArrayClass(Thread* self, mirror::Class** element_class)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  // Reutrns true if the class linker is initialized.
+  // Returns true if the class linker is initialized.
   bool IsInitialized() const;
 
   // Define a new a class based on a ClassDef from a DexFile
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 20f01d9..c962c14 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -636,7 +636,7 @@
   CHECK_EQ(sysconf(_SC_PAGE_SIZE), kPageSize);
 
   std::unique_ptr<ParsedOptions> options(ParsedOptions::Create(raw_options, ignore_unrecognized));
-  if (options.get() == NULL) {
+  if (options.get() == nullptr) {
     LOG(ERROR) << "Failed to parse options";
     return false;
   }
@@ -759,9 +759,9 @@
   // ClassLinker needs an attached thread, but we can't fully attach a thread without creating
   // objects. We can't supply a thread group yet; it will be fixed later. Since we are the main
   // thread, we do not get a java peer.
-  Thread* self = Thread::Attach("main", false, NULL, false);
+  Thread* self = Thread::Attach("main", false, nullptr, false);
   CHECK_EQ(self->GetThreadId(), ThreadList::kMainThreadId);
-  CHECK(self != NULL);
+  CHECK(self != nullptr);
 
   // Set us to runnable so tools using a runtime can allocate and GC by default
   self->TransitionFromSuspendedToRunnable();
@@ -791,11 +791,11 @@
       }
     }
   } else {
-    CHECK(options->boot_class_path_ != NULL);
+    CHECK(options->boot_class_path_ != nullptr);
     CHECK_NE(options->boot_class_path_->size(), 0U);
     class_linker_->InitWithoutImage(*options->boot_class_path_);
   }
-  CHECK(class_linker_ != NULL);
+  CHECK(class_linker_ != nullptr);
   verifier::MethodVerifier::Init();
 
   method_trace_ = options->method_trace_;
@@ -821,6 +821,13 @@
   pre_allocated_OutOfMemoryError_ = GcRoot<mirror::Throwable>(self->GetException(NULL));
   self->ClearException();
 
+  // Pre-allocate a NoClassDefFoundError for the common case of failing to find a system class
+  // ahead of checking the application's class loader.
+  self->ThrowNewException(ThrowLocation(), "Ljava/lang/NoClassDefFoundError;",
+                          "Class not found using the boot class loader; no stack available");
+  pre_allocated_NoClassDefFoundError_ = GcRoot<mirror::Throwable>(self->GetException(NULL));
+  self->ClearException();
+
   // Look for a native bridge.
   native_bridge_library_filename_ = options->native_bridge_library_filename_;
   android::SetupNativeBridge(native_bridge_library_filename_.c_str(), &native_bridge_art_callbacks_);
@@ -1031,12 +1038,20 @@
 
 mirror::Throwable* Runtime::GetPreAllocatedOutOfMemoryError() {
   mirror::Throwable* oome = pre_allocated_OutOfMemoryError_.Read();
-  if (oome == NULL) {
+  if (oome == nullptr) {
     LOG(ERROR) << "Failed to return pre-allocated OOME";
   }
   return oome;
 }
 
+mirror::Throwable* Runtime::GetPreAllocatedNoClassDefFoundError() {
+  mirror::Throwable* ncdfe = pre_allocated_NoClassDefFoundError_.Read();
+  if (ncdfe == nullptr) {
+    LOG(ERROR) << "Failed to return pre-allocated NoClassDefFoundError";
+  }
+  return ncdfe;
+}
+
 void Runtime::VisitConstantRoots(RootCallback* callback, void* arg) {
   // Visit the classes held as static in mirror classes, these can be visited concurrently and only
   // need to be visited once per GC since they never change.
@@ -1075,6 +1090,10 @@
   }
   resolution_method_.VisitRoot(callback, arg, 0, kRootVMInternal);
   DCHECK(!resolution_method_.IsNull());
+  if (!pre_allocated_NoClassDefFoundError_.IsNull()) {
+    pre_allocated_NoClassDefFoundError_.VisitRoot(callback, arg, 0, kRootVMInternal);
+    DCHECK(!pre_allocated_NoClassDefFoundError_.IsNull());
+  }
   if (HasImtConflictMethod()) {
     imt_conflict_method_.VisitRoot(callback, arg, 0, kRootVMInternal);
   }
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 9dff745..79d4554 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -246,6 +246,9 @@
 
   mirror::Throwable* GetPreAllocatedOutOfMemoryError() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
+  mirror::Throwable* GetPreAllocatedNoClassDefFoundError()
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
   const std::vector<std::string>& GetProperties() const {
     return properties_;
   }
@@ -509,6 +512,7 @@
 
   GcRoot<mirror::ArtMethod> callee_save_methods_[kLastCalleeSaveType];
   GcRoot<mirror::Throwable> pre_allocated_OutOfMemoryError_;
+  GcRoot<mirror::Throwable> pre_allocated_NoClassDefFoundError_;
   GcRoot<mirror::ArtMethod> resolution_method_;
   GcRoot<mirror::ArtMethod> imt_conflict_method_;
   GcRoot<mirror::ObjectArray<mirror::ArtMethod>> default_imt_;
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index e4ee4a7..7da57dd 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -151,41 +151,48 @@
  # disable timing sensitive tests on "dist" builds.
 ifdef dist_goal
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(PREBUILD_TYPES), \
-        $(COMPILER_TYPES), $(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
+        $(COMPILER_TYPES),$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
         $(IMAGE_TYPES), $(TEST_ART_TIMING_SENSITIVE_RUN_TESTS), $(ALL_ADDRESS_SIZES))
 endif
 
 TEST_ART_TIMING_SENSITIVE_RUN_TESTS :=
 
-# NB 116-nodex2oat is not broken per-se it just doesn't (and isn't meant to) work with --prebuild.
+# Note 116-nodex2oat is not broken per-se it just doesn't (and isn't meant to) work with --prebuild.
 TEST_ART_BROKEN_PREBUILD_RUN_TESTS := \
   116-nodex2oat
 
-ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),prebuild, \
-    $(COMPILER_TYPES), $(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
-    $(IMAGE_TYPES), $(TEST_ART_BROKEN_PREBUILD_RUN_TESTS), $(ALL_ADDRESS_SIZES))
+ifneq (,$(filter prebuild,$(PREBUILD_TYPES)))
+  ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),prebuild, \
+      $(COMPILER_TYPES),$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
+      $(IMAGE_TYPES), $(TEST_ART_BROKEN_PREBUILD_RUN_TESTS), $(ALL_ADDRESS_SIZES))
+endif
 
 TEST_ART_BROKEN_PREBUILD_RUN_TESTS :=
 
-# NB 117-nopatchoat is not broken per-se it just doesn't work (and isn't meant to) without --prebuild --relocate
-TEST_ART_BROKEN_NO_RELOCATE_TESTS := \
-  117-nopatchoat
-
-ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(PREBUILD_TYPES), \
-    $(COMPILER_TYPES), no-relocate,$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
-    $(IMAGE_TYPES), $(TEST_ART_BROKEN_NO_RELOCATE_TESTS), $(ALL_ADDRESS_SIZES))
-
-TEST_ART_BROKEN_NO_RELOCATE_TESTS :=
-
 TEST_ART_BROKEN_NO_PREBUILD_TESTS := \
   117-nopatchoat
 
-ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),no-prebuild, \
-    $(COMPILER_TYPES), $(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
-    $(IMAGE_TYPES), $(TEST_ART_BROKEN_NO_PREBUILD_TESTS), $(ALL_ADDRESS_SIZES))
+ifneq (,$(filter no-prebuild,$(PREBUILD_TYPES)))
+  ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),no-prebuild, \
+      $(COMPILER_TYPES),$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
+      $(IMAGE_TYPES), $(TEST_ART_BROKEN_NO_PREBUILD_TESTS), $(ALL_ADDRESS_SIZES))
+endif
 
 TEST_ART_BROKEN_NO_PREBUILD_TESTS :=
 
+# Note 117-nopatchoat is not broken per-se it just doesn't work (and isn't meant to) without
+# --prebuild --relocate
+TEST_ART_BROKEN_NO_RELOCATE_TESTS := \
+  117-nopatchoat
+
+ifneq (,$(filter no-relocate,$(RELOCATE_TYPES)))
+  ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(PREBUILD_TYPES), \
+      $(COMPILER_TYPES), no-relocate,$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
+      $(IMAGE_TYPES), $(TEST_ART_BROKEN_NO_RELOCATE_TESTS), $(ALL_ADDRESS_SIZES))
+endif
+
+TEST_ART_BROKEN_NO_RELOCATE_TESTS :=
+
 # Tests that are broken with tracing.
 TEST_ART_BROKEN_TRACE_RUN_TESTS := \
   004-SignalTest \
@@ -193,12 +200,26 @@
   097-duplicate-method \
   107-int-math2
 
-ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(PREBUILD_TYPES), \
-    $(COMPILER_TYPES), $(RELOCATE_TYPES),trace,$(GC_TYPES),$(JNI_TYPES), \
-    $(IMAGE_TYPES), $(TEST_ART_BROKEN_TRACE_RUN_TESTS), $(ALL_ADDRESS_SIZES))
+ifneq (,$(filter trace,$(TRACE_TYPES)))
+  ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(PREBUILD_TYPES), \
+      $(COMPILER_TYPES),$(RELOCATE_TYPES),trace,$(GC_TYPES),$(JNI_TYPES), \
+      $(IMAGE_TYPES), $(TEST_ART_BROKEN_TRACE_RUN_TESTS), $(ALL_ADDRESS_SIZES))
+endif
 
 TEST_ART_BROKEN_TRACE_RUN_TESTS :=
 
+# Tests that are broken with GC stress.
+TEST_ART_BROKEN_GCSTRESS_RUN_TESTS := \
+  004-SignalTest
+
+ifneq (,$(filter gcstress,$(GC_TYPES)))
+  ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(PREBUILD_TYPES), \
+      $(COMPILER_TYPES),$(RELOCATE_TYPES),$(TRACE_TYPES),gcstress,$(JNI_TYPES), \
+      $(IMAGE_TYPES), $(TEST_ART_BROKEN_GCSTRESS_RUN_TESTS), $(ALL_ADDRESS_SIZES))
+endif
+
+TEST_ART_BROKEN_GCSTRESS_RUN_TESTS :=
+
 # 115-native-bridge setup is complicated. Need to implement it correctly for the target.
 ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,target,$(PREBUILD_TYPES),$(COMPILER_TYPES), \
     $(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES),$(IMAGE_TYPES),115-native-bridge, \
@@ -213,17 +234,24 @@
   118-noimage-dex2oat \
   119-noimage-patchoat
 
-ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),no-dex2oat,$(COMPILER_TYPES), \
-    $(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES),$(IMAGE_TYPES), \
-    $(TEST_ART_BROKEN_FALLBACK_RUN_TESTS),$(ALL_ADDRESS_SIZES))
+ifneq (,$(filter no-dex2oat,$(PREBUILD_TYPES)))
+  ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),no-dex2oat, \
+      $(COMPILER_TYPES),$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES),$(IMAGE_TYPES), \
+      $(TEST_ART_BROKEN_FALLBACK_RUN_TESTS),$(ALL_ADDRESS_SIZES))
+endif
 
-ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(PREBUILD_TYPES),$(COMPILER_TYPES), \
-    $(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES),no-image, \
-    $(TEST_ART_BROKEN_FALLBACK_RUN_TESTS),$(ALL_ADDRESS_SIZES))
 
-ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(PREBUILD_TYPES),$(COMPILER_TYPES), \
-    relocate-no-patchoat,$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES),$(IMAGE_TYPES), \
-    $(TEST_ART_BROKEN_FALLBACK_RUN_TESTS),$(ALL_ADDRESS_SIZES))
+ifneq (,$(filter no-image,$(IMAGE_TYPES)))
+  ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(PREBUILD_TYPES), \
+      $(COMPILER_TYPES), $(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES),no-image, \
+      $(TEST_ART_BROKEN_FALLBACK_RUN_TESTS),$(ALL_ADDRESS_SIZES))
+endif
+
+ifneq (,$(filter relocate-no-patchoat,$(RELOCATE_TYPES)))
+  ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(PREBUILD_TYPES), \
+      $(COMPILER_TYPES), relocate-no-patchoat,$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
+      $(IMAGE_TYPES),$(TEST_ART_BROKEN_FALLBACK_RUN_TESTS),$(ALL_ADDRESS_SIZES))
+endif
 
 TEST_ART_BROKEN_FALLBACK_RUN_TESTS :=