Change FieldHelper to use a handle.
Fixed compaction bugs related to FieldHelper::GetType in:
artSet32InstanceFromCode
SetFieldValueImpl
CheckReceiver
Field_set
interpreter::DoFieldPut
MethodVerifier::VerifyISGet
MethodVerifier::VerifyISPut
MethodVerifier::VerifyIGetQuick
Bug: 13077697
Change-Id: I7de9ded2893b5568d43e4daa86fd135bf5508b72
diff --git a/runtime/arch/stub_test.cc b/runtime/arch/stub_test.cc
index 0b7f268c..56d51e2 100644
--- a/runtime/arch/stub_test.cc
+++ b/runtime/arch/stub_test.cc
@@ -1567,8 +1567,7 @@
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 @@
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 @@
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 @@
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 cfd0c00..46c4389 100644
--- a/runtime/check_jni.cc
+++ b/runtime/check_jni.cc
@@ -195,8 +195,9 @@
*/
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 @@
} 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 @@
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 b9c42ee..330b110 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -502,29 +502,24 @@
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 @@
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 @@
}
}
// 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 @@
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 @@
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 @@
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 @@
// 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 @@
<< " 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 e397a5c..45ab33a 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -171,11 +171,12 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
} 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 @@
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 @@
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 984f287..051ddec 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -1377,8 +1377,7 @@
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();
}
/*
@@ -1453,10 +1452,9 @@
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);
@@ -1622,7 +1620,7 @@
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);
}
@@ -1645,11 +1643,11 @@
}
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,
@@ -1693,7 +1691,7 @@
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;
@@ -1742,7 +1740,7 @@
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) {
@@ -1760,7 +1758,14 @@
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 58b4286..d0ae746 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -327,8 +327,8 @@
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 @@
// 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 844367d..3178cde 100644
--- a/runtime/entrypoints/quick/quick_field_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_field_entrypoints.cc
@@ -197,7 +197,7 @@
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 @@
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 3cb8d94..e2cf114 100644
--- a/runtime/gc/accounting/space_bitmap.cc
+++ b/runtime/gc/accounting/space_bitmap.cc
@@ -180,11 +180,10 @@
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);
}
}
}
@@ -210,8 +209,7 @@
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 91f1718..33339f8 100644
--- a/runtime/hprof/hprof.cc
+++ b/runtime/hprof/hprof.cc
@@ -919,8 +919,6 @@
rec->AddU2(0); // empty const pool
- FieldHelper fh;
-
// Static fields
if (sFieldCount == 0) {
rec->AddU2((uint16_t)0);
@@ -932,11 +930,10 @@
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 @@
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 @@
// 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 19b85e4..a66bd94 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -334,12 +334,10 @@
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 @@
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 029af8d..6e136d6 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -363,9 +363,15 @@
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 ad24d0a..686fded 100644
--- a/runtime/mirror/art_field-inl.h
+++ b/runtime/mirror/art_field-inl.h
@@ -116,60 +116,52 @@
}
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 @@
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 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 @@
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 @@
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 @@
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 b3b1b71..f2729f6 100644
--- a/runtime/mirror/art_field.cc
+++ b/runtime/mirror/art_field.cc
@@ -55,7 +55,7 @@
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 30cd180..4858613 100644
--- a/runtime/mirror/art_field.h
+++ b/runtime/mirror/art_field.h
@@ -139,6 +139,14 @@
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 4b02c0f..06c2796 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -517,11 +517,9 @@
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::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 62ab2c1..11735fb 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -598,8 +598,9 @@
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 69e5a84..422a88b 100644
--- a/runtime/mirror/object.cc
+++ b/runtime/mirror/object.cc
@@ -204,7 +204,8 @@
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 @@
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 442909d..f0c5a73 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -316,6 +316,7 @@
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 0d54772..3564dfd 100644
--- a/runtime/native/java_lang_reflect_Field.cc
+++ b/runtime/native/java_lang_reflect_Field.cc
@@ -90,12 +90,13 @@
}
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 @@
}
*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 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 @@
}
// 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 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 @@
// 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 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 @@
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 664ac89..a05ebe6 100644
--- a/runtime/object_utils.h
+++ b/runtime/object_utils.h
@@ -68,68 +68,33 @@
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 @@
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 f38fb21..76badc8 100644
--- a/runtime/proxy_test.cc
+++ b/runtime/proxy_test.cc
@@ -140,52 +140,60 @@
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);
- mirror::Class* proxyClass = GenerateProxyClass(soa, jclass_loader, "$Proxy1234", interfaces);
- ASSERT_TRUE(proxyClass != 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));
+ }
+
+ 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 3645ed2..a03b389 100644
--- a/runtime/transaction_test.cc
+++ b/runtime/transaction_test.cc
@@ -115,48 +115,48 @@
// 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 @@
// 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 f562252..d447e8c 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -290,15 +290,15 @@
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 b5c07aa..0a19ce1 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -3513,13 +3513,17 @@
}
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();
}
@@ -3580,10 +3584,15 @@
<< " 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();
@@ -3643,18 +3652,23 @@
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();
@@ -3698,7 +3712,7 @@
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) {