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 "object.h" 25 #include "method_type.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 kInstanceGet, 52 kInstancePut, 53 kStaticGet, 54 kStaticPut, 55 kLastValidKind = kStaticPut, 56 kFirstAccessorKind = kInstanceGet, 57 kLastAccessorKind = kStaticPut, 58 kLastInvokeKind = kInvokeCallSiteTransform 59 }; 60 GetHandleKind()61 Kind GetHandleKind() REQUIRES_SHARED(Locks::mutator_lock_) { 62 const int32_t handle_kind = GetField32(OFFSET_OF_OBJECT_MEMBER(MethodHandle, handle_kind_)); 63 DCHECK(handle_kind >= 0 && 64 handle_kind <= static_cast<int32_t>(Kind::kLastValidKind)); 65 return static_cast<Kind>(handle_kind); 66 } 67 68 ALWAYS_INLINE mirror::MethodType* GetMethodType() REQUIRES_SHARED(Locks::mutator_lock_); 69 70 ALWAYS_INLINE mirror::MethodType* GetNominalType() REQUIRES_SHARED(Locks::mutator_lock_); 71 GetTargetField()72 ArtField* GetTargetField() REQUIRES_SHARED(Locks::mutator_lock_) { 73 return reinterpret_cast<ArtField*>( 74 GetField64(OFFSET_OF_OBJECT_MEMBER(MethodHandle, art_field_or_method_))); 75 } 76 GetTargetMethod()77 ArtMethod* GetTargetMethod() REQUIRES_SHARED(Locks::mutator_lock_) { 78 return reinterpret_cast<ArtMethod*>( 79 GetField64(OFFSET_OF_OBJECT_MEMBER(MethodHandle, art_field_or_method_))); 80 } 81 82 ALWAYS_INLINE ObjPtr<mirror::Class> GetTargetClass() REQUIRES_SHARED(Locks::mutator_lock_); 83 84 static mirror::Class* StaticClass() REQUIRES_SHARED(Locks::mutator_lock_); 85 86 protected: 87 void Initialize(uintptr_t art_field_or_method, Kind kind, Handle<MethodType> method_type) 88 REQUIRES_SHARED(Locks::mutator_lock_); 89 90 private: 91 HeapReference<mirror::MethodHandle> cached_spread_invoker_; 92 HeapReference<mirror::MethodType> nominal_type_; 93 HeapReference<mirror::MethodType> method_type_; 94 uint32_t handle_kind_; 95 uint64_t art_field_or_method_; 96 97 private: CachedSpreadInvokerOffset()98 static MemberOffset CachedSpreadInvokerOffset() { 99 return MemberOffset(OFFSETOF_MEMBER(MethodHandle, cached_spread_invoker_)); 100 } NominalTypeOffset()101 static MemberOffset NominalTypeOffset() { 102 return MemberOffset(OFFSETOF_MEMBER(MethodHandle, nominal_type_)); 103 } MethodTypeOffset()104 static MemberOffset MethodTypeOffset() { 105 return MemberOffset(OFFSETOF_MEMBER(MethodHandle, method_type_)); 106 } ArtFieldOrMethodOffset()107 static MemberOffset ArtFieldOrMethodOffset() { 108 return MemberOffset(OFFSETOF_MEMBER(MethodHandle, art_field_or_method_)); 109 } HandleKindOffset()110 static MemberOffset HandleKindOffset() { 111 return MemberOffset(OFFSETOF_MEMBER(MethodHandle, handle_kind_)); 112 } 113 114 friend struct art::MethodHandleOffsets; // for verifying offset information 115 DISALLOW_IMPLICIT_CONSTRUCTORS(MethodHandle); 116 }; 117 118 // C++ mirror of java.lang.invoke.MethodHandleImpl 119 class MANAGED MethodHandleImpl : public MethodHandle { 120 public: 121 static 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 static mirror::Class* StaticClass() REQUIRES_SHARED(Locks::mutator_lock_); 128 129 static void SetClass(Class* klass) REQUIRES_SHARED(Locks::mutator_lock_); 130 static void ResetClass() REQUIRES_SHARED(Locks::mutator_lock_); 131 static void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_); 132 133 private: InfoOffset()134 static MemberOffset InfoOffset() { 135 return MemberOffset(OFFSETOF_MEMBER(MethodHandleImpl, info_)); 136 } 137 138 HeapReference<mirror::Object> info_; // Unused by the runtime. 139 static GcRoot<mirror::Class> static_class_; // java.lang.invoke.MethodHandleImpl.class 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