Change FieldHelper to use a handle.
Fixed compaction bugs related to FieldHelper::GetType in:
artSet32InstanceFromCode
SetFieldValueImpl
CheckReceiver
Field_set
interpreter::DoFieldPut
MethodVerifier::VerifyISGet
MethodVerifier::VerifyISPut
MethodVerifier::VerifyIGetQuick
Bug: 13077697
Change-Id: I7de9ded2893b5568d43e4daa86fd135bf5508b72
diff --git a/runtime/native/java_lang_reflect_Field.cc b/runtime/native/java_lang_reflect_Field.cc
index 0d54772..3564dfd 100644
--- a/runtime/native/java_lang_reflect_Field.cc
+++ b/runtime/native/java_lang_reflect_Field.cc
@@ -90,12 +90,13 @@
}
static bool CheckReceiver(const ScopedFastNativeObjectAccess& soa, jobject j_rcvr,
- mirror::ArtField* f, mirror::Object** class_or_rcvr)
+ mirror::ArtField** f, mirror::Object** class_or_rcvr)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
soa.Self()->AssertThreadSuspensionIsAllowable();
- if (f->IsStatic()) {
- StackHandleScope<1> hs(soa.Self());
- Handle<mirror::Class> h_klass(hs.NewHandle(f->GetDeclaringClass()));
+ if ((*f)->IsStatic()) {
+ StackHandleScope<2> hs(soa.Self());
+ HandleWrapper<mirror::ArtField> h_f(hs.NewHandleWrapper(f));
+ Handle<mirror::Class> h_klass(hs.NewHandle((*f)->GetDeclaringClass()));
if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(h_klass, true, true))) {
DCHECK(soa.Self()->IsExceptionPending());
*class_or_rcvr = nullptr;
@@ -106,7 +107,7 @@
}
*class_or_rcvr = soa.Decode<mirror::Object*>(j_rcvr);
- mirror::Class* declaringClass = f->GetDeclaringClass();
+ mirror::Class* declaringClass = (*f)->GetDeclaringClass();
if (!VerifyObjectIsClass(*class_or_rcvr, declaringClass)) {
DCHECK(soa.Self()->IsExceptionPending());
*class_or_rcvr = nullptr;
@@ -117,10 +118,9 @@
static jobject Field_get(JNIEnv* env, jobject javaField, jobject javaObj, jboolean accessible) {
ScopedFastNativeObjectAccess soa(env);
- CHECK(!kMovingFields) << "CheckReceiver may trigger thread suspension for initialization";
mirror::ArtField* f = mirror::ArtField::FromReflectedField(soa, javaField);
mirror::Object* o = nullptr;
- if (!CheckReceiver(soa, javaObj, f, &o)) {
+ if (!CheckReceiver(soa, javaObj, &f, &o)) {
DCHECK(soa.Self()->IsExceptionPending());
return nullptr;
}
@@ -131,7 +131,7 @@
}
// We now don't expect suspension unless an exception is thrown.
// Get the field's value, boxing if necessary.
- Primitive::Type field_type = FieldHelper(f).GetTypeAsPrimitiveType();
+ Primitive::Type field_type = f->GetTypeAsPrimitiveType();
JValue value;
if (!GetFieldValue(soa, o, f, field_type, true, &value)) {
DCHECK(soa.Self()->IsExceptionPending());
@@ -143,10 +143,9 @@
static JValue GetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj,
char dst_descriptor, jboolean accessible) {
ScopedFastNativeObjectAccess soa(env);
- CHECK(!kMovingFields) << "CheckReceiver may trigger thread suspension for initialization";
mirror::ArtField* f = mirror::ArtField::FromReflectedField(soa, javaField);
mirror::Object* o = nullptr;
- if (!CheckReceiver(soa, javaObj, f, &o)) {
+ if (!CheckReceiver(soa, javaObj, &f, &o)) {
DCHECK(soa.Self()->IsExceptionPending());
return JValue();
}
@@ -159,7 +158,7 @@
// We now don't expect suspension unless an exception is thrown.
// Read the value.
- Primitive::Type field_type = FieldHelper(f).GetTypeAsPrimitiveType();
+ Primitive::Type field_type = f->GetTypeAsPrimitiveType();
JValue field_value;
if (!GetFieldValue(soa, o, f, field_type, false, &field_value)) {
DCHECK(soa.Self()->IsExceptionPending());
@@ -257,33 +256,29 @@
static void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject javaValue,
jboolean accessible) {
ScopedFastNativeObjectAccess soa(env);
- CHECK(!kMovingFields) << "CheckReceiver may trigger thread suspension for initialization";
mirror::ArtField* f = mirror::ArtField::FromReflectedField(soa, javaField);
// Check that the receiver is non-null and an instance of the field's declaring class.
mirror::Object* o = nullptr;
- if (!CheckReceiver(soa, javaObj, f, &o)) {
+ if (!CheckReceiver(soa, javaObj, &f, &o)) {
DCHECK(soa.Self()->IsExceptionPending());
return;
}
- Primitive::Type field_prim_type;
mirror::Class* field_type;
- {
- FieldHelper fh(f);
- const char* field_type_desciptor = fh.GetTypeDescriptor();
- field_prim_type = Primitive::GetType(field_type_desciptor[0]);
- if (field_prim_type == Primitive::kPrimNot) {
- StackHandleScope<1> hs(soa.Self());
- HandleWrapper<mirror::Object> h(hs.NewHandleWrapper(&o));
- // May cause resolution.
- CHECK(!kMovingFields) << "Resolution may trigger thread suspension";
- field_type = fh.GetType(true);
- if (field_type == nullptr) {
- DCHECK(soa.Self()->IsExceptionPending());
- return;
- }
- } else {
- field_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(field_type_desciptor[0]);
+ const char* field_type_desciptor = f->GetTypeDescriptor();
+ Primitive::Type field_prim_type = Primitive::GetType(field_type_desciptor[0]);
+ if (field_prim_type == Primitive::kPrimNot) {
+ StackHandleScope<2> hs(soa.Self());
+ HandleWrapper<mirror::Object> h_o(hs.NewHandleWrapper(&o));
+ HandleWrapper<mirror::ArtField> h_f(hs.NewHandleWrapper(&f));
+ FieldHelper fh(h_f);
+ // May cause resolution.
+ field_type = fh.GetType(true);
+ if (field_type == nullptr) {
+ DCHECK(soa.Self()->IsExceptionPending());
+ return;
}
+ } else {
+ field_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(field_type_desciptor[0]);
}
// We now don't expect suspension unless an exception is thrown.
// Unbox the value, if necessary.
@@ -306,10 +301,10 @@
ScopedFastNativeObjectAccess soa(env);
mirror::ArtField* f = mirror::ArtField::FromReflectedField(soa, javaField);
mirror::Object* o = nullptr;
- if (!CheckReceiver(soa, javaObj, f, &o)) {
+ if (!CheckReceiver(soa, javaObj, &f, &o)) {
return;
}
- Primitive::Type field_type = FieldHelper(f).GetTypeAsPrimitiveType();
+ Primitive::Type field_type = f->GetTypeAsPrimitiveType();
if (UNLIKELY(field_type == Primitive::kPrimNot)) {
ThrowIllegalArgumentException(nullptr, StringPrintf("Not a primitive field: %s",
PrettyField(f).c_str()).c_str());