summaryrefslogtreecommitdiffstats
path: root/runtime/reflection.cc
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2015-04-24 16:55:16 -0700
committerAndreas Gampe <agampe@google.com>2015-04-25 22:08:16 +0000
commitf36cb5f65cb150151aa40b23937e2b0ad75cc546 (patch)
tree25365c69a089bc491a4b070ee3403be964cfc606 /runtime/reflection.cc
parent33984b4d6b79b2d65258e69506e5669be704db82 (diff)
downloadart-f36cb5f65cb150151aa40b23937e2b0ad75cc546.tar.gz
art-f36cb5f65cb150151aa40b23937e2b0ad75cc546.tar.bz2
art-f36cb5f65cb150151aa40b23937e2b0ad75cc546.zip
Move Class.newInstance to native
Avoids 1 allocation and several JNI transitions. Before: Class_classNewInstance: 4462.39 ns; σ=39.42 ns @ 3 trials After: Class_classNewInstance: 1073.39 ns; σ=24.14 ns @ 10 trials Bug: 20269715 Bug: 20566996 Change-Id: Icd52155ce79a978a4d869855bfdfd7735abd8187
Diffstat (limited to 'runtime/reflection.cc')
-rw-r--r--runtime/reflection.cc32
1 files changed, 20 insertions, 12 deletions
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index 3099094ed4..a2ce0cbf12 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -799,40 +799,48 @@ bool UnboxPrimitiveForField(mirror::Object* o, mirror::Class* dst_class, ArtFiel
return UnboxPrimitive(o, dst_class, f, unboxed_value);
}
-bool UnboxPrimitiveForResult(mirror::Object* o,
- mirror::Class* dst_class, JValue* unboxed_value) {
+bool UnboxPrimitiveForResult(mirror::Object* o, mirror::Class* dst_class, JValue* unboxed_value) {
return UnboxPrimitive(o, dst_class, nullptr, unboxed_value);
}
+mirror::Class* GetCallingClass(Thread* self, size_t num_frames) {
+ NthCallerVisitor visitor(self, num_frames);
+ visitor.WalkStack();
+ return visitor.caller != nullptr ? visitor.caller->GetDeclaringClass() : nullptr;
+}
+
bool VerifyAccess(Thread* self, mirror::Object* obj, mirror::Class* declaring_class,
uint32_t access_flags, mirror::Class** calling_class, size_t num_frames) {
if ((access_flags & kAccPublic) != 0) {
return true;
}
- NthCallerVisitor visitor(self, num_frames);
- visitor.WalkStack();
- if (UNLIKELY(visitor.caller == nullptr)) {
+ auto* klass = GetCallingClass(self, num_frames);
+ if (UNLIKELY(klass == nullptr)) {
// The caller is an attached native thread.
return false;
}
- mirror::Class* caller_class = visitor.caller->GetDeclaringClass();
- if (caller_class == declaring_class) {
+ *calling_class = klass;
+ return VerifyAccess(self, obj, declaring_class, access_flags, klass);
+}
+
+bool VerifyAccess(Thread* self, mirror::Object* obj, mirror::Class* declaring_class,
+ uint32_t access_flags, mirror::Class* calling_class) {
+ if (calling_class == declaring_class) {
return true;
}
ScopedAssertNoThreadSuspension sants(self, "verify-access");
- *calling_class = caller_class;
if ((access_flags & kAccPrivate) != 0) {
return false;
}
if ((access_flags & kAccProtected) != 0) {
- if (obj != nullptr && !obj->InstanceOf(caller_class) &&
- !declaring_class->IsInSamePackage(caller_class)) {
+ if (obj != nullptr && !obj->InstanceOf(calling_class) &&
+ !declaring_class->IsInSamePackage(calling_class)) {
return false;
- } else if (declaring_class->IsAssignableFrom(caller_class)) {
+ } else if (declaring_class->IsAssignableFrom(calling_class)) {
return true;
}
}
- return declaring_class->IsInSamePackage(caller_class);
+ return declaring_class->IsInSamePackage(calling_class);
}
void InvalidReceiverError(mirror::Object* o, mirror::Class* c) {