• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "method_handle_impl-inl.h"
18 
19 #include "class-inl.h"
20 #include "gc_root-inl.h"
21 
22 namespace art {
23 namespace mirror {
24 
GetReturnTypeDescriptor(const char * invoke_method_name)25 const char* MethodHandle::GetReturnTypeDescriptor(const char* invoke_method_name) {
26   if (strcmp(invoke_method_name, "invoke") == 0 || strcmp(invoke_method_name, "invokeExact") == 0) {
27     return "Ljava/lang/Object;";
28   } else {
29     return nullptr;
30   }
31 }
32 
StaticClass()33 mirror::Class* MethodHandle::StaticClass() {
34   mirror::Class* klass = MethodHandleImpl::StaticClass()->GetSuperClass();
35   DCHECK(klass->DescriptorEquals("Ljava/lang/invoke/MethodHandle;"));
36   return klass;
37 }
38 
Initialize(uintptr_t art_field_or_method,Kind kind,Handle<MethodType> method_type)39 void MethodHandle::Initialize(uintptr_t art_field_or_method,
40                               Kind kind,
41                               Handle<MethodType> method_type)
42     REQUIRES_SHARED(Locks::mutator_lock_) {
43   CHECK(!Runtime::Current()->IsActiveTransaction());
44   SetFieldObject<false>(CachedSpreadInvokerOffset(), nullptr);
45   SetFieldObject<false>(NominalTypeOffset(), nullptr);
46   SetFieldObject<false>(MethodTypeOffset(), method_type.Get());
47   SetField32<false>(HandleKindOffset(), static_cast<uint32_t>(kind));
48   SetField64<false>(ArtFieldOrMethodOffset(), art_field_or_method);
49 }
50 
51 GcRoot<mirror::Class> MethodHandleImpl::static_class_;
52 
StaticClass()53 mirror::Class* MethodHandleImpl::StaticClass()  {
54   return static_class_.Read();
55 }
56 
SetClass(Class * klass)57 void MethodHandleImpl::SetClass(Class* klass) {
58   CHECK(static_class_.IsNull()) << static_class_.Read() << " " << klass;
59   CHECK(klass != nullptr);
60   static_class_ = GcRoot<Class>(klass);
61 }
62 
ResetClass()63 void MethodHandleImpl::ResetClass() {
64   CHECK(!static_class_.IsNull());
65   static_class_ = GcRoot<Class>(nullptr);
66 }
67 
VisitRoots(RootVisitor * visitor)68 void MethodHandleImpl::VisitRoots(RootVisitor* visitor) {
69   static_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
70 }
71 
Create(Thread * const self,uintptr_t art_field_or_method,MethodHandle::Kind kind,Handle<MethodType> method_type)72 mirror::MethodHandleImpl* MethodHandleImpl::Create(Thread* const self,
73                                                    uintptr_t art_field_or_method,
74                                                    MethodHandle::Kind kind,
75                                                    Handle<MethodType> method_type)
76     REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_) {
77   StackHandleScope<1> hs(self);
78   Handle<mirror::MethodHandleImpl> mh(
79       hs.NewHandle(ObjPtr<MethodHandleImpl>::DownCast(StaticClass()->AllocObject(self))));
80   mh->Initialize(art_field_or_method, kind, method_type);
81   return mh.Get();
82 }
83 
84 }  // namespace mirror
85 }  // namespace art
86