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