Home | History | Annotate | Download | only in portable
      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 
     22 namespace art {
     23 
     24 static 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 
     56 extern "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 
     64 extern "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 
     72 extern "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 
     80 extern "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 
     88 extern "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 
     96 extern "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