Tracking java.lang.reflect.Executable changes

Added a method to Class: total vtable entries increases
by one.

Handling knock-ons of introducing Executable into the
class hierarchy above AbstractMethod.

Rearranging java_lang_reflect_*.cc code to track libcore
changes that reduce duplication between Constructor / Method
/ Executable and AbstractMethod and track the OpenJDK 8
more closely.

Bug: 28666126
Change-Id: I6b5c476a14b8ea25556c35448431de744519b6c2
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 7999aef..5f225be 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -32,6 +32,7 @@
 #include "mirror/accessible_object.h"
 #include "mirror/class-inl.h"
 #include "mirror/dex_cache.h"
+#include "mirror/executable.h"
 #include "mirror/field.h"
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
@@ -691,6 +692,12 @@
   };
 };
 
+struct ExecutableOffsets : public CheckOffsets<mirror::Executable> {
+  ExecutableOffsets() : CheckOffsets<mirror::Executable>(
+      false, "Ljava/lang/reflect/Executable;") {
+  };
+};
+
 struct AbstractMethodOffsets : public CheckOffsets<mirror::AbstractMethod> {
   AbstractMethodOffsets() : CheckOffsets<mirror::AbstractMethod>(
       false, "Ljava/lang/reflect/AbstractMethod;") {
@@ -720,6 +727,7 @@
   EXPECT_TRUE(FinalizerReferenceOffsets().Check());
   EXPECT_TRUE(AccessibleObjectOffsets().Check());
   EXPECT_TRUE(FieldOffsets().Check());
+  EXPECT_TRUE(ExecutableOffsets().Check());
   EXPECT_TRUE(AbstractMethodOffsets().Check());
 }
 
diff --git a/runtime/mirror/abstract_method.h b/runtime/mirror/abstract_method.h
index cfbe492..4f714a6 100644
--- a/runtime/mirror/abstract_method.h
+++ b/runtime/mirror/abstract_method.h
@@ -17,7 +17,7 @@
 #ifndef ART_RUNTIME_MIRROR_ABSTRACT_METHOD_H_
 #define ART_RUNTIME_MIRROR_ABSTRACT_METHOD_H_
 
-#include "accessible_object.h"
+#include "executable.h"
 #include "gc_root.h"
 #include "object.h"
 #include "object_callbacks.h"
@@ -31,7 +31,7 @@
 namespace mirror {
 
 // C++ mirror of java.lang.reflect.AbstractMethod.
-class MANAGED AbstractMethod : public AccessibleObject {
+class MANAGED AbstractMethod : public Executable {
  public:
   // Called from Constructor::CreateFromArtMethod, Method::CreateFromArtMethod.
   template <PointerSize kPointerSize, bool kTransactionActive>
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index e2cd649..21af15e 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -571,7 +571,7 @@
   // The size of java.lang.Class.class.
   static uint32_t ClassClassSize(PointerSize pointer_size) {
     // The number of vtable entries in java.lang.Class.
-    uint32_t vtable_entries = Object::kVTableLength + 70;
+    uint32_t vtable_entries = Object::kVTableLength + 71;
     return ComputeClassSize(true, vtable_entries, 0, 0, 4, 1, 0, pointer_size);
   }
 
diff --git a/runtime/mirror/executable.h b/runtime/mirror/executable.h
new file mode 100644
index 0000000..8786657
--- /dev/null
+++ b/runtime/mirror/executable.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef ART_RUNTIME_MIRROR_EXECUTABLE_H_
+#define ART_RUNTIME_MIRROR_EXECUTABLE_H_
+
+#include "accessible_object.h"
+#include "gc_root.h"
+#include "object.h"
+#include "object_callbacks.h"
+#include "read_barrier_option.h"
+
+namespace art {
+
+struct ExecutableOffsets;
+class ArtMethod;
+
+namespace mirror {
+
+// C++ mirror of java.lang.reflect.Executable.
+class MANAGED Executable : public AccessibleObject {
+ private:
+  friend struct art::ExecutableOffsets;  // for verifying offset information
+  DISALLOW_IMPLICIT_CONSTRUCTORS(Executable);
+};
+
+}  // namespace mirror
+}  // namespace art
+
+#endif  // ART_RUNTIME_MIRROR_EXECUTABLE_H_
diff --git a/runtime/native/java_lang_reflect_AbstractMethod.cc b/runtime/native/java_lang_reflect_AbstractMethod.cc
index 7e11c11..33e0dae 100644
--- a/runtime/native/java_lang_reflect_AbstractMethod.cc
+++ b/runtime/native/java_lang_reflect_AbstractMethod.cc
@@ -41,6 +41,21 @@
   return soa.AddLocalReference<jobjectArray>(method->GetDexFile()->GetAnnotationsForMethod(method));
 }
 
+static jobject AbstractMethod_getAnnotationNative(JNIEnv* env,
+                                                  jobject javaMethod,
+                                                  jclass annotationType) {
+  ScopedFastNativeObjectAccess soa(env);
+  StackHandleScope<1> hs(soa.Self());
+  ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
+  if (method->IsProxyMethod()) {
+    return nullptr;
+  } else {
+    Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType)));
+    return soa.AddLocalReference<jobject>(
+        method->GetDexFile()->GetAnnotationForMethod(method, klass));
+  }
+}
+
 static jobjectArray AbstractMethod_getSignatureAnnotation(JNIEnv* env, jobject javaMethod) {
   ScopedFastNativeObjectAccess soa(env);
   ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
@@ -53,7 +68,19 @@
 }
 
 
-static jboolean AbstractMethod_isAnnotationPresentNative(JNIEnv* env, jobject javaMethod,
+static jobjectArray AbstractMethod_getParameterAnnotationsNative(JNIEnv* env, jobject javaMethod) {
+  ScopedFastNativeObjectAccess soa(env);
+  ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
+  if (method->IsProxyMethod()) {
+    return nullptr;
+  } else {
+    return soa.AddLocalReference<jobjectArray>(
+        method->GetDexFile()->GetParameterAnnotations(method));
+  }
+}
+
+static jboolean AbstractMethod_isAnnotationPresentNative(JNIEnv* env,
+                                                         jobject javaMethod,
                                                          jclass annotationType) {
   ScopedFastNativeObjectAccess soa(env);
   ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
@@ -66,7 +93,11 @@
 }
 
 static JNINativeMethod gMethods[] = {
+  NATIVE_METHOD(AbstractMethod, getAnnotationNative,
+                "!(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"),
   NATIVE_METHOD(AbstractMethod, getDeclaredAnnotations, "!()[Ljava/lang/annotation/Annotation;"),
+  NATIVE_METHOD(AbstractMethod, getParameterAnnotationsNative,
+                "!()[[Ljava/lang/annotation/Annotation;"),
   NATIVE_METHOD(AbstractMethod, getSignatureAnnotation, "!()[Ljava/lang/String;"),
   NATIVE_METHOD(AbstractMethod, isAnnotationPresentNative, "!(Ljava/lang/Class;)Z"),
 };
diff --git a/runtime/native/java_lang_reflect_Constructor.cc b/runtime/native/java_lang_reflect_Constructor.cc
index dd46233..f699d6b 100644
--- a/runtime/native/java_lang_reflect_Constructor.cc
+++ b/runtime/native/java_lang_reflect_Constructor.cc
@@ -30,39 +30,6 @@
 
 namespace art {
 
-static jobject Constructor_getAnnotationNative(JNIEnv* env, jobject javaMethod,
-                                               jclass annotationType) {
-  ScopedFastNativeObjectAccess soa(env);
-  StackHandleScope<1> hs(soa.Self());
-  ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
-  if (method->IsProxyMethod()) {
-    return nullptr;
-  } else {
-    Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType)));
-    return soa.AddLocalReference<jobject>(
-        method->GetDexFile()->GetAnnotationForMethod(method, klass));
-  }
-}
-
-static jobjectArray Constructor_getDeclaredAnnotations(JNIEnv* env, jobject javaMethod) {
-  ScopedFastNativeObjectAccess soa(env);
-  ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
-  if (method->IsProxyMethod()) {
-    mirror::Class* class_class = mirror::Class::GetJavaLangClass();
-    mirror::Class* class_array_class =
-        Runtime::Current()->GetClassLinker()->FindArrayClass(soa.Self(), &class_class);
-    if (class_array_class == nullptr) {
-      return nullptr;
-    }
-    mirror::ObjectArray<mirror::Class>* empty_array =
-        mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class, 0);
-    return soa.AddLocalReference<jobjectArray>(empty_array);
-  } else {
-    return soa.AddLocalReference<jobjectArray>(
-        method->GetDexFile()->GetAnnotationsForMethod(method));
-  }
-}
-
 static jobjectArray Constructor_getExceptionTypes(JNIEnv* env, jobject javaMethod) {
   ScopedFastNativeObjectAccess soa(env);
   ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod)
@@ -85,30 +52,6 @@
   }
 }
 
-static jobjectArray Constructor_getParameterAnnotationsNative(JNIEnv* env, jobject javaMethod) {
-  ScopedFastNativeObjectAccess soa(env);
-  ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
-  if (method->IsProxyMethod()) {
-    return nullptr;
-  } else {
-    return soa.AddLocalReference<jobjectArray>(
-        method->GetDexFile()->GetParameterAnnotations(method));
-  }
-}
-
-static jboolean Constructor_isAnnotationPresentNative(JNIEnv* env, jobject javaMethod,
-                                                      jclass annotationType) {
-  ScopedFastNativeObjectAccess soa(env);
-  StackHandleScope<1> hs(soa.Self());
-  ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
-  if (method->IsProxyMethod()) {
-    // Proxies have no annotations.
-    return false;
-  }
-  Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType)));
-  return method->GetDexFile()->IsMethodAnnotationPresent(method, klass);
-}
-
 /*
  * We can also safely assume the constructor isn't associated
  * with an interface, array, or primitive class. If this is coming from
@@ -179,13 +122,7 @@
 }
 
 static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(Constructor, getAnnotationNative,
-                "!(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"),
-  NATIVE_METHOD(Constructor, getDeclaredAnnotations, "!()[Ljava/lang/annotation/Annotation;"),
   NATIVE_METHOD(Constructor, getExceptionTypes, "!()[Ljava/lang/Class;"),
-  NATIVE_METHOD(Constructor, getParameterAnnotationsNative,
-                "!()[[Ljava/lang/annotation/Annotation;"),
-  NATIVE_METHOD(Constructor, isAnnotationPresentNative, "!(Ljava/lang/Class;)Z"),
   NATIVE_METHOD(Constructor, newInstance0, "!([Ljava/lang/Object;)Ljava/lang/Object;"),
   NATIVE_METHOD(Constructor, newInstanceFromSerialization, "!(Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/Object;"),
 };
diff --git a/runtime/native/java_lang_reflect_Method.cc b/runtime/native/java_lang_reflect_Method.cc
index c3f2a27..3360f41 100644
--- a/runtime/native/java_lang_reflect_Method.cc
+++ b/runtime/native/java_lang_reflect_Method.cc
@@ -30,18 +30,6 @@
 
 namespace art {
 
-static jobject Method_getAnnotationNative(JNIEnv* env, jobject javaMethod, jclass annotationType) {
-  ScopedFastNativeObjectAccess soa(env);
-  ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
-  if (method->GetDeclaringClass()->IsProxyClass()) {
-    return nullptr;
-  }
-  StackHandleScope<1> hs(soa.Self());
-  Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType)));
-  return soa.AddLocalReference<jobject>(
-      method->GetDexFile()->GetAnnotationForMethod(method, klass));
-}
-
 static jobject Method_getDefaultValue(JNIEnv* env, jobject javaMethod) {
   ScopedFastNativeObjectAccess soa(env);
   ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
@@ -88,15 +76,6 @@
   }
 }
 
-static jobjectArray Method_getParameterAnnotationsNative(JNIEnv* env, jobject javaMethod) {
-  ScopedFastNativeObjectAccess soa(env);
-  ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
-  if (method->GetDeclaringClass()->IsProxyClass()) {
-    return nullptr;
-  }
-  return soa.AddLocalReference<jobjectArray>(method->GetDexFile()->GetParameterAnnotations(method));
-}
-
 static jobject Method_invoke(JNIEnv* env, jobject javaMethod, jobject javaReceiver,
                              jobject javaArgs) {
   ScopedFastNativeObjectAccess soa(env);
@@ -104,11 +83,8 @@
 }
 
 static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(Method, getAnnotationNative,
-                "!(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"),
   NATIVE_METHOD(Method, getDefaultValue, "!()Ljava/lang/Object;"),
   NATIVE_METHOD(Method, getExceptionTypes, "!()[Ljava/lang/Class;"),
-  NATIVE_METHOD(Method, getParameterAnnotationsNative, "!()[[Ljava/lang/annotation/Annotation;"),
   NATIVE_METHOD(Method, invoke, "!(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"),
 };