diff options
author | Mathieu Chartier <mathieuc@google.com> | 2014-06-06 23:37:27 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-06-06 23:37:27 +0000 |
commit | 4479ba35389b03ccc9eabd17fba6168f9505517a (patch) | |
tree | fb8091b4637b27d8a9d3d4f390b79263a12d9881 | |
parent | 081203e06534e4aa27a942e47084289eecab29ed (diff) | |
parent | 61c5ebc6aee2cac1c363de6fbdac25ada1697fdb (diff) | |
download | art-4479ba35389b03ccc9eabd17fba6168f9505517a.tar.gz art-4479ba35389b03ccc9eabd17fba6168f9505517a.tar.bz2 art-4479ba35389b03ccc9eabd17fba6168f9505517a.zip |
Merge "Change FieldHelper to use a handle."
26 files changed, 327 insertions, 343 deletions
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h index 45abfcc895..324f7172a6 100644 --- a/compiler/driver/compiler_driver-inl.h +++ b/compiler/driver/compiler_driver-inl.h @@ -135,8 +135,10 @@ inline std::pair<bool, bool> CompilerDriver::IsFastStaticField( } else { // Search dex file for localized ssb index, may fail if field's class is a parent // of the class mentioned in the dex file and there is no dex cache entry. + StackHandleScope<1> hs(Thread::Current()); const DexFile::StringId* string_id = - dex_file->FindStringId(FieldHelper(resolved_field).GetDeclaringClassDescriptor()); + dex_file->FindStringId( + FieldHelper(hs.NewHandle(resolved_field)).GetDeclaringClassDescriptor()); if (string_id != nullptr) { const DexFile::TypeId* type_id = dex_file->FindTypeId(dex_file->GetIndexForStringId(*string_id)); diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 183f6672dc..d51179e25a 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -919,10 +919,11 @@ class ImageDumper { static void PrintField(std::ostream& os, mirror::ArtField* field, mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - FieldHelper fh(field); - const char* descriptor = fh.GetTypeDescriptor(); - os << StringPrintf("%s: ", fh.GetName()); + const char* descriptor = field->GetTypeDescriptor(); + os << StringPrintf("%s: ", field->GetName()); if (descriptor[0] != 'L' && descriptor[0] != '[') { + StackHandleScope<1> hs(Thread::Current()); + FieldHelper fh(hs.NewHandle(field)); mirror::Class* type = fh.GetType(); if (type->IsPrimitiveLong()) { os << StringPrintf("%" PRId64 " (0x%" PRIx64 ")\n", field->Get64(obj), field->Get64(obj)); @@ -942,6 +943,8 @@ class ImageDumper { os << StringPrintf("null %s\n", PrettyDescriptor(descriptor).c_str()); } else { // Grab the field type without causing resolution. + StackHandleScope<1> hs(Thread::Current()); + FieldHelper fh(hs.NewHandle(field)); mirror::Class* field_type = fh.GetType(false); if (field_type != NULL) { PrettyObjectValue(os, field_type, value); diff --git a/runtime/arch/stub_test.cc b/runtime/arch/stub_test.cc index 0b7f268c5e..56d51e20f2 100644 --- a/runtime/arch/stub_test.cc +++ b/runtime/arch/stub_test.cc @@ -1567,8 +1567,7 @@ static void TestFields(Thread* self, StubTest* test, Primitive::Type test_type) StackHandleScope<1> hs(self); Handle<mirror::ArtField> f(hs.NewHandle(fields->Get(i))); - FieldHelper fh(f.Get()); - Primitive::Type type = fh.GetTypeAsPrimitiveType(); + Primitive::Type type = f->GetTypeAsPrimitiveType(); switch (type) { case Primitive::Type::kPrimInt: if (test_type == type) { @@ -1584,7 +1583,7 @@ static void TestFields(Thread* self, StubTest* test, Primitive::Type test_type) case Primitive::Type::kPrimNot: // Don't try array. - if (test_type == type && fh.GetTypeDescriptor()[0] != '[') { + if (test_type == type && f->GetTypeDescriptor()[0] != '[') { GetSetObjStatic(&obj, &f, self, m.Get(), test); } break; @@ -1603,8 +1602,7 @@ static void TestFields(Thread* self, StubTest* test, Primitive::Type test_type) StackHandleScope<1> hs(self); Handle<mirror::ArtField> f(hs.NewHandle(fields->Get(i))); - FieldHelper fh(f.Get()); - Primitive::Type type = fh.GetTypeAsPrimitiveType(); + Primitive::Type type = f->GetTypeAsPrimitiveType(); switch (type) { case Primitive::Type::kPrimInt: if (test_type == type) { @@ -1620,7 +1618,7 @@ static void TestFields(Thread* self, StubTest* test, Primitive::Type test_type) case Primitive::Type::kPrimNot: // Don't try array. - if (test_type == type && fh.GetTypeDescriptor()[0] != '[') { + if (test_type == type && f->GetTypeDescriptor()[0] != '[') { GetSetObjInstance(&obj, &f, self, m.Get(), test); } break; diff --git a/runtime/check_jni.cc b/runtime/check_jni.cc index cfd0c007f1..46c4389d1d 100644 --- a/runtime/check_jni.cc +++ b/runtime/check_jni.cc @@ -195,8 +195,9 @@ class ScopedCheck { */ void CheckFieldType(jvalue value, jfieldID fid, char prim, bool isStatic) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - mirror::ArtField* f = CheckFieldID(fid); - if (f == nullptr) { + StackHandleScope<1> hs(Thread::Current()); + Handle<mirror::ArtField> f(hs.NewHandle(CheckFieldID(fid))); + if (f.Get() == nullptr) { return; } mirror::Class* field_type = FieldHelper(f).GetType(); @@ -215,22 +216,24 @@ class ScopedCheck { } else { if (!obj->InstanceOf(field_type)) { JniAbortF(function_name_, "attempt to set field %s with value of wrong type: %s", - PrettyField(f).c_str(), PrettyTypeOf(obj).c_str()); + PrettyField(f.Get()).c_str(), PrettyTypeOf(obj).c_str()); return; } } } } else if (field_type != Runtime::Current()->GetClassLinker()->FindPrimitiveClass(prim)) { JniAbortF(function_name_, "attempt to set field %s with value of wrong type: %c", - PrettyField(f).c_str(), prim); + PrettyField(f.Get()).c_str(), prim); return; } - if (isStatic != f->IsStatic()) { + if (isStatic != f.Get()->IsStatic()) { if (isStatic) { - JniAbortF(function_name_, "accessing non-static field %s as static", PrettyField(f).c_str()); + JniAbortF(function_name_, "accessing non-static field %s as static", + PrettyField(f.Get()).c_str()); } else { - JniAbortF(function_name_, "accessing static field %s as non-static", PrettyField(f).c_str()); + JniAbortF(function_name_, "accessing static field %s as non-static", + PrettyField(f.Get()).c_str()); } return; } @@ -256,8 +259,7 @@ class ScopedCheck { return; } mirror::Class* c = o->GetClass(); - FieldHelper fh(f); - if (c->FindInstanceField(fh.GetName(), fh.GetTypeDescriptor()) == nullptr) { + if (c->FindInstanceField(f->GetName(), f->GetTypeDescriptor()) == nullptr) { JniAbortF(function_name_, "jfieldID %s not valid for an object of class %s", PrettyField(f).c_str(), PrettyTypeOf(o).c_str()); } diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index b9c42ee111..330b110e90 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -502,29 +502,24 @@ void ClassLinker::FinishInit(Thread* self) { FindSystemClass(self, "Ljava/lang/ref/FinalizerReference;"); mirror::ArtField* pendingNext = java_lang_ref_Reference->GetInstanceField(0); - FieldHelper fh(pendingNext); - CHECK_STREQ(fh.GetName(), "pendingNext"); - CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/ref/Reference;"); + CHECK_STREQ(pendingNext->GetName(), "pendingNext"); + CHECK_STREQ(pendingNext->GetTypeDescriptor(), "Ljava/lang/ref/Reference;"); mirror::ArtField* queue = java_lang_ref_Reference->GetInstanceField(1); - fh.ChangeField(queue); - CHECK_STREQ(fh.GetName(), "queue"); - CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/ref/ReferenceQueue;"); + CHECK_STREQ(queue->GetName(), "queue"); + CHECK_STREQ(queue->GetTypeDescriptor(), "Ljava/lang/ref/ReferenceQueue;"); mirror::ArtField* queueNext = java_lang_ref_Reference->GetInstanceField(2); - fh.ChangeField(queueNext); - CHECK_STREQ(fh.GetName(), "queueNext"); - CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/ref/Reference;"); + CHECK_STREQ(queueNext->GetName(), "queueNext"); + CHECK_STREQ(queueNext->GetTypeDescriptor(), "Ljava/lang/ref/Reference;"); mirror::ArtField* referent = java_lang_ref_Reference->GetInstanceField(3); - fh.ChangeField(referent); - CHECK_STREQ(fh.GetName(), "referent"); - CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/Object;"); + CHECK_STREQ(referent->GetName(), "referent"); + CHECK_STREQ(referent->GetTypeDescriptor(), "Ljava/lang/Object;"); mirror::ArtField* zombie = java_lang_ref_FinalizerReference->GetInstanceField(2); - fh.ChangeField(zombie); - CHECK_STREQ(fh.GetName(), "zombie"); - CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/Object;"); + CHECK_STREQ(zombie->GetName(), "zombie"); + CHECK_STREQ(zombie->GetTypeDescriptor(), "Ljava/lang/Object;"); // ensure all class_roots_ are initialized for (size_t i = 0; i < kClassRootsMax; i++) { @@ -3896,10 +3891,8 @@ struct LinkFieldsComparator { bool operator()(mirror::ArtField* field1, mirror::ArtField* field2) NO_THREAD_SAFETY_ANALYSIS { // First come reference fields, then 64-bit, and finally 32-bit - FieldHelper fh1(field1); - Primitive::Type type1 = fh1.GetTypeAsPrimitiveType(); - FieldHelper fh2(field2); - Primitive::Type type2 = fh2.GetTypeAsPrimitiveType(); + Primitive::Type type1 = field1->GetTypeAsPrimitiveType(); + Primitive::Type type2 = field2->GetTypeAsPrimitiveType(); if (type1 != type2) { bool is_primitive1 = type1 != Primitive::kPrimNot; bool is_primitive2 = type2 != Primitive::kPrimNot; @@ -3914,9 +3907,7 @@ struct LinkFieldsComparator { } } // same basic group? then sort by string. - const char* name1 = fh1.GetName(); - const char* name2 = fh2.GetName(); - return strcmp(name1, name2) < 0; + return strcmp(field1->GetName(), field2->GetName()) < 0; } }; @@ -3961,8 +3952,7 @@ bool ClassLinker::LinkFields(Handle<mirror::Class> klass, bool is_static) { size_t num_reference_fields = 0; for (; current_field < num_fields; current_field++) { mirror::ArtField* field = grouped_and_sorted_fields.front(); - FieldHelper fh(field); - Primitive::Type type = fh.GetTypeAsPrimitiveType(); + Primitive::Type type = field->GetTypeAsPrimitiveType(); bool isPrimitive = type != Primitive::kPrimNot; if (isPrimitive) { break; // past last reference, move on to the next phase @@ -3980,8 +3970,7 @@ bool ClassLinker::LinkFields(Handle<mirror::Class> klass, bool is_static) { if (current_field != num_fields && !IsAligned<8>(field_offset.Uint32Value())) { for (size_t i = 0; i < grouped_and_sorted_fields.size(); i++) { mirror::ArtField* field = grouped_and_sorted_fields[i]; - FieldHelper fh(field); - Primitive::Type type = fh.GetTypeAsPrimitiveType(); + Primitive::Type type = field->GetTypeAsPrimitiveType(); CHECK(type != Primitive::kPrimNot) << PrettyField(field); // should be primitive types if (type == Primitive::kPrimLong || type == Primitive::kPrimDouble) { continue; @@ -4003,8 +3992,7 @@ bool ClassLinker::LinkFields(Handle<mirror::Class> klass, bool is_static) { while (!grouped_and_sorted_fields.empty()) { mirror::ArtField* field = grouped_and_sorted_fields.front(); grouped_and_sorted_fields.pop_front(); - FieldHelper fh(field); - Primitive::Type type = fh.GetTypeAsPrimitiveType(); + Primitive::Type type = field->GetTypeAsPrimitiveType(); CHECK(type != Primitive::kPrimNot) << PrettyField(field); // should be primitive types fields->Set<false>(current_field, field); field->SetOffset(field_offset); @@ -4020,8 +4008,7 @@ bool ClassLinker::LinkFields(Handle<mirror::Class> klass, bool is_static) { // We know there are no non-reference fields in the Reference classes, and we know // that 'referent' is alphabetically last, so this is easy... CHECK_EQ(num_reference_fields, num_fields) << PrettyClass(klass.Get()); - FieldHelper fh(fields->Get(num_fields - 1)); - CHECK_STREQ(fh.GetName(), "referent") << PrettyClass(klass.Get()); + CHECK_STREQ(fields->Get(num_fields - 1)->GetName(), "referent") << PrettyClass(klass.Get()); --num_reference_fields; } @@ -4038,11 +4025,10 @@ bool ClassLinker::LinkFields(Handle<mirror::Class> klass, bool is_static) { << " offset=" << field->GetField32(MemberOffset(mirror::ArtField::OffsetOffset())); } - FieldHelper fh(field); - Primitive::Type type = fh.GetTypeAsPrimitiveType(); + Primitive::Type type = field->GetTypeAsPrimitiveType(); bool is_primitive = type != Primitive::kPrimNot; if (klass->DescriptorEquals("Ljava/lang/ref/Reference;") && - strcmp("referent", fh.GetName()) == 0) { + strcmp("referent", field->GetName()) == 0) { is_primitive = true; // We lied above, so we have to expect a lie here. } if (is_primitive) { diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc index e397a5ce30..45ab33a7f3 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -171,11 +171,12 @@ class ClassLinkerTest : public CommonRuntimeTest { void AssertField(mirror::Class* klass, mirror::ArtField* field) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - FieldHelper fh(field); EXPECT_TRUE(field != NULL); EXPECT_TRUE(field->GetClass() != NULL); EXPECT_EQ(klass, field->GetDeclaringClass()); - EXPECT_TRUE(fh.GetName() != NULL); + EXPECT_TRUE(field->GetName() != NULL); + StackHandleScope<1> hs(Thread::Current()); + FieldHelper fh(hs.NewHandle(field)); EXPECT_TRUE(fh.GetType() != NULL); } @@ -269,11 +270,12 @@ class ClassLinkerTest : public CommonRuntimeTest { // Confirm that all instances fields are packed together at the start EXPECT_GE(klass->NumInstanceFields(), klass->NumReferenceInstanceFields()); - FieldHelper fh; + StackHandleScope<1> hs(Thread::Current()); + FieldHelper fh(hs.NewHandle<mirror::ArtField>(nullptr)); for (size_t i = 0; i < klass->NumReferenceInstanceFields(); i++) { mirror::ArtField* field = klass->GetInstanceField(i); fh.ChangeField(field); - ASSERT_TRUE(!fh.IsPrimitiveType()); + ASSERT_TRUE(!field->IsPrimitiveType()); mirror::Class* field_type = fh.GetType(); ASSERT_TRUE(field_type != NULL); ASSERT_TRUE(!field_type->IsPrimitive()); @@ -283,10 +285,10 @@ class ClassLinkerTest : public CommonRuntimeTest { fh.ChangeField(field); mirror::Class* field_type = fh.GetType(); ASSERT_TRUE(field_type != NULL); - if (!fh.IsPrimitiveType() || !field_type->IsPrimitive()) { + if (!fh.GetField()->IsPrimitiveType() || !field_type->IsPrimitive()) { // While Reference.referent is not primitive, the ClassLinker // treats it as such so that the garbage collector won't scan it. - EXPECT_EQ(PrettyField(field), "java.lang.Object java.lang.ref.Reference.referent"); + EXPECT_EQ(PrettyField(fh.GetField()), "java.lang.Object java.lang.ref.Reference.referent"); } } @@ -390,11 +392,9 @@ struct CheckOffsets { error = true; } - FieldHelper fh; for (size_t i = 0; i < offsets.size(); i++) { mirror::ArtField* field = is_static ? klass->GetStaticField(i) : klass->GetInstanceField(i); - fh.ChangeField(field); - StringPiece field_name(fh.GetName()); + StringPiece field_name(field->GetName()); if (field_name != offsets[i].java_name) { error = true; } @@ -403,8 +403,7 @@ struct CheckOffsets { for (size_t i = 0; i < offsets.size(); i++) { CheckOffset& offset = offsets[i]; mirror::ArtField* field = is_static ? klass->GetStaticField(i) : klass->GetInstanceField(i); - fh.ChangeField(field); - StringPiece field_name(fh.GetName()); + StringPiece field_name(field->GetName()); if (field_name != offsets[i].java_name) { LOG(ERROR) << "JAVA FIELD ORDER MISMATCH NEXT LINE:"; } @@ -731,15 +730,11 @@ TEST_F(ClassLinkerTest, FindClass) { } else { EXPECT_EQ(4U, JavaLangObject->NumInstanceFields()); } - FieldHelper fh(JavaLangObject->GetInstanceField(0)); - EXPECT_STREQ(fh.GetName(), "shadow$_klass_"); - fh.ChangeField(JavaLangObject->GetInstanceField(1)); - EXPECT_STREQ(fh.GetName(), "shadow$_monitor_"); + EXPECT_STREQ(JavaLangObject->GetInstanceField(0)->GetName(), "shadow$_klass_"); + EXPECT_STREQ(JavaLangObject->GetInstanceField(1)->GetName(), "shadow$_monitor_"); if (kUseBakerOrBrooksReadBarrier) { - fh.ChangeField(JavaLangObject->GetInstanceField(2)); - EXPECT_STREQ(fh.GetName(), "shadow$_x_rb_ptr_"); - fh.ChangeField(JavaLangObject->GetInstanceField(3)); - EXPECT_STREQ(fh.GetName(), "shadow$_x_xpadding_"); + EXPECT_STREQ(JavaLangObject->GetInstanceField(2)->GetName(), "shadow$_x_rb_ptr_"); + EXPECT_STREQ(JavaLangObject->GetInstanceField(3)->GetName(), "shadow$_x_xpadding_"); } EXPECT_EQ(0U, JavaLangObject->NumStaticFields()); @@ -850,29 +845,21 @@ TEST_F(ClassLinkerTest, ValidateBoxedTypes) { NullHandle<mirror::ClassLoader> class_loader; mirror::Class* c; c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Boolean;", class_loader); - FieldHelper fh(c->GetIFields()->Get(0)); - EXPECT_STREQ("value", fh.GetName()); + EXPECT_STREQ("value", c->GetIFields()->Get(0)->GetName()); c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Byte;", class_loader); - fh.ChangeField(c->GetIFields()->Get(0)); - EXPECT_STREQ("value", fh.GetName()); + EXPECT_STREQ("value", c->GetIFields()->Get(0)->GetName()); c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Character;", class_loader); - fh.ChangeField(c->GetIFields()->Get(0)); - EXPECT_STREQ("value", fh.GetName()); + EXPECT_STREQ("value", c->GetIFields()->Get(0)->GetName()); c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Double;", class_loader); - fh.ChangeField(c->GetIFields()->Get(0)); - EXPECT_STREQ("value", fh.GetName()); + EXPECT_STREQ("value", c->GetIFields()->Get(0)->GetName()); c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Float;", class_loader); - fh.ChangeField(c->GetIFields()->Get(0)); - EXPECT_STREQ("value", fh.GetName()); + EXPECT_STREQ("value", c->GetIFields()->Get(0)->GetName()); c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Integer;", class_loader); - fh.ChangeField(c->GetIFields()->Get(0)); - EXPECT_STREQ("value", fh.GetName()); + EXPECT_STREQ("value", c->GetIFields()->Get(0)->GetName()); c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Long;", class_loader); - fh.ChangeField(c->GetIFields()->Get(0)); - EXPECT_STREQ("value", fh.GetName()); + EXPECT_STREQ("value", c->GetIFields()->Get(0)->GetName()); c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Short;", class_loader); - fh.ChangeField(c->GetIFields()->Get(0)); - EXPECT_STREQ("value", fh.GetName()); + EXPECT_STREQ("value", c->GetIFields()->Get(0)->GetName()); } TEST_F(ClassLinkerTest, TwoClassLoadersOneClass) { @@ -907,58 +894,49 @@ TEST_F(ClassLinkerTest, StaticFields) { EXPECT_EQ(9U, statics->NumStaticFields()); mirror::ArtField* s0 = mirror::Class::FindStaticField(soa.Self(), statics, "s0", "Z"); - FieldHelper fh(s0); EXPECT_STREQ(s0->GetClass()->GetDescriptor().c_str(), "Ljava/lang/reflect/ArtField;"); - EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimBoolean); + EXPECT_EQ(s0->GetTypeAsPrimitiveType(), Primitive::kPrimBoolean); EXPECT_EQ(true, s0->GetBoolean(statics.Get())); s0->SetBoolean<false>(statics.Get(), false); mirror::ArtField* s1 = mirror::Class::FindStaticField(soa.Self(), statics, "s1", "B"); - fh.ChangeField(s1); - EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimByte); + EXPECT_EQ(s1->GetTypeAsPrimitiveType(), Primitive::kPrimByte); EXPECT_EQ(5, s1->GetByte(statics.Get())); s1->SetByte<false>(statics.Get(), 6); mirror::ArtField* s2 = mirror::Class::FindStaticField(soa.Self(), statics, "s2", "C"); - fh.ChangeField(s2); - EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimChar); + EXPECT_EQ(s2->GetTypeAsPrimitiveType(), Primitive::kPrimChar); EXPECT_EQ('a', s2->GetChar(statics.Get())); s2->SetChar<false>(statics.Get(), 'b'); mirror::ArtField* s3 = mirror::Class::FindStaticField(soa.Self(), statics, "s3", "S"); - fh.ChangeField(s3); - EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimShort); + EXPECT_EQ(s3->GetTypeAsPrimitiveType(), Primitive::kPrimShort); EXPECT_EQ(-536, s3->GetShort(statics.Get())); s3->SetShort<false>(statics.Get(), -535); mirror::ArtField* s4 = mirror::Class::FindStaticField(soa.Self(), statics, "s4", "I"); - fh.ChangeField(s4); - EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimInt); + EXPECT_EQ(s4->GetTypeAsPrimitiveType(), Primitive::kPrimInt); EXPECT_EQ(2000000000, s4->GetInt(statics.Get())); s4->SetInt<false>(statics.Get(), 2000000001); mirror::ArtField* s5 = mirror::Class::FindStaticField(soa.Self(), statics, "s5", "J"); - fh.ChangeField(s5); - EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimLong); + EXPECT_EQ(s5->GetTypeAsPrimitiveType(), Primitive::kPrimLong); EXPECT_EQ(0x1234567890abcdefLL, s5->GetLong(statics.Get())); s5->SetLong<false>(statics.Get(), INT64_C(0x34567890abcdef12)); mirror::ArtField* s6 = mirror::Class::FindStaticField(soa.Self(), statics, "s6", "F"); - fh.ChangeField(s6); - EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimFloat); + EXPECT_EQ(s6->GetTypeAsPrimitiveType(), Primitive::kPrimFloat); EXPECT_EQ(0.5, s6->GetFloat(statics.Get())); s6->SetFloat<false>(statics.Get(), 0.75); mirror::ArtField* s7 = mirror::Class::FindStaticField(soa.Self(), statics, "s7", "D"); - fh.ChangeField(s7); - EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimDouble); + EXPECT_EQ(s7->GetTypeAsPrimitiveType(), Primitive::kPrimDouble); EXPECT_EQ(16777217, s7->GetDouble(statics.Get())); s7->SetDouble<false>(statics.Get(), 16777219); mirror::ArtField* s8 = mirror::Class::FindStaticField(soa.Self(), statics, "s8", "Ljava/lang/String;"); - fh.ChangeField(s8); - EXPECT_TRUE(fh.GetTypeAsPrimitiveType() == Primitive::kPrimNot); + EXPECT_EQ(s8->GetTypeAsPrimitiveType(), Primitive::kPrimNot); EXPECT_TRUE(s8->GetObject(statics.Get())->AsString()->Equals("android")); s8->SetObject<false>(s8->GetDeclaringClass(), mirror::String::AllocFromModifiedUtf8(soa.Self(), "robot")); diff --git a/runtime/debugger.cc b/runtime/debugger.cc index 07cb9d17f4..8e2340c7a3 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -1378,8 +1378,7 @@ std::string Dbg::GetMethodName(JDWP::MethodId method_id) std::string Dbg::GetFieldName(JDWP::FieldId field_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - mirror::ArtField* f = FromFieldId(field_id); - return FieldHelper(f).GetName(); + return FromFieldId(field_id)->GetName(); } /* @@ -1454,10 +1453,9 @@ JDWP::JdwpError Dbg::OutputDeclaredFields(JDWP::RefTypeId class_id, bool with_ge for (size_t i = 0; i < instance_field_count + static_field_count; ++i) { mirror::ArtField* f = (i < instance_field_count) ? c->GetInstanceField(i) : c->GetStaticField(i - instance_field_count); - FieldHelper fh(f); expandBufAddFieldId(pReply, ToFieldId(f)); - expandBufAddUtf8String(pReply, fh.GetName()); - expandBufAddUtf8String(pReply, fh.GetTypeDescriptor()); + expandBufAddUtf8String(pReply, f->GetName()); + expandBufAddUtf8String(pReply, f->GetTypeDescriptor()); if (with_generic) { static const char genericSignature[1] = ""; expandBufAddUtf8String(pReply, genericSignature); @@ -1623,7 +1621,7 @@ void Dbg::OutputMethodReturnValue(JDWP::MethodId method_id, const JValue* return void Dbg::OutputFieldValue(JDWP::FieldId field_id, const JValue* field_value, JDWP::ExpandBuf* pReply) { mirror::ArtField* f = FromFieldId(field_id); - JDWP::JdwpTag tag = BasicTagFromDescriptor(FieldHelper(f).GetTypeDescriptor()); + JDWP::JdwpTag tag = BasicTagFromDescriptor(f->GetTypeDescriptor()); OutputJValue(tag, field_value, pReply); } @@ -1646,11 +1644,11 @@ JDWP::JdwpError Dbg::GetBytecodes(JDWP::RefTypeId, JDWP::MethodId method_id, } JDWP::JdwpTag Dbg::GetFieldBasicTag(JDWP::FieldId field_id) { - return BasicTagFromDescriptor(FieldHelper(FromFieldId(field_id)).GetTypeDescriptor()); + return BasicTagFromDescriptor(FromFieldId(field_id)->GetTypeDescriptor()); } JDWP::JdwpTag Dbg::GetStaticFieldBasicTag(JDWP::FieldId field_id) { - return BasicTagFromDescriptor(FieldHelper(FromFieldId(field_id)).GetTypeDescriptor()); + return BasicTagFromDescriptor(FromFieldId(field_id)->GetTypeDescriptor()); } static JDWP::JdwpError GetFieldValueImpl(JDWP::RefTypeId ref_type_id, JDWP::ObjectId object_id, @@ -1694,7 +1692,7 @@ static JDWP::JdwpError GetFieldValueImpl(JDWP::RefTypeId ref_type_id, JDWP::Obje o = f->GetDeclaringClass(); } - JDWP::JdwpTag tag = BasicTagFromDescriptor(FieldHelper(f).GetTypeDescriptor()); + JDWP::JdwpTag tag = BasicTagFromDescriptor(f->GetTypeDescriptor()); JValue field_value; if (tag == JDWP::JT_VOID) { LOG(FATAL) << "Unknown tag: " << tag; @@ -1743,7 +1741,7 @@ static JDWP::JdwpError SetFieldValueImpl(JDWP::ObjectId object_id, JDWP::FieldId o = f->GetDeclaringClass(); } - JDWP::JdwpTag tag = BasicTagFromDescriptor(FieldHelper(f).GetTypeDescriptor()); + JDWP::JdwpTag tag = BasicTagFromDescriptor(f->GetTypeDescriptor()); if (IsPrimitiveTag(tag)) { if (tag == JDWP::JT_DOUBLE || tag == JDWP::JT_LONG) { @@ -1761,7 +1759,14 @@ static JDWP::JdwpError SetFieldValueImpl(JDWP::ObjectId object_id, JDWP::FieldId return JDWP::ERR_INVALID_OBJECT; } if (v != NULL) { - mirror::Class* field_type = FieldHelper(f).GetType(); + mirror::Class* field_type; + { + StackHandleScope<3> hs(Thread::Current()); + HandleWrapper<mirror::Object> h_v(hs.NewHandleWrapper(&v)); + HandleWrapper<mirror::ArtField> h_f(hs.NewHandleWrapper(&f)); + HandleWrapper<mirror::Object> h_o(hs.NewHandleWrapper(&o)); + field_type = FieldHelper(h_f).GetType(); + } if (!field_type->IsAssignableFrom(v->GetClass())) { return JDWP::ERR_INVALID_OBJECT; } diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h index 58b4286c30..d0ae746b20 100644 --- a/runtime/entrypoints/entrypoint_utils.h +++ b/runtime/entrypoints/entrypoint_utils.h @@ -327,8 +327,8 @@ static inline mirror::ArtField* FindFieldFromCode(uint32_t field_idx, mirror::Ar ThrowIllegalAccessErrorFinalField(referrer, resolved_field); return nullptr; // Failure. } else { - FieldHelper fh(resolved_field); - if (UNLIKELY(fh.IsPrimitiveType() != is_primitive || fh.FieldSize() != expected_size)) { + if (UNLIKELY(resolved_field->IsPrimitiveType() != is_primitive || + resolved_field->FieldSize() != expected_size)) { ThrowLocation throw_location = self->GetCurrentLocationForThrow(); DCHECK(throw_location.GetMethod() == referrer); self->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchFieldError;", @@ -553,9 +553,8 @@ static inline mirror::ArtField* FindFieldFast(uint32_t field_idx, // Illegal access. return NULL; } - FieldHelper fh(resolved_field); - if (UNLIKELY(fh.IsPrimitiveType() != is_primitive || - fh.FieldSize() != expected_size)) { + if (UNLIKELY(resolved_field->IsPrimitiveType() != is_primitive || + resolved_field->FieldSize() != expected_size)) { return NULL; } return resolved_field; diff --git a/runtime/entrypoints/quick/quick_field_entrypoints.cc b/runtime/entrypoints/quick/quick_field_entrypoints.cc index 844367d2cb..3178cdea03 100644 --- a/runtime/entrypoints/quick/quick_field_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_field_entrypoints.cc @@ -197,7 +197,7 @@ extern "C" int artSetObjStaticFromCode(uint32_t field_idx, mirror::Object* new_v mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectWrite, sizeof(mirror::HeapReference<mirror::Object>)); if (LIKELY(field != NULL)) { - if (LIKELY(!FieldHelper(field).IsPrimitiveType())) { + if (LIKELY(!field->IsPrimitiveType())) { // Compiled code can't use transactional mode. field->SetObj<false>(field->GetDeclaringClass(), new_value); return 0; // success @@ -226,8 +226,12 @@ extern "C" int artSet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj, return 0; // success } FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); - field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, self, - sizeof(int32_t)); + { + StackHandleScope<1> hs(self); + HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(&obj)); + field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, self, + sizeof(int32_t)); + } if (LIKELY(field != NULL)) { if (UNLIKELY(obj == NULL)) { ThrowLocation throw_location = self->GetCurrentLocationForThrow(); diff --git a/runtime/gc/accounting/space_bitmap.cc b/runtime/gc/accounting/space_bitmap.cc index 436a5b5fd6..c294bae4a3 100644 --- a/runtime/gc/accounting/space_bitmap.cc +++ b/runtime/gc/accounting/space_bitmap.cc @@ -186,11 +186,10 @@ void SpaceBitmap<kAlignment>::WalkInstanceFields(SpaceBitmap<kAlignment>* visite if (fields != NULL) { for (int32_t i = 0; i < fields->GetLength(); i++) { mirror::ArtField* field = fields->Get(i); - FieldHelper fh(field); - if (!fh.IsPrimitiveType()) { + if (!field->IsPrimitiveType()) { mirror::Object* value = field->GetObj(obj); if (value != NULL) { - WalkFieldsInOrder(visited, callback, value, arg); + WalkFieldsInOrder(visited, callback, value, arg); } } } @@ -216,8 +215,7 @@ void SpaceBitmap<kAlignment>::WalkFieldsInOrder(SpaceBitmap<kAlignment>* visited if (fields != NULL) { for (int32_t i = 0; i < fields->GetLength(); i++) { mirror::ArtField* field = fields->Get(i); - FieldHelper fh(field); - if (!fh.IsPrimitiveType()) { + if (!field->IsPrimitiveType()) { mirror::Object* value = field->GetObj(NULL); if (value != NULL) { WalkFieldsInOrder(visited, callback, value, arg); diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc index 91f1718559..33339f8f6c 100644 --- a/runtime/hprof/hprof.cc +++ b/runtime/hprof/hprof.cc @@ -919,8 +919,6 @@ int Hprof::DumpHeapObject(mirror::Object* obj) { rec->AddU2(0); // empty const pool - FieldHelper fh; - // Static fields if (sFieldCount == 0) { rec->AddU2((uint16_t)0); @@ -932,11 +930,10 @@ int Hprof::DumpHeapObject(mirror::Object* obj) { for (size_t i = 0; i < sFieldCount; ++i) { mirror::ArtField* f = thisClass->GetStaticField(i); - fh.ChangeField(f); size_t size; - HprofBasicType t = SignatureToBasicTypeAndSize(fh.GetTypeDescriptor(), &size); - rec->AddStringId(LookupStringId(fh.GetName())); + HprofBasicType t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), &size); + rec->AddStringId(LookupStringId(f->GetName())); rec->AddU1(t); if (size == 1) { rec->AddU1(static_cast<uint8_t>(f->Get32(thisClass))); @@ -957,9 +954,8 @@ int Hprof::DumpHeapObject(mirror::Object* obj) { rec->AddU2((uint16_t)iFieldCount); for (int i = 0; i < iFieldCount; ++i) { mirror::ArtField* f = thisClass->GetInstanceField(i); - fh.ChangeField(f); - HprofBasicType t = SignatureToBasicTypeAndSize(fh.GetTypeDescriptor(), NULL); - rec->AddStringId(LookupStringId(fh.GetName())); + HprofBasicType t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), NULL); + rec->AddStringId(LookupStringId(f->GetName())); rec->AddU1(t); } } else if (c->IsArrayClass()) { @@ -1015,14 +1011,12 @@ int Hprof::DumpHeapObject(mirror::Object* obj) { // Write the instance data; fields for this class, followed by super class fields, // and so on. Don't write the klass or monitor fields of Object.class. mirror::Class* sclass = c; - FieldHelper fh; while (!sclass->IsObjectClass()) { int ifieldCount = sclass->NumInstanceFields(); for (int i = 0; i < ifieldCount; ++i) { mirror::ArtField* f = sclass->GetInstanceField(i); - fh.ChangeField(f); size_t size; - SignatureToBasicTypeAndSize(fh.GetTypeDescriptor(), &size); + SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), &size); if (size == 1) { rec->AddU1(f->Get32(obj)); } else if (size == 2) { diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index 19b85e43a2..a66bd94ede 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -334,12 +334,10 @@ static void UnstartedRuntimeInvoke(Thread* self, MethodHelper& mh, Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass(); String* name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString(); ArtField* found = NULL; - FieldHelper fh; ObjectArray<ArtField>* fields = klass->GetIFields(); for (int32_t i = 0; i < fields->GetLength() && found == NULL; ++i) { ArtField* f = fields->Get(i); - fh.ChangeField(f); - if (name->Equals(fh.GetName())) { + if (name->Equals(f->GetName())) { found = f; } } @@ -347,8 +345,7 @@ static void UnstartedRuntimeInvoke(Thread* self, MethodHelper& mh, fields = klass->GetSFields(); for (int32_t i = 0; i < fields->GetLength() && found == NULL; ++i) { ArtField* f = fields->Get(i); - fh.ChangeField(f); - if (name->Equals(fh.GetName())) { + if (name->Equals(f->GetName())) { found = f; } } diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h index 029af8d88c..6e136d62c3 100644 --- a/runtime/interpreter/interpreter_common.h +++ b/runtime/interpreter/interpreter_common.h @@ -363,9 +363,15 @@ static SOMETIMES_INLINE_KEYWORD bool DoFieldPut(Thread* self, const ShadowFrame& if (do_assignability_check && reg != nullptr) { // FieldHelper::GetType can resolve classes, use a handle wrapper which will restore the // object in the destructor. - StackHandleScope<1> hs(self); - HandleWrapper<mirror::Object> wrapper(hs.NewHandleWrapper(&obj)); - Class* field_class = FieldHelper(f).GetType(); + Class* field_class; + { + StackHandleScope<3> hs(self); + HandleWrapper<mirror::ArtField> h_f(hs.NewHandleWrapper(&f)); + HandleWrapper<mirror::Object> h_reg(hs.NewHandleWrapper(®)); + HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(&obj)); + FieldHelper fh(h_f); + field_class = fh.GetType(); + } if (!reg->VerifierInstanceOf(field_class)) { // This should never happen. self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(), diff --git a/runtime/mirror/art_field-inl.h b/runtime/mirror/art_field-inl.h index ad24d0a551..686fded404 100644 --- a/runtime/mirror/art_field-inl.h +++ b/runtime/mirror/art_field-inl.h @@ -116,60 +116,52 @@ inline void ArtField::SetObj(Object* object, Object* new_value) { } inline bool ArtField::GetBoolean(Object* object) { - DCHECK_EQ(Primitive::kPrimBoolean, FieldHelper(this).GetTypeAsPrimitiveType()) - << PrettyField(this); + DCHECK_EQ(Primitive::kPrimBoolean, GetTypeAsPrimitiveType()) << PrettyField(this); return Get32(object); } template<bool kTransactionActive> inline void ArtField::SetBoolean(Object* object, bool z) { - DCHECK_EQ(Primitive::kPrimBoolean, FieldHelper(this).GetTypeAsPrimitiveType()) - << PrettyField(this); + DCHECK_EQ(Primitive::kPrimBoolean, GetTypeAsPrimitiveType()) << PrettyField(this); Set32<kTransactionActive>(object, z); } inline int8_t ArtField::GetByte(Object* object) { - DCHECK_EQ(Primitive::kPrimByte, FieldHelper(this).GetTypeAsPrimitiveType()) - << PrettyField(this); + DCHECK_EQ(Primitive::kPrimByte, GetTypeAsPrimitiveType()) << PrettyField(this); return Get32(object); } template<bool kTransactionActive> inline void ArtField::SetByte(Object* object, int8_t b) { - DCHECK_EQ(Primitive::kPrimByte, FieldHelper(this).GetTypeAsPrimitiveType()) - << PrettyField(this); + DCHECK_EQ(Primitive::kPrimByte, GetTypeAsPrimitiveType()) << PrettyField(this); Set32<kTransactionActive>(object, b); } inline uint16_t ArtField::GetChar(Object* object) { - DCHECK_EQ(Primitive::kPrimChar, FieldHelper(this).GetTypeAsPrimitiveType()) - << PrettyField(this); + DCHECK_EQ(Primitive::kPrimChar, GetTypeAsPrimitiveType()) << PrettyField(this); return Get32(object); } template<bool kTransactionActive> inline void ArtField::SetChar(Object* object, uint16_t c) { - DCHECK_EQ(Primitive::kPrimChar, FieldHelper(this).GetTypeAsPrimitiveType()) - << PrettyField(this); + DCHECK_EQ(Primitive::kPrimChar, GetTypeAsPrimitiveType()) << PrettyField(this); Set32<kTransactionActive>(object, c); } inline int16_t ArtField::GetShort(Object* object) { - DCHECK_EQ(Primitive::kPrimShort, FieldHelper(this).GetTypeAsPrimitiveType()) - << PrettyField(this); + DCHECK_EQ(Primitive::kPrimShort, GetTypeAsPrimitiveType()) << PrettyField(this); return Get32(object); } template<bool kTransactionActive> inline void ArtField::SetShort(Object* object, int16_t s) { - DCHECK_EQ(Primitive::kPrimShort, FieldHelper(this).GetTypeAsPrimitiveType()) - << PrettyField(this); + DCHECK_EQ(Primitive::kPrimShort, GetTypeAsPrimitiveType()) << PrettyField(this); Set32<kTransactionActive>(object, s); } inline int32_t ArtField::GetInt(Object* object) { if (kIsDebugBuild) { - Primitive::Type type = FieldHelper(this).GetTypeAsPrimitiveType(); + Primitive::Type type = GetTypeAsPrimitiveType(); CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this); } return Get32(object); @@ -178,7 +170,7 @@ inline int32_t ArtField::GetInt(Object* object) { template<bool kTransactionActive> inline void ArtField::SetInt(Object* object, int32_t i) { if (kIsDebugBuild) { - Primitive::Type type = FieldHelper(this).GetTypeAsPrimitiveType(); + Primitive::Type type = GetTypeAsPrimitiveType(); CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this); } Set32<kTransactionActive>(object, i); @@ -186,7 +178,7 @@ inline void ArtField::SetInt(Object* object, int32_t i) { inline int64_t ArtField::GetLong(Object* object) { if (kIsDebugBuild) { - Primitive::Type type = FieldHelper(this).GetTypeAsPrimitiveType(); + Primitive::Type type = GetTypeAsPrimitiveType(); CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this); } return Get64(object); @@ -195,15 +187,14 @@ inline int64_t ArtField::GetLong(Object* object) { template<bool kTransactionActive> inline void ArtField::SetLong(Object* object, int64_t j) { if (kIsDebugBuild) { - Primitive::Type type = FieldHelper(this).GetTypeAsPrimitiveType(); + Primitive::Type type = GetTypeAsPrimitiveType(); CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this); } Set64<kTransactionActive>(object, j); } inline float ArtField::GetFloat(Object* object) { - DCHECK_EQ(Primitive::kPrimFloat, FieldHelper(this).GetTypeAsPrimitiveType()) - << PrettyField(this); + DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField(this); JValue bits; bits.SetI(Get32(object)); return bits.GetF(); @@ -211,16 +202,14 @@ inline float ArtField::GetFloat(Object* object) { template<bool kTransactionActive> inline void ArtField::SetFloat(Object* object, float f) { - DCHECK_EQ(Primitive::kPrimFloat, FieldHelper(this).GetTypeAsPrimitiveType()) - << PrettyField(this); + DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField(this); JValue bits; bits.SetF(f); Set32<kTransactionActive>(object, bits.GetI()); } inline double ArtField::GetDouble(Object* object) { - DCHECK_EQ(Primitive::kPrimDouble, FieldHelper(this).GetTypeAsPrimitiveType()) - << PrettyField(this); + DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField(this); JValue bits; bits.SetJ(Get64(object)); return bits.GetD(); @@ -228,26 +217,68 @@ inline double ArtField::GetDouble(Object* object) { template<bool kTransactionActive> inline void ArtField::SetDouble(Object* object, double d) { - DCHECK_EQ(Primitive::kPrimDouble, FieldHelper(this).GetTypeAsPrimitiveType()) - << PrettyField(this); + DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField(this); JValue bits; bits.SetD(d); Set64<kTransactionActive>(object, bits.GetJ()); } inline Object* ArtField::GetObject(Object* object) { - DCHECK_EQ(Primitive::kPrimNot, FieldHelper(this).GetTypeAsPrimitiveType()) - << PrettyField(this); + DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField(this); return GetObj(object); } template<bool kTransactionActive> inline void ArtField::SetObject(Object* object, Object* l) { - DCHECK_EQ(Primitive::kPrimNot, FieldHelper(this).GetTypeAsPrimitiveType()) - << PrettyField(this); + DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField(this); SetObj<kTransactionActive>(object, l); } +inline const char* ArtField::GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + uint32_t field_index = GetDexFieldIndex(); + if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) { + DCHECK(IsStatic()); + DCHECK_LT(field_index, 2U); + return field_index == 0 ? "interfaces" : "throws"; + } + const DexFile* dex_file = GetDexFile(); + return dex_file->GetFieldName(dex_file->GetFieldId(field_index)); +} + +inline const char* ArtField::GetTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + uint32_t field_index = GetDexFieldIndex(); + if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) { + DCHECK(IsStatic()); + DCHECK_LT(field_index, 2U); + // 0 == Class[] interfaces; 1 == Class[][] throws; + return field_index == 0 ? "[Ljava/lang/Class;" : "[[Ljava/lang/Class;"; + } + const DexFile* dex_file = GetDexFile(); + const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index); + return dex_file->GetFieldTypeDescriptor(field_id); +} + +inline Primitive::Type ArtField::GetTypeAsPrimitiveType() + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + return Primitive::GetType(GetTypeDescriptor()[0]); +} + +inline bool ArtField::IsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + return GetTypeAsPrimitiveType() != Primitive::kPrimNot; +} + +inline size_t ArtField::FieldSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + return Primitive::FieldSize(GetTypeAsPrimitiveType()); +} + +inline mirror::DexCache* ArtField::GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + return GetDeclaringClass()->GetDexCache(); +} + +inline const DexFile* ArtField::GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + return GetDexCache()->GetDexFile(); +} + } // namespace mirror } // namespace art diff --git a/runtime/mirror/art_field.cc b/runtime/mirror/art_field.cc index b3b1b71e5b..f2729f660e 100644 --- a/runtime/mirror/art_field.cc +++ b/runtime/mirror/art_field.cc @@ -55,7 +55,7 @@ void ArtField::SetOffset(MemberOffset num_bytes) { DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous()); if (kIsDebugBuild && Runtime::Current()->IsCompiler() && !Runtime::Current()->UseCompileTimeClassPath()) { - Primitive::Type type = FieldHelper(this).GetTypeAsPrimitiveType(); + Primitive::Type type = GetTypeAsPrimitiveType(); if (type == Primitive::kPrimDouble || type == Primitive::kPrimLong) { DCHECK_ALIGNED(num_bytes.Uint32Value(), 8); } diff --git a/runtime/mirror/art_field.h b/runtime/mirror/art_field.h index 30cd1802cf..4858613d68 100644 --- a/runtime/mirror/art_field.h +++ b/runtime/mirror/art_field.h @@ -139,6 +139,14 @@ class MANAGED ArtField : public Object { static ArtField* FindInstanceFieldWithOffset(mirror::Class* klass, uint32_t field_offset) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const char* GetTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + Primitive::Type GetTypeAsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool IsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + size_t FieldSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const DexFile* GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + private: // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". // The class we are a part of diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc index 42ef68a59a..a4090932fd 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc @@ -517,11 +517,9 @@ ArtMethod* Class::FindClassInitializer() { ArtField* Class::FindDeclaredInstanceField(const StringPiece& name, const StringPiece& type) { // Is the field in this class? // Interfaces are not relevant because they can't contain instance fields. - FieldHelper fh; for (size_t i = 0; i < NumInstanceFields(); ++i) { ArtField* f = GetInstanceField(i); - fh.ChangeField(f); - if (name == fh.GetName() && type == fh.GetTypeDescriptor()) { + if (name == f->GetName() && type == f->GetTypeDescriptor()) { return f; } } @@ -566,11 +564,9 @@ ArtField* Class::FindInstanceField(const DexCache* dex_cache, uint32_t dex_field ArtField* Class::FindDeclaredStaticField(const StringPiece& name, const StringPiece& type) { DCHECK(type != NULL); - FieldHelper fh; for (size_t i = 0; i < NumStaticFields(); ++i) { ArtField* f = GetStaticField(i); - fh.ChangeField(f); - if (name == fh.GetName() && type == fh.GetTypeDescriptor()) { + if (name == f->GetName() && type == f->GetTypeDescriptor()) { return f; } } diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h index 62ab2c19b5..11735fbd40 100644 --- a/runtime/mirror/object-inl.h +++ b/runtime/mirror/object-inl.h @@ -598,8 +598,9 @@ inline void Object::SetFieldObject(MemberOffset field_offset, Object* new_value) SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags, kIsVolatile>(field_offset, new_value); if (new_value != nullptr) { - CheckFieldAssignment(field_offset, new_value); Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value); + // TODO: Check field assignment could theoretically cause thread suspension, TODO: fix this. + CheckFieldAssignment(field_offset, new_value); } } diff --git a/runtime/mirror/object.cc b/runtime/mirror/object.cc index 69e5a84fed..422a88b688 100644 --- a/runtime/mirror/object.cc +++ b/runtime/mirror/object.cc @@ -204,7 +204,8 @@ void Object::CheckFieldAssignmentImpl(MemberOffset field_offset, Object* new_val for (size_t i = 0; i < num_ref_ifields; ++i) { ArtField* field = fields->Get(i); if (field->GetOffset().Int32Value() == field_offset.Int32Value()) { - FieldHelper fh(field); + StackHandleScope<1> hs(Thread::Current()); + FieldHelper fh(hs.NewHandle(field)); CHECK(fh.GetType()->IsAssignableFrom(new_value->GetClass())); return; } @@ -222,7 +223,8 @@ void Object::CheckFieldAssignmentImpl(MemberOffset field_offset, Object* new_val for (size_t i = 0; i < num_ref_sfields; ++i) { ArtField* field = fields->Get(i); if (field->GetOffset().Int32Value() == field_offset.Int32Value()) { - FieldHelper fh(field); + StackHandleScope<1> hs(Thread::Current()); + FieldHelper fh(hs.NewHandle(field)); CHECK(fh.GetType()->IsAssignableFrom(new_value->GetClass())); return; } diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h index 442909dfab..f0c5a73349 100644 --- a/runtime/mirror/object.h +++ b/runtime/mirror/object.h @@ -316,6 +316,7 @@ class MANAGED LOCKABLE Object { private: // Verify the type correctness of stores to fields. + // TODO: This can cause thread suspension and isn't moving GC safe. void CheckFieldAssignmentImpl(MemberOffset field_offset, Object* new_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void CheckFieldAssignment(MemberOffset field_offset, Object* new_value) diff --git a/runtime/native/java_lang_reflect_Field.cc b/runtime/native/java_lang_reflect_Field.cc index 0d5477275a..3564dfdf47 100644 --- a/runtime/native/java_lang_reflect_Field.cc +++ b/runtime/native/java_lang_reflect_Field.cc @@ -90,12 +90,13 @@ static bool GetFieldValue(const ScopedFastNativeObjectAccess& soa, mirror::Objec } static bool CheckReceiver(const ScopedFastNativeObjectAccess& soa, jobject j_rcvr, - mirror::ArtField* f, mirror::Object** class_or_rcvr) + mirror::ArtField** f, mirror::Object** class_or_rcvr) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { soa.Self()->AssertThreadSuspensionIsAllowable(); - if (f->IsStatic()) { - StackHandleScope<1> hs(soa.Self()); - Handle<mirror::Class> h_klass(hs.NewHandle(f->GetDeclaringClass())); + if ((*f)->IsStatic()) { + StackHandleScope<2> hs(soa.Self()); + HandleWrapper<mirror::ArtField> h_f(hs.NewHandleWrapper(f)); + Handle<mirror::Class> h_klass(hs.NewHandle((*f)->GetDeclaringClass())); if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(h_klass, true, true))) { DCHECK(soa.Self()->IsExceptionPending()); *class_or_rcvr = nullptr; @@ -106,7 +107,7 @@ static bool CheckReceiver(const ScopedFastNativeObjectAccess& soa, jobject j_rcv } *class_or_rcvr = soa.Decode<mirror::Object*>(j_rcvr); - mirror::Class* declaringClass = f->GetDeclaringClass(); + mirror::Class* declaringClass = (*f)->GetDeclaringClass(); if (!VerifyObjectIsClass(*class_or_rcvr, declaringClass)) { DCHECK(soa.Self()->IsExceptionPending()); *class_or_rcvr = nullptr; @@ -117,10 +118,9 @@ static bool CheckReceiver(const ScopedFastNativeObjectAccess& soa, jobject j_rcv static jobject Field_get(JNIEnv* env, jobject javaField, jobject javaObj, jboolean accessible) { ScopedFastNativeObjectAccess soa(env); - CHECK(!kMovingFields) << "CheckReceiver may trigger thread suspension for initialization"; mirror::ArtField* f = mirror::ArtField::FromReflectedField(soa, javaField); mirror::Object* o = nullptr; - if (!CheckReceiver(soa, javaObj, f, &o)) { + if (!CheckReceiver(soa, javaObj, &f, &o)) { DCHECK(soa.Self()->IsExceptionPending()); return nullptr; } @@ -131,7 +131,7 @@ static jobject Field_get(JNIEnv* env, jobject javaField, jobject javaObj, jboole } // We now don't expect suspension unless an exception is thrown. // Get the field's value, boxing if necessary. - Primitive::Type field_type = FieldHelper(f).GetTypeAsPrimitiveType(); + Primitive::Type field_type = f->GetTypeAsPrimitiveType(); JValue value; if (!GetFieldValue(soa, o, f, field_type, true, &value)) { DCHECK(soa.Self()->IsExceptionPending()); @@ -143,10 +143,9 @@ static jobject Field_get(JNIEnv* env, jobject javaField, jobject javaObj, jboole static JValue GetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char dst_descriptor, jboolean accessible) { ScopedFastNativeObjectAccess soa(env); - CHECK(!kMovingFields) << "CheckReceiver may trigger thread suspension for initialization"; mirror::ArtField* f = mirror::ArtField::FromReflectedField(soa, javaField); mirror::Object* o = nullptr; - if (!CheckReceiver(soa, javaObj, f, &o)) { + if (!CheckReceiver(soa, javaObj, &f, &o)) { DCHECK(soa.Self()->IsExceptionPending()); return JValue(); } @@ -159,7 +158,7 @@ static JValue GetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, // We now don't expect suspension unless an exception is thrown. // Read the value. - Primitive::Type field_type = FieldHelper(f).GetTypeAsPrimitiveType(); + Primitive::Type field_type = f->GetTypeAsPrimitiveType(); JValue field_value; if (!GetFieldValue(soa, o, f, field_type, false, &field_value)) { DCHECK(soa.Self()->IsExceptionPending()); @@ -257,33 +256,29 @@ static void SetFieldValue(ScopedFastNativeObjectAccess& soa, mirror::Object* o, static void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject javaValue, jboolean accessible) { ScopedFastNativeObjectAccess soa(env); - CHECK(!kMovingFields) << "CheckReceiver may trigger thread suspension for initialization"; mirror::ArtField* f = mirror::ArtField::FromReflectedField(soa, javaField); // Check that the receiver is non-null and an instance of the field's declaring class. mirror::Object* o = nullptr; - if (!CheckReceiver(soa, javaObj, f, &o)) { + if (!CheckReceiver(soa, javaObj, &f, &o)) { DCHECK(soa.Self()->IsExceptionPending()); return; } - Primitive::Type field_prim_type; mirror::Class* field_type; - { - FieldHelper fh(f); - const char* field_type_desciptor = fh.GetTypeDescriptor(); - field_prim_type = Primitive::GetType(field_type_desciptor[0]); - if (field_prim_type == Primitive::kPrimNot) { - StackHandleScope<1> hs(soa.Self()); - HandleWrapper<mirror::Object> h(hs.NewHandleWrapper(&o)); - // May cause resolution. - CHECK(!kMovingFields) << "Resolution may trigger thread suspension"; - field_type = fh.GetType(true); - if (field_type == nullptr) { - DCHECK(soa.Self()->IsExceptionPending()); - return; - } - } else { - field_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(field_type_desciptor[0]); + const char* field_type_desciptor = f->GetTypeDescriptor(); + Primitive::Type field_prim_type = Primitive::GetType(field_type_desciptor[0]); + if (field_prim_type == Primitive::kPrimNot) { + StackHandleScope<2> hs(soa.Self()); + HandleWrapper<mirror::Object> h_o(hs.NewHandleWrapper(&o)); + HandleWrapper<mirror::ArtField> h_f(hs.NewHandleWrapper(&f)); + FieldHelper fh(h_f); + // May cause resolution. + field_type = fh.GetType(true); + if (field_type == nullptr) { + DCHECK(soa.Self()->IsExceptionPending()); + return; } + } else { + field_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(field_type_desciptor[0]); } // We now don't expect suspension unless an exception is thrown. // Unbox the value, if necessary. @@ -306,10 +301,10 @@ static void SetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, c ScopedFastNativeObjectAccess soa(env); mirror::ArtField* f = mirror::ArtField::FromReflectedField(soa, javaField); mirror::Object* o = nullptr; - if (!CheckReceiver(soa, javaObj, f, &o)) { + if (!CheckReceiver(soa, javaObj, &f, &o)) { return; } - Primitive::Type field_type = FieldHelper(f).GetTypeAsPrimitiveType(); + Primitive::Type field_type = f->GetTypeAsPrimitiveType(); if (UNLIKELY(field_type == Primitive::kPrimNot)) { ThrowIllegalArgumentException(nullptr, StringPrintf("Not a primitive field: %s", PrettyField(f).c_str()).c_str()); diff --git a/runtime/object_utils.h b/runtime/object_utils.h index 664ac897cb..a05ebe6df3 100644 --- a/runtime/object_utils.h +++ b/runtime/object_utils.h @@ -68,68 +68,33 @@ class ObjectLock { class FieldHelper { public: - FieldHelper() : field_(nullptr) {} - explicit FieldHelper(mirror::ArtField* f) : field_(f) {} + explicit FieldHelper(Handle<mirror::ArtField> f) : field_(f) {} void ChangeField(mirror::ArtField* new_f) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { DCHECK(new_f != nullptr); - field_ = new_f; + field_.Assign(new_f); } - const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - uint32_t field_index = field_->GetDexFieldIndex(); - if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) { - DCHECK(field_->IsStatic()); - DCHECK_LT(field_index, 2U); - return field_index == 0 ? "interfaces" : "throws"; - } - const DexFile& dex_file = GetDexFile(); - return dex_file.GetFieldName(dex_file.GetFieldId(field_index)); + mirror::ArtField* GetField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + return field_.Get(); } mirror::Class* GetType(bool resolve = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { uint32_t field_index = field_->GetDexFieldIndex(); if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) { - return GetClassLinker()->FindSystemClass(Thread::Current(), GetTypeDescriptor()); + return Runtime::Current()->GetClassLinker()->FindSystemClass(Thread::Current(), + field_->GetTypeDescriptor()); } - const DexFile& dex_file = GetDexFile(); - const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index); - mirror::Class* type = GetDexCache()->GetResolvedType(field_id.type_idx_); + const DexFile* dex_file = field_->GetDexFile(); + const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index); + mirror::Class* type = field_->GetDexCache()->GetResolvedType(field_id.type_idx_); if (resolve && (type == nullptr)) { - type = GetClassLinker()->ResolveType(field_id.type_idx_, field_); + type = Runtime::Current()->GetClassLinker()->ResolveType(field_id.type_idx_, field_.Get()); CHECK(type != nullptr || Thread::Current()->IsExceptionPending()); } return type; } - const char* GetTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - uint32_t field_index = field_->GetDexFieldIndex(); - if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) { - DCHECK(field_->IsStatic()); - DCHECK_LT(field_index, 2U); - // 0 == Class[] interfaces; 1 == Class[][] throws; - return field_index == 0 ? "[Ljava/lang/Class;" : "[[Ljava/lang/Class;"; - } - const DexFile& dex_file = GetDexFile(); - const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index); - return dex_file.GetFieldTypeDescriptor(field_id); - } - - Primitive::Type GetTypeAsPrimitiveType() - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - return Primitive::GetType(GetTypeDescriptor()[0]); - } - - bool IsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - Primitive::Type type = GetTypeAsPrimitiveType(); - return type != Primitive::kPrimNot; - } - - size_t FieldSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - Primitive::Type type = GetTypeAsPrimitiveType(); - return Primitive::FieldSize(type); - } - // The returned const char* is only guaranteed to be valid for the lifetime of the FieldHelper. // If you need it longer, copy it into a std::string. const char* GetDeclaringClassDescriptor() @@ -142,22 +107,13 @@ class FieldHelper { declaring_class_descriptor_ = field_->GetDeclaringClass()->GetDescriptor(); return declaring_class_descriptor_.c_str(); } - const DexFile& dex_file = GetDexFile(); - const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index); - return dex_file.GetFieldDeclaringClassDescriptor(field_id); + const DexFile* dex_file = field_->GetDexFile(); + const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index); + return dex_file->GetFieldDeclaringClassDescriptor(field_id); } private: - mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - return field_->GetDeclaringClass()->GetDexCache(); - } - ClassLinker* GetClassLinker() ALWAYS_INLINE { - return Runtime::Current()->GetClassLinker(); - } - const DexFile& GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - return *GetDexCache()->GetDexFile(); - } - mirror::ArtField* field_; + Handle<mirror::ArtField> field_; std::string declaring_class_descriptor_; DISALLOW_COPY_AND_ASSIGN(FieldHelper); diff --git a/runtime/proxy_test.cc b/runtime/proxy_test.cc index 9724bcc50e..093c129add 100644 --- a/runtime/proxy_test.cc +++ b/runtime/proxy_test.cc @@ -140,52 +140,60 @@ TEST_F(ProxyTest, ProxyClassHelper) { TEST_F(ProxyTest, ProxyFieldHelper) { ScopedObjectAccess soa(Thread::Current()); jobject jclass_loader = LoadDex("Interfaces"); - StackHandleScope<1> hs(soa.Self()); + StackHandleScope<9> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader))); - mirror::Class* I = class_linker_->FindClass(soa.Self(), "LInterfaces$I;", class_loader); - mirror::Class* J = class_linker_->FindClass(soa.Self(), "LInterfaces$J;", class_loader); - ASSERT_TRUE(I != nullptr); - ASSERT_TRUE(J != nullptr); - std::vector<mirror::Class*> interfaces; - interfaces.push_back(I); - interfaces.push_back(J); + Handle<mirror::Class> I(hs.NewHandle( + class_linker_->FindClass(soa.Self(), "LInterfaces$I;", class_loader))); + Handle<mirror::Class> J(hs.NewHandle( + class_linker_->FindClass(soa.Self(), "LInterfaces$J;", class_loader))); + ASSERT_TRUE(I.Get() != nullptr); + ASSERT_TRUE(J.Get() != nullptr); + + Handle<mirror::Class> proxyClass; + { + std::vector<mirror::Class*> interfaces; + interfaces.push_back(I.Get()); + interfaces.push_back(J.Get()); + proxyClass = hs.NewHandle(GenerateProxyClass(soa, jclass_loader, "$Proxy1234", interfaces)); + } - mirror::Class* proxyClass = GenerateProxyClass(soa, jclass_loader, "$Proxy1234", interfaces); - ASSERT_TRUE(proxyClass != nullptr); + ASSERT_TRUE(proxyClass.Get() != nullptr); ASSERT_TRUE(proxyClass->IsProxyClass()); ASSERT_TRUE(proxyClass->IsInitialized()); - mirror::ObjectArray<mirror::ArtField>* instance_fields = proxyClass->GetIFields(); - EXPECT_TRUE(instance_fields == nullptr); + Handle<mirror::ObjectArray<mirror::ArtField>> instance_fields( + hs.NewHandle(proxyClass->GetIFields())); + EXPECT_TRUE(instance_fields.Get() == nullptr); - mirror::ObjectArray<mirror::ArtField>* static_fields = proxyClass->GetSFields(); - ASSERT_TRUE(static_fields != nullptr); + Handle<mirror::ObjectArray<mirror::ArtField>> static_fields( + hs.NewHandle(proxyClass->GetSFields())); + ASSERT_TRUE(static_fields.Get() != nullptr); ASSERT_EQ(2, static_fields->GetLength()); - mirror::Class* interfacesFieldClass = class_linker_->FindSystemClass(soa.Self(), - "[Ljava/lang/Class;"); - ASSERT_TRUE(interfacesFieldClass != nullptr); - mirror::Class* throwsFieldClass = class_linker_->FindSystemClass(soa.Self(), - "[[Ljava/lang/Class;"); - ASSERT_TRUE(throwsFieldClass != nullptr); + Handle<mirror::Class> interfacesFieldClass( + hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Class;"))); + ASSERT_TRUE(interfacesFieldClass.Get() != nullptr); + Handle<mirror::Class> throwsFieldClass( + hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[[Ljava/lang/Class;"))); + ASSERT_TRUE(throwsFieldClass.Get() != nullptr); // Test "Class[] interfaces" field. - FieldHelper fh(static_fields->Get(0)); - EXPECT_EQ("interfaces", std::string(fh.GetName())); - EXPECT_EQ("[Ljava/lang/Class;", std::string(fh.GetTypeDescriptor())); - EXPECT_EQ(interfacesFieldClass, fh.GetType()); + FieldHelper fh(hs.NewHandle(static_fields->Get(0))); + EXPECT_EQ("interfaces", std::string(fh.GetField()->GetName())); + EXPECT_EQ("[Ljava/lang/Class;", std::string(fh.GetField()->GetTypeDescriptor())); + EXPECT_EQ(interfacesFieldClass.Get(), fh.GetType()); EXPECT_EQ("L$Proxy1234;", std::string(fh.GetDeclaringClassDescriptor())); - EXPECT_FALSE(fh.IsPrimitiveType()); + EXPECT_FALSE(fh.GetField()->IsPrimitiveType()); // Test "Class[][] throws" field. fh.ChangeField(static_fields->Get(1)); - EXPECT_EQ("throws", std::string(fh.GetName())); - EXPECT_EQ("[[Ljava/lang/Class;", std::string(fh.GetTypeDescriptor())); - EXPECT_EQ(throwsFieldClass, fh.GetType()); + EXPECT_EQ("throws", std::string(fh.GetField()->GetName())); + EXPECT_EQ("[[Ljava/lang/Class;", std::string(fh.GetField()->GetTypeDescriptor())); + EXPECT_EQ(throwsFieldClass.Get(), fh.GetType()); EXPECT_EQ("L$Proxy1234;", std::string(fh.GetDeclaringClassDescriptor())); - EXPECT_FALSE(fh.IsPrimitiveType()); + EXPECT_FALSE(fh.GetField()->IsPrimitiveType()); } } // namespace art diff --git a/runtime/transaction_test.cc b/runtime/transaction_test.cc index 3645ed20c9..a03b389e0b 100644 --- a/runtime/transaction_test.cc +++ b/runtime/transaction_test.cc @@ -115,48 +115,48 @@ TEST_F(TransactionTest, StaticFieldsTest) { // Lookup fields. mirror::ArtField* booleanField = h_klass->FindDeclaredStaticField("booleanField", "Z"); ASSERT_TRUE(booleanField != nullptr); - ASSERT_EQ(FieldHelper(booleanField).GetTypeAsPrimitiveType(), Primitive::kPrimBoolean); + ASSERT_EQ(booleanField->GetTypeAsPrimitiveType(), Primitive::kPrimBoolean); ASSERT_EQ(booleanField->GetBoolean(h_klass.Get()), false); mirror::ArtField* byteField = h_klass->FindDeclaredStaticField("byteField", "B"); ASSERT_TRUE(byteField != nullptr); - ASSERT_EQ(FieldHelper(byteField).GetTypeAsPrimitiveType(), Primitive::kPrimByte); + ASSERT_EQ(byteField->GetTypeAsPrimitiveType(), Primitive::kPrimByte); ASSERT_EQ(byteField->GetByte(h_klass.Get()), 0); mirror::ArtField* charField = h_klass->FindDeclaredStaticField("charField", "C"); ASSERT_TRUE(charField != nullptr); - ASSERT_EQ(FieldHelper(charField).GetTypeAsPrimitiveType(), Primitive::kPrimChar); + ASSERT_EQ(charField->GetTypeAsPrimitiveType(), Primitive::kPrimChar); ASSERT_EQ(charField->GetChar(h_klass.Get()), 0u); mirror::ArtField* shortField = h_klass->FindDeclaredStaticField("shortField", "S"); ASSERT_TRUE(shortField != nullptr); - ASSERT_EQ(FieldHelper(shortField).GetTypeAsPrimitiveType(), Primitive::kPrimShort); + ASSERT_EQ(shortField->GetTypeAsPrimitiveType(), Primitive::kPrimShort); ASSERT_EQ(shortField->GetShort(h_klass.Get()), 0); mirror::ArtField* intField = h_klass->FindDeclaredStaticField("intField", "I"); ASSERT_TRUE(intField != nullptr); - ASSERT_EQ(FieldHelper(intField).GetTypeAsPrimitiveType(), Primitive::kPrimInt); + ASSERT_EQ(intField->GetTypeAsPrimitiveType(), Primitive::kPrimInt); ASSERT_EQ(intField->GetInt(h_klass.Get()), 0); mirror::ArtField* longField = h_klass->FindDeclaredStaticField("longField", "J"); ASSERT_TRUE(longField != nullptr); - ASSERT_EQ(FieldHelper(longField).GetTypeAsPrimitiveType(), Primitive::kPrimLong); + ASSERT_EQ(longField->GetTypeAsPrimitiveType(), Primitive::kPrimLong); ASSERT_EQ(longField->GetLong(h_klass.Get()), static_cast<int64_t>(0)); mirror::ArtField* floatField = h_klass->FindDeclaredStaticField("floatField", "F"); ASSERT_TRUE(floatField != nullptr); - ASSERT_EQ(FieldHelper(floatField).GetTypeAsPrimitiveType(), Primitive::kPrimFloat); + ASSERT_EQ(floatField->GetTypeAsPrimitiveType(), Primitive::kPrimFloat); ASSERT_EQ(floatField->GetFloat(h_klass.Get()), static_cast<float>(0.0f)); mirror::ArtField* doubleField = h_klass->FindDeclaredStaticField("doubleField", "D"); ASSERT_TRUE(doubleField != nullptr); - ASSERT_EQ(FieldHelper(doubleField).GetTypeAsPrimitiveType(), Primitive::kPrimDouble); + ASSERT_EQ(doubleField->GetTypeAsPrimitiveType(), Primitive::kPrimDouble); ASSERT_EQ(doubleField->GetDouble(h_klass.Get()), static_cast<double>(0.0)); mirror::ArtField* objectField = h_klass->FindDeclaredStaticField("objectField", "Ljava/lang/Object;"); ASSERT_TRUE(objectField != nullptr); - ASSERT_EQ(FieldHelper(objectField).GetTypeAsPrimitiveType(), Primitive::kPrimNot); + ASSERT_EQ(objectField->GetTypeAsPrimitiveType(), Primitive::kPrimNot); ASSERT_EQ(objectField->GetObject(h_klass.Get()), nullptr); // Create a java.lang.Object instance to set objectField. @@ -214,48 +214,48 @@ TEST_F(TransactionTest, InstanceFieldsTest) { // Lookup fields. mirror::ArtField* booleanField = h_klass->FindDeclaredInstanceField("booleanField", "Z"); ASSERT_TRUE(booleanField != nullptr); - ASSERT_EQ(FieldHelper(booleanField).GetTypeAsPrimitiveType(), Primitive::kPrimBoolean); + ASSERT_EQ(booleanField->GetTypeAsPrimitiveType(), Primitive::kPrimBoolean); ASSERT_EQ(booleanField->GetBoolean(h_instance.Get()), false); mirror::ArtField* byteField = h_klass->FindDeclaredInstanceField("byteField", "B"); ASSERT_TRUE(byteField != nullptr); - ASSERT_EQ(FieldHelper(byteField).GetTypeAsPrimitiveType(), Primitive::kPrimByte); + ASSERT_EQ(byteField->GetTypeAsPrimitiveType(), Primitive::kPrimByte); ASSERT_EQ(byteField->GetByte(h_instance.Get()), 0); mirror::ArtField* charField = h_klass->FindDeclaredInstanceField("charField", "C"); ASSERT_TRUE(charField != nullptr); - ASSERT_EQ(FieldHelper(charField).GetTypeAsPrimitiveType(), Primitive::kPrimChar); + ASSERT_EQ(charField->GetTypeAsPrimitiveType(), Primitive::kPrimChar); ASSERT_EQ(charField->GetChar(h_instance.Get()), 0u); mirror::ArtField* shortField = h_klass->FindDeclaredInstanceField("shortField", "S"); ASSERT_TRUE(shortField != nullptr); - ASSERT_EQ(FieldHelper(shortField).GetTypeAsPrimitiveType(), Primitive::kPrimShort); + ASSERT_EQ(shortField->GetTypeAsPrimitiveType(), Primitive::kPrimShort); ASSERT_EQ(shortField->GetShort(h_instance.Get()), 0); mirror::ArtField* intField = h_klass->FindDeclaredInstanceField("intField", "I"); ASSERT_TRUE(intField != nullptr); - ASSERT_EQ(FieldHelper(intField).GetTypeAsPrimitiveType(), Primitive::kPrimInt); + ASSERT_EQ(intField->GetTypeAsPrimitiveType(), Primitive::kPrimInt); ASSERT_EQ(intField->GetInt(h_instance.Get()), 0); mirror::ArtField* longField = h_klass->FindDeclaredInstanceField("longField", "J"); ASSERT_TRUE(longField != nullptr); - ASSERT_EQ(FieldHelper(longField).GetTypeAsPrimitiveType(), Primitive::kPrimLong); + ASSERT_EQ(longField->GetTypeAsPrimitiveType(), Primitive::kPrimLong); ASSERT_EQ(longField->GetLong(h_instance.Get()), static_cast<int64_t>(0)); mirror::ArtField* floatField = h_klass->FindDeclaredInstanceField("floatField", "F"); ASSERT_TRUE(floatField != nullptr); - ASSERT_EQ(FieldHelper(floatField).GetTypeAsPrimitiveType(), Primitive::kPrimFloat); + ASSERT_EQ(floatField->GetTypeAsPrimitiveType(), Primitive::kPrimFloat); ASSERT_EQ(floatField->GetFloat(h_instance.Get()), static_cast<float>(0.0f)); mirror::ArtField* doubleField = h_klass->FindDeclaredInstanceField("doubleField", "D"); ASSERT_TRUE(doubleField != nullptr); - ASSERT_EQ(FieldHelper(doubleField).GetTypeAsPrimitiveType(), Primitive::kPrimDouble); + ASSERT_EQ(doubleField->GetTypeAsPrimitiveType(), Primitive::kPrimDouble); ASSERT_EQ(doubleField->GetDouble(h_instance.Get()), static_cast<double>(0.0)); mirror::ArtField* objectField = h_klass->FindDeclaredInstanceField("objectField", "Ljava/lang/Object;"); ASSERT_TRUE(objectField != nullptr); - ASSERT_EQ(FieldHelper(objectField).GetTypeAsPrimitiveType(), Primitive::kPrimNot); + ASSERT_EQ(objectField->GetTypeAsPrimitiveType(), Primitive::kPrimNot); ASSERT_EQ(objectField->GetObject(h_instance.Get()), nullptr); // Create a java.lang.Object instance to set objectField. diff --git a/runtime/utils.cc b/runtime/utils.cc index dd64e52dfb..ef2047b8c5 100644 --- a/runtime/utils.cc +++ b/runtime/utils.cc @@ -290,15 +290,15 @@ std::string PrettyField(mirror::ArtField* f, bool with_type) { if (f == NULL) { return "null"; } - FieldHelper fh(f); std::string result; if (with_type) { - result += PrettyDescriptor(fh.GetTypeDescriptor()); + result += PrettyDescriptor(f->GetTypeDescriptor()); result += ' '; } - result += PrettyDescriptor(fh.GetDeclaringClassDescriptor()); + StackHandleScope<1> hs(Thread::Current()); + result += PrettyDescriptor(FieldHelper(hs.NewHandle(f)).GetDeclaringClassDescriptor()); result += '.'; - result += fh.GetName(); + result += f->GetName(); return result; } diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index 8d46812dae..c7bb20c950 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -3518,13 +3518,17 @@ void MethodVerifier::VerifyISGet(const Instruction* inst, const RegType& insn_ty } const RegType* field_type = nullptr; if (field != NULL) { - FieldHelper fh(field); - mirror::Class* field_type_class = fh.GetType(can_load_classes_); + Thread* self = Thread::Current(); + mirror::Class* field_type_class; + { + StackHandleScope<1> hs(self); + HandleWrapper<mirror::ArtField> h_field(hs.NewHandleWrapper(&field)); + field_type_class = FieldHelper(h_field).GetType(can_load_classes_); + } if (field_type_class != nullptr) { - field_type = ®_types_.FromClass(fh.GetTypeDescriptor(), field_type_class, + field_type = ®_types_.FromClass(field->GetTypeDescriptor(), field_type_class, field_type_class->CannotBeAssignedFromOtherTypes()); } else { - Thread* self = Thread::Current(); DCHECK(!can_load_classes_ || self->IsExceptionPending()); self->ClearException(); } @@ -3585,10 +3589,15 @@ void MethodVerifier::VerifyISPut(const Instruction* inst, const RegType& insn_ty << " from other class " << GetDeclaringClass(); return; } - FieldHelper fh(field); - mirror::Class* field_type_class = fh.GetType(can_load_classes_); + mirror::Class* field_type_class; + { + StackHandleScope<1> hs(Thread::Current()); + HandleWrapper<mirror::ArtField> h_field(hs.NewHandleWrapper(&field)); + FieldHelper fh(h_field); + field_type_class = fh.GetType(can_load_classes_); + } if (field_type_class != nullptr) { - field_type = ®_types_.FromClass(fh.GetTypeDescriptor(), field_type_class, + field_type = ®_types_.FromClass(field->GetTypeDescriptor(), field_type_class, field_type_class->CannotBeAssignedFromOtherTypes()); } else { Thread* self = Thread::Current(); @@ -3648,18 +3657,23 @@ void MethodVerifier::VerifyIGetQuick(const Instruction* inst, const RegType& ins Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Cannot infer field from " << inst->Name(); return; } - FieldHelper fh(field); - mirror::Class* field_type_class = fh.GetType(can_load_classes_); + mirror::Class* field_type_class; + { + StackHandleScope<1> hs(Thread::Current()); + HandleWrapper<mirror::ArtField> h_field(hs.NewHandleWrapper(&field)); + FieldHelper fh(h_field); + field_type_class = fh.GetType(can_load_classes_); + } const RegType* field_type; if (field_type_class != nullptr) { - field_type = ®_types_.FromClass(fh.GetTypeDescriptor(), field_type_class, + field_type = ®_types_.FromClass(field->GetTypeDescriptor(), field_type_class, field_type_class->CannotBeAssignedFromOtherTypes()); } else { Thread* self = Thread::Current(); DCHECK(!can_load_classes_ || self->IsExceptionPending()); self->ClearException(); field_type = ®_types_.FromDescriptor(field->GetDeclaringClass()->GetClassLoader(), - fh.GetTypeDescriptor(), false); + field->GetTypeDescriptor(), false); } DCHECK(field_type != nullptr); const uint32_t vregA = inst->VRegA_22c(); @@ -3703,7 +3717,7 @@ void MethodVerifier::VerifyIPutQuick(const Instruction* inst, const RegType& ins Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Cannot infer field from " << inst->Name(); return; } - const char* descriptor = FieldHelper(field).GetTypeDescriptor(); + const char* descriptor = field->GetTypeDescriptor(); mirror::ClassLoader* loader = field->GetDeclaringClass()->GetClassLoader(); const RegType& field_type = reg_types_.FromDescriptor(loader, descriptor, false); if (field != NULL) { |