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