summaryrefslogtreecommitdiff
path: root/runtime/entrypoints/entrypoint_utils.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/entrypoints/entrypoint_utils.cc')
-rw-r--r--runtime/entrypoints/entrypoint_utils.cc65
1 files changed, 38 insertions, 27 deletions
diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc
index 63d2aa4351..ae6e98a544 100644
--- a/runtime/entrypoints/entrypoint_utils.cc
+++ b/runtime/entrypoints/entrypoint_utils.cc
@@ -22,6 +22,7 @@
#include "base/mutex.h"
#include "base/sdk_version.h"
#include "class_linker-inl.h"
+#include "class_root-inl.h"
#include "dex/dex_file-inl.h"
#include "dex/method_reference.h"
#include "entrypoints/entrypoint_utils-inl.h"
@@ -33,14 +34,14 @@
#include "mirror/class-inl.h"
#include "mirror/method.h"
#include "mirror/object-inl.h"
-#include "mirror/object_array-inl.h"
+#include "mirror/object_array-alloc-inl.h"
#include "nth_caller_visitor.h"
#include "oat_file.h"
#include "oat_file-inl.h"
#include "oat_quick_method_header.h"
#include "reflection.h"
#include "scoped_thread_state_change-inl.h"
-#include "well_known_classes.h"
+#include "well_known_classes-inl.h"
namespace art {
@@ -65,60 +66,70 @@ JValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa,
jobject rcvr_jobj,
jobject interface_method_jobj,
std::vector<jvalue>& args) {
- DCHECK(soa.Env()->IsInstanceOf(rcvr_jobj, WellKnownClasses::java_lang_reflect_Proxy));
+ StackHandleScope<4u> hs(soa.Self());
+ DCHECK(rcvr_jobj != nullptr);
+ Handle<mirror::Object> h_receiver = hs.NewHandle(soa.Decode<mirror::Object>(rcvr_jobj));
+ DCHECK(h_receiver->InstanceOf(GetClassRoot(ClassRoot::kJavaLangReflectProxy)));
+ Handle<mirror::Method> h_interface_method =
+ hs.NewHandle(soa.Decode<mirror::Method>(interface_method_jobj));
// Build argument array possibly triggering GC.
soa.Self()->AssertThreadSuspensionIsAllowable();
- jobjectArray args_jobj = nullptr;
+ auto h_args = hs.NewHandle<mirror::ObjectArray<mirror::Object>>(nullptr);
const JValue zero;
- uint32_t target_sdk_version = Runtime::Current()->GetTargetSdkVersion();
+ Runtime* runtime = Runtime::Current();
+ uint32_t target_sdk_version = runtime->GetTargetSdkVersion();
// Do not create empty arrays unless needed to maintain Dalvik bug compatibility.
if (args.size() > 0 || IsSdkVersionSetAndAtMost(target_sdk_version, SdkVersion::kL)) {
- args_jobj = soa.Env()->NewObjectArray(args.size(), WellKnownClasses::java_lang_Object, nullptr);
- if (args_jobj == nullptr) {
+ h_args.Assign(mirror::ObjectArray<mirror::Object>::Alloc(
+ soa.Self(), GetClassRoot<mirror::ObjectArray<mirror::Object>>(), args.size()));
+ if (h_args == nullptr) {
CHECK(soa.Self()->IsExceptionPending());
return zero;
}
for (size_t i = 0; i < args.size(); ++i) {
+ ObjPtr<mirror::Object> value;
if (shorty[i + 1] == 'L') {
- jobject val = args[i].l;
- soa.Env()->SetObjectArrayElement(args_jobj, i, val);
+ value = soa.Decode<mirror::Object>(args[i].l);
} else {
JValue jv;
jv.SetJ(args[i].j);
- ObjPtr<mirror::Object> val = BoxPrimitive(Primitive::GetType(shorty[i + 1]), jv);
- if (val == nullptr) {
+ value = BoxPrimitive(Primitive::GetType(shorty[i + 1]), jv);
+ if (value == nullptr) {
CHECK(soa.Self()->IsExceptionPending());
return zero;
}
- soa.Decode<mirror::ObjectArray<mirror::Object>>(args_jobj)->Set<false>(i, val);
}
+ // We do not support `Proxy.invoke()` in a transaction.
+ h_args->SetWithoutChecks</*kActiveTransaction=*/ false>(i, value);
}
}
// Call Proxy.invoke(Proxy proxy, Method method, Object[] args).
- jvalue invocation_args[3];
- invocation_args[0].l = rcvr_jobj;
- invocation_args[1].l = interface_method_jobj;
- invocation_args[2].l = args_jobj;
- jobject result =
- soa.Env()->CallStaticObjectMethodA(WellKnownClasses::java_lang_reflect_Proxy,
- WellKnownClasses::java_lang_reflect_Proxy_invoke,
- invocation_args);
+ Handle<mirror::Object> h_result = hs.NewHandle(
+ WellKnownClasses::java_lang_reflect_Proxy_invoke->InvokeStatic<'L', 'L', 'L', 'L'>(
+ soa.Self(), h_receiver.Get(), h_interface_method.Get(), h_args.Get()));
// Unbox result and handle error conditions.
if (LIKELY(!soa.Self()->IsExceptionPending())) {
- if (shorty[0] == 'V' || (shorty[0] == 'L' && result == nullptr)) {
+ if (shorty[0] == 'V' || (shorty[0] == 'L' && h_result == nullptr)) {
// Do nothing.
return zero;
} else {
- ArtMethod* interface_method =
- soa.Decode<mirror::Method>(interface_method_jobj)->GetArtMethod();
- // This can cause thread suspension.
- ObjPtr<mirror::Class> result_type = interface_method->ResolveReturnType();
- ObjPtr<mirror::Object> result_ref = soa.Decode<mirror::Object>(result);
+ ObjPtr<mirror::Class> result_type;
+ if (shorty[0] == 'L') {
+ // This can cause thread suspension.
+ result_type = h_interface_method->GetArtMethod()->ResolveReturnType();
+ if (result_type == nullptr) {
+ DCHECK(soa.Self()->IsExceptionPending());
+ return zero;
+ }
+ } else {
+ result_type = runtime->GetClassLinker()->LookupPrimitiveClass(shorty[0]);
+ DCHECK(result_type != nullptr);
+ }
JValue result_unboxed;
- if (!UnboxPrimitiveForResult(result_ref, result_type, &result_unboxed)) {
+ if (!UnboxPrimitiveForResult(h_result.Get(), result_type, &result_unboxed)) {
DCHECK(soa.Self()->IsExceptionPending());
return zero;
}