Merge "Inline field and method resolution." into dalvik-dev
diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc
index d9c9e31..24ab1ce 100644
--- a/runtime/entrypoints/entrypoint_utils.cc
+++ b/runtime/entrypoints/entrypoint_utils.cc
@@ -96,201 +96,6 @@
return mirror::Array::AllocInstrumented(self, klass, component_count);
}
-mirror::ArtField* FindFieldFromCode(uint32_t field_idx, const mirror::ArtMethod* referrer,
- Thread* self, FindFieldType type, size_t expected_size,
- bool access_check) {
- bool is_primitive;
- bool is_set;
- bool is_static;
- switch (type) {
- case InstanceObjectRead: is_primitive = false; is_set = false; is_static = false; break;
- case InstanceObjectWrite: is_primitive = false; is_set = true; is_static = false; break;
- case InstancePrimitiveRead: is_primitive = true; is_set = false; is_static = false; break;
- case InstancePrimitiveWrite: is_primitive = true; is_set = true; is_static = false; break;
- case StaticObjectRead: is_primitive = false; is_set = false; is_static = true; break;
- case StaticObjectWrite: is_primitive = false; is_set = true; is_static = true; break;
- case StaticPrimitiveRead: is_primitive = true; is_set = false; is_static = true; break;
- case StaticPrimitiveWrite: // Keep GCC happy by having a default handler, fall-through.
- default: is_primitive = true; is_set = true; is_static = true; break;
- }
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- mirror::ArtField* resolved_field = class_linker->ResolveField(field_idx, referrer, is_static);
- if (UNLIKELY(resolved_field == NULL)) {
- DCHECK(self->IsExceptionPending()); // Throw exception and unwind.
- return NULL; // Failure.
- }
- mirror::Class* fields_class = resolved_field->GetDeclaringClass();
- if (access_check) {
- if (UNLIKELY(resolved_field->IsStatic() != is_static)) {
- ThrowIncompatibleClassChangeErrorField(resolved_field, is_static, referrer);
- return NULL;
- }
- mirror::Class* referring_class = referrer->GetDeclaringClass();
- if (UNLIKELY(!referring_class->CanAccess(fields_class) ||
- !referring_class->CanAccessMember(fields_class,
- resolved_field->GetAccessFlags()))) {
- // The referring class can't access the resolved field, this may occur as a result of a
- // protected field being made public by a sub-class. Resort to the dex file to determine
- // the correct class for the access check.
- const DexFile& dex_file = *referring_class->GetDexCache()->GetDexFile();
- fields_class = class_linker->ResolveType(dex_file,
- dex_file.GetFieldId(field_idx).class_idx_,
- referring_class);
- if (UNLIKELY(!referring_class->CanAccess(fields_class))) {
- ThrowIllegalAccessErrorClass(referring_class, fields_class);
- return NULL; // failure
- } else if (UNLIKELY(!referring_class->CanAccessMember(fields_class,
- resolved_field->GetAccessFlags()))) {
- ThrowIllegalAccessErrorField(referring_class, resolved_field);
- return NULL; // failure
- }
- }
- if (UNLIKELY(is_set && resolved_field->IsFinal() && (fields_class != referring_class))) {
- ThrowIllegalAccessErrorFinalField(referrer, resolved_field);
- return NULL; // failure
- } else {
- FieldHelper fh(resolved_field);
- if (UNLIKELY(fh.IsPrimitiveType() != is_primitive ||
- fh.FieldSize() != expected_size)) {
- ThrowLocation throw_location = self->GetCurrentLocationForThrow();
- DCHECK(throw_location.GetMethod() == referrer);
- self->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchFieldError;",
- "Attempted read of %zd-bit %s on field '%s'",
- expected_size * (32 / sizeof(int32_t)),
- is_primitive ? "primitive" : "non-primitive",
- PrettyField(resolved_field, true).c_str());
- return NULL; // failure
- }
- }
- }
- if (!is_static) {
- // instance fields must be being accessed on an initialized class
- return resolved_field;
- } else {
- // If the class is initialized we're done.
- if (fields_class->IsInitialized()) {
- return resolved_field;
- } else if (Runtime::Current()->GetClassLinker()->EnsureInitialized(fields_class, true, true)) {
- // Otherwise let's ensure the class is initialized before resolving the field.
- return resolved_field;
- } else {
- DCHECK(self->IsExceptionPending()); // Throw exception and unwind
- return NULL; // failure
- }
- }
-}
-
-// Slow path method resolution
-mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx, mirror::Object* this_object,
- mirror::ArtMethod* referrer,
- Thread* self, bool access_check, InvokeType type) {
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- bool is_direct = type == kStatic || type == kDirect;
- mirror::ArtMethod* resolved_method = class_linker->ResolveMethod(method_idx, referrer, type);
- if (UNLIKELY(resolved_method == NULL)) {
- DCHECK(self->IsExceptionPending()); // Throw exception and unwind.
- return NULL; // Failure.
- } else if (UNLIKELY(this_object == NULL && type != kStatic)) {
- // Maintain interpreter-like semantics where NullPointerException is thrown
- // after potential NoSuchMethodError from class linker.
- ThrowLocation throw_location = self->GetCurrentLocationForThrow();
- DCHECK(referrer == throw_location.GetMethod());
- ThrowNullPointerExceptionForMethodAccess(throw_location, method_idx, type);
- return NULL; // Failure.
- } else {
- if (!access_check) {
- if (is_direct) {
- return resolved_method;
- } else if (type == kInterface) {
- mirror::ArtMethod* interface_method =
- this_object->GetClass()->FindVirtualMethodForInterface(resolved_method);
- if (UNLIKELY(interface_method == NULL)) {
- ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(resolved_method, this_object,
- referrer);
- return NULL; // Failure.
- } else {
- return interface_method;
- }
- } else {
- mirror::ObjectArray<mirror::ArtMethod>* vtable;
- uint16_t vtable_index = resolved_method->GetMethodIndex();
- if (type == kSuper) {
- vtable = referrer->GetDeclaringClass()->GetSuperClass()->GetVTable();
- } else {
- vtable = this_object->GetClass()->GetVTable();
- }
- // TODO: eliminate bounds check?
- return vtable->Get(vtable_index);
- }
- } else {
- // Incompatible class change should have been handled in resolve method.
- if (UNLIKELY(resolved_method->CheckIncompatibleClassChange(type))) {
- ThrowIncompatibleClassChangeError(type, resolved_method->GetInvokeType(), resolved_method,
- referrer);
- return NULL; // Failure.
- }
- mirror::Class* methods_class = resolved_method->GetDeclaringClass();
- mirror::Class* referring_class = referrer->GetDeclaringClass();
- if (UNLIKELY(!referring_class->CanAccess(methods_class) ||
- !referring_class->CanAccessMember(methods_class,
- resolved_method->GetAccessFlags()))) {
- // The referring class can't access the resolved method, this may occur as a result of a
- // protected method being made public by implementing an interface that re-declares the
- // method public. Resort to the dex file to determine the correct class for the access check
- const DexFile& dex_file = *referring_class->GetDexCache()->GetDexFile();
- methods_class = class_linker->ResolveType(dex_file,
- dex_file.GetMethodId(method_idx).class_idx_,
- referring_class);
- if (UNLIKELY(!referring_class->CanAccess(methods_class))) {
- ThrowIllegalAccessErrorClassForMethodDispatch(referring_class, methods_class,
- referrer, resolved_method, type);
- return NULL; // Failure.
- } else if (UNLIKELY(!referring_class->CanAccessMember(methods_class,
- resolved_method->GetAccessFlags()))) {
- ThrowIllegalAccessErrorMethod(referring_class, resolved_method);
- return NULL; // Failure.
- }
- }
- if (is_direct) {
- return resolved_method;
- } else if (type == kInterface) {
- mirror::ArtMethod* interface_method =
- this_object->GetClass()->FindVirtualMethodForInterface(resolved_method);
- if (UNLIKELY(interface_method == NULL)) {
- ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(resolved_method, this_object,
- referrer);
- return NULL; // Failure.
- } else {
- return interface_method;
- }
- } else {
- mirror::ObjectArray<mirror::ArtMethod>* vtable;
- uint16_t vtable_index = resolved_method->GetMethodIndex();
- if (type == kSuper) {
- mirror::Class* super_class = referring_class->GetSuperClass();
- if (LIKELY(super_class != NULL)) {
- vtable = referring_class->GetSuperClass()->GetVTable();
- } else {
- vtable = NULL;
- }
- } else {
- vtable = this_object->GetClass()->GetVTable();
- }
- if (LIKELY(vtable != NULL &&
- vtable_index < static_cast<uint32_t>(vtable->GetLength()))) {
- return vtable->GetWithoutChecks(vtable_index);
- } else {
- // Behavior to agree with that of the verifier.
- MethodHelper mh(resolved_method);
- ThrowNoSuchMethodError(type, resolved_method->GetDeclaringClass(), mh.GetName(),
- mh.GetSignature());
- return NULL; // Failure.
- }
- }
- }
- }
-}
-
void ThrowStackOverflowError(Thread* self) {
if (self->IsHandlingStackOverflow()) {
LOG(ERROR) << "Recursive stack overflow.";
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index c32a661..2008604 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -178,11 +178,235 @@
StaticPrimitiveWrite,
};
-// Slow field find that can initialize classes and may throw exceptions.
-extern mirror::ArtField* FindFieldFromCode(uint32_t field_idx, const mirror::ArtMethod* referrer,
- Thread* self, FindFieldType type, size_t expected_size,
- bool access_check)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+template<FindFieldType type, bool access_check>
+static inline mirror::ArtField* FindFieldFromCode(uint32_t field_idx, const mirror::ArtMethod* referrer,
+ Thread* self, size_t expected_size) {
+ bool is_primitive;
+ bool is_set;
+ bool is_static;
+ switch (type) {
+ case InstanceObjectRead: is_primitive = false; is_set = false; is_static = false; break;
+ case InstanceObjectWrite: is_primitive = false; is_set = true; is_static = false; break;
+ case InstancePrimitiveRead: is_primitive = true; is_set = false; is_static = false; break;
+ case InstancePrimitiveWrite: is_primitive = true; is_set = true; is_static = false; break;
+ case StaticObjectRead: is_primitive = false; is_set = false; is_static = true; break;
+ case StaticObjectWrite: is_primitive = false; is_set = true; is_static = true; break;
+ case StaticPrimitiveRead: is_primitive = true; is_set = false; is_static = true; break;
+ case StaticPrimitiveWrite: // Keep GCC happy by having a default handler, fall-through.
+ default: is_primitive = true; is_set = true; is_static = true; break;
+ }
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ mirror::ArtField* resolved_field = class_linker->ResolveField(field_idx, referrer, is_static);
+ if (UNLIKELY(resolved_field == nullptr)) {
+ DCHECK(self->IsExceptionPending()); // Throw exception and unwind.
+ return nullptr; // Failure.
+ }
+ mirror::Class* fields_class = resolved_field->GetDeclaringClass();
+ if (access_check) {
+ if (UNLIKELY(resolved_field->IsStatic() != is_static)) {
+ ThrowIncompatibleClassChangeErrorField(resolved_field, is_static, referrer);
+ return nullptr;
+ }
+ mirror::Class* referring_class = referrer->GetDeclaringClass();
+ if (UNLIKELY(!referring_class->CanAccess(fields_class) ||
+ !referring_class->CanAccessMember(fields_class,
+ resolved_field->GetAccessFlags()))) {
+ // The referring class can't access the resolved field, this may occur as a result of a
+ // protected field being made public by a sub-class. Resort to the dex file to determine
+ // the correct class for the access check.
+ const DexFile& dex_file = *referring_class->GetDexCache()->GetDexFile();
+ fields_class = class_linker->ResolveType(dex_file,
+ dex_file.GetFieldId(field_idx).class_idx_,
+ referring_class);
+ if (UNLIKELY(!referring_class->CanAccess(fields_class))) {
+ ThrowIllegalAccessErrorClass(referring_class, fields_class);
+ return nullptr; // failure
+ } else if (UNLIKELY(!referring_class->CanAccessMember(fields_class,
+ resolved_field->GetAccessFlags()))) {
+ ThrowIllegalAccessErrorField(referring_class, resolved_field);
+ return nullptr; // failure
+ }
+ }
+ if (UNLIKELY(is_set && resolved_field->IsFinal() && (fields_class != referring_class))) {
+ ThrowIllegalAccessErrorFinalField(referrer, resolved_field);
+ return nullptr; // failure
+ } else {
+ FieldHelper fh(resolved_field);
+ if (UNLIKELY(fh.IsPrimitiveType() != is_primitive ||
+ fh.FieldSize() != expected_size)) {
+ ThrowLocation throw_location = self->GetCurrentLocationForThrow();
+ DCHECK(throw_location.GetMethod() == referrer);
+ self->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchFieldError;",
+ "Attempted read of %zd-bit %s on field '%s'",
+ expected_size * (32 / sizeof(int32_t)),
+ is_primitive ? "primitive" : "non-primitive",
+ PrettyField(resolved_field, true).c_str());
+ return nullptr; // failure
+ }
+ }
+ }
+ if (!is_static) {
+ // instance fields must be being accessed on an initialized class
+ return resolved_field;
+ } else {
+ // If the class is initialized we're done.
+ if (LIKELY(fields_class->IsInitialized())) {
+ return resolved_field;
+ } else if (LIKELY(class_linker->EnsureInitialized(fields_class, true, true))) {
+ // Otherwise let's ensure the class is initialized before resolving the field.
+ return resolved_field;
+ } else {
+ DCHECK(self->IsExceptionPending()); // Throw exception and unwind
+ return nullptr; // failure
+ }
+ }
+}
+
+// Explicit template declarations of FindFieldFromCode for all field access types.
+#define EXPLICIT_FIND_FIELD_FROM_CODE_TEMPLATE_DECL(_type, _access_check) \
+template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE \
+static mirror::ArtField* FindFieldFromCode<_type, _access_check>(uint32_t field_idx, \
+ const mirror::ArtMethod* referrer, \
+ Thread* self, size_t expected_size) \
+
+#define EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(_type) \
+ EXPLICIT_FIND_FIELD_FROM_CODE_TEMPLATE_DECL(_type, false); \
+ EXPLICIT_FIND_FIELD_FROM_CODE_TEMPLATE_DECL(_type, true)
+
+EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(InstanceObjectRead);
+EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(InstanceObjectWrite);
+EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(InstancePrimitiveRead);
+EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(InstancePrimitiveWrite);
+EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(StaticObjectRead);
+EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(StaticObjectWrite);
+EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(StaticPrimitiveRead);
+EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(StaticPrimitiveWrite);
+
+#undef EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL
+#undef EXPLICIT_FIND_FIELD_FROM_CODE_TEMPLATE_DECL
+
+template<InvokeType type, bool access_check>
+static inline mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx, mirror::Object* this_object,
+ mirror::ArtMethod* referrer, Thread* self) {
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ mirror::ArtMethod* resolved_method = class_linker->ResolveMethod(method_idx, referrer, type);
+ if (UNLIKELY(resolved_method == nullptr)) {
+ DCHECK(self->IsExceptionPending()); // Throw exception and unwind.
+ return nullptr; // Failure.
+ } else if (UNLIKELY(this_object == nullptr && type != kStatic)) {
+ // Maintain interpreter-like semantics where NullPointerException is thrown
+ // after potential NoSuchMethodError from class linker.
+ ThrowLocation throw_location = self->GetCurrentLocationForThrow();
+ DCHECK(referrer == throw_location.GetMethod());
+ ThrowNullPointerExceptionForMethodAccess(throw_location, method_idx, type);
+ return nullptr; // Failure.
+ } else if (access_check) {
+ // Incompatible class change should have been handled in resolve method.
+ if (UNLIKELY(resolved_method->CheckIncompatibleClassChange(type))) {
+ ThrowIncompatibleClassChangeError(type, resolved_method->GetInvokeType(), resolved_method,
+ referrer);
+ return nullptr; // Failure.
+ }
+ mirror::Class* methods_class = resolved_method->GetDeclaringClass();
+ mirror::Class* referring_class = referrer->GetDeclaringClass();
+ if (UNLIKELY(!referring_class->CanAccess(methods_class) ||
+ !referring_class->CanAccessMember(methods_class,
+ resolved_method->GetAccessFlags()))) {
+ // The referring class can't access the resolved method, this may occur as a result of a
+ // protected method being made public by implementing an interface that re-declares the
+ // method public. Resort to the dex file to determine the correct class for the access check
+ const DexFile& dex_file = *referring_class->GetDexCache()->GetDexFile();
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ methods_class = class_linker->ResolveType(dex_file,
+ dex_file.GetMethodId(method_idx).class_idx_,
+ referring_class);
+ if (UNLIKELY(!referring_class->CanAccess(methods_class))) {
+ ThrowIllegalAccessErrorClassForMethodDispatch(referring_class, methods_class,
+ referrer, resolved_method, type);
+ return nullptr; // Failure.
+ } else if (UNLIKELY(!referring_class->CanAccessMember(methods_class,
+ resolved_method->GetAccessFlags()))) {
+ ThrowIllegalAccessErrorMethod(referring_class, resolved_method);
+ return nullptr; // Failure.
+ }
+ }
+ }
+ switch (type) {
+ case kStatic:
+ case kDirect:
+ return resolved_method;
+ case kVirtual: {
+ mirror::ObjectArray<mirror::ArtMethod>* vtable = this_object->GetClass()->GetVTable();
+ uint16_t vtable_index = resolved_method->GetMethodIndex();
+ if (access_check &&
+ (vtable == nullptr || vtable_index >= static_cast<uint32_t>(vtable->GetLength()))) {
+ // Behavior to agree with that of the verifier.
+ MethodHelper mh(resolved_method);
+ ThrowNoSuchMethodError(type, resolved_method->GetDeclaringClass(), mh.GetName(),
+ mh.GetSignature());
+ return nullptr; // Failure.
+ }
+ DCHECK(vtable != nullptr);
+ return vtable->GetWithoutChecks(vtable_index);
+ }
+ case kSuper: {
+ mirror::Class* super_class = referrer->GetDeclaringClass()->GetSuperClass();
+ uint16_t vtable_index = resolved_method->GetMethodIndex();
+ mirror::ObjectArray<mirror::ArtMethod>* vtable;
+ if (access_check) {
+ // Check existence of super class.
+ vtable = (super_class != nullptr) ? super_class->GetVTable() : nullptr;
+ if (vtable == nullptr || vtable_index >= static_cast<uint32_t>(vtable->GetLength())) {
+ // Behavior to agree with that of the verifier.
+ MethodHelper mh(resolved_method);
+ ThrowNoSuchMethodError(type, resolved_method->GetDeclaringClass(), mh.GetName(),
+ mh.GetSignature());
+ return nullptr; // Failure.
+ }
+ } else {
+ // Super class must exist.
+ DCHECK(super_class != nullptr);
+ vtable = super_class->GetVTable();
+ }
+ DCHECK(vtable != nullptr);
+ return vtable->GetWithoutChecks(vtable_index);
+ }
+ case kInterface: {
+ mirror::ArtMethod* interface_method =
+ this_object->GetClass()->FindVirtualMethodForInterface(resolved_method);
+ if (UNLIKELY(interface_method == nullptr)) {
+ ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(resolved_method, this_object,
+ referrer);
+ return nullptr; // Failure.
+ } else {
+ return interface_method;
+ }
+ }
+ default:
+ LOG(FATAL) << "Unknown invoke type " << type;
+ return nullptr; // Failure.
+ }
+}
+
+// Explicit template declarations of FindMethodFromCode for all invoke types.
+#define EXPLICIT_FIND_METHOD_FROM_CODE_TEMPLATE_DECL(_type, _access_check) \
+ template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE \
+ static mirror::ArtMethod* FindMethodFromCode<_type, _access_check>(uint32_t method_idx, \
+ mirror::Object* this_object, \
+ mirror::ArtMethod* referrer, \
+ Thread* self)
+#define EXPLICIT_FIND_METHOD_FROM_CODE_TYPED_TEMPLATE_DECL(_type) \
+ EXPLICIT_FIND_METHOD_FROM_CODE_TEMPLATE_DECL(_type, false); \
+ EXPLICIT_FIND_METHOD_FROM_CODE_TEMPLATE_DECL(_type, true)
+
+EXPLICIT_FIND_METHOD_FROM_CODE_TYPED_TEMPLATE_DECL(kStatic);
+EXPLICIT_FIND_METHOD_FROM_CODE_TYPED_TEMPLATE_DECL(kDirect);
+EXPLICIT_FIND_METHOD_FROM_CODE_TYPED_TEMPLATE_DECL(kVirtual);
+EXPLICIT_FIND_METHOD_FROM_CODE_TYPED_TEMPLATE_DECL(kSuper);
+EXPLICIT_FIND_METHOD_FROM_CODE_TYPED_TEMPLATE_DECL(kInterface);
+
+#undef EXPLICIT_FIND_METHOD_FROM_CODE_TYPED_TEMPLATE_DECL
+#undef EXPLICIT_FIND_METHOD_FROM_CODE_TEMPLATE_DECL
// Fast path field resolution that can't initialize classes or throw exceptions.
static inline mirror::ArtField* FindFieldFast(uint32_t field_idx,
@@ -282,11 +506,6 @@
}
}
-extern mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx, mirror::Object* this_object,
- mirror::ArtMethod* referrer,
- Thread* self, bool access_check, InvokeType type)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
static inline mirror::Class* ResolveVerifyAndClinit(uint32_t type_idx,
const mirror::ArtMethod* referrer,
Thread* self, bool can_run_clinit,
diff --git a/runtime/entrypoints/portable/portable_field_entrypoints.cc b/runtime/entrypoints/portable/portable_field_entrypoints.cc
index bd6f795..095e99e 100644
--- a/runtime/entrypoints/portable/portable_field_entrypoints.cc
+++ b/runtime/entrypoints/portable/portable_field_entrypoints.cc
@@ -33,12 +33,8 @@
field->Set32(field->GetDeclaringClass(), new_value);
return 0;
}
- field = FindFieldFromCode(field_idx,
- referrer,
- Thread::Current(),
- StaticPrimitiveWrite,
- sizeof(uint32_t),
- true);
+ field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, Thread::Current(),
+ sizeof(uint32_t));
if (LIKELY(field != NULL)) {
field->Set32(field->GetDeclaringClass(), new_value);
return 0;
@@ -55,12 +51,8 @@
field->Set64(field->GetDeclaringClass(), new_value);
return 0;
}
- field = FindFieldFromCode(field_idx,
- referrer,
- Thread::Current(),
- StaticPrimitiveWrite,
- sizeof(uint64_t),
- true);
+ field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, Thread::Current(),
+ sizeof(uint64_t));
if (LIKELY(field != NULL)) {
field->Set64(field->GetDeclaringClass(), new_value);
return 0;
@@ -78,8 +70,8 @@
field->SetObj(field->GetDeclaringClass(), new_value);
return 0;
}
- field = FindFieldFromCode(field_idx, referrer, Thread::Current(),
- StaticObjectWrite, sizeof(mirror::Object*), true);
+ field = FindFieldFromCode<StaticObjectWrite, true>(field_idx, referrer, Thread::Current(),
+ sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
field->SetObj(field->GetDeclaringClass(), new_value);
return 0;
@@ -94,8 +86,8 @@
if (LIKELY(field != NULL)) {
return field->Get32(field->GetDeclaringClass());
}
- field = FindFieldFromCode(field_idx, referrer, Thread::Current(),
- StaticPrimitiveRead, sizeof(uint32_t), true);
+ field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, Thread::Current(),
+ sizeof(uint32_t));
if (LIKELY(field != NULL)) {
return field->Get32(field->GetDeclaringClass());
}
@@ -109,8 +101,8 @@
if (LIKELY(field != NULL)) {
return field->Get64(field->GetDeclaringClass());
}
- field = FindFieldFromCode(field_idx, referrer, Thread::Current(),
- StaticPrimitiveRead, sizeof(uint64_t), true);
+ field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, Thread::Current(),
+ sizeof(uint64_t));
if (LIKELY(field != NULL)) {
return field->Get64(field->GetDeclaringClass());
}
@@ -125,8 +117,8 @@
if (LIKELY(field != NULL)) {
return field->GetObj(field->GetDeclaringClass());
}
- field = FindFieldFromCode(field_idx, referrer, Thread::Current(),
- StaticObjectRead, sizeof(mirror::Object*), true);
+ field = FindFieldFromCode<StaticObjectRead, true>(field_idx, referrer, Thread::Current(),
+ sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
return field->GetObj(field->GetDeclaringClass());
}
@@ -142,8 +134,8 @@
field->Set32(obj, new_value);
return 0;
}
- field = FindFieldFromCode(field_idx, referrer, Thread::Current(),
- InstancePrimitiveWrite, sizeof(uint32_t), true);
+ field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, Thread::Current(),
+ sizeof(uint32_t));
if (LIKELY(field != NULL)) {
field->Set32(obj, new_value);
return 0;
@@ -160,8 +152,8 @@
field->Set64(obj, new_value);
return 0;
}
- field = FindFieldFromCode(field_idx, referrer, Thread::Current(),
- InstancePrimitiveWrite, sizeof(uint64_t), true);
+ field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, Thread::Current(),
+ sizeof(uint64_t));
if (LIKELY(field != NULL)) {
field->Set64(obj, new_value);
return 0;
@@ -180,8 +172,8 @@
field->SetObj(obj, new_value);
return 0;
}
- field = FindFieldFromCode(field_idx, referrer, Thread::Current(),
- InstanceObjectWrite, sizeof(mirror::Object*), true);
+ field = FindFieldFromCode<InstanceObjectWrite, true>(field_idx, referrer, Thread::Current(),
+ sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
field->SetObj(obj, new_value);
return 0;
@@ -197,8 +189,8 @@
if (LIKELY(field != NULL)) {
return field->Get32(obj);
}
- field = FindFieldFromCode(field_idx, referrer, Thread::Current(),
- InstancePrimitiveRead, sizeof(uint32_t), true);
+ field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, Thread::Current(),
+ sizeof(uint32_t));
if (LIKELY(field != NULL)) {
return field->Get32(obj);
}
@@ -213,8 +205,8 @@
if (LIKELY(field != NULL)) {
return field->Get64(obj);
}
- field = FindFieldFromCode(field_idx, referrer, Thread::Current(),
- InstancePrimitiveRead, sizeof(uint64_t), true);
+ field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, Thread::Current(),
+ sizeof(uint64_t));
if (LIKELY(field != NULL)) {
return field->Get64(obj);
}
@@ -230,8 +222,8 @@
if (LIKELY(field != NULL)) {
return field->GetObj(obj);
}
- field = FindFieldFromCode(field_idx, referrer, Thread::Current(),
- InstanceObjectRead, sizeof(mirror::Object*), true);
+ field = FindFieldFromCode<InstanceObjectRead, true>(field_idx, referrer, Thread::Current(),
+ sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
return field->GetObj(obj);
}
diff --git a/runtime/entrypoints/portable/portable_invoke_entrypoints.cc b/runtime/entrypoints/portable/portable_invoke_entrypoints.cc
index 14cbd84..e2a0cc2 100644
--- a/runtime/entrypoints/portable/portable_invoke_entrypoints.cc
+++ b/runtime/entrypoints/portable/portable_invoke_entrypoints.cc
@@ -21,21 +21,13 @@
namespace art {
-static mirror::ArtMethod* FindMethodHelper(uint32_t method_idx,
- mirror::Object* this_object,
- mirror::ArtMethod* caller_method,
- bool access_check,
- InvokeType type,
- Thread* thread)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::ArtMethod* method = FindMethodFast(method_idx,
- this_object,
- caller_method,
- access_check,
- type);
+template<InvokeType type, bool access_check>
+static mirror::ArtMethod* FindMethodHelper(uint32_t method_idx, mirror::Object* this_object,
+ mirror::ArtMethod* caller_method, Thread* thread) {
+ mirror::ArtMethod* method = FindMethodFast(method_idx, this_object, caller_method,
+ access_check, type);
if (UNLIKELY(method == NULL)) {
- method = FindMethodFromCode(method_idx, this_object, caller_method,
- thread, access_check, type);
+ method = FindMethodFromCode<type, access_check>(method_idx, this_object, caller_method, thread);
if (UNLIKELY(method == NULL)) {
CHECK(thread->IsExceptionPending());
return 0; // failure
@@ -53,12 +45,32 @@
return method;
}
+// Explicit template declarations of FindMethodHelper for all invoke types.
+#define EXPLICIT_FIND_METHOD_HELPER_TEMPLATE_DECL(_type, _access_check) \
+ template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) \
+ static mirror::ArtMethod* FindMethodHelper<_type, _access_check>(uint32_t method_idx, \
+ mirror::Object* this_object, \
+ mirror::ArtMethod* caller_method, \
+ Thread* thread)
+#define EXPLICIT_FIND_METHOD_HELPER_TYPED_TEMPLATE_DECL(_type) \
+ EXPLICIT_FIND_METHOD_HELPER_TEMPLATE_DECL(_type, false); \
+ EXPLICIT_FIND_METHOD_HELPER_TEMPLATE_DECL(_type, true)
+
+EXPLICIT_FIND_METHOD_HELPER_TYPED_TEMPLATE_DECL(kStatic);
+EXPLICIT_FIND_METHOD_HELPER_TYPED_TEMPLATE_DECL(kDirect);
+EXPLICIT_FIND_METHOD_HELPER_TYPED_TEMPLATE_DECL(kVirtual);
+EXPLICIT_FIND_METHOD_HELPER_TYPED_TEMPLATE_DECL(kSuper);
+EXPLICIT_FIND_METHOD_HELPER_TYPED_TEMPLATE_DECL(kInterface);
+
+#undef EXPLICIT_FIND_METHOD_HELPER_TYPED_TEMPLATE_DECL
+#undef EXPLICIT_FIND_METHOD_HELPER_TEMPLATE_DECL
+
extern "C" mirror::Object* art_portable_find_static_method_from_code_with_access_check(uint32_t method_idx,
mirror::Object* this_object,
mirror::ArtMethod* referrer,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return FindMethodHelper(method_idx, this_object, referrer, true, kStatic, thread);
+ return FindMethodHelper<kStatic, true>(method_idx, this_object, referrer, thread);
}
extern "C" mirror::Object* art_portable_find_direct_method_from_code_with_access_check(uint32_t method_idx,
@@ -66,7 +78,7 @@
mirror::ArtMethod* referrer,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return FindMethodHelper(method_idx, this_object, referrer, true, kDirect, thread);
+ return FindMethodHelper<kDirect, true>(method_idx, this_object, referrer, thread);
}
extern "C" mirror::Object* art_portable_find_virtual_method_from_code_with_access_check(uint32_t method_idx,
@@ -74,7 +86,7 @@
mirror::ArtMethod* referrer,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return FindMethodHelper(method_idx, this_object, referrer, true, kVirtual, thread);
+ return FindMethodHelper<kVirtual, true>(method_idx, this_object, referrer, thread);
}
extern "C" mirror::Object* art_portable_find_super_method_from_code_with_access_check(uint32_t method_idx,
@@ -82,7 +94,7 @@
mirror::ArtMethod* referrer,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return FindMethodHelper(method_idx, this_object, referrer, true, kSuper, thread);
+ return FindMethodHelper<kSuper, true>(method_idx, this_object, referrer, thread);
}
extern "C" mirror::Object* art_portable_find_interface_method_from_code_with_access_check(uint32_t method_idx,
@@ -90,7 +102,7 @@
mirror::ArtMethod* referrer,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return FindMethodHelper(method_idx, this_object, referrer, true, kInterface, thread);
+ return FindMethodHelper<kInterface, true>(method_idx, this_object, referrer, thread);
}
extern "C" mirror::Object* art_portable_find_interface_method_from_code(uint32_t method_idx,
@@ -98,7 +110,7 @@
mirror::ArtMethod* referrer,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return FindMethodHelper(method_idx, this_object, referrer, false, kInterface, thread);
+ return FindMethodHelper<kInterface, false>(method_idx, this_object, referrer, thread);
}
} // namespace art
diff --git a/runtime/entrypoints/quick/quick_field_entrypoints.cc b/runtime/entrypoints/quick/quick_field_entrypoints.cc
index 0ec1eb7..0a533bd 100644
--- a/runtime/entrypoints/quick/quick_field_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_field_entrypoints.cc
@@ -35,7 +35,7 @@
return field->Get32(field->GetDeclaringClass());
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
- field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveRead, sizeof(int32_t), true);
+ field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int32_t));
if (LIKELY(field != NULL)) {
return field->Get32(field->GetDeclaringClass());
}
@@ -52,7 +52,7 @@
return field->Get64(field->GetDeclaringClass());
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
- field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveRead, sizeof(int64_t), true);
+ field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int64_t));
if (LIKELY(field != NULL)) {
return field->Get64(field->GetDeclaringClass());
}
@@ -69,8 +69,8 @@
return field->GetObj(field->GetDeclaringClass());
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
- field = FindFieldFromCode(field_idx, referrer, self, StaticObjectRead, sizeof(mirror::Object*),
- true);
+ field = FindFieldFromCode<StaticObjectRead, true>(field_idx, referrer, self,
+ sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
return field->GetObj(field->GetDeclaringClass());
}
@@ -87,8 +87,8 @@
return field->Get32(obj);
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
- field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveRead, sizeof(int32_t),
- true);
+ field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self,
+ sizeof(int32_t));
if (LIKELY(field != NULL)) {
if (UNLIKELY(obj == NULL)) {
ThrowLocation throw_location = self->GetCurrentLocationForThrow();
@@ -110,8 +110,8 @@
return field->Get64(obj);
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
- field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveRead, sizeof(int64_t),
- true);
+ field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self,
+ sizeof(int64_t));
if (LIKELY(field != NULL)) {
if (UNLIKELY(obj == NULL)) {
ThrowLocation throw_location = self->GetCurrentLocationForThrow();
@@ -134,8 +134,8 @@
return field->GetObj(obj);
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
- field = FindFieldFromCode(field_idx, referrer, self, InstanceObjectRead, sizeof(mirror::Object*),
- true);
+ field = FindFieldFromCode<InstanceObjectRead, true>(field_idx, referrer, self,
+ sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
if (UNLIKELY(obj == NULL)) {
ThrowLocation throw_location = self->GetCurrentLocationForThrow();
@@ -158,7 +158,7 @@
return 0; // success
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
- field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveWrite, sizeof(int32_t), true);
+ field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, self, sizeof(int32_t));
if (LIKELY(field != NULL)) {
field->Set32(field->GetDeclaringClass(), new_value);
return 0; // success
@@ -176,7 +176,7 @@
return 0; // success
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
- field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveWrite, sizeof(int64_t), true);
+ field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, self, sizeof(int64_t));
if (LIKELY(field != NULL)) {
field->Set64(field->GetDeclaringClass(), new_value);
return 0; // success
@@ -197,7 +197,8 @@
}
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
- field = FindFieldFromCode(field_idx, referrer, self, StaticObjectWrite, sizeof(mirror::Object*), true);
+ field = FindFieldFromCode<StaticObjectWrite, true>(field_idx, referrer, self,
+ sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
field->SetObj(field->GetDeclaringClass(), new_value);
return 0; // success
@@ -216,8 +217,8 @@
return 0; // success
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
- field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveWrite, sizeof(int32_t),
- true);
+ field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, self,
+ sizeof(int32_t));
if (LIKELY(field != NULL)) {
if (UNLIKELY(obj == NULL)) {
ThrowLocation throw_location = self->GetCurrentLocationForThrow();
@@ -244,8 +245,8 @@
}
*sp = callee_save;
self->SetTopOfStack(sp, 0);
- field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveWrite, sizeof(int64_t),
- true);
+ field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, self,
+ sizeof(int64_t));
if (LIKELY(field != NULL)) {
if (UNLIKELY(obj == NULL)) {
ThrowLocation throw_location = self->GetCurrentLocationForThrow();
@@ -270,8 +271,8 @@
return 0; // success
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
- field = FindFieldFromCode(field_idx, referrer, self, InstanceObjectWrite,
- sizeof(mirror::Object*), true);
+ field = FindFieldFromCode<InstanceObjectWrite, true>(field_idx, referrer, self,
+ sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
if (UNLIKELY(obj == NULL)) {
ThrowLocation throw_location = self->GetCurrentLocationForThrow();
diff --git a/runtime/entrypoints/quick/quick_invoke_entrypoints.cc b/runtime/entrypoints/quick/quick_invoke_entrypoints.cc
index 07c1c01..b852a32 100644
--- a/runtime/entrypoints/quick/quick_invoke_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_invoke_entrypoints.cc
@@ -118,8 +118,7 @@
DCHECK_EQ(instr_code, Instruction::INVOKE_INTERFACE_RANGE);
dex_method_idx = instr->VRegB_3rc();
}
- method = FindMethodFromCode(dex_method_idx, this_object, caller_method, self,
- false, kInterface);
+ method = FindMethodFromCode<kInterface, false>(dex_method_idx, this_object, caller_method, self);
if (UNLIKELY(method == NULL)) {
CHECK(self->IsExceptionPending());
return 0; // Failure.
@@ -142,17 +141,15 @@
return result;
}
-
+template<InvokeType type, bool access_check>
static uint64_t artInvokeCommon(uint32_t method_idx, mirror::Object* this_object,
mirror::ArtMethod* caller_method,
- Thread* self, mirror::ArtMethod** sp, bool access_check,
- InvokeType type)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ Thread* self, mirror::ArtMethod** sp) {
mirror::ArtMethod* method = FindMethodFast(method_idx, this_object, caller_method,
access_check, type);
if (UNLIKELY(method == NULL)) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsAndArgs);
- method = FindMethodFromCode(method_idx, this_object, caller_method, self, access_check, type);
+ method = FindMethodFromCode<type, access_check>(method_idx, this_object, caller_method, self);
if (UNLIKELY(method == NULL)) {
CHECK(self->IsExceptionPending());
return 0; // failure
@@ -176,6 +173,27 @@
return result;
}
+// Explicit template declarations of artInvokeCommon for all invoke types.
+#define EXPLICIT_ART_INVOKE_COMMON_TEMPLATE_DECL(_type, _access_check) \
+ template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) \
+ static uint64_t artInvokeCommon<_type, _access_check>(uint32_t method_idx, \
+ mirror::Object* this_object, \
+ mirror::ArtMethod* caller_method, \
+ Thread* self, mirror::ArtMethod** sp)
+
+#define EXPLICIT_ART_INVOKE_COMMON_TYPED_TEMPLATE_DECL(_type) \
+ EXPLICIT_ART_INVOKE_COMMON_TEMPLATE_DECL(_type, false); \
+ EXPLICIT_ART_INVOKE_COMMON_TEMPLATE_DECL(_type, true)
+
+EXPLICIT_ART_INVOKE_COMMON_TYPED_TEMPLATE_DECL(kStatic);
+EXPLICIT_ART_INVOKE_COMMON_TYPED_TEMPLATE_DECL(kDirect);
+EXPLICIT_ART_INVOKE_COMMON_TYPED_TEMPLATE_DECL(kVirtual);
+EXPLICIT_ART_INVOKE_COMMON_TYPED_TEMPLATE_DECL(kSuper);
+EXPLICIT_ART_INVOKE_COMMON_TYPED_TEMPLATE_DECL(kInterface);
+
+#undef EXPLICIT_ART_INVOKE_COMMON_TYPED_TEMPLATE_DECL
+#undef EXPLICIT_ART_INVOKE_COMMON_TEMPLATE_DECL
+
// See comments in runtime_support_asm.S
extern "C" uint64_t artInvokeInterfaceTrampolineWithAccessCheck(uint32_t method_idx,
mirror::Object* this_object,
@@ -183,7 +201,7 @@
Thread* self,
mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return artInvokeCommon(method_idx, this_object, caller_method, self, sp, true, kInterface);
+ return artInvokeCommon<kInterface, true>(method_idx, this_object, caller_method, self, sp);
}
@@ -193,7 +211,7 @@
Thread* self,
mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return artInvokeCommon(method_idx, this_object, caller_method, self, sp, true, kDirect);
+ return artInvokeCommon<kDirect, true>(method_idx, this_object, caller_method, self, sp);
}
extern "C" uint64_t artInvokeStaticTrampolineWithAccessCheck(uint32_t method_idx,
@@ -202,7 +220,7 @@
Thread* self,
mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return artInvokeCommon(method_idx, this_object, caller_method, self, sp, true, kStatic);
+ return artInvokeCommon<kStatic, true>(method_idx, this_object, caller_method, self, sp);
}
extern "C" uint64_t artInvokeSuperTrampolineWithAccessCheck(uint32_t method_idx,
@@ -211,7 +229,7 @@
Thread* self,
mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return artInvokeCommon(method_idx, this_object, caller_method, self, sp, true, kSuper);
+ return artInvokeCommon<kSuper, true>(method_idx, this_object, caller_method, self, sp);
}
extern "C" uint64_t artInvokeVirtualTrampolineWithAccessCheck(uint32_t method_idx,
@@ -220,7 +238,7 @@
Thread* self,
mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return artInvokeCommon(method_idx, this_object, caller_method, self, sp, true, kVirtual);
+ return artInvokeCommon<kVirtual, true>(method_idx, this_object, caller_method, self, sp);
}
} // namespace art
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index 29b00d2..0bc834c 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -90,7 +90,6 @@
bool DoCall(ArtMethod* method, Object* receiver, Thread* self, ShadowFrame& shadow_frame,
const Instruction* inst, uint16_t inst_data, JValue* result);
-
// Handles invoke-XXX/range instructions.
// Returns true on success, otherwise throws an exception and returns false.
template<InvokeType type, bool is_range, bool do_access_check>
@@ -99,14 +98,14 @@
const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
const uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c();
Object* receiver = (type == kStatic) ? nullptr : shadow_frame.GetVRegReference(vregC);
- ArtMethod* const method = FindMethodFromCode(method_idx, receiver, shadow_frame.GetMethod(), self,
- do_access_check, type);
+ ArtMethod* const method = FindMethodFromCode<type, do_access_check>(method_idx, receiver,
+ shadow_frame.GetMethod(),
+ self);
if (type != kStatic) {
// Reload the vreg since the GC may have moved the object.
receiver = shadow_frame.GetVRegReference(vregC);
}
-
- if (UNLIKELY(method == NULL)) {
+ if (UNLIKELY(method == nullptr)) {
CHECK(self->IsExceptionPending());
result->SetJ(0);
return false;
@@ -128,7 +127,7 @@
JValue* result) {
const uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c();
Object* const receiver = shadow_frame.GetVRegReference(vregC);
- if (UNLIKELY(receiver == NULL)) {
+ if (UNLIKELY(receiver == nullptr)) {
// We lost the reference to the method index so we cannot get a more
// precised exception message.
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
@@ -136,7 +135,7 @@
}
const uint32_t vtable_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
ArtMethod* const method = receiver->GetClass()->GetVTable()->GetWithoutChecks(vtable_idx);
- if (UNLIKELY(method == NULL)) {
+ if (UNLIKELY(method == nullptr)) {
CHECK(self->IsExceptionPending());
result->SetJ(0);
return false;
@@ -155,12 +154,11 @@
template<FindFieldType find_type, Primitive::Type field_type, bool do_access_check>
static inline bool DoFieldGet(Thread* self, ShadowFrame& shadow_frame,
const Instruction* inst, uint16_t inst_data) {
- bool is_static = (find_type == StaticObjectRead) || (find_type == StaticPrimitiveRead);
- uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c();
- ArtField* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self,
- find_type, Primitive::FieldSize(field_type),
- do_access_check);
- if (UNLIKELY(f == NULL)) {
+ const bool is_static = (find_type == StaticObjectRead) || (find_type == StaticPrimitiveRead);
+ const uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c();
+ ArtField* f = FindFieldFromCode<find_type, do_access_check>(field_idx, shadow_frame.GetMethod(), self,
+ Primitive::FieldSize(field_type));
+ if (UNLIKELY(f == nullptr)) {
CHECK(self->IsExceptionPending());
return false;
}
@@ -169,7 +167,7 @@
obj = f->GetDeclaringClass();
} else {
obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
- if (UNLIKELY(obj == NULL)) {
+ if (UNLIKELY(obj == nullptr)) {
ThrowNullPointerExceptionForFieldAccess(shadow_frame.GetCurrentLocationForThrow(), f, true);
return false;
}
@@ -208,7 +206,7 @@
template<Primitive::Type field_type>
static inline bool DoIGetQuick(ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data) {
Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
- if (UNLIKELY(obj == NULL)) {
+ if (UNLIKELY(obj == nullptr)) {
// We lost the reference to the field index so we cannot get a more
// precised exception message.
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
@@ -241,10 +239,9 @@
bool do_assignability_check = do_access_check;
bool is_static = (find_type == StaticObjectWrite) || (find_type == StaticPrimitiveWrite);
uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c();
- ArtField* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self,
- find_type, Primitive::FieldSize(field_type),
- do_access_check);
- if (UNLIKELY(f == NULL)) {
+ ArtField* f = FindFieldFromCode<find_type, do_access_check>(field_idx, shadow_frame.GetMethod(), self,
+ Primitive::FieldSize(field_type));
+ if (UNLIKELY(f == nullptr)) {
CHECK(self->IsExceptionPending());
return false;
}
@@ -253,7 +250,7 @@
obj = f->GetDeclaringClass();
} else {
obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
- if (UNLIKELY(obj == NULL)) {
+ if (UNLIKELY(obj == nullptr)) {
ThrowNullPointerExceptionForFieldAccess(shadow_frame.GetCurrentLocationForThrow(),
f, false);
return false;
@@ -281,7 +278,7 @@
break;
case Primitive::kPrimNot: {
Object* reg = shadow_frame.GetVRegReference(vregA);
- if (do_assignability_check && reg != NULL) {
+ if (do_assignability_check && reg != nullptr) {
Class* field_class = FieldHelper(f).GetType();
if (!reg->VerifierInstanceOf(field_class)) {
// This should never happen.
@@ -308,7 +305,7 @@
template<Primitive::Type field_type>
static inline bool DoIPutQuick(const ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data) {
Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
- if (UNLIKELY(obj == NULL)) {
+ if (UNLIKELY(obj == nullptr)) {
// We lost the reference to the field index so we cannot get a more
// precised exception message.
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc
index 4c5f90c..6c6d488 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -291,8 +291,8 @@
ASSERT_TRUE(field_id != NULL);
uint32_t field_idx = dex_file->GetIndexForFieldId(*field_id);
- ArtField* field = FindFieldFromCode(field_idx, clinit, Thread::Current(), StaticObjectRead,
- sizeof(Object*), true);
+ ArtField* field = FindFieldFromCode<StaticObjectRead, true>(field_idx, clinit, Thread::Current(),
+ sizeof(Object*));
Object* s0 = field->GetObj(klass);
EXPECT_TRUE(s0 != NULL);