portable_invoke_entrypoints.cc revision ea46f950e7a51585db293cd7f047de190a482414
1/* 2 * Copyright (C) 2012 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 "entrypoints/entrypoint_utils.h" 18#include "mirror/art_method-inl.h" 19#include "mirror/dex_cache-inl.h" 20#include "mirror/object-inl.h" 21 22namespace art { 23 24static mirror::ArtMethod* FindMethodHelper(uint32_t method_idx, 25 mirror::Object* this_object, 26 mirror::ArtMethod* caller_method, 27 bool access_check, 28 InvokeType type, 29 Thread* thread) 30 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 31 mirror::ArtMethod* method = FindMethodFast(method_idx, 32 this_object, 33 caller_method, 34 access_check, 35 type); 36 if (UNLIKELY(method == NULL)) { 37 method = FindMethodFromCode(method_idx, this_object, caller_method, 38 thread, access_check, type); 39 if (UNLIKELY(method == NULL)) { 40 CHECK(thread->IsExceptionPending()); 41 return 0; // failure 42 } 43 } 44 DCHECK(!thread->IsExceptionPending()); 45 const void* code = method->GetEntryPointFromCompiledCode(); 46 47 // When we return, the caller will branch to this address, so it had better not be 0! 48 if (UNLIKELY(code == NULL)) { 49 MethodHelper mh(method); 50 LOG(FATAL) << "Code was NULL in method: " << PrettyMethod(method) 51 << " location: " << mh.GetDexFile().GetLocation(); 52 } 53 return method; 54} 55 56extern "C" mirror::Object* art_portable_find_static_method_from_code_with_access_check(uint32_t method_idx, 57 mirror::Object* this_object, 58 mirror::ArtMethod* referrer, 59 Thread* thread) 60 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 61 return FindMethodHelper(method_idx, this_object, referrer, true, kStatic, thread); 62} 63 64extern "C" mirror::Object* art_portable_find_direct_method_from_code_with_access_check(uint32_t method_idx, 65 mirror::Object* this_object, 66 mirror::ArtMethod* referrer, 67 Thread* thread) 68 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 69 return FindMethodHelper(method_idx, this_object, referrer, true, kDirect, thread); 70} 71 72extern "C" mirror::Object* art_portable_find_virtual_method_from_code_with_access_check(uint32_t method_idx, 73 mirror::Object* this_object, 74 mirror::ArtMethod* referrer, 75 Thread* thread) 76 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 77 return FindMethodHelper(method_idx, this_object, referrer, true, kVirtual, thread); 78} 79 80extern "C" mirror::Object* art_portable_find_super_method_from_code_with_access_check(uint32_t method_idx, 81 mirror::Object* this_object, 82 mirror::ArtMethod* referrer, 83 Thread* thread) 84 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 85 return FindMethodHelper(method_idx, this_object, referrer, true, kSuper, thread); 86} 87 88extern "C" mirror::Object* art_portable_find_interface_method_from_code_with_access_check(uint32_t method_idx, 89 mirror::Object* this_object, 90 mirror::ArtMethod* referrer, 91 Thread* thread) 92 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 93 return FindMethodHelper(method_idx, this_object, referrer, true, kInterface, thread); 94} 95 96extern "C" mirror::Object* art_portable_find_interface_method_from_code(uint32_t method_idx, 97 mirror::Object* this_object, 98 mirror::ArtMethod* referrer, 99 Thread* thread) 100 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 101 return FindMethodHelper(method_idx, this_object, referrer, false, kInterface, thread); 102} 103 104} // namespace art 105