Merge "ART: Remove experimental flags for plugins and agents"
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index b00d083..3203048 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -940,6 +940,31 @@
   DCHECK(single_thread_pool_ != nullptr);
 }
 
+static void EnsureVerifiedOrVerifyAtRuntime(jobject jclass_loader,
+                                            const std::vector<const DexFile*>& dex_files) {
+  ScopedObjectAccess soa(Thread::Current());
+  StackHandleScope<2> hs(soa.Self());
+  Handle<mirror::ClassLoader> class_loader(
+      hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
+  MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+
+  for (const DexFile* dex_file : dex_files) {
+    for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
+      const DexFile::ClassDef& class_def = dex_file->GetClassDef(i);
+      const char* descriptor = dex_file->GetClassDescriptor(class_def);
+      cls.Assign(class_linker->FindClass(soa.Self(), descriptor, class_loader));
+      if (cls.Get() == nullptr) {
+        soa.Self()->ClearException();
+      } else if (&cls->GetDexFile() == dex_file) {
+        DCHECK(cls->IsErroneous() || cls->IsVerified() || cls->IsCompileTimeVerified())
+            << cls->PrettyClass()
+            << " " << cls->GetStatus();
+      }
+    }
+  }
+}
+
 void CompilerDriver::PreCompile(jobject class_loader,
                                 const std::vector<const DexFile*>& dex_files,
                                 TimingLogger* timings) {
@@ -984,6 +1009,9 @@
   }
 
   if (compiler_options_->IsAnyMethodCompilationEnabled()) {
+    if (kIsDebugBuild) {
+      EnsureVerifiedOrVerifyAtRuntime(class_loader, dex_files);
+    }
     InitializeClasses(class_loader, dex_files, timings);
     VLOG(compiler) << "InitializeClasses: " << GetMemoryUsageString(false);
   }
@@ -1949,6 +1977,31 @@
   DCHECK(!it.HasNext());
 }
 
+static void LoadAndUpdateStatus(const DexFile& dex_file,
+                                const DexFile::ClassDef& class_def,
+                                mirror::Class::Status status,
+                                Handle<mirror::ClassLoader> class_loader,
+                                Thread* self)
+    REQUIRES_SHARED(Locks::mutator_lock_) {
+  StackHandleScope<1> hs(self);
+  const char* descriptor = dex_file.GetClassDescriptor(class_def);
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+  Handle<mirror::Class> cls(hs.NewHandle<mirror::Class>(
+      class_linker->FindClass(self, descriptor, class_loader)));
+  if (cls.Get() != nullptr) {
+    // Check that the class is resolved with the current dex file. We might get
+    // a boot image class, or a class in a different dex file for multidex, and
+    // we should not update the status in that case.
+    if (&cls->GetDexFile() == &dex_file) {
+      ObjectLock<mirror::Class> lock(self, cls);
+      mirror::Class::SetStatus(cls, status, self);
+    }
+  } else {
+    DCHECK(self->IsExceptionPending());
+    self->ClearException();
+  }
+}
+
 bool CompilerDriver::FastVerify(jobject jclass_loader,
                                 const std::vector<const DexFile*>& dex_files,
                                 TimingLogger* timings) {
@@ -1963,12 +2016,12 @@
   StackHandleScope<2> hs(soa.Self());
   Handle<mirror::ClassLoader> class_loader(
       hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
-  MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
-  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   if (!verifier_deps->ValidateDependencies(class_loader, soa.Self())) {
     return false;
   }
 
+  bool compiler_only_verifies = !GetCompilerOptions().IsAnyMethodCompilationEnabled();
+
   // We successfully validated the dependencies, now update class status
   // of verified classes. Note that the dependencies also record which classes
   // could not be fully verified; we could try again, but that would hurt verification
@@ -1983,28 +2036,16 @@
     for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
       const DexFile::ClassDef& class_def = dex_file->GetClassDef(i);
       if (set.find(class_def.class_idx_) == set.end()) {
-        if (!GetCompilerOptions().IsAnyMethodCompilationEnabled()) {
+        if (compiler_only_verifies) {
           // Just update the compiled_classes_ map. The compiler doesn't need to resolve
           // the type.
           compiled_classes_.Overwrite(
               ClassReference(dex_file, i), new CompiledClass(mirror::Class::kStatusVerified));
         } else {
-          // Resolve the type, so later compilation stages know they don't need to verify
+          // Update the class status, so later compilation stages know they don't need to verify
           // the class.
-          const char* descriptor = dex_file->GetClassDescriptor(class_def);
-          cls.Assign(class_linker->FindClass(soa.Self(), descriptor, class_loader));
-          if (cls.Get() != nullptr) {
-            // Check that the class is resolved with the current dex file. We might get
-            // a boot image class, or a class in a different dex file for multidex, and
-            // we should not update the status in that case.
-            if (&cls->GetDexFile() == dex_file) {
-              ObjectLock<mirror::Class> lock(soa.Self(), cls);
-              mirror::Class::SetStatus(cls, mirror::Class::kStatusVerified, soa.Self());
-            }
-          } else {
-            DCHECK(soa.Self()->IsExceptionPending());
-            soa.Self()->ClearException();
-          }
+          LoadAndUpdateStatus(
+              *dex_file, class_def, mirror::Class::kStatusVerified, class_loader, soa.Self());
           // Create `VerifiedMethod`s for each methods, the compiler expects one for
           // quickening or compiling.
           // Note that this means:
@@ -2013,6 +2054,14 @@
           // TODO(ngeoffray): Reconsider this once we refactor compiler filters.
           PopulateVerifiedMethods(*dex_file, i, verification_results_);
         }
+      } else if (!compiler_only_verifies) {
+        // Make sure later compilation stages know they should not try to verify
+        // this class again.
+        LoadAndUpdateStatus(*dex_file,
+                            class_def,
+                            mirror::Class::kStatusRetryVerificationAtRuntime,
+                            class_loader,
+                            soa.Self());
       }
     }
   }
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index cb798f0..b4c6b45 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -512,10 +512,13 @@
 # Known broken tests for the interpreter.
 # CFI unwinding expects managed frames.
 # 629 requires compilation.
+# 934 and 935 are broken due to the PreDefine hook not yet inserting them into the classpath. This should be fixed shortly
 TEST_ART_BROKEN_INTERPRETER_RUN_TESTS := \
   137-cfi \
   554-jit-profile-file \
-  629-vdex-speed
+  629-vdex-speed \
+  934-load-transform \
+  935-non-retransformable \
 
 ifneq (,$(filter interpreter,$(COMPILER_TYPES)))
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \
@@ -538,6 +541,7 @@
 # resolved but until then just disable them. Test 916 already checks this
 # feature for JIT use cases in a way that is resilient to the jit frames.
 # 912: b/34655682
+# 934 and 935 are broken due to the PreDefine hook not yet inserting them into the classpath. This should be fixed shortly
 TEST_ART_BROKEN_JIT_RUN_TESTS := \
   137-cfi \
   629-vdex-speed \
@@ -550,6 +554,8 @@
   917-fields-transformation \
   919-obsolete-fields \
   926-multi-obsolescence \
+  934-load-transform \
+  935-non-retransformable \
 
 ifneq (,$(filter jit,$(COMPILER_TYPES)))
   ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \