Add java.lang.ClassValue support.
Fields in class-ext.h were reordered to follow layout in java class
file. Otherwise build fails with fields offsets do match in java and C
code message.
Bug: 32299208
Test: ./art/test.py --host
Change-Id: Ib967d15ab7707f1a572e87cddad59a03b0964713
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 010b384..6a6a388 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -598,6 +598,7 @@
struct ClassExtOffsets : public CheckOffsets<mirror::ClassExt> {
ClassExtOffsets() : CheckOffsets<mirror::ClassExt>(false, "Ldalvik/system/ClassExt;") {
+ addOffset(OFFSETOF_MEMBER(mirror::ClassExt, class_value_map_), "classValueMap");
addOffset(OFFSETOF_MEMBER(mirror::ClassExt, erroneous_state_error_), "erroneousStateError");
addOffset(OFFSETOF_MEMBER(mirror::ClassExt, instance_jfield_ids_), "instanceJfieldIDs");
addOffset(OFFSETOF_MEMBER(mirror::ClassExt, jmethod_ids_), "jmethodIDs");
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 90efce5..4c08bdd 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -553,7 +553,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 + 67;
+ uint32_t vtable_entries = Object::kVTableLength + 68;
return ComputeClassSize(true, vtable_entries, 0, 0, 4, 1, 0, pointer_size);
}
diff --git a/runtime/mirror/class_ext.h b/runtime/mirror/class_ext.h
index 4ce3b10..b805ea0 100644
--- a/runtime/mirror/class_ext.h
+++ b/runtime/mirror/class_ext.h
@@ -156,6 +156,10 @@
bool EnsureJniIdsArrayPresent(MemberOffset off, size_t count)
REQUIRES_SHARED(Locks::mutator_lock_);
+ // Backing store of user-defined values pertaining to a class.
+ // Maintained by the ClassValue class.
+ HeapReference<Object> class_value_map_;
+
// The saved error for this class being erroneous.
HeapReference<Throwable> erroneous_state_error_;
@@ -181,9 +185,10 @@
// classes sfields_ array or '0' if no id has been assigned to that field yet.
HeapReference<PointerArray> static_jfield_ids_;
+ int32_t pre_redefine_class_def_index_;
+
// Native pointer to DexFile and ClassDef index of this class before it was JVMTI-redefined.
int64_t pre_redefine_dex_file_ptr_;
- int32_t pre_redefine_class_def_index_;
friend struct art::ClassExtOffsets; // for verifying offset information
DISALLOW_IMPLICIT_CONSTRUCTORS(ClassExt);
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index da42e61..9a2c88b 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -32,6 +32,7 @@
#include "hidden_api.h"
#include "jni/jni_internal.h"
#include "mirror/class-alloc-inl.h"
+#include "mirror/class_ext.h"
#include "mirror/class-inl.h"
#include "mirror/class_loader.h"
#include "mirror/field.h"
@@ -750,6 +751,17 @@
return soa.AddLocalReference<jclass>(annotations::GetDeclaringClass(klass));
}
+static jobject Class_ensureExtDataPresent(JNIEnv* env, jobject javaThis) {
+ ScopedFastNativeObjectAccess soa(env);
+ StackHandleScope<2> hs(soa.Self());
+ Handle<mirror::Class> klass = hs.NewHandle(DecodeClass(soa, javaThis));
+
+ ObjPtr<mirror::Object> extDataPtr =
+ mirror::Class::EnsureExtDataPresent(klass, Thread::Current());
+
+ return soa.AddLocalReference<jobject>(extDataPtr);
+}
+
static jobject Class_newInstance(JNIEnv* env, jobject javaThis) {
ScopedFastNativeObjectAccess soa(env);
StackHandleScope<4> hs(soa.Self());
@@ -841,6 +853,7 @@
static JNINativeMethod gMethods[] = {
FAST_NATIVE_METHOD(Class, classForName,
"(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"),
+ FAST_NATIVE_METHOD(Class, ensureExtDataPresent, "()Ldalvik/system/ClassExt;"),
FAST_NATIVE_METHOD(Class, getDeclaredAnnotation,
"(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"),
FAST_NATIVE_METHOD(Class, getDeclaredAnnotations, "()[Ljava/lang/annotation/Annotation;"),