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 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 ObjPtr<mirror::MethodType> GetMethodType() REQUIRES_SHARED(Locks::mutator_lock_); 71 72 ALWAYS_INLINE ObjPtr<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 protected: 91 void Initialize(uintptr_t art_field_or_method, Kind kind, Handle<MethodType> method_type) 92 REQUIRES_SHARED(Locks::mutator_lock_); 93 94 private: 95 HeapReference<mirror::MethodHandle> cached_spread_invoker_; 96 HeapReference<mirror::MethodType> nominal_type_; 97 HeapReference<mirror::MethodType> method_type_; 98 uint32_t handle_kind_; 99 uint64_t art_field_or_method_; 100 101 private: CachedSpreadInvokerOffset()102 static MemberOffset CachedSpreadInvokerOffset() { 103 return MemberOffset(OFFSETOF_MEMBER(MethodHandle, cached_spread_invoker_)); 104 } NominalTypeOffset()105 static MemberOffset NominalTypeOffset() { 106 return MemberOffset(OFFSETOF_MEMBER(MethodHandle, nominal_type_)); 107 } MethodTypeOffset()108 static MemberOffset MethodTypeOffset() { 109 return MemberOffset(OFFSETOF_MEMBER(MethodHandle, method_type_)); 110 } ArtFieldOrMethodOffset()111 static MemberOffset ArtFieldOrMethodOffset() { 112 return MemberOffset(OFFSETOF_MEMBER(MethodHandle, art_field_or_method_)); 113 } HandleKindOffset()114 static MemberOffset HandleKindOffset() { 115 return MemberOffset(OFFSETOF_MEMBER(MethodHandle, handle_kind_)); 116 } 117 118 friend struct art::MethodHandleOffsets; // for verifying offset information 119 DISALLOW_IMPLICIT_CONSTRUCTORS(MethodHandle); 120 }; 121 122 // C++ mirror of java.lang.invoke.MethodHandleImpl 123 class MANAGED MethodHandleImpl : public MethodHandle { 124 public: 125 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 private: InfoOffset()132 static MemberOffset InfoOffset() { 133 return MemberOffset(OFFSETOF_MEMBER(MethodHandleImpl, info_)); 134 } 135 136 HeapReference<mirror::Object> info_; // Unused by the runtime. 137 138 friend struct art::MethodHandleImplOffsets; // for verifying offset information 139 DISALLOW_IMPLICIT_CONSTRUCTORS(MethodHandleImpl); 140 }; 141 142 } // namespace mirror 143 } // namespace art 144 145 #endif // ART_RUNTIME_MIRROR_METHOD_HANDLE_IMPL_H_ 146