OSDN Git Service

Change FieldHelper to use a handle.
authorMathieu Chartier <mathieuc@google.com>
Fri, 6 Jun 2014 00:42:53 +0000 (17:42 -0700)
committerMathieu Chartier <mathieuc@google.com>
Fri, 6 Jun 2014 20:12:17 +0000 (13:12 -0700)
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

26 files changed:
compiler/driver/compiler_driver-inl.h
oatdump/oatdump.cc
runtime/arch/stub_test.cc
runtime/check_jni.cc
runtime/class_linker.cc
runtime/class_linker_test.cc
runtime/debugger.cc
runtime/entrypoints/entrypoint_utils.h
runtime/entrypoints/quick/quick_field_entrypoints.cc
runtime/gc/accounting/space_bitmap.cc
runtime/hprof/hprof.cc
runtime/interpreter/interpreter_common.cc
runtime/interpreter/interpreter_common.h
runtime/mirror/art_field-inl.h
runtime/mirror/art_field.cc
runtime/mirror/art_field.h
runtime/mirror/class.cc
runtime/mirror/object-inl.h
runtime/mirror/object.cc
runtime/mirror/object.h
runtime/native/java_lang_reflect_Field.cc
runtime/object_utils.h
runtime/proxy_test.cc
runtime/transaction_test.cc
runtime/utils.cc
runtime/verifier/method_verifier.cc

index 45abfcc..324f717 100644 (file)
@@ -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));
index 183f667..d51179e 100644 (file)
@@ -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);
index 0b7f268..56d51e2 100644 (file)
@@ -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;
index cfd0c00..46c4389 100644 (file)
@@ -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());
     }
index b9c42ee..330b110 100644 (file)
@@ -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) {
index e397a5c..45ab33a 100644 (file)
@@ -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"));
index 984f287..051ddec 100644 (file)
@@ -1377,8 +1377,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();
 }
 
 /*
@@ -1453,10 +1452,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);
@@ -1622,7 +1620,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);
 }
 
@@ -1645,11 +1643,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,
@@ -1693,7 +1691,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;
@@ -1742,7 +1740,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) {
@@ -1760,7 +1758,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;
       }
index 58b4286..d0ae746 100644 (file)
@@ -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;
index 844367d..3178cde 100644 (file)
@@ -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();
index 3cb8d94..e2cf114 100644 (file)
@@ -180,11 +180,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);
         }
       }
     }
@@ -210,8 +209,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);
index 91f1718..33339f8 100644 (file)
@@ -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) {
index 19b85e4..a66bd94 100644 (file)
@@ -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;
         }
       }
index 029af8d..6e136d6 100644 (file)
@@ -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(),
index ad24d0a..686fded 100644 (file)
@@ -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
 
index b3b1b71..f2729f6 100644 (file)
@@ -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);
     }
index 30cd180..4858613 100644 (file)
@@ -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
index 4b02c0f..06c2796 100644 (file)
@@ -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;
     }
   }
index 62ab2c1..11735fb 100644 (file)
@@ -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);
   }
 }
 
index 69e5a84..422a88b 100644 (file)
@@ -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;
         }
index 442909d..f0c5a73 100644 (file)
@@ -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)
index 0d54772..3564dfd 100644 (file)
@@ -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());
index 664ac89..a05ebe6 100644 (file)
@@ -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);
index f38fb21..76badc8 100644 (file)
@@ -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
index 3645ed2..a03b389 100644 (file)
@@ -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.
index f562252..d447e8c 100644 (file)
@@ -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;
 }
 
index b5c07aa..0a19ce1 100644 (file)
@@ -3513,13 +3513,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();
     }
@@ -3580,10 +3584,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();
@@ -3643,18 +3652,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();
@@ -3698,7 +3712,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) {