Merge "Snap for 4416925 from f5e4cdca6dbad04ebff46e6d4b8e0c96969c199d to oreo-cts-release" into oreo-cts-release
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 419b2af..c9a6898 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -2522,28 +2522,21 @@
   if (CanGenerateTest(condition, codegen_->GetAssembler())) {
     Label* non_fallthrough_target;
     bool invert;
-    bool emit_both_branches;
 
     if (true_target_in == nullptr) {
-      // The true target is fallthrough.
       DCHECK(false_target_in != nullptr);
       non_fallthrough_target = false_target_in;
       invert = true;
-      emit_both_branches = false;
     } else {
-      // Either the false target is fallthrough, or there is no fallthrough
-      // and both branches must be emitted.
       non_fallthrough_target = true_target_in;
       invert = false;
-      emit_both_branches = (false_target_in != nullptr);
     }
 
     const auto cond = GenerateTest(condition, invert, codegen_);
 
     __ b(non_fallthrough_target, cond.first);
 
-    if (emit_both_branches) {
-      // No target falls through, we need to branch.
+    if (false_target_in != nullptr && false_target_in != non_fallthrough_target) {
       __ b(false_target_in);
     }
 
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index da146d7..fccb567 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -3563,6 +3563,9 @@
                                                           size_t condition_input_index,
                                                           vixl::aarch64::Label* true_target,
                                                           vixl::aarch64::Label* false_target) {
+  // FP branching requires both targets to be explicit. If either of the targets
+  // is nullptr (fallthrough) use and bind `fallthrough_target` instead.
+  vixl::aarch64::Label fallthrough_target;
   HInstruction* cond = instruction->InputAt(condition_input_index);
 
   if (true_target == nullptr && false_target == nullptr) {
@@ -3663,6 +3666,10 @@
   if (true_target != nullptr && false_target != nullptr) {
     __ B(false_target);
   }
+
+  if (fallthrough_target.IsLinked()) {
+    __ Bind(&fallthrough_target);
+  }
 }
 
 void LocationsBuilderARM64::VisitIf(HIf* if_instr) {
diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc
index c37cc52..59cd5f9 100644
--- a/compiler/optimizing/code_generator_arm_vixl.cc
+++ b/compiler/optimizing/code_generator_arm_vixl.cc
@@ -2557,28 +2557,21 @@
   if (CanGenerateTest(condition, codegen_->GetAssembler())) {
     vixl32::Label* non_fallthrough_target;
     bool invert;
-    bool emit_both_branches;
 
     if (true_target_in == nullptr) {
-      // The true target is fallthrough.
       DCHECK(false_target_in != nullptr);
       non_fallthrough_target = false_target_in;
       invert = true;
-      emit_both_branches = false;
     } else {
       non_fallthrough_target = true_target_in;
       invert = false;
-      // Either the false target is fallthrough, or there is no fallthrough
-      // and both branches must be emitted.
-      emit_both_branches = (false_target_in != nullptr);
     }
 
     const auto cond = GenerateTest(condition, invert, codegen_);
 
     __ B(cond.first, non_fallthrough_target);
 
-    if (emit_both_branches) {
-      // No target falls through, we need to branch.
+    if (false_target_in != nullptr && false_target_in != non_fallthrough_target) {
       __ B(false_target_in);
     }
 
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index 820ba0e..7220644 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -2611,19 +2611,19 @@
     RESTORE_TWO_REGS x14, x15, 112
     RESTORE_TWO_REGS x18, x19, 128    // Skip x16, x17, i.e. IP0, IP1.
     RESTORE_REG      xLR,      144    // Restore return address.
-    // Restore caller-save floating-point registers.
-    ldp   d0, d1,   [sp, #160]
-    ldp   d2, d3,   [sp, #176]
-    ldp   d4, d5,   [sp, #192]
-    ldp   d6, d7,   [sp, #208]
-    ldp   d16, d17, [sp, #224]
-    ldp   d18, d19, [sp, #240]
-    ldp   d20, d21, [sp, #256]
-    ldp   d22, d23, [sp, #272]
-    ldp   d24, d25, [sp, #288]
-    ldp   d26, d27, [sp, #304]
-    ldp   d28, d29, [sp, #320]
-    ldp   d30, d31, [sp, #336]
+    // Save all potentially live caller-save floating-point registers.
+    stp   d0, d1,   [sp, #160]
+    stp   d2, d3,   [sp, #176]
+    stp   d4, d5,   [sp, #192]
+    stp   d6, d7,   [sp, #208]
+    stp   d16, d17, [sp, #224]
+    stp   d18, d19, [sp, #240]
+    stp   d20, d21, [sp, #256]
+    stp   d22, d23, [sp, #272]
+    stp   d24, d25, [sp, #288]
+    stp   d26, d27, [sp, #304]
+    stp   d28, d29, [sp, #320]
+    stp   d30, d31, [sp, #336]
 
     ldr   x0, [lr, #\ldr_offset]      // Load the instruction.
     adr   xIP1, .Lmark_introspection_return_switch
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index 67038b4..7de8916 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -403,19 +403,15 @@
 
 bool ArtMethod::IsAnnotatedWithFastNative() {
   return IsAnnotatedWith(WellKnownClasses::dalvik_annotation_optimization_FastNative,
-                         DexFile::kDexVisibilityBuild,
-                         /* lookup_in_resolved_boot_classes */ true);
+                         DexFile::kDexVisibilityBuild);
 }
 
 bool ArtMethod::IsAnnotatedWithCriticalNative() {
   return IsAnnotatedWith(WellKnownClasses::dalvik_annotation_optimization_CriticalNative,
-                         DexFile::kDexVisibilityBuild,
-                         /* lookup_in_resolved_boot_classes */ true);
+                         DexFile::kDexVisibilityBuild);
 }
 
-bool ArtMethod::IsAnnotatedWith(jclass klass,
-                                uint32_t visibility,
-                                bool lookup_in_resolved_boot_classes) {
+bool ArtMethod::IsAnnotatedWith(jclass klass, uint32_t visibility) {
   Thread* self = Thread::Current();
   ScopedObjectAccess soa(self);
   StackHandleScope<1> shs(self);
@@ -424,8 +420,10 @@
   DCHECK(annotation->IsAnnotation());
   Handle<mirror::Class> annotation_handle(shs.NewHandle(annotation));
 
-  return annotations::IsMethodAnnotationPresent(
-      this, annotation_handle, visibility, lookup_in_resolved_boot_classes);
+  // Note: Resolves any method annotations' classes as a side-effect.
+  // -- This seems allowed by the spec since it says we can preload any classes
+  //    referenced by another classes's constant pool table.
+  return annotations::IsMethodAnnotationPresent(this, annotation_handle, visibility);
 }
 
 static uint32_t GetOatMethodIndexFromMethodIndex(const DexFile& dex_file,
diff --git a/runtime/art_method.h b/runtime/art_method.h
index 9ed056a..856bfd2 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -716,10 +716,7 @@
  private:
   uint16_t FindObsoleteDexClassDefIndex() REQUIRES_SHARED(Locks::mutator_lock_);
 
-  // If `lookup_in_resolved_boot_classes` is true, look up any of the
-  // method's annotations' classes in the bootstrap class loader's
-  // resolved types; otherwise, resolve them as a side effect.
-  bool IsAnnotatedWith(jclass klass, uint32_t visibility, bool lookup_in_resolved_boot_classes);
+  bool IsAnnotatedWith(jclass klass, uint32_t visibility);
 
   static constexpr size_t PtrSizedFieldsOffset(PointerSize pointer_size) {
     // Round up to pointer size for padding field. Tested in art_method.cc.
diff --git a/runtime/dex_file_annotations.cc b/runtime/dex_file_annotations.cc
index ebacb27..005bb4a 100644
--- a/runtime/dex_file_annotations.cc
+++ b/runtime/dex_file_annotations.cc
@@ -751,8 +751,7 @@
     const ClassData& klass,
     const DexFile::AnnotationSetItem* annotation_set,
     uint32_t visibility,
-    Handle<mirror::Class> annotation_class,
-    bool lookup_in_resolved_boot_classes = false)
+    Handle<mirror::Class> annotation_class)
     REQUIRES_SHARED(Locks::mutator_lock_) {
   const DexFile& dex_file = klass.GetDexFile();
   for (uint32_t i = 0; i < annotation_set->size_; ++i) {
@@ -762,37 +761,19 @@
     }
     const uint8_t* annotation = annotation_item->annotation_;
     uint32_t type_index = DecodeUnsignedLeb128(&annotation);
-    mirror::Class* resolved_class;
-    if (lookup_in_resolved_boot_classes) {
-      ObjPtr<mirror::Class> looked_up_class =
-          Runtime::Current()->GetClassLinker()->LookupResolvedType(
-              klass.GetDexFile(),
-              dex::TypeIndex(type_index),
-              klass.GetDexCache(),
-              // Force the use of the bootstrap class loader.
-              static_cast<mirror::ClassLoader*>(nullptr));
-      resolved_class = looked_up_class.Ptr();
-      if (resolved_class == nullptr) {
-        // If `resolved_class` is null, this is fine: just ignore that
-        // annotation item. We expect this to happen, as we do not
-        // attempt to resolve the annotation's class in this code path.
-        continue;
-      }
-    } else {
-      StackHandleScope<2> hs(Thread::Current());
-      resolved_class = Runtime::Current()->GetClassLinker()->ResolveType(
-          klass.GetDexFile(),
-          dex::TypeIndex(type_index),
-          hs.NewHandle(klass.GetDexCache()),
-          hs.NewHandle(klass.GetClassLoader()));
-      if (resolved_class == nullptr) {
-        std::string temp;
-        LOG(WARNING) << StringPrintf("Unable to resolve %s annotation class %d",
-                                     klass.GetRealClass()->GetDescriptor(&temp), type_index);
-        CHECK(Thread::Current()->IsExceptionPending());
-        Thread::Current()->ClearException();
-        continue;
-      }
+    StackHandleScope<2> hs(Thread::Current());
+    mirror::Class* resolved_class = Runtime::Current()->GetClassLinker()->ResolveType(
+        klass.GetDexFile(),
+        dex::TypeIndex(type_index),
+        hs.NewHandle(klass.GetDexCache()),
+        hs.NewHandle(klass.GetClassLoader()));
+    if (resolved_class == nullptr) {
+      std::string temp;
+      LOG(WARNING) << StringPrintf("Unable to resolve %s annotation class %d",
+                                   klass.GetRealClass()->GetDescriptor(&temp), type_index);
+      CHECK(Thread::Current()->IsExceptionPending());
+      Thread::Current()->ClearException();
+      continue;
     }
     if (resolved_class == annotation_class.Get()) {
       return annotation_item;
@@ -1219,20 +1200,15 @@
   return GetSignatureValue(ClassData(method), annotation_set);
 }
 
-bool IsMethodAnnotationPresent(ArtMethod* method,
-                               Handle<mirror::Class> annotation_class,
-                               uint32_t visibility /* = DexFile::kDexVisibilityRuntime */,
-                               bool lookup_in_resolved_boot_classes /* = false */) {
+bool IsMethodAnnotationPresent(ArtMethod* method, Handle<mirror::Class> annotation_class,
+                               uint32_t visibility /* = DexFile::kDexVisibilityRuntime */) {
   const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
   if (annotation_set == nullptr) {
     return false;
   }
   const DexFile::AnnotationItem* annotation_item =
       GetAnnotationItemFromAnnotationSet(ClassData(method),
-                                         annotation_set,
-                                         visibility,
-                                         annotation_class,
-                                         lookup_in_resolved_boot_classes);
+                                         annotation_set, visibility, annotation_class);
   return annotation_item != nullptr;
 }
 
diff --git a/runtime/dex_file_annotations.h b/runtime/dex_file_annotations.h
index e108882..651c984 100644
--- a/runtime/dex_file_annotations.h
+++ b/runtime/dex_file_annotations.h
@@ -65,15 +65,8 @@
     REQUIRES_SHARED(Locks::mutator_lock_);
 mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForMethod(ArtMethod* method)
     REQUIRES_SHARED(Locks::mutator_lock_);
-// Check whether `method` is annotated with `annotation_class`.
-// If `lookup_in_resolved_boot_classes` is true, look up any of the
-// method's annotations' classes in the bootstrap class loader's
-// resolved types; if it is false (default value), resolve them as a
-// side effect.
-bool IsMethodAnnotationPresent(ArtMethod* method,
-                               Handle<mirror::Class> annotation_class,
-                               uint32_t visibility = DexFile::kDexVisibilityRuntime,
-                               bool lookup_in_resolved_boot_classes = false)
+bool IsMethodAnnotationPresent(ArtMethod* method, Handle<mirror::Class> annotation_class,
+                               uint32_t visibility = DexFile::kDexVisibilityRuntime)
     REQUIRES_SHARED(Locks::mutator_lock_);
 
 // Class annotations.
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 629148e..2b349e3 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -2075,39 +2075,11 @@
     REQUIRES_SHARED(Locks::mutator_lock_) {
   ArtMethod* called = *sp;
   DCHECK(called->IsNative()) << called->PrettyMethod(true);
-  // Fix up a callee-save frame at the bottom of the stack (at `*sp`,
-  // above the alloca region) while we check for optimization
-  // annotations, thus allowing stack walking until the completion of
-  // the JNI frame creation.
-  //
-  // Note however that the Generic JNI trampoline does not expect
-  // exception being thrown at that stage.
-  *sp = Runtime::Current()->GetCalleeSaveMethod(Runtime::CalleeSaveType::kSaveRefsAndArgs);
-  self->SetTopOfStack(sp);
   uint32_t shorty_len = 0;
   const char* shorty = called->GetShorty(&shorty_len);
-  // Optimization annotations lookup does not try to resolve classes,
-  // as this may throw an exception, which is not supported by the
-  // Generic JNI trampoline at this stage; instead, method's
-  // annotations' classes are looked up in the bootstrap class
-  // loader's resolved types (which won't trigger an exception).
   bool critical_native = called->IsAnnotatedWithCriticalNative();
-  // ArtMethod::IsAnnotatedWithCriticalNative should not throw
-  // an exception; clear it if it happened anyway.
-  // TODO: Revisit this code path and turn this into a CHECK(!self->IsExceptionPending()).
-  if (self->IsExceptionPending()) {
-    self->ClearException();
-  }
   bool fast_native = called->IsAnnotatedWithFastNative();
-  // ArtMethod::IsAnnotatedWithFastNative should not throw
-  // an exception; clear it if it happened anyway.
-  // TODO: Revisit this code path and turn this into a CHECK(!self->IsExceptionPending()).
-  if (self->IsExceptionPending()) {
-    self->ClearException();
-  }
   bool normal_native = !critical_native && !fast_native;
-  // Restore the initial ArtMethod pointer at `*sp`.
-  *sp = called;
 
   // Run the visitor and update sp.
   BuildGenericJniFrameVisitor visitor(self,
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index dcfe25b..b191dd7 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -196,20 +196,7 @@
         inst = inst->Next_1xx();
         break;
       case Instruction::MOVE_RESULT_OBJECT:
-        if (UNLIKELY(instrumentation->HasDexPcListeners())) {
-          // Special case the preamble to save and restore the result object. It could move
-          // during DexPcMovedEvent.
-          // Note that ideally we should have the result object be visible to GC as soon as it
-          // is returned, but that involves pretty heave surgery to the interpreter and the runtime
-          // that it may not be worth it. The way it is currently written, there is an implicit
-          // assumption the result register is updated last in the leaf method, and all methods
-          // in-between just return.
-          StackHandleScope<1> hs(self);
-          Handle<mirror::Object> result_object(hs.NewHandle(result_register.GetL()));
-          instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
-                                           shadow_frame.GetMethod(), dex_pc);
-          result_register.SetL(result_object.Get());
-        }
+        PREAMBLE();
         shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
         inst = inst->Next_1xx();
         break;
diff --git a/test/656-annotation-lookup-generic-jni/expected.txt b/test/656-annotation-lookup-generic-jni/expected.txt
deleted file mode 100644
index 4519c7e..0000000
--- a/test/656-annotation-lookup-generic-jni/expected.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-JNI_OnLoad called
-Java_Test_nativeMethodWithAnnotation
-passed
diff --git a/test/656-annotation-lookup-generic-jni/info.txt b/test/656-annotation-lookup-generic-jni/info.txt
deleted file mode 100644
index ddc1930..0000000
--- a/test/656-annotation-lookup-generic-jni/info.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Non-regression test for b/38454151, where the invocation of a native
-method with an annotatation through Generic JNI would crash the
-Generic JNI trampoline because it would throw and exception when
-trying to resolve the annotation (during the CriticalNative/FastNative
-optimization annotation lookup).
diff --git a/test/656-annotation-lookup-generic-jni/src-ex/DummyAnnotation.java b/test/656-annotation-lookup-generic-jni/src-ex/DummyAnnotation.java
deleted file mode 100644
index 6caac66..0000000
--- a/test/656-annotation-lookup-generic-jni/src-ex/DummyAnnotation.java
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) 2017 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 @interface DummyAnnotation {}
diff --git a/test/656-annotation-lookup-generic-jni/src-ex/Test.java b/test/656-annotation-lookup-generic-jni/src-ex/Test.java
deleted file mode 100644
index 838b4fe..0000000
--- a/test/656-annotation-lookup-generic-jni/src-ex/Test.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2017 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 Test {
-
-  public static void initialize(String libname) {
-    // Load test native library to get access to the implementation of
-    // Test.nativeMethodWithAnnotation.
-    System.loadLibrary(libname);
-  }
-
-  @DummyAnnotation
-  public static native void nativeMethodWithAnnotation();
-
-}
diff --git a/test/656-annotation-lookup-generic-jni/src/Main.java b/test/656-annotation-lookup-generic-jni/src/Main.java
deleted file mode 100644
index 01b288a..0000000
--- a/test/656-annotation-lookup-generic-jni/src/Main.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-import dalvik.system.InMemoryDexClassLoader;
-
-import java.io.InputStream;
-import java.lang.reflect.Method;
-import java.nio.ByteBuffer;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-public class Main {
-
-  public static void main(String[] args) throws Exception {
-    // Extract Dex file contents from the secondary Jar file.
-    String jarFilename =
-        System.getenv("DEX_LOCATION") + "/656-annotation-lookup-generic-jni-ex.jar";
-    ZipFile zipFile = new ZipFile(jarFilename);
-    ZipEntry zipEntry = zipFile.getEntry("classes.dex");
-    InputStream inputStream = zipFile.getInputStream(zipEntry);
-    int dexFileSize = (int) zipEntry.getSize();
-    byte[] dexFileContents = new byte[dexFileSize];
-    inputStream.read(dexFileContents, 0, dexFileSize);
-
-    // Create class loader from secondary Dex file.
-    ByteBuffer dexBuffer = ByteBuffer.wrap(dexFileContents);
-    ClassLoader classLoader = createUnquickenedDexClassLoader(dexBuffer);
-
-    // Load and initialize the Test class.
-    Class<?> testClass = classLoader.loadClass("Test");
-    Method initialize = testClass.getMethod("initialize", String.class);
-    initialize.invoke(null, args[0]);
-
-    // Invoke Test.nativeMethodWithAnnotation().
-    Method nativeMethodWithAnnotation = testClass.getMethod("nativeMethodWithAnnotation");
-    // Invoking the native method Test.nativeMethodWithAnnotation used
-    // to crash the Generic JNI trampoline during the resolution of
-    // the method's annotations (DummyAnnotation) (see b/38454151).
-    nativeMethodWithAnnotation.invoke(null);
-
-    zipFile.close();
-    System.out.println("passed");
-  }
-
-  // Create a class loader loading a Dex file in memory
-  // *without creating an Oat file*. This way, the Dex file won't be
-  // quickened and JNI stubs won't be compiled, thus forcing the use
-  // of Generic JNI when invoking the native method
-  // Test.nativeMethodWithAnnotation.
-  static ClassLoader createUnquickenedDexClassLoader(ByteBuffer dexBuffer) {
-    InMemoryDexClassLoader cl = new InMemoryDexClassLoader(dexBuffer, getBootClassLoader());
-    return cl;
-  }
-
-  static ClassLoader getBootClassLoader() {
-    ClassLoader cl = Main.class.getClassLoader();
-    while (cl.getParent() != null) {
-      cl = cl.getParent();
-    }
-    return cl;
-  }
-
-}
diff --git a/test/656-annotation-lookup-generic-jni/test.cc b/test/656-annotation-lookup-generic-jni/test.cc
deleted file mode 100644
index c8aa2af..0000000
--- a/test/656-annotation-lookup-generic-jni/test.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include "jni.h"
-
-#include <iostream>
-
-namespace art {
-
-// Native method annotated with `DummyAnnotation` in Java source.
-extern "C" JNIEXPORT void JNICALL Java_Test_nativeMethodWithAnnotation(JNIEnv*, jclass) {
-  std::cout << "Java_Test_nativeMethodWithAnnotation" << std::endl;
-}
-
-}  // namespace art
diff --git a/test/657-branches/expected.txt b/test/657-branches/expected.txt
deleted file mode 100644
index d9fd864..0000000
--- a/test/657-branches/expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-Hello World: 4.0
diff --git a/test/657-branches/info.txt b/test/657-branches/info.txt
deleted file mode 100644
index 84a2bb9..0000000
--- a/test/657-branches/info.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Regression test for the ARM backend, which used to have a bug
-handling branches fallthrough.
diff --git a/test/657-branches/src/Main.java b/test/657-branches/src/Main.java
deleted file mode 100644
index 2b62c5f..0000000
--- a/test/657-branches/src/Main.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2017 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 Main {
-
-  public static void foo(float f) {
-    // The reason this used to break:
-    // 1) We inline the 'foo' call, so blocks now only contain HLoadClass instructions.
-    // 2) We then run the select_generator pass, which cannot change the
-    //    if/else because blocks contain instructions.
-    // 3) We run GVN which will remove the HLoadClass instructions in the blocks.
-    // 4) At code generation, we are in the unlikely situation that a diamond shape
-    //    contains no instruction (usually removed by select_generator). This used
-    //    to trip the ARM code generators.
-    if (f < 1.2f) {
-      foo(Main.class, Object.class);
-      if (f < 0.2f) {
-        foo(Main.class, Object.class);
-      } else {
-        foo(Main.class, Object.class);
-      }
-    } else {
-      System.out.println("Hello World: " + f);
-    }
-  }
-
-  public static void foo(Object a, Object b) {}
-
-  public static void main(String[] args) {
-    foo(0f);
-    foo(4f);
-    foo(0.1f);
-  }
-}
diff --git a/test/658-fp-read-barrier/expected.txt b/test/658-fp-read-barrier/expected.txt
deleted file mode 100644
index e69de29..0000000
--- a/test/658-fp-read-barrier/expected.txt
+++ /dev/null
diff --git a/test/658-fp-read-barrier/info.txt b/test/658-fp-read-barrier/info.txt
deleted file mode 100644
index 26ecb60..0000000
--- a/test/658-fp-read-barrier/info.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Regression test for the read barrier implementation in ARM64,
-which used to not restore floating point registers.
diff --git a/test/658-fp-read-barrier/src/Main.java b/test/658-fp-read-barrier/src/Main.java
deleted file mode 100644
index c2bd10d..0000000
--- a/test/658-fp-read-barrier/src/Main.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2017 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 Main {
-  static volatile boolean done = false;
-
-  public static void main(String[] args) {
-    // Run a thread for 30 seconds, allocating memory and triggering garbage
-    // collection.
-    // Time is limited to 30 seconds to not make this test too long. The test used
-    // to trigger the failure around 1 every 10 runs.
-    Thread t = new Thread() {
-      public void run() {
-        long time = System.currentTimeMillis();
-        while (System.currentTimeMillis() - time < 30000) {
-          for (int j = 0; j < 10000; j++) {
-            o = new Object[1000];
-          }
-          Runtime.getRuntime().gc();
-          Thread.yield();
-        }
-        Main.done = true;
-      }
-      Object o;
-    };
-    // Make the thread a daemon to quit early in case of an
-    // exception throw below.
-    t.setDaemon(true);
-    t.start();
-
-    // Run 'foo' as long as the test runs.
-    while (!done) {
-      double res = foo(staticMain);
-      if (res != 529.0) {
-        throw new Error("Unexpected result " + res);
-      }
-    }
-  }
-
-  public static double foo(Main main) {
-    // Use up all D registers on arm64.
-    double d1 = main.field1;
-    double d2 = main.field2;
-    double d3 = main.field3;
-    double d4 = main.field4;
-    double d5 = main.field5;
-    double d6 = main.field6;
-    double d7 = main.field7;
-    double d8 = main.field8;
-    double d9 = main.field9;
-    double d10 = main.field10;
-    double d11 = main.field11;
-    double d12 = main.field12;
-    double d13 = main.field13;
-    double d14 = main.field14;
-    double d15 = main.field15;
-    double d16 = main.field16;
-    double d17 = main.field17;
-    double d18 = main.field18;
-    double d19 = main.field19;
-    double d20 = main.field20;
-    double d21 = main.field21;
-    double d22 = main.field22;
-    double d23 = main.field23;
-    double d24 = main.field24;
-    double d25 = main.field25;
-    double d26 = main.field26;
-    double d27 = main.field27;
-    double d28 = main.field28;
-    double d29 = main.field29;
-    double d30 = main.field30;
-    double d31 = main.field31;
-    double d32 = main.field32;
-
-    // Trigger a read barrier. This used to make the test trip on ARM64 as
-    // the read barrier stub used to not restore the D registers.
-    double p = main.objectField.field1;
-
-    return p + d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8 + d9 + d10 + d11 + d12 + d13 + d14 + d15 + d16 + d17 + d18 + d19 + d20 + d21 + d22 + d23 + d24 + d25 + d26 + d27 + d28 + d29 + d30 + d31 + d32;
-  }
-
-  // Initialize objects here and not in 'main' to avoid having
-  // these objects in roots.
-  public static Main staticMain = new Main();
-  static {
-    staticMain.objectField = new Main();
-  }
-
-  public Main objectField;
-
-  public double field1 = 1.0;
-  public double field2 = 2.0;
-  public double field3 = 3.0;
-  public double field4 = 4.0;
-  public double field5 = 5.0;
-  public double field6 = 6.0;
-  public double field7 = 7.0;
-  public double field8 = 8.0;
-  public double field9 = 9.0;
-  public double field10 = 10.0;
-  public double field11 = 11.0;
-  public double field12 = 12.0;
-  public double field13 = 13.0;
-  public double field14 = 14.0;
-  public double field15 = 15.0;
-  public double field16 = 16.0;
-  public double field17 = 17.0;
-  public double field18 = 18.0;
-  public double field19 = 19.0;
-  public double field20 = 20.0;
-  public double field21 = 21.0;
-  public double field22 = 22.0;
-  public double field23 = 23.0;
-  public double field24 = 24.0;
-  public double field25 = 25.0;
-  public double field26 = 26.0;
-  public double field27 = 27.0;
-  public double field28 = 28.0;
-  public double field29 = 29.0;
-  public double field30 = 30.0;
-  public double field31 = 31.0;
-  public double field32 = 32.0;
-}
diff --git a/test/911-get-stack-trace/src/art/PrintThread.java b/test/911-get-stack-trace/src/art/PrintThread.java
index fee5ba0..d8b3cbc 100644
--- a/test/911-get-stack-trace/src/art/PrintThread.java
+++ b/test/911-get-stack-trace/src/art/PrintThread.java
@@ -42,7 +42,7 @@
   // may not exist depending on the environment.
   public final static String IGNORE_THREAD_NAME_REGEX =
       "Binder:|RenderThread|hwuiTask|Jit thread pool worker|Instr:|JDWP|Profile Saver|main|" +
-      "queued-work-looper";
+      "queued-work-looper|InstrumentationConnectionThread";
   public final static Matcher IGNORE_THREADS =
       Pattern.compile(IGNORE_THREAD_NAME_REGEX).matcher("");
 
diff --git a/test/912-classes/expected.txt b/test/912-classes/expected.txt
index 9dcc5f9..7ad5d60 100644
--- a/test/912-classes/expected.txt
+++ b/test/912-classes/expected.txt
@@ -56,7 +56,7 @@
 boot <- 1+2 (A,B)
 [class A, class B, class java.lang.Object]
 
-[37, 0]
+[35, 0]
 
 B, false
 Load: LB; on ClassEvents
diff --git a/test/912-classes/src/art/Test912.java b/test/912-classes/src/art/Test912.java
index 9896eac..cea42a6 100644
--- a/test/912-classes/src/art/Test912.java
+++ b/test/912-classes/src/art/Test912.java
@@ -19,8 +19,10 @@
 import java.lang.ref.Reference;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Proxy;
+import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Base64;
 import java.util.Comparator;
 
 public class Test912 {
@@ -214,8 +216,34 @@
     }
   }
 
-  private static void testClassVersion() {
-    System.out.println(Arrays.toString(getClassVersion(Main.class)));
+  /**
+   * base64 encoded class/dex file for
+   * class Transform {
+   *   public void sayHi() {
+   *    System.out.println("Goodbye");
+   *   }
+   * }
+   */
+  private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+    "ZGV4CjAzNQCLXSBQ5FiS3f16krSYZFF8xYZtFVp0GRXMAgAAcAAAAHhWNBIAAAAAAAAAACwCAAAO" +
+    "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACsAQAAIAEAAGIB" +
+    "AABqAQAAcwEAAIABAACXAQAAqwEAAL8BAADTAQAA4wEAAOYBAADqAQAA/gEAAAMCAAAMAgAAAgAA" +
+    "AAMAAAAEAAAABQAAAAYAAAAIAAAACAAAAAUAAAAAAAAACQAAAAUAAABcAQAABAABAAsAAAAAAAAA" +
+    "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAHAAAAAAAAAB4CAAAA" +
+    "AAAAAQABAAEAAAATAgAABAAAAHAQAwAAAA4AAwABAAIAAAAYAgAACQAAAGIAAAAbAQEAAABuIAIA" +
+    "EAAOAAAAAQAAAAMABjxpbml0PgAHR29vZGJ5ZQALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50" +
+    "U3RyZWFtOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xh" +
+    "bmcvU3lzdGVtOwAOVHJhbnNmb3JtLmphdmEAAVYAAlZMABJlbWl0dGVyOiBqYWNrLTMuMzYAA291" +
+    "dAAHcHJpbnRsbgAFc2F5SGkAEQAHDgATAAcOhQAAAAEBAICABKACAQG4Ag0AAAAAAAAAAQAAAAAA" +
+    "AAABAAAADgAAAHAAAAACAAAABgAAAKgAAAADAAAAAgAAAMAAAAAEAAAAAQAAANgAAAAFAAAABAAA" +
+    "AOAAAAAGAAAAAQAAAAABAAABIAAAAgAAACABAAABEAAAAQAAAFwBAAACIAAADgAAAGIBAAADIAAA" +
+    "AgAAABMCAAAAIAAAAQAAAB4CAAAAEAAAAQAAACwCAAA=");
+  private static void testClassVersion() throws Exception {
+    Class<?> class_loader_class = Class.forName("dalvik.system.InMemoryDexClassLoader");
+    Constructor<?> ctor = class_loader_class.getConstructor(ByteBuffer.class, ClassLoader.class);
+    Class target = ((ClassLoader)ctor.newInstance(
+        ByteBuffer.wrap(DEX_BYTES), Test912.class.getClassLoader())).loadClass("Transform");
+    System.out.println(Arrays.toString(getClassVersion(target)));
   }
 
   private static void testClassEvents() throws Exception {
diff --git a/test/Android.bp b/test/Android.bp
index 2d682ed..1679669 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -393,7 +393,6 @@
         "626-const-class-linking/clear_dex_cache_types.cc",
         "642-fp-callees/fp_callees.cc",
         "647-jni-get-field-id/get_field_id.cc",
-        "656-annotation-lookup-generic-jni/test.cc"
     ],
     shared_libs: [
         "libbacktrace",