Merge "madvise away app image dex cache arrays"
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 6bc2a13..f078bf6 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -2306,9 +2306,9 @@
           mirror::Class::SetStatus(klass, mirror::Class::kStatusVerified, soa.Self());
           // Mark methods as pre-verified. If we don't do this, the interpreter will run with
           // access checks.
-          klass->SetPreverifiedFlagOnAllMethods(
+          klass->SetSkipAccessChecksFlagOnAllMethods(
               GetInstructionSetPointerSize(manager_->GetCompiler()->GetInstructionSet()));
-          klass->SetPreverified();
+          klass->SetVerificationAttempted();
         }
         // Record the final class status if necessary.
         ClassReference ref(manager_->GetDexFile(), class_def_index);
diff --git a/compiler/elf_builder.h b/compiler/elf_builder.h
index 3d24d19..bc7c83e 100644
--- a/compiler/elf_builder.h
+++ b/compiler/elf_builder.h
@@ -110,18 +110,27 @@
       CHECK(sections.empty() || sections.back()->finished_);
       // The first ELF section index is 1. Index 0 is reserved for NULL.
       section_index_ = sections.size() + 1;
-      // Push this section on the list of written sections.
-      sections.push_back(this);
+      // Page-align if we switch between allocated and non-allocated sections,
+      // or if we change the type of allocation (e.g. executable vs non-executable).
+      if (!sections.empty()) {
+        if (header_.sh_flags != sections.back()->header_.sh_flags) {
+          header_.sh_addralign = kPageSize;
+        }
+      }
       // Align file position.
       if (header_.sh_type != SHT_NOBITS) {
-        header_.sh_offset = RoundUp(owner_->stream_.Seek(0, kSeekCurrent), header_.sh_addralign);
-        owner_->stream_.Seek(header_.sh_offset, kSeekSet);
+        header_.sh_offset = owner_->AlignFileOffset(header_.sh_addralign);
+      } else {
+        header_.sh_offset = 0;
       }
       // Align virtual memory address.
       if ((header_.sh_flags & SHF_ALLOC) != 0) {
-        header_.sh_addr = RoundUp(owner_->virtual_address_, header_.sh_addralign);
-        owner_->virtual_address_ = header_.sh_addr;
+        header_.sh_addr = owner_->AlignVirtualAddress(header_.sh_addralign);
+      } else {
+        header_.sh_addr = 0;
       }
+      // Push this section on the list of written sections.
+      sections.push_back(this);
     }
 
     // Finish writing of this section.
@@ -170,8 +179,8 @@
     // and it will be zero-initialized when the ELF file is loaded in the running program.
     void WriteNoBitsSection(Elf_Word size) {
       DCHECK_NE(header_.sh_flags & SHF_ALLOC, 0u);
-      Start();
       header_.sh_type = SHT_NOBITS;
+      Start();
       header_.sh_size = size;
       End();
     }
@@ -293,12 +302,13 @@
         dynamic_(this, ".dynamic", SHT_DYNAMIC, SHF_ALLOC, &dynstr_, 0, kPageSize, sizeof(Elf_Dyn)),
         eh_frame_(this, ".eh_frame", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, kPageSize, 0),
         eh_frame_hdr_(this, ".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, 4, 0),
-        strtab_(this, ".strtab", 0, kPageSize),
+        strtab_(this, ".strtab", 0, 1),
         symtab_(this, ".symtab", SHT_SYMTAB, 0, &strtab_),
         debug_frame_(this, ".debug_frame", SHT_PROGBITS, 0, nullptr, 0, sizeof(Elf_Addr), 0),
         debug_info_(this, ".debug_info", SHT_PROGBITS, 0, nullptr, 0, 1, 0),
         debug_line_(this, ".debug_line", SHT_PROGBITS, 0, nullptr, 0, 1, 0),
         shstrtab_(this, ".shstrtab", 0, 1),
+        started_(false),
         virtual_address_(0) {
     text_.phdr_flags_ = PF_R | PF_X;
     bss_.phdr_flags_ = PF_R | PF_W;
@@ -357,16 +367,25 @@
     virtual_address_ = address;
   }
 
-  void Start() {
-    // Reserve space for ELF header and program headers.
-    // We do not know the number of headers until later, so
-    // it is easiest to just reserve a fixed amount of space.
-    int size = sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * kMaxProgramHeaders;
+  // Reserve space for ELF header and program headers.
+  // We do not know the number of headers until later, so
+  // it is easiest to just reserve a fixed amount of space.
+  // Program headers are required for loading by the linker.
+  // It is possible to omit them for ELF files used for debugging.
+  void Start(bool write_program_headers = true) {
+    int size = sizeof(Elf_Ehdr);
+    if (write_program_headers) {
+      size += sizeof(Elf_Phdr) * kMaxProgramHeaders;
+    }
     stream_.Seek(size, kSeekSet);
+    started_ = true;
     virtual_address_ += size;
+    write_program_headers_ = write_program_headers;
   }
 
   void End() {
+    DCHECK(started_);
+
     // Write section names and finish the section headers.
     shstrtab_.Start();
     shstrtab_.Write("");
@@ -386,8 +405,7 @@
       shdrs.push_back(section->header_);
     }
     Elf_Off section_headers_offset;
-    section_headers_offset = RoundUp(stream_.Seek(0, kSeekCurrent), sizeof(Elf_Off));
-    stream_.Seek(section_headers_offset, kSeekSet);
+    section_headers_offset = AlignFileOffset(sizeof(Elf_Off));
     stream_.WriteFully(shdrs.data(), shdrs.size() * sizeof(shdrs[0]));
 
     // Flush everything else before writing the program headers. This should prevent
@@ -395,14 +413,21 @@
     // and partially written data if we suddenly lose power, for example.
     stream_.Flush();
 
-    // Write the initial file headers.
-    std::vector<Elf_Phdr> phdrs = MakeProgramHeaders();
+    // The main ELF header.
     Elf_Ehdr elf_header = MakeElfHeader(isa_);
-    elf_header.e_phoff = sizeof(Elf_Ehdr);
     elf_header.e_shoff = section_headers_offset;
-    elf_header.e_phnum = phdrs.size();
     elf_header.e_shnum = shdrs.size();
     elf_header.e_shstrndx = shstrtab_.GetSectionIndex();
+
+    // Program headers (i.e. mmap instructions).
+    std::vector<Elf_Phdr> phdrs;
+    if (write_program_headers_) {
+      phdrs = MakeProgramHeaders();
+      CHECK_LE(phdrs.size(), kMaxProgramHeaders);
+      elf_header.e_phoff = sizeof(Elf_Ehdr);
+      elf_header.e_phnum = phdrs.size();
+    }
+
     stream_.Seek(0, kSeekSet);
     stream_.WriteFully(&elf_header, sizeof(elf_header));
     stream_.WriteFully(phdrs.data(), phdrs.size() * sizeof(phdrs[0]));
@@ -492,6 +517,14 @@
     return &stream_;
   }
 
+  off_t AlignFileOffset(size_t alignment) {
+     return stream_.Seek(RoundUp(stream_.Seek(0, kSeekCurrent), alignment), kSeekSet);
+  }
+
+  Elf_Addr AlignVirtualAddress(size_t alignment) {
+     return virtual_address_ = RoundUp(virtual_address_, alignment);
+  }
+
  private:
   static Elf_Ehdr MakeElfHeader(InstructionSet isa) {
     Elf_Ehdr elf_header = Elf_Ehdr();
@@ -666,9 +699,13 @@
   // List of used section in the order in which they were written.
   std::vector<Section*> sections_;
 
+  bool started_;
+
   // Used for allocation of virtual address space.
   Elf_Addr virtual_address_;
 
+  size_t write_program_headers_;
+
   DISALLOW_COPY_AND_ASSIGN(ElfBuilder);
 };
 
diff --git a/compiler/elf_writer_debug.cc b/compiler/elf_writer_debug.cc
index d1f5007..ca8cd68 100644
--- a/compiler/elf_writer_debug.cc
+++ b/compiler/elf_writer_debug.cc
@@ -1148,13 +1148,19 @@
     writer.Write(types);
   }
 
-  void End() {
+  void End(bool write_oat_patches) {
     builder_->GetDebugInfo()->End();
-    builder_->WritePatches(".debug_info.oat_patches",
-                           ArrayRef<const uintptr_t>(debug_info_patches_));
+    if (write_oat_patches) {
+      builder_->WritePatches(".debug_info.oat_patches",
+                             ArrayRef<const uintptr_t>(debug_info_patches_));
+    }
     builder_->WriteSection(".debug_abbrev", &debug_abbrev_buffer_);
-    builder_->WriteSection(".debug_loc", &debug_loc_);
-    builder_->WriteSection(".debug_ranges", &debug_ranges_);
+    if (!debug_loc_.empty()) {
+      builder_->WriteSection(".debug_loc", &debug_loc_);
+    }
+    if (!debug_ranges_.empty()) {
+      builder_->WriteSection(".debug_ranges", &debug_ranges_);
+    }
   }
 
  private:
@@ -1357,10 +1363,12 @@
     return buffer.size();
   }
 
-  void End() {
+  void End(bool write_oat_patches) {
     builder_->GetDebugLine()->End();
-    builder_->WritePatches(".debug_line.oat_patches",
-                           ArrayRef<const uintptr_t>(debug_line_patches));
+    if (write_oat_patches) {
+      builder_->WritePatches(".debug_line.oat_patches",
+                             ArrayRef<const uintptr_t>(debug_line_patches));
+    }
   }
 
  private:
@@ -1370,7 +1378,8 @@
 
 template<typename ElfTypes>
 static void WriteDebugSections(ElfBuilder<ElfTypes>* builder,
-                               const ArrayRef<const MethodDebugInfo>& method_infos) {
+                               const ArrayRef<const MethodDebugInfo>& method_infos,
+                               bool write_oat_patches) {
   // Group the methods into compilation units based on source file.
   std::vector<CompilationUnit> compilation_units;
   const char* last_source_file = nullptr;
@@ -1394,7 +1403,7 @@
     for (auto& compilation_unit : compilation_units) {
       line_writer.WriteCompilationUnit(compilation_unit);
     }
-    line_writer.End();
+    line_writer.End(write_oat_patches);
   }
 
   // Write .debug_info section.
@@ -1404,7 +1413,7 @@
     for (const auto& compilation_unit : compilation_units) {
       info_writer.WriteCompilationUnit(compilation_unit);
     }
-    info_writer.End();
+    info_writer.End(write_oat_patches);
   }
 }
 
@@ -1484,13 +1493,14 @@
 template <typename ElfTypes>
 void WriteDebugInfo(ElfBuilder<ElfTypes>* builder,
                     const ArrayRef<const MethodDebugInfo>& method_infos,
-                    CFIFormat cfi_format) {
+                    CFIFormat cfi_format,
+                    bool write_oat_patches) {
   // Add methods to .symtab.
   WriteDebugSymbols(builder, method_infos, true /* with_signature */);
   // Generate CFI (stack unwinding information).
-  WriteCFISection(builder, method_infos, cfi_format, true /* write_oat_patches */);
+  WriteCFISection(builder, method_infos, cfi_format, write_oat_patches);
   // Write DWARF .debug_* sections.
-  WriteDebugSections(builder, method_infos);
+  WriteDebugSections(builder, method_infos, write_oat_patches);
 }
 
 static void XzCompress(const std::vector<uint8_t>* src, std::vector<uint8_t>* dst) {
@@ -1571,10 +1581,12 @@
   buffer.reserve(KB);
   VectorOutputStream out("Debug ELF file", &buffer);
   std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
-  builder->Start();
+  // No program headers since the ELF file is not linked and has no allocated sections.
+  builder->Start(false /* write_program_headers */);
   WriteDebugInfo(builder.get(),
                  ArrayRef<const MethodDebugInfo>(&method_info, 1),
-                 DW_DEBUG_FRAME_FORMAT);
+                 DW_DEBUG_FRAME_FORMAT,
+                 false /* write_oat_patches */);
   builder->End();
   CHECK(builder->Good());
   // Make a copy of the buffer.  We want to shrink it anyway.
@@ -1601,12 +1613,12 @@
   buffer.reserve(KB);
   VectorOutputStream out("Debug ELF file", &buffer);
   std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
