diff options
author | Mathieu Chartier <mathieuc@google.com> | 2015-04-24 16:55:16 -0700 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2015-04-25 22:08:16 +0000 |
commit | f36cb5f65cb150151aa40b23937e2b0ad75cc546 (patch) | |
tree | 25365c69a089bc491a4b070ee3403be964cfc606 /runtime/reflection.cc | |
parent | 33984b4d6b79b2d65258e69506e5669be704db82 (diff) | |
download | art-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.cc | 32 |
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) { |