diff options
author | Mathieu Chartier <mathieuc@google.com> | 2015-03-24 13:30:28 -0700 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2015-03-29 14:13:08 -0700 |
commit | daaf3265806eb2eadb2e03302bd68022fab5ca28 (patch) | |
tree | aff5d6d53d6d2b65995aa204839f88ee66400989 /runtime/class_linker_test.cc | |
parent | 68e22f3b982ff9ccbdfb3b65b7cfc16fcae907ba (diff) | |
download | art-daaf3265806eb2eadb2e03302bd68022fab5ca28.tar.gz art-daaf3265806eb2eadb2e03302bd68022fab5ca28.tar.bz2 art-daaf3265806eb2eadb2e03302bd68022fab5ca28.zip |
Add AccessibleObject and Field to mirror
Main motivation is to remove all the functionality / field access on
java side to ArtField. Also comes with some reflection speedups /
slowdowns.
Summary results:
getDeclaredField/getField are slower mostly due to JNI overhead.
However, there is a large speedup in getInt, setInt,
GetInstanceField, and GetStaticField.
Before timings (N5 --compiler-filter=everything):
benchmark ns linear runtime
Class_getDeclaredField 782.86 ===
Class_getField 832.77 ===
Field_getInt 160.17 =
Field_setInt 195.88 =
GetInstanceField 3214.38 ==============
GetStaticField 6809.49 ==============================
After:
Class_getDeclaredField 1068.15 ============
Class_getField 1180.00 ==============
Field_getInt 121.85 =
Field_setInt 139.98 =
GetInstanceField 1986.15 =======================
GetStaticField 2523.63 ==============================
Bug: 19264997
Change-Id: Ic0d0fc1b56b95cd6d60f8e76f19caeaa23045c77
Diffstat (limited to 'runtime/class_linker_test.cc')
-rw-r--r-- | runtime/class_linker_test.cc | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc index a895a494a1..3e727e7408 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -24,11 +24,13 @@ #include "dex_file.h" #include "entrypoints/entrypoint_utils-inl.h" #include "gc/heap.h" +#include "mirror/accessible_object.h" #include "mirror/art_field-inl.h" #include "mirror/art_method.h" #include "mirror/art_method-inl.h" #include "mirror/class-inl.h" #include "mirror/dex_cache.h" +#include "mirror/field.h" #include "mirror/object-inl.h" #include "mirror/object_array-inl.h" #include "mirror/proxy.h" @@ -177,7 +179,7 @@ class ClassLinkerTest : public CommonRuntimeTest { EXPECT_TRUE(field->GetClass() != nullptr); EXPECT_EQ(klass, field->GetDeclaringClass()); EXPECT_TRUE(field->GetName() != nullptr); - EXPECT_TRUE(field->GetType(true) != nullptr); + EXPECT_TRUE(field->GetType<true>() != nullptr); } void AssertClass(const std::string& descriptor, Handle<mirror::Class> klass) @@ -283,7 +285,7 @@ class ClassLinkerTest : public CommonRuntimeTest { for (size_t i = 0; i < klass->NumInstanceFields(); i++) { mirror::ArtField* field = klass->GetInstanceField(i); fhandle.Assign(field); - mirror::Class* field_type = fhandle->GetType(true); + mirror::Class* field_type = fhandle->GetType<true>(); ASSERT_TRUE(field_type != nullptr); if (!field->IsPrimitiveType()) { ASSERT_TRUE(!field_type->IsPrimitive()); @@ -394,7 +396,12 @@ struct CheckOffsets { // Art method have a different size due to the padding field. if (!klass->IsArtMethodClass() && !klass->IsClassClass() && !is_static) { - size_t expected_size = is_static ? klass->GetClassSize(): klass->GetObjectSize(); + // Currently only required for AccessibleObject since of the padding fields. The class linker + // says AccessibleObject is 9 bytes but sizeof(AccessibleObject) is 12 bytes due to padding. + // The RoundUp is to get around this case. + static constexpr size_t kPackAlignment = 4; + size_t expected_size = RoundUp(is_static ? klass->GetClassSize(): klass->GetObjectSize(), + kPackAlignment); if (sizeof(T) != expected_size) { LOG(ERROR) << "Class size mismatch:" << " class=" << class_descriptor @@ -596,6 +603,22 @@ struct FinalizerReferenceOffsets : public CheckOffsets<mirror::FinalizerReferenc }; }; +struct AccessibleObjectOffsets : public CheckOffsets<mirror::AccessibleObject> { + AccessibleObjectOffsets() : CheckOffsets<mirror::AccessibleObject>(false, "Ljava/lang/reflect/AccessibleObject;") { + offsets.push_back(CheckOffset(mirror::AccessibleObject::FlagOffset().Uint32Value(), "flag")); + }; +}; + +struct FieldOffsets : public CheckOffsets<mirror::Field> { + FieldOffsets() : CheckOffsets<mirror::Field>(false, "Ljava/lang/reflect/Field;") { + offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Field, access_flags_), "accessFlags")); + offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Field, declaring_class_), "declaringClass")); + offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Field, dex_field_index_), "dexFieldIndex")); + offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Field, offset_), "offset")); + offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Field, type_), "type")); + }; +}; + // C++ fields must exactly match the fields in the Java classes. If this fails, // reorder the fields in the C++ class. Managed class fields are ordered by // ClassLinker::LinkFields. @@ -613,6 +636,8 @@ TEST_F(ClassLinkerTest, ValidateFieldOrderOfJavaCppUnionClasses) { EXPECT_TRUE(DexCacheOffsets().Check()); EXPECT_TRUE(ReferenceOffsets().Check()); EXPECT_TRUE(FinalizerReferenceOffsets().Check()); + EXPECT_TRUE(AccessibleObjectOffsets().Check()); + EXPECT_TRUE(FieldOffsets().Check()); } TEST_F(ClassLinkerTest, FindClassNonexistent) { |