-  builder->Start();
-
+  // No program headers since the ELF file is not linked and has no allocated sections.
+  builder->Start(false /* write_program_headers */);
   DebugInfoWriter<ElfTypes> info_writer(builder.get());
   info_writer.Start();
   info_writer.WriteTypes(types);
-  info_writer.End();
+  info_writer.End(false /* write_oat_patches */);
 
   builder->End();
   CHECK(builder->Good());
@@ -1630,11 +1642,13 @@
 template void WriteDebugInfo<ElfTypes32>(
     ElfBuilder<ElfTypes32>* builder,
     const ArrayRef<const MethodDebugInfo>& method_infos,
-    CFIFormat cfi_format);
+    CFIFormat cfi_format,
+    bool write_oat_patches);
 template void WriteDebugInfo<ElfTypes64>(
     ElfBuilder<ElfTypes64>* builder,
     const ArrayRef<const MethodDebugInfo>& method_infos,
-    CFIFormat cfi_format);
+    CFIFormat cfi_format,
+    bool write_oat_patches);
 template void WriteMiniDebugInfo<ElfTypes32>(
     ElfBuilder<ElfTypes32>* builder,
     const ArrayRef<const MethodDebugInfo>& method_infos);
diff --git a/compiler/elf_writer_debug.h b/compiler/elf_writer_debug.h
index e19da08..8e8472f 100644
--- a/compiler/elf_writer_debug.h
+++ b/compiler/elf_writer_debug.h
@@ -33,7 +33,8 @@
 template <typename ElfTypes>
 void WriteDebugInfo(ElfBuilder<ElfTypes>* builder,
                     const ArrayRef<const MethodDebugInfo>& method_infos,
-                    CFIFormat cfi_format);
+                    CFIFormat cfi_format,
+                    bool write_oat_patches);
 
 template <typename ElfTypes>
 void WriteMiniDebugInfo(ElfBuilder<ElfTypes>* builder,
diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc
index 6bf080a..f2a95f2 100644
--- a/compiler/elf_writer_quick.cc
+++ b/compiler/elf_writer_quick.cc
@@ -151,7 +151,7 @@
     const ArrayRef<const dwarf::MethodDebugInfo>& method_infos) {
   if (compiler_options_->GetGenerateDebugInfo()) {
     // Generate all the debug information we can.
-    dwarf::WriteDebugInfo(builder_.get(), method_infos, kCFIFormat);
+    dwarf::WriteDebugInfo(builder_.get(), method_infos, kCFIFormat, true /* write_oat_patches */);
   }
   if (compiler_options_->GetGenerateMiniDebugInfo()) {
     // Generate only some information and compress it.
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index c057eca..3dda850 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -858,7 +858,6 @@
       // At the end of the loop pre-header, the corresponding value for instruction
       // is the first input of the phi.
       HInstruction* initial = instruction->AsPhi()->InputAt(0);
-      DCHECK(initial->GetBlock()->Dominates(loop_header));
       SetRawEnvAt(i, initial);
       initial->AddEnvUseAt(this, i);
     } else {
diff --git a/runtime/art_method.h b/runtime/art_method.h
index ce23c2a..078a978 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -174,13 +174,13 @@
 
   bool IsProxyMethod() SHARED_REQUIRES(Locks::mutator_lock_);
 
-  bool IsPreverified() {
-    return (GetAccessFlags() & kAccPreverified) != 0;
+  bool SkipAccessChecks() {
+    return (GetAccessFlags() & kAccSkipAccessChecks) != 0;
   }
 
-  void SetPreverified() {
-    DCHECK(!IsPreverified());
-    SetAccessFlags(GetAccessFlags() | kAccPreverified);
+  void SetSkipAccessChecks() {
+    DCHECK(!SkipAccessChecks());
+    SetAccessFlags(GetAccessFlags() | kAccSkipAccessChecks);
   }
 
   // Returns true if this method could be overridden by a default method.
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 205ba3e..88d49b2 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -3641,7 +3641,7 @@
 
   // Don't attempt to re-verify if already sufficiently verified.
   if (klass->IsVerified()) {
-    EnsurePreverifiedMethods(klass);
+    EnsureSkipAccessChecksMethods(klass);
     return;
   }
   if (klass->IsCompileTimeVerified() && Runtime::Current()->IsAotCompiler()) {
@@ -3664,22 +3664,10 @@
     mirror::Class::SetStatus(klass, mirror::Class::kStatusVerifyingAtRuntime, self);
   }
 
-  // Skip verification if we are forcing a soft fail.
-  // This has to be before the normal verification enabled check,
-  // since technically verification is disabled in this mode.
-  if (UNLIKELY(Runtime::Current()->IsVerificationSoftFail())) {
-    // Force verification to be a 'soft failure'.
-    mirror::Class::SetStatus(klass, mirror::Class::kStatusVerified, self);
-    // As this is a fake verified status, make sure the methods are _not_ marked preverified
-    // later.
-    klass->SetPreverified();
-    return;
-  }
-
   // Skip verification if disabled.
   if (!Runtime::Current()->IsVerificationEnabled()) {
     mirror::Class::SetStatus(klass, mirror::Class::kStatusVerified, self);
-    EnsurePreverifiedMethods(klass);
+    EnsureSkipAccessChecksMethods(klass);
     return;
   }
 
@@ -3782,9 +3770,9 @@
         mirror::Class::SetStatus(klass, mirror::Class::kStatusRetryVerificationAtRuntime, self);
       } else {
         mirror::Class::SetStatus(klass, mirror::Class::kStatusVerified, self);
-        // As this is a fake verified status, make sure the methods are _not_ marked preverified
-        // later.
-        klass->SetPreverified();
+        // As this is a fake verified status, make sure the methods are _not_ marked
+        // kAccSkipAccessChecks later.
+        klass->SetVerificationAttempted();
       }
     }
   } else {
@@ -3797,19 +3785,26 @@
   }
   if (preverified || verifier_failure == verifier::MethodVerifier::kNoFailure) {
     // Class is verified so we don't need to do any access check on its methods.
-    // Let the interpreter know it by setting the kAccPreverified flag onto each
+    // Let the interpreter know it by setting the kAccSkipAccessChecks flag onto each
     // method.
     // Note: we're going here during compilation and at runtime. When we set the
-    // kAccPreverified flag when compiling image classes, the flag is recorded
+    // kAccSkipAccessChecks flag when compiling image classes, the flag is recorded
     // in the image and is set when loading the image.
-    EnsurePreverifiedMethods(klass);
+
+    if (UNLIKELY(Runtime::Current()->IsVerificationSoftFail())) {
+      // Never skip access checks if the verification soft fail is forced.
+      // Mark the class as having a verification attempt to avoid re-running the verifier.
+      klass->SetVerificationAttempted();
+    } else {
+      EnsureSkipAccessChecksMethods(klass);
+    }
   }
 }
 
-void ClassLinker::EnsurePreverifiedMethods(Handle<mirror::Class> klass) {
-  if (!klass->IsPreverified()) {
-    klass->SetPreverifiedFlagOnAllMethods(image_pointer_size_);
-    klass->SetPreverified();
+void ClassLinker::EnsureSkipAccessChecksMethods(Handle<mirror::Class> klass) {
+  if (!klass->WasVerificationAttempted()) {
+    klass->SetSkipAccessChecksFlagOnAllMethods(image_pointer_size_);
+    klass->SetVerificationAttempted();
   }
 }
 
@@ -3840,7 +3835,7 @@
   }
 
   // We may be running with a preopted oat file but without image. In this case,
-  // we don't skip verification of preverified classes to ensure we initialize
+  // we don't skip verification of skip_access_checks classes to ensure we initialize
   // dex caches with all types resolved during verification.
   // We need to trust image classes, as these might be coming out of a pre-opted, quickened boot
   // image (that we just failed loading), and the verifier can't be run on quickened opcodes when
@@ -3948,8 +3943,9 @@
   }
   DCHECK(klass->GetClass() != nullptr);
   klass->SetObjectSize(sizeof(mirror::Proxy));
-  // Set the class access flags incl. preverified, so we do not try to set the flag on the methods.
-  klass->SetAccessFlags(kAccClassIsProxy | kAccPublic | kAccFinal | kAccPreverified);
+  // Set the class access flags incl. VerificationAttempted, so we do not try to set the flag on
+  // the methods.
+  klass->SetAccessFlags(kAccClassIsProxy | kAccPublic | kAccFinal | kAccVerificationAttempted);
   klass->SetClassLoader(soa.Decode<mirror::ClassLoader*>(loader));
   DCHECK_EQ(klass->GetPrimitiveType(), Primitive::kPrimNot);
   klass->SetName(soa.Decode<mirror::String*>(name));
@@ -4758,7 +4754,7 @@
                                     bool can_init_parents) {
   DCHECK(c.Get() != nullptr);
   if (c->IsInitialized()) {
-    EnsurePreverifiedMethods(c);
+    EnsureSkipAccessChecksMethods(c);
     return true;
   }
   const bool success = InitializeClass(self, c, can_init_fields, can_init_parents);
@@ -6453,11 +6449,11 @@
     for (ArtMethod* def_method : default_methods) {
       ArtMethod& new_method = *out;
       new_method.CopyFrom(def_method, image_pointer_size_);
-      // Clear the preverified flag if it is present. Since this class hasn't been verified yet it
-      // shouldn't have methods that are preverified.
+      // Clear the kAccSkipAccessChecks flag if it is present. Since this class hasn't been verified
+      // yet it shouldn't have methods that are skipping access checks.
       // TODO This is rather arbitrary. We should maybe support classes where only some of its
-      // methods are preverified.
-      new_method.SetAccessFlags((new_method.GetAccessFlags() | kAccDefault) & ~kAccPreverified);
+      // methods are skip_access_checks.
+      new_method.SetAccessFlags((new_method.GetAccessFlags() | kAccDefault) & ~kAccSkipAccessChecks);
       move_table.emplace(def_method, &new_method);
       ++out;
     }
@@ -6465,11 +6461,11 @@
       ArtMethod& new_method = *out;
       new_method.CopyFrom(conf_method, image_pointer_size_);
       // This is a type of default method (there are default method impls, just a conflict) so mark
-      // this as a default, non-abstract method, since thats what it is. Also clear the preverified
-      // bit since this class hasn't been verified yet it shouldn't have methods that are
-      // preverified.
+      // this as a default, non-abstract method, since thats what it is. Also clear the
+      // kAccSkipAccessChecks bit since this class hasn't been verified yet it shouldn't have
+      // methods that are skipping access checks.
       constexpr uint32_t kSetFlags = kAccDefault | kAccDefaultConflict;
-      constexpr uint32_t kMaskFlags = ~(kAccAbstract | kAccPreverified);
+      constexpr uint32_t kMaskFlags = ~(kAccAbstract | kAccSkipAccessChecks);
       new_method.SetAccessFlags((new_method.GetAccessFlags() | kSetFlags) & kMaskFlags);
       DCHECK(new_method.IsDefaultConflicting());
       // The actual method might or might not be marked abstract since we just copied it from a
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 9217c32..71fcf29 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -964,9 +964,10 @@
   void CreateProxyMethod(Handle<mirror::Class> klass, ArtMethod* prototype, ArtMethod* out)
       SHARED_REQUIRES(Locks::mutator_lock_);
 
-  // Ensures that methods have the kAccPreverified bit set. We use the kAccPreverfied bit on the
-  // class access flags to determine whether this has been done before.
-  void EnsurePreverifiedMethods(Handle<mirror::Class> c)
+  // Ensures that methods have the kAccSkipAccessChecks bit set. We use the
+  // kAccVerificationAttempted bit on the class access flags to determine whether this has been done
+  // before.
+  void EnsureSkipAccessChecksMethods(Handle<mirror::Class> c)
       SHARED_REQUIRES(Locks::mutator_lock_);
 
   mirror::Class* LookupClassFromBootImage(const char* descriptor)
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index a909cd8..3a0f3e5 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -1125,14 +1125,14 @@
 static void CheckMethod(ArtMethod* method, bool verified)
     SHARED_REQUIRES(Locks::mutator_lock_) {
   if (!method->IsNative() && !method->IsAbstract()) {
-    EXPECT_EQ((method->GetAccessFlags() & kAccPreverified) != 0U, verified)
+    EXPECT_EQ((method->GetAccessFlags() & kAccSkipAccessChecks) != 0U, verified)
         << PrettyMethod(method, true);
   }
 }
 
-static void CheckPreverified(mirror::Class* c, bool preverified)
+static void CheckVerificationAttempted(mirror::Class* c, bool preverified)
     SHARED_REQUIRES(Locks::mutator_lock_) {
-  EXPECT_EQ((c->GetAccessFlags() & kAccPreverified) != 0U, preverified)
+  EXPECT_EQ((c->GetAccessFlags() & kAccVerificationAttempted) != 0U, preverified)
       << "Class " << PrettyClass(c) << " not as expected";
   for (auto& m : c->GetMethods(sizeof(void*))) {
     CheckMethod(&m, preverified);
@@ -1146,7 +1146,7 @@
   ASSERT_TRUE(JavaLangObject != nullptr);
   EXPECT_TRUE(JavaLangObject->IsInitialized()) << "Not testing already initialized class from the "
                                                   "core";
-  CheckPreverified(JavaLangObject, true);
+  CheckVerificationAttempted(JavaLangObject, true);
 }
 
 TEST_F(ClassLinkerTest, Preverified_UninitializedBoot) {
@@ -1159,10 +1159,10 @@
   EXPECT_FALSE(security_manager->IsInitialized()) << "Not testing uninitialized class from the "
                                                      "core";
 
-  CheckPreverified(security_manager.Get(), false);
+  CheckVerificationAttempted(security_manager.Get(), false);
 
   class_linker_->EnsureInitialized(soa.Self(), security_manager, true, true);
-  CheckPreverified(security_manager.Get(), true);
+  CheckVerificationAttempted(security_manager.Get(), true);
 }
 
 TEST_F(ClassLinkerTest, Preverified_App) {
@@ -1174,10 +1174,10 @@
   Handle<mirror::Class> statics(
       hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStatics;", class_loader)));
 
-  CheckPreverified(statics.Get(), false);
+  CheckVerificationAttempted(statics.Get(), false);
 
   class_linker_->EnsureInitialized(soa.Self(), statics, true, true);
-  CheckPreverified(statics.Get(), true);
+  CheckVerificationAttempted(statics.Get(), true);
 }
 
 TEST_F(ClassLinkerTest, IsBootStrapClassLoaded) {
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 136b793..8269f76 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -271,7 +271,7 @@
     // The loaded spaces. Secondary images may fail to load, in which case we need to remove
     // already added spaces.
     std::vector<space::Space*> added_image_spaces;
-
+    uint8_t* const original_requested_alloc_space_begin = requested_alloc_space_begin;
     for (size_t index = 0; index < image_file_names.size(); ++index) {
       std::string& image_name = image_file_names[index];
       ATRACE_BEGIN("ImageSpace::Create");
@@ -320,7 +320,7 @@
           delete loaded_space;
         }
         boot_image_spaces_.clear();
-        requested_alloc_space_begin = nullptr;
+        requested_alloc_space_begin = original_requested_alloc_space_begin;
         break;
       }
     }
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index 3eff7fc..0b2471b 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -311,7 +311,7 @@
   shadow_frame.GetMethod()->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self);
 
   bool transaction_active = Runtime::Current()->IsActiveTransaction();
-  if (LIKELY(shadow_frame.GetMethod()->IsPreverified())) {
+  if (LIKELY(shadow_frame.GetMethod()->SkipAccessChecks())) {
     // Enter the "without access check" interpreter.
     if (kInterpreterImplKind == kMterpImplKind) {
       if (transaction_active) {
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index b97d994..cdc6204 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -800,11 +800,11 @@
   return nullptr;
 }
 
-void Class::SetPreverifiedFlagOnAllMethods(size_t pointer_size) {
+void Class::SetSkipAccessChecksFlagOnAllMethods(size_t pointer_size) {
   DCHECK(IsVerified());
   for (auto& m : GetMethods(pointer_size)) {
     if (!m.IsNative() && m.IsInvokable()) {
-      m.SetPreverified();
+      m.SetSkipAccessChecks();
     }
   }
 }
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 1dae194..79adfb65 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -287,14 +287,19 @@
     return (GetAccessFlags() & kAccSynthetic) != 0;
   }
 
-  // Returns true if the class can avoid access checks.
-  bool IsPreverified() SHARED_REQUIRES(Locks::mutator_lock_) {
-    return (GetAccessFlags() & kAccPreverified) != 0;
+  // Returns true if the class had run the verifier at least once.
+  // This does not necessarily mean that access checks are avoidable,
+  // since the class methods might still need to be run with access checks.
+  // If this bit returns false, then the methods are not to be trusted with skipping access checks.
+  bool WasVerificationAttempted() SHARED_REQUIRES(Locks::mutator_lock_) {
+    return (GetAccessFlags() & kAccSkipAccessChecks) != 0;
   }
 
-  void SetPreverified() SHARED_REQUIRES(Locks::mutator_lock_) {
+  // Mark the class as having gone through a verification attempt.
+  // Mutually exclusive from whether or not each method is allowed to skip access checks.
+  void SetVerificationAttempted() SHARED_REQUIRES(Locks::mutator_lock_) {
     uint32_t flags = GetField32(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_));
-    SetAccessFlags(flags | kAccPreverified);
+    SetAccessFlags(flags | kAccVerificationAttempted);
   }
 
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
@@ -1136,8 +1141,8 @@
   void VisitNativeRoots(Visitor& visitor, size_t pointer_size)
       SHARED_REQUIRES(Locks::mutator_lock_);
 
-  // When class is verified, set the kAccPreverified flag on each method.
-  void SetPreverifiedFlagOnAllMethods(size_t pointer_size)
+  // When class is verified, set the kAccSkipAccessChecks flag on each method.
+  void SetSkipAccessChecksFlagOnAllMethods(size_t pointer_size)
       SHARED_REQUIRES(Locks::mutator_lock_);
 
   // Get the descriptor of the class. In a few cases a std::string is required, rather than
diff --git a/runtime/modifiers.h b/runtime/modifiers.h
index 9946eab..ed4c5fc 100644
--- a/runtime/modifiers.h
+++ b/runtime/modifiers.h
@@ -42,14 +42,16 @@
 
 static constexpr uint32_t kAccJavaFlagsMask = 0xffff;  // bits set from Java sources (low 16)
 
-static constexpr uint32_t kAccConstructor =          0x00010000;  // method (dex only) <(cl)init>
-static constexpr uint32_t kAccDeclaredSynchronized = 0x00020000;  // method (dex only)
-static constexpr uint32_t kAccClassIsProxy =         0x00040000;  // class  (dex only)
-static constexpr uint32_t kAccPreverified =          0x00080000;  // class (runtime),
-                                                                  // method (dex only)
-static constexpr uint32_t kAccFastNative =           0x00080000;  // method (dex only)
-static constexpr uint32_t kAccMiranda =              0x00200000;  // method (dex only)
-static constexpr uint32_t kAccDefault =              0x00400000;  // method (runtime)
+static constexpr uint32_t kAccConstructor =           0x00010000;  // method (dex only) <(cl)init>
+static constexpr uint32_t kAccDeclaredSynchronized =  0x00020000;  // method (dex only)
+static constexpr uint32_t kAccClassIsProxy =          0x00040000;  // class  (dex only)
+// Used by a method to denote that its execution does not need to go through slow path interpreter.
+static constexpr uint32_t kAccSkipAccessChecks =      0x00080000;  // method (dex only)
+// Used by a class to denote that the verifier has attempted to check it at least once.
+static constexpr uint32_t kAccVerificationAttempted = 0x00080000;  // class (runtime)
+static constexpr uint32_t kAccFastNative =            0x00080000;  // method (dex only)
+static constexpr uint32_t kAccMiranda =               0x00200000;  // method (dex only)
+static constexpr uint32_t kAccDefault =               0x00400000;  // method (runtime)
 // This is set by the class linker during LinkInterfaceMethods. Prior to that point we do not know
 // if any particular method needs to be a default conflict. Used to figure out at runtime if
 // invoking this method will throw an exception.
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index aa64ee3..2ea4b14 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -277,6 +277,8 @@
           .WithType<ExperimentalFlags>()
           .AppendValues()
           .IntoKey(M::Experimental)
+      .Define("-Xforce-nb-testing")
+          .IntoKey(M::ForceNativeBridge)
       .Ignore({
           "-ea", "-da", "-enableassertions", "-disableassertions", "--runtime-arg", "-esa",
           "-dsa", "-enablesystemassertions", "-disablesystemassertions", "-Xrs", "-Xint:_",
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 0c06ca6..b1b7473 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -602,9 +602,12 @@
     if (is_native_bridge_loaded_) {
       PreInitializeNativeBridge(".");
     }
+    NativeBridgeAction action = force_native_bridge_
+        ? NativeBridgeAction::kInitialize
+        : NativeBridgeAction::kUnload;
     InitNonZygoteOrPostFork(self->GetJniEnv(),
                             /* is_system_server */ false,
-                            NativeBridgeAction::kInitialize,
+                            action,
                             GetInstructionSetString(kRuntimeISA));
   }
 
@@ -939,6 +942,7 @@
   allow_dex_file_fallback_ = !runtime_options.Exists(Opt::NoDexFileFallback);
 
   no_sig_chain_ = runtime_options.Exists(Opt::NoSigChain);
+  force_native_bridge_ = runtime_options.Exists(Opt::ForceNativeBridge);
 
   Split(runtime_options.GetOrDefault(Opt::CpuAbiList), ',', &cpu_abilist_);
 
@@ -1914,7 +1918,8 @@
 }
 
 bool Runtime::IsVerificationEnabled() const {
-  return verify_ == verifier::VerifyMode::kEnable;
+  return verify_ == verifier::VerifyMode::kEnable ||
+      verify_ == verifier::VerifyMode::kSoftFail;
 }
 
 bool Runtime::IsVerificationSoftFail() const {
diff --git a/runtime/runtime.h b/runtime/runtime.h
index c8c2ee5..bec26f8 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -774,6 +774,9 @@
   // building a statically link version of dex2oat.
   bool no_sig_chain_;
 
+  // Force the use of native bridge even if the app ISA matches the runtime ISA.
+  bool force_native_bridge_;
+
   // Whether or not a native bridge has been loaded.
   //
   // The native bridge allows running native code compiled for a foreign ISA. The way it works is,
diff --git a/runtime/runtime_options.def b/runtime/runtime_options.def
index 308f3ba..097bccb 100644
--- a/runtime/runtime_options.def
+++ b/runtime/runtime_options.def
@@ -92,6 +92,7 @@
 
 RUNTIME_OPTIONS_KEY (Unit,                DisableExplicitGC)
 RUNTIME_OPTIONS_KEY (Unit,                NoSigChain)
+RUNTIME_OPTIONS_KEY (Unit,                ForceNativeBridge)
 RUNTIME_OPTIONS_KEY (LogVerbosity,        Verbose)
 RUNTIME_OPTIONS_KEY (unsigned int,        LockProfThreshold)
 RUNTIME_OPTIONS_KEY (std::string,         StackTraceFile)
diff --git a/test/115-native-bridge/run b/test/115-native-bridge/run
index ea2045b..aeb5721 100644
--- a/test/115-native-bridge/run
+++ b/test/115-native-bridge/run
@@ -28,4 +28,4 @@
 LEFT=$(echo ${ARGS} | sed -r 's/-Djava.library.path.*//')
 RIGHT=$(echo ${ARGS} | sed -r 's/.*Djava.library.path[^ ]* //')
 MODARGS="${LEFT} -Djava.library.path=`pwd` ${RIGHT}"
-exec ${RUN} --runtime-option -XX:NativeBridge=libnativebridgetest.so ${MODARGS} NativeBridgeMain
+exec ${RUN} --runtime-option -Xforce-nb-testing --runtime-option -XX:NativeBridge=libnativebridgetest.so ${MODARGS} NativeBridgeMain
diff --git a/test/562-bce-preheader/src/Main.java b/test/562-bce-preheader/src/Main.java
index 8de0533..8b527b4 100644
--- a/test/562-bce-preheader/src/Main.java
+++ b/test/562-bce-preheader/src/Main.java
@@ -70,6 +70,26 @@
     return acc;
   }
 
+  /**
+   * An artificial example with an inconsistent phi structure during
+   * dynamic bce that is corrected afterwards. Note that only the last
+   * assignment is really live, but the other statements set up an
+   * interesting phi structure.
+   */
+  private static int doit(int[] z) {
+    int a = 0;
+    for (int i = 0; i < 10; ++i) {
+      for (int j = i; j < 10; ++j) {
+        a = z[i];
+        for (int k = 0; k < 10; ++k) {
+          a += z[k];
+          a = z[i];
+        }
+      }
+    }
+    return a;
+  }
+
   public static void main(String args[]) {
     int[][] x = new int[2][2];
     int y;
@@ -96,6 +116,9 @@
     expectEquals(26, foo(a, b,  2));
     expectEquals(38, foo(a, b,  3));
 
+    int[] z = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+    expectEquals(10, doit(z));
+
     System.out.println("passed");
   }
 
diff --git a/test/565-checker-doublenegbitwise/src/Main.java b/test/565-checker-doublenegbitwise/src/Main.java
index d681ad7..c51eda8 100644
--- a/test/565-checker-doublenegbitwise/src/Main.java
+++ b/test/565-checker-doublenegbitwise/src/Main.java
@@ -37,7 +37,7 @@
 
   // Note: before the instruction_simplifier pass, Xor's are used instead of
   // Not's (the simplification happens during the same pass).
-  /// CHECK-START-ARM64: int Main.$opt$noinline$andToOr(int, int) instruction_simplifier (before)
+  /// CHECK-START: int Main.$opt$noinline$andToOr(int, int) instruction_simplifier (before)
   /// CHECK:       <<P1:i\d+>>          ParameterValue
   /// CHECK:       <<P2:i\d+>>          ParameterValue
   /// CHECK:       <<CstM1:i\d+>>       IntConstant -1
@@ -46,14 +46,14 @@
   /// CHECK:       <<And:i\d+>>         And [<<Not1>>,<<Not2>>]
   /// CHECK:                            Return [<<And>>]
 
-  /// CHECK-START-ARM64: int Main.$opt$noinline$andToOr(int, int) instruction_simplifier (after)
+  /// CHECK-START: int Main.$opt$noinline$andToOr(int, int) instruction_simplifier (after)
   /// CHECK:       <<P1:i\d+>>          ParameterValue
   /// CHECK:       <<P2:i\d+>>          ParameterValue
   /// CHECK:       <<Or:i\d+>>          Or [<<P1>>,<<P2>>]
   /// CHECK:       <<Not:i\d+>>         Not [<<Or>>]
   /// CHECK:                            Return [<<Not>>]
 
-  /// CHECK-START-ARM64: int Main.$opt$noinline$andToOr(int, int) instruction_simplifier (after)
+  /// CHECK-START: int Main.$opt$noinline$andToOr(int, int) instruction_simplifier (after)
   /// CHECK:                            Not
   /// CHECK-NOT:                        Not
   /// CHECK-NOT:                        And
@@ -69,7 +69,7 @@
 
   // See note above.
   // The second Xor has its arguments reversed for no obvious reason.
-  /// CHECK-START-ARM64: long Main.$opt$noinline$orToAnd(long, long) instruction_simplifier (before)
+  /// CHECK-START: long Main.$opt$noinline$orToAnd(long, long) instruction_simplifier (before)
   /// CHECK:       <<P1:j\d+>>          ParameterValue
   /// CHECK:       <<P2:j\d+>>          ParameterValue
   /// CHECK:       <<CstM1:j\d+>>       LongConstant -1
@@ -78,14 +78,14 @@
   /// CHECK:       <<Or:j\d+>>          Or [<<Not1>>,<<Not2>>]
   /// CHECK:                            Return [<<Or>>]
 
-  /// CHECK-START-ARM64: long Main.$opt$noinline$orToAnd(long, long) instruction_simplifier (after)
+  /// CHECK-START: long Main.$opt$noinline$orToAnd(long, long) instruction_simplifier (after)
   /// CHECK:       <<P1:j\d+>>          ParameterValue
   /// CHECK:       <<P2:j\d+>>          ParameterValue
   /// CHECK:       <<And:j\d+>>         And [<<P1>>,<<P2>>]
   /// CHECK:       <<Not:j\d+>>         Not [<<And>>]
   /// CHECK:                            Return [<<Not>>]
 
-  /// CHECK-START-ARM64: long Main.$opt$noinline$orToAnd(long, long) instruction_simplifier (after)
+  /// CHECK-START: long Main.$opt$noinline$orToAnd(long, long) instruction_simplifier (after)
   /// CHECK:                            Not
   /// CHECK-NOT:                        Not
   /// CHECK-NOT:                        Or
@@ -102,7 +102,7 @@
    * operation incorrectly.
    */
 
-  /// CHECK-START-ARM64: int Main.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (before)
+  /// CHECK-START: int Main.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (before)
   /// CHECK:       <<P1:i\d+>>          ParameterValue
   /// CHECK:       <<P2:i\d+>>          ParameterValue
   /// CHECK-DAG:   <<Cst1:i\d+>>        IntConstant 1
@@ -114,7 +114,7 @@
   /// CHECK:       <<Or:i\d+>>          Or [<<Not1>>,<<Not2>>]
   /// CHECK:                            Return [<<Or>>]
 
-  /// CHECK-START-ARM64: int Main.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (after)
+  /// CHECK-START: int Main.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (after)
   /// CHECK:       <<P1:i\d+>>          ParameterValue
   /// CHECK:       <<P2:i\d+>>          ParameterValue
   /// CHECK:       <<Cst1:i\d+>>        IntConstant 1
@@ -124,7 +124,7 @@
   /// CHECK:       <<Not:i\d+>>         Not [<<And>>]
   /// CHECK:                            Return [<<Not>>]
 
-  /// CHECK-START-ARM64: int Main.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (after)
+  /// CHECK-START: int Main.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (after)
   /// CHECK:                            Not
   /// CHECK-NOT:                        Not
   /// CHECK-NOT:                        Or
@@ -143,7 +143,7 @@
    */
 
   // See first note above.
-  /// CHECK-START-ARM64: int Main.$opt$noinline$notXorToXor(int, int) instruction_simplifier (before)
+  /// CHECK-START: int Main.$opt$noinline$notXorToXor(int, int) instruction_simplifier (before)
   /// CHECK:       <<P1:i\d+>>          ParameterValue
   /// CHECK:       <<P2:i\d+>>          ParameterValue
   /// CHECK:       <<CstM1:i\d+>>       IntConstant -1
@@ -152,13 +152,13 @@
   /// CHECK:       <<Xor:i\d+>>         Xor [<<Not1>>,<<Not2>>]
   /// CHECK:                            Return [<<Xor>>]
 
-  /// CHECK-START-ARM64: int Main.$opt$noinline$notXorToXor(int, int) instruction_simplifier (after)
+  /// CHECK-START: int Main.$opt$noinline$notXorToXor(int, int) instruction_simplifier (after)
   /// CHECK:       <<P1:i\d+>>          ParameterValue
   /// CHECK:       <<P2:i\d+>>          ParameterValue
   /// CHECK:       <<Xor:i\d+>>         Xor [<<P1>>,<<P2>>]
   /// CHECK:                            Return [<<Xor>>]
 
-  /// CHECK-START-ARM64: int Main.$opt$noinline$notXorToXor(int, int) instruction_simplifier (after)
+  /// CHECK-START: int Main.$opt$noinline$notXorToXor(int, int) instruction_simplifier (after)
   /// CHECK-NOT:                        Not
 
   public static int $opt$noinline$notXorToXor(int a, int b) {
@@ -170,7 +170,7 @@
    * Check that no transformation is done when one Not has multiple uses.
    */
 
-  /// CHECK-START-ARM64: int Main.$opt$noinline$notMultipleUses(int, int) instruction_simplifier (before)
+  /// CHECK-START: int Main.$opt$noinline$notMultipleUses(int, int) instruction_simplifier (before)
   /// CHECK:       <<P1:i\d+>>          ParameterValue
   /// CHECK:       <<P2:i\d+>>          ParameterValue
   /// CHECK:       <<CstM1:i\d+>>       IntConstant -1
@@ -182,7 +182,7 @@
   /// CHECK:       <<Add:i\d+>>         Add [<<And2>>,<<And1>>]
   /// CHECK:                            Return [<<Add>>]
 
-  /// CHECK-START-ARM64: int Main.$opt$noinline$notMultipleUses(int, int) instruction_simplifier (after)
+  /// CHECK-START: int Main.$opt$noinline$notMultipleUses(int, int) instruction_simplifier (after)
   /// CHECK:       <<P1:i\d+>>          ParameterValue
   /// CHECK:       <<P2:i\d+>>          ParameterValue
   /// CHECK:       <<One:i\d+>>         IntConstant 1
@@ -193,7 +193,7 @@
   /// CHECK:       <<Add:i\d+>>         Add [<<And2>>,<<And1>>]
   /// CHECK:                            Return [<<Add>>]
 
-  /// CHECK-START-ARM64: int Main.$opt$noinline$notMultipleUses(int, int) instruction_simplifier (after)
+  /// CHECK-START: int Main.$opt$noinline$notMultipleUses(int, int) instruction_simplifier (after)
   /// CHECK-NOT:                        Or
 
   public static int $opt$noinline$notMultipleUses(int a, int b) {
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 870b514..a8938fa 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -302,12 +302,7 @@
 
 # Temporarily disable some broken tests when forcing access checks in interpreter b/22414682
 TEST_ART_BROKEN_INTERPRETER_ACCESS_CHECK_TESTS := \
-  135-MirandaDispatch \
-  137-cfi \
-  412-new-array \
-  471-uninitialized-locals \
-  506-verify-aput \
-  800-smali
+  137-cfi
 
 ifneq (,$(filter interp-ac,$(COMPILER_TYPES)))
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \
@@ -464,10 +459,7 @@
 
 # Known broken tests for the mips32 optimizing compiler backend.
 TEST_ART_BROKEN_OPTIMIZING_MIPS_RUN_TESTS := \
-    441-checker-inliner \
     510-checker-try-catch \
-    536-checker-intrinsic-optimization \
-    557-checker-instruction-simplifier-ror \
 
 ifeq (mips,$(TARGET_ARCH))
   ifneq (,$(filter optimizing,$(COMPILER_TYPES)))
@@ -482,7 +474,6 @@
 
 # Known broken tests for the mips64 optimizing compiler backend.
 TEST_ART_BROKEN_OPTIMIZING_MIPS64_RUN_TESTS := \
-    557-checker-instruction-simplifier-ror \
 
 ifeq (mips64,$(TARGET_ARCH))
   ifneq (,$(filter optimizing,$(COMPILER_TYPES)))
diff --git a/tools/libcore_failures_concurrent_collector.txt b/tools/libcore_failures_concurrent_collector.txt
index 95d1292..d8ef9ba 100644
--- a/tools/libcore_failures_concurrent_collector.txt
+++ b/tools/libcore_failures_concurrent_collector.txt
@@ -27,7 +27,8 @@
   description: "TimeoutException on host-{x86,x86-64}-concurrent-collector",
   result: EXEC_FAILED,
   modes: [host],
-  names: ["libcore.java.util.zip.DeflaterOutputStreamTest#testSyncFlushDisabled",
+  names: ["libcore.java.util.zip.DeflaterOutputStreamTest#testSyncFlushEnabled",
+          "libcore.java.util.zip.DeflaterOutputStreamTest#testSyncFlushDisabled",
           "libcore.java.util.zip.GZIPOutputStreamTest#testSyncFlushEnabled",
           "libcore.java.util.zip.OldAndroidGZIPStreamTest#testGZIPStream",
           "libcore.java.util.zip.OldAndroidZipStreamTest#testZipStream",
@@ -40,7 +41,8 @@
   result: EXEC_FAILED,
   modes: [device],
   names: ["libcore.icu.RelativeDateTimeFormatterTest#test_bug25821045",
-          "libcore.java.text.SimpleDateFormatTest#testLocales"],
+          "libcore.java.text.SimpleDateFormatTest#testLocales",
+          "libcore.java.util.zip.ZipFileTest#testZipFileWithLotsOfEntries"],
   bug: 26711853
 }
 ]