• 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 #ifndef ART_RUNTIME_MIRROR_METHOD_HANDLE_IMPL_H_
18 #define ART_RUNTIME_MIRROR_METHOD_HANDLE_IMPL_H_
19 
20 #include "art_field.h"
21 #include "art_method.h"
22 #include "class.h"
23 #include "method_type.h"
24 #include "obj_ptr.h"
25 #include "object.h"
26 
27 namespace art {
28 
29 struct MethodHandleOffsets;
30 struct MethodHandleImplOffsets;
31 class ReflectiveValueVisitor;
32 
33 namespace mirror {
34 
35 // C++ mirror of java.lang.invoke.MethodHandle
36 class MANAGED MethodHandle : public Object {
37  public:
38   MIRROR_CLASS("Ljava/lang/invoke/MethodHandle;");
39 
40   // Defines the behaviour of a given method handle. The behaviour
41   // of a handle of a given kind is identical to the dex bytecode behaviour
42   // of the equivalent instruction.
43   //
44   // NOTE: These must be kept in sync with the constants defined in
45   // java.lang.invoke.MethodHandle.
46   enum Kind {
47     kInvokeVirtual = 0,
48     kInvokeSuper,
49     kInvokeDirect,
50     kInvokeStatic,
51     kInvokeInterface,
52     kInvokeTransform,
53     kInvokeVarHandle,
54     kInvokeVarHandleExact,
55     kInstanceGet,
56     kInstancePut,
57     kStaticGet,
58     kStaticPut,
59     kLastValidKind = kStaticPut,
60     kFirstAccessorKind = kInstanceGet,
61     kLastAccessorKind = kStaticPut,
62     kLastInvokeKind = kInvokeVarHandleExact
63   };
64 
65   Kind GetHandleKind() REQUIRES_SHARED(Locks::mutator_lock_);
66 
67   ObjPtr<mirror::MethodType> GetMethodType() REQUIRES_SHARED(Locks::mutator_lock_);
68 
69   ObjPtr<mirror::MethodHandle> GetAsTypeCache() REQUIRES_SHARED(Locks::mutator_lock_);
70 
71   ArtField* GetTargetField() REQUIRES_SHARED(Locks::mutator_lock_);
72 
73   ArtMethod* GetTargetMethod() REQUIRES_SHARED(Locks::mutator_lock_);
74 
75   // Gets the return type for a named invoke method, or nullptr if the invoke method is not
76   // supported.
77   static const char* GetReturnTypeDescriptor(const char* invoke_method_name);
78 
79   // Used when classes become structurally obsolete to change the MethodHandle to refer to the new
80   // method or field.
81   void VisitTarget(ReflectiveValueVisitor* v) REQUIRES(Locks::mutator_lock_);
82 
83  protected:
84   void Initialize(uintptr_t art_field_or_method, Kind kind, Handle<MethodType> method_type)
85       REQUIRES_SHARED(Locks::mutator_lock_);
86 
87  private:
88   HeapReference<mirror::MethodHandle> as_type_cache_;
89   HeapReference<mirror::MethodHandle> cached_spread_invoker_;
90   HeapReference<mirror::MethodType> method_type_;
91   uint32_t handle_kind_;
92   uint64_t art_field_or_method_;
93 
94  private:
CachedSpreadInvokerOffset()95   static MemberOffset CachedSpreadInvokerOffset() {
96     return MemberOffset(OFFSETOF_MEMBER(MethodHandle, cached_spread_invoker_));
97   }
AsTypeCacheOffset()98   static MemberOffset AsTypeCacheOffset() {
99     return MemberOffset(OFFSETOF_MEMBER(MethodHandle, as_type_cache_));
100   }
MethodTypeOffset()101   static MemberOffset MethodTypeOffset() {
102     return MemberOffset(OFFSETOF_MEMBER(MethodHandle, method_type_));
103   }
ArtFieldOrMethodOffset()104   static MemberOffset ArtFieldOrMethodOffset() {
105     return MemberOffset(OFFSETOF_MEMBER(MethodHandle, art_field_or_method_));
106   }
HandleKindOffset()107   static MemberOffset HandleKindOffset() {
108     return MemberOffset(OFFSETOF_MEMBER(MethodHandle, handle_kind_));
109   }
110 
111   friend struct art::MethodHandleOffsets;  // for verifying offset information
112   DISALLOW_IMPLICIT_CONSTRUCTORS(MethodHandle);
113 };
114 
115 // C++ mirror of java.lang.invoke.MethodHandleImpl
116 class MANAGED MethodHandleImpl : public MethodHandle {
117  public:
118   MIRROR_CLASS("Ljava/lang/invoke/MethodHandleImpl;");
119 
120   static ObjPtr<mirror::MethodHandleImpl> Create(Thread* const self,
121                                                  uintptr_t art_field_or_method,
122                                                  MethodHandle::Kind kind,
123                                                  Handle<MethodType> method_type)
124       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
125 
126  private:
InfoOffset()127   static MemberOffset InfoOffset() {
128     return MemberOffset(OFFSETOF_MEMBER(MethodHandleImpl, info_));
129   }
130 
131   HeapReference<mirror::Object> info_;  // Unused by the runtime.
132 
133   friend struct art::MethodHandleImplOffsets;  // for verifying offset information
134   DISALLOW_IMPLICIT_CONSTRUCTORS(MethodHandleImpl);
135 };
136 
137 }  // namespace mirror
138 }  // namespace art
139 
140 #endif  // ART_RUNTIME_MIRROR_METHOD_HANDLE_IMPL_H_
141