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