summaryrefslogtreecommitdiffstats
path: root/runtime/class_linker_test.cc
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2015-03-24 13:30:28 -0700
committerMathieu Chartier <mathieuc@google.com>2015-03-29 14:13:08 -0700
commitdaaf3265806eb2eadb2e03302bd68022fab5ca28 (patch)
treeaff5d6d53d6d2b65995aa204839f88ee66400989 /runtime/class_linker_test.cc
parent68e22f3b982ff9ccbdfb3b65b7cfc16fcae907ba (diff)
downloadart-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.cc31
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) {