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 #include "method_handle_impl-inl.h" 18 19 #include "class-inl.h" 20 #include "gc_root-inl.h" 21 22 namespace art { 23 namespace mirror { 24 25 const char* MethodHandle::GetReturnTypeDescriptor(const char* invoke_method_name) { 26 if (strcmp(invoke_method_name, "invoke") == 0 || strcmp(invoke_method_name, "invokeExact") == 0) { 27 return "Ljava/lang/Object;"; 28 } else { 29 return nullptr; 30 } 31 } 32 33 mirror::Class* MethodHandle::StaticClass() { 34 mirror::Class* klass = MethodHandleImpl::StaticClass()->GetSuperClass(); 35 DCHECK(klass->DescriptorEquals("Ljava/lang/invoke/MethodHandle;")); 36 return klass; 37 } 38 39 void MethodHandle::Initialize(uintptr_t art_field_or_method, 40 Kind kind, 41 Handle<MethodType> method_type) 42 REQUIRES_SHARED(Locks::mutator_lock_) { 43 CHECK(!Runtime::Current()->IsActiveTransaction()); 44 SetFieldObject<false>(CachedSpreadInvokerOffset(), nullptr); 45 SetFieldObject<false>(NominalTypeOffset(), nullptr); 46 SetFieldObject<false>(MethodTypeOffset(), method_type.Get()); 47 SetField32<false>(HandleKindOffset(), static_cast<uint32_t>(kind)); 48 SetField64<false>(ArtFieldOrMethodOffset(), art_field_or_method); 49 } 50 51 GcRoot<mirror::Class> MethodHandleImpl::static_class_; 52 53 mirror::Class* MethodHandleImpl::StaticClass() { 54 return static_class_.Read(); 55 } 56 57 void MethodHandleImpl::SetClass(Class* klass) { 58 CHECK(static_class_.IsNull()) << static_class_.Read() << " " << klass; 59 CHECK(klass != nullptr); 60 static_class_ = GcRoot<Class>(klass); 61 } 62 63 void MethodHandleImpl::ResetClass() { 64 CHECK(!static_class_.IsNull()); 65 static_class_ = GcRoot<Class>(nullptr); 66 } 67 68 void MethodHandleImpl::VisitRoots(RootVisitor* visitor) { 69 static_class_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass)); 70 } 71 72 mirror::MethodHandleImpl* MethodHandleImpl::Create(Thread* const self, 73 uintptr_t art_field_or_method, 74 MethodHandle::Kind kind, 75 Handle<MethodType> method_type) 76 REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_) { 77 StackHandleScope<1> hs(self); 78 Handle<mirror::MethodHandleImpl> mh( 79 hs.NewHandle(ObjPtr<MethodHandleImpl>::DownCast(StaticClass()->AllocObject(self)))); 80 mh->Initialize(art_field_or_method, kind, method_type); 81 return mh.Get(); 82 } 83 84 } // namespace mirror 85 } // namespace art 86