summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2014-06-06 23:37:27 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-06-06 23:37:27 +0000
commit4479ba35389b03ccc9eabd17fba6168f9505517a (patch)
treefb8091b4637b27d8a9d3d4f390b79263a12d9881
parent081203e06534e4aa27a942e47084289eecab29ed (diff)
parent61c5ebc6aee2cac1c363de6fbdac25ada1697fdb (diff)
downloadart-4479ba35389b03ccc9eabd17fba6168f9505517a.tar.gz
art-4479ba35389b03ccc9eabd17fba6168f9505517a.tar.bz2
art-4479ba35389b03ccc9eabd17fba6168f9505517a.zip
Merge "Change FieldHelper to use a handle."
-rw-r--r--compiler/driver/compiler_driver-inl.h4
-rw-r--r--oatdump/oatdump.cc9
-rw-r--r--runtime/arch/stub_test.cc10
-rw-r--r--runtime/check_jni.cc20
-rw-r--r--runtime/class_linker.cc52
-rw-r--r--runtime/class_linker_test.cc84
-rw-r--r--runtime/debugger.cc27
-rw-r--r--runtime/entrypoints/entrypoint_utils.h9
-rw-r--r--runtime/entrypoints/quick/quick_field_entrypoints.cc10
-rw-r--r--runtime/gc/accounting/space_bitmap.cc8
-rw-r--r--runtime/hprof/hprof.cc16
-rw-r--r--runtime/interpreter/interpreter_common.cc7
-rw-r--r--runtime/interpreter/interpreter_common.h12
-rw-r--r--runtime/mirror/art_field-inl.h95
-rw-r--r--runtime/mirror/art_field.cc2
-rw-r--r--runtime/mirror/art_field.h8
-rw-r--r--runtime/mirror/class.cc8
-rw-r--r--runtime/mirror/object-inl.h3
-rw-r--r--runtime/mirror/object.cc6
-rw-r--r--runtime/mirror/object.h1
-rw-r--r--runtime/native/java_lang_reflect_Field.cc59
-rw-r--r--runtime/object_utils.h72
-rw-r--r--runtime/proxy_test.cc66
-rw-r--r--runtime/transaction_test.cc36
-rw-r--r--runtime/utils.cc8
-rw-r--r--runtime/verifier/method_verifier.cc38
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(&reg));
+ 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 = &reg_types_.FromClass(fh.GetTypeDescriptor(), field_type_class,
+ field_type = &reg_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 = &reg_types_.FromClass(fh.GetTypeDescriptor(), field_type_class,
+ field_type = &reg_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 = &reg_types_.FromClass(fh.GetTypeDescriptor(), field_type_class,
+ field_type = &reg_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 = &reg_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) {