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