Home | History | Annotate | Download | only in quick
      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 "callee_save_frame.h"
     18 #include "common_throws.h"
     19 #include "dex_file-inl.h"
     20 #include "dex_instruction-inl.h"
     21 #include "entrypoints/entrypoint_utils.h"
     22 #include "interpreter/interpreter.h"
     23 #include "invoke_arg_array_builder.h"
     24 #include "mirror/art_method-inl.h"
     25 #include "mirror/class-inl.h"
     26 #include "mirror/object-inl.h"
     27 #include "mirror/object_array-inl.h"
     28 #include "object_utils.h"
     29 #include "runtime.h"
     30 
     31 
     32 
     33 namespace art {
     34 
     35 // Visits the arguments as saved to the stack by a Runtime::kRefAndArgs callee save frame.
     36 class QuickArgumentVisitor {
     37  public:
     38 // Offset to first (not the Method*) argument in a Runtime::kRefAndArgs callee save frame.
     39 // Size of Runtime::kRefAndArgs callee save frame.
     40 // Size of Method* and register parameters in out stack arguments.
     41 #if defined(__arm__)
     42   // The callee save frame is pointed to by SP.
     43   // | argN       |  |
     44   // | ...        |  |
     45   // | arg4       |  |
     46   // | arg3 spill |  |  Caller's frame
     47   // | arg2 spill |  |
     48   // | arg1 spill |  |
     49   // | Method*    | ---
     50   // | LR         |
     51   // | ...        |    callee saves
     52   // | R3         |    arg3
     53   // | R2         |    arg2
     54   // | R1         |    arg1
     55   // | R0         |
     56   // | Method*    |  <- sp
     57 #define QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__R1_OFFSET 8
     58 #define QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__LR_OFFSET 44
     59 #define QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__FRAME_SIZE 48
     60 #define QUICK_STACK_ARG_SKIP 16
     61 #elif defined(__mips__)
     62   // The callee save frame is pointed to by SP.
     63   // | argN       |  |
     64   // | ...        |  |
     65   // | arg4       |  |
     66   // | arg3 spill |  |  Caller's frame
     67   // | arg2 spill |  |
     68   // | arg1 spill |  |
     69   // | Method*    | ---
     70   // | RA         |
     71   // | ...        |    callee saves
     72   // | A3         |    arg3
     73   // | A2         |    arg2
     74   // | A1         |    arg1
     75   // | A0/Method* |  <- sp
     76 #define QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__R1_OFFSET 4
     77 #define QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__LR_OFFSET 60
     78 #define QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__FRAME_SIZE 64
     79 #define QUICK_STACK_ARG_SKIP 16
     80 #elif defined(__i386__)
     81   // The callee save frame is pointed to by SP.
     82   // | argN        |  |
     83   // | ...         |  |
     84   // | arg4        |  |
     85   // | arg3 spill  |  |  Caller's frame
     86   // | arg2 spill  |  |
     87   // | arg1 spill  |  |
     88   // | Method*     | ---
     89   // | Return      |
     90   // | EBP,ESI,EDI |    callee saves
     91   // | EBX         |    arg3
     92   // | EDX         |    arg2
     93   // | ECX         |    arg1
     94   // | EAX/Method* |  <- sp
     95 #define QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__R1_OFFSET 4
     96 #define QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__LR_OFFSET 28
     97 #define QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__FRAME_SIZE 32
     98 #define QUICK_STACK_ARG_SKIP 16
     99 #else
    100 #error "Unsupported architecture"
    101 #define QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__R1_OFFSET 0
    102 #define QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__LR_OFFSET 0
    103 #define QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__FRAME_SIZE 0
    104 #define QUICK_STACK_ARG_SKIP 0
    105 #endif
    106 
    107   static mirror::ArtMethod* GetCallingMethod(mirror::ArtMethod** sp) {
    108     byte* previous_sp = reinterpret_cast<byte*>(sp) +
    109         QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__FRAME_SIZE;
    110     return *reinterpret_cast<mirror::ArtMethod**>(previous_sp);
    111   }
    112 
    113   static uintptr_t GetCallingPc(mirror::ArtMethod** sp) {
    114     byte* lr = reinterpret_cast<byte*>(sp) + QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__LR_OFFSET;
    115     return *reinterpret_cast<uintptr_t*>(lr);
    116   }
    117 
    118   QuickArgumentVisitor(mirror::ArtMethod** sp, bool is_static,
    119                        const char* shorty, uint32_t shorty_len)
    120     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) :
    121     is_static_(is_static), shorty_(shorty), shorty_len_(shorty_len),
    122     args_in_regs_(ComputeArgsInRegs(is_static, shorty, shorty_len)),
    123     num_params_((is_static ? 0 : 1) + shorty_len - 1),  // +1 for this, -1 for return type
    124     reg_args_(reinterpret_cast<byte*>(sp) + QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__R1_OFFSET),
    125     stack_args_(reinterpret_cast<byte*>(sp) + QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__FRAME_SIZE
    126                 + QUICK_STACK_ARG_SKIP),
    127     cur_args_(reg_args_),
    128     cur_arg_index_(0),
    129     param_index_(0),
    130     is_split_long_or_double_(false) {
    131     DCHECK_EQ(static_cast<size_t>(QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__FRAME_SIZE),
    132               Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs)->GetFrameSizeInBytes());
    133   }
    134 
    135   virtual ~QuickArgumentVisitor() {}
    136 
    137   virtual void Visit() = 0;
    138 
    139   Primitive::Type GetParamPrimitiveType() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    140     size_t index = param_index_;
    141     if (is_static_) {
    142       index++;  // 0th argument must skip return value at start of the shorty
    143     } else if (index == 0) {
    144       return Primitive::kPrimNot;
    145     }
    146     CHECK_LT(index, shorty_len_);
    147     return Primitive::GetType(shorty_[index]);
    148   }
    149 
    150   byte* GetParamAddress() const {
    151     return cur_args_ + (cur_arg_index_ * kPointerSize);
    152   }
    153 
    154   bool IsSplitLongOrDouble() const {
    155     return is_split_long_or_double_;
    156   }
    157 
    158   bool IsParamAReference() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    159     return GetParamPrimitiveType() == Primitive::kPrimNot;
    160   }
    161 
    162   bool IsParamALongOrDouble() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    163     Primitive::Type type = GetParamPrimitiveType();
    164     return type == Primitive::kPrimLong || type == Primitive::kPrimDouble;
    165   }
    166 
    167   uint64_t ReadSplitLongParam() const {
    168     DCHECK(IsSplitLongOrDouble());
    169     uint64_t low_half = *reinterpret_cast<uint32_t*>(GetParamAddress());
    170     uint64_t high_half = *reinterpret_cast<uint32_t*>(stack_args_);
    171     return (low_half & 0xffffffffULL) | (high_half << 32);
    172   }
    173 
    174   void VisitArguments() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    175     for (cur_arg_index_ = 0;  cur_arg_index_ < args_in_regs_ && param_index_ < num_params_; ) {
    176       is_split_long_or_double_ = (cur_arg_index_ == 2) && IsParamALongOrDouble();
    177       Visit();
    178       cur_arg_index_ += (IsParamALongOrDouble() ? 2 : 1);
    179       param_index_++;
    180     }
    181     cur_args_ = stack_args_;
    182     cur_arg_index_ = is_split_long_or_double_ ? 1 : 0;
    183     is_split_long_or_double_ = false;
    184     while (param_index_ < num_params_) {
    185       Visit();
    186       cur_arg_index_ += (IsParamALongOrDouble() ? 2 : 1);
    187       param_index_++;
    188     }
    189   }
    190 
    191  private:
    192   static size_t ComputeArgsInRegs(bool is_static, const char* shorty, uint32_t shorty_len)
    193       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    194     size_t args_in_regs = (is_static ? 0 : 1);
    195     for (size_t i = 0; i < shorty_len; i++) {
    196       char s = shorty[i];
    197       if (s == 'J' || s == 'D') {
    198         args_in_regs += 2;
    199       } else {
    200         args_in_regs++;
    201       }
    202       if (args_in_regs > 3) {
    203         args_in_regs = 3;
    204         break;
    205       }
    206     }
    207     return args_in_regs;
    208   }
    209 
    210   const bool is_static_;
    211   const char* const shorty_;
    212   const uint32_t shorty_len_;
    213   const size_t args_in_regs_;
    214   const size_t num_params_;
    215   byte* const reg_args_;
    216   byte* const stack_args_;
    217   byte* cur_args_;
    218   size_t cur_arg_index_;
    219   size_t param_index_;
    220   // Does a 64bit parameter straddle the register and stack arguments?
    221   bool is_split_long_or_double_;
    222 };
    223 
    224 // Visits arguments on the stack placing them into the shadow frame.
    225 class BuildQuickShadowFrameVisitor : public QuickArgumentVisitor {
    226  public:
    227   BuildQuickShadowFrameVisitor(mirror::ArtMethod** sp,
    228       bool is_static, const char* shorty,
    229        uint32_t shorty_len, ShadowFrame& sf, size_t first_arg_reg) :
    230     QuickArgumentVisitor(sp, is_static, shorty, shorty_len), sf_(sf), cur_reg_(first_arg_reg) {}
    231 
    232   virtual void Visit() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    233     Primitive::Type type = GetParamPrimitiveType();
    234     switch (type) {
    235       case Primitive::kPrimLong:  // Fall-through.
    236       case Primitive::kPrimDouble:
    237         if (IsSplitLongOrDouble()) {
    238           sf_.SetVRegLong(cur_reg_, ReadSplitLongParam());
    239         } else {
    240           sf_.SetVRegLong(cur_reg_, *reinterpret_cast<jlong*>(GetParamAddress()));
    241         }
    242         ++cur_reg_;
    243         break;
    244       case Primitive::kPrimNot:
    245         sf_.SetVRegReference(cur_reg_, *reinterpret_cast<mirror::Object**>(GetParamAddress()));
    246         break;
    247       case Primitive::kPrimBoolean:  // Fall-through.
    248       case Primitive::kPrimByte:     // Fall-through.
    249       case Primitive::kPrimChar:     // Fall-through.
    250       case Primitive::kPrimShort:    // Fall-through.
    251       case Primitive::kPrimInt:      // Fall-through.
    252       case Primitive::kPrimFloat:
    253         sf_.SetVReg(cur_reg_, *reinterpret_cast<jint*>(GetParamAddress()));
    254         break;
    255       case Primitive::kPrimVoid:
    256         LOG(FATAL) << "UNREACHABLE";
    257         break;
    258     }
    259     ++cur_reg_;
    260   }
    261 
    262  private:
    263   ShadowFrame& sf_;
    264   size_t cur_reg_;
    265 
    266   DISALLOW_COPY_AND_ASSIGN(BuildQuickShadowFrameVisitor);
    267 };
    268 
    269 extern "C" uint64_t artQuickToInterpreterBridge(mirror::ArtMethod* method, Thread* self,
    270                                                 mirror::ArtMethod** sp)
    271     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    272   // Ensure we don't get thread suspension until the object arguments are safely in the shadow
    273   // frame.
    274   FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsAndArgs);
    275 
    276   if (method->IsAbstract()) {
    277     ThrowAbstractMethodError(method);
    278     return 0;
    279   } else {
    280     const char* old_cause = self->StartAssertNoThreadSuspension("Building interpreter shadow frame");
    281     MethodHelper mh(method);
    282     const DexFile::CodeItem* code_item = mh.GetCodeItem();
    283     uint16_t num_regs = code_item->registers_size_;
    284     void* memory = alloca(ShadowFrame::ComputeSize(num_regs));
    285     ShadowFrame* shadow_frame(ShadowFrame::Create(num_regs, NULL,  // No last shadow coming from quick.
    286                                                   method, 0, memory));
    287     size_t first_arg_reg = code_item->registers_size_ - code_item->ins_size_;
    288     BuildQuickShadowFrameVisitor shadow_frame_builder(sp, mh.IsStatic(), mh.GetShorty(),
    289                                                  mh.GetShortyLength(),
    290                                                  *shadow_frame, first_arg_reg);
    291     shadow_frame_builder.VisitArguments();
    292     // Push a transition back into managed code onto the linked list in thread.
    293     ManagedStack fragment;
    294     self->PushManagedStackFragment(&fragment);
    295     self->PushShadowFrame(shadow_frame);
    296     self->EndAssertNoThreadSuspension(old_cause);
    297 
    298     if (method->IsStatic() && !method->GetDeclaringClass()->IsInitializing()) {
    299       // Ensure static method's class is initialized.
    300       if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(method->GetDeclaringClass(),
    301                                                                    true, true)) {
    302         DCHECK(Thread::Current()->IsExceptionPending());
    303         self->PopManagedStackFragment(fragment);
    304         return 0;
    305       }
    306     }
    307 
    308     JValue result = interpreter::EnterInterpreterFromStub(self, mh, code_item, *shadow_frame);
    309     // Pop transition.
    310     self->PopManagedStackFragment(fragment);
    311     return result.GetJ();
    312   }
    313 }
    314 
    315 // Visits arguments on the stack placing them into the args vector, Object* arguments are converted
    316 // to jobjects.
    317 class BuildQuickArgumentVisitor : public QuickArgumentVisitor {
    318  public:
    319   BuildQuickArgumentVisitor(mirror::ArtMethod** sp, bool is_static, const char* shorty,
    320                             uint32_t shorty_len, ScopedObjectAccessUnchecked* soa,
    321                             std::vector<jvalue>* args) :
    322     QuickArgumentVisitor(sp, is_static, shorty, shorty_len), soa_(soa), args_(args) {}
    323 
    324   virtual void Visit() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    325     jvalue val;
    326     Primitive::Type type = GetParamPrimitiveType();
    327     switch (type) {
    328       case Primitive::kPrimNot: {
    329         mirror::Object* obj = *reinterpret_cast<mirror::Object**>(GetParamAddress());
    330         val.l = soa_->AddLocalReference<jobject>(obj);
    331         break;
    332       }
    333       case Primitive::kPrimLong:  // Fall-through.
    334       case Primitive::kPrimDouble:
    335         if (IsSplitLongOrDouble()) {
    336           val.j = ReadSplitLongParam();
    337         } else {
    338           val.j = *reinterpret_cast<jlong*>(GetParamAddress());
    339         }
    340         break;
    341       case Primitive::kPrimBoolean:  // Fall-through.
    342       case Primitive::kPrimByte:     // Fall-through.
    343       case Primitive::kPrimChar:     // Fall-through.
    344       case Primitive::kPrimShort:    // Fall-through.
    345       case Primitive::kPrimInt:      // Fall-through.
    346       case Primitive::kPrimFloat:
    347         val.i =  *reinterpret_cast<jint*>(GetParamAddress());
    348         break;
    349       case Primitive::kPrimVoid:
    350         LOG(FATAL) << "UNREACHABLE";
    351         val.j = 0;
    352         break;
    353     }
    354     args_->push_back(val);
    355   }
    356 
    357  private:
    358   ScopedObjectAccessUnchecked* soa_;
    359   std::vector<jvalue>* args_;
    360 
    361   DISALLOW_COPY_AND_ASSIGN(BuildQuickArgumentVisitor);
    362 };
    363 
    364 // Handler for invocation on proxy methods. On entry a frame will exist for the proxy object method
    365 // which is responsible for recording callee save registers. We explicitly place into jobjects the
    366 // incoming reference arguments (so they survive GC). We invoke the invocation handler, which is a
    367 // field within the proxy object, which will box the primitive arguments and deal with error cases.
    368 extern "C" uint64_t artQuickProxyInvokeHandler(mirror::ArtMethod* proxy_method,
    369                                                mirror::Object* receiver,
    370                                                Thread* self, mirror::ArtMethod** sp)
    371     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    372   DCHECK(proxy_method->IsProxyMethod()) << PrettyMethod(proxy_method);
    373   DCHECK(receiver->GetClass()->IsProxyClass()) << PrettyMethod(proxy_method);
    374   // Ensure we don't get thread suspension until the object arguments are safely in jobjects.
    375   const char* old_cause =
    376       self->StartAssertNoThreadSuspension("Adding to IRT proxy object arguments");
    377   // Register the top of the managed stack, making stack crawlable.
    378   DCHECK_EQ(*sp, proxy_method) << PrettyMethod(proxy_method);
    379   self->SetTopOfStack(sp, 0);
    380   DCHECK_EQ(proxy_method->GetFrameSizeInBytes(),
    381             Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs)->GetFrameSizeInBytes())
    382       << PrettyMethod(proxy_method);
    383   self->VerifyStack();
    384   // Start new JNI local reference state.
    385   JNIEnvExt* env = self->GetJniEnv();
    386   ScopedObjectAccessUnchecked soa(env);
    387   ScopedJniEnvLocalRefState env_state(env);
    388   // Create local ref. copies of proxy method and the receiver.
    389   jobject rcvr_jobj = soa.AddLocalReference<jobject>(receiver);
    390 
    391   // Placing arguments into args vector and remove the receiver.
    392   MethodHelper proxy_mh(proxy_method);
    393   DCHECK(!proxy_mh.IsStatic()) << PrettyMethod(proxy_method);
    394   std::vector<jvalue> args;
    395   BuildQuickArgumentVisitor local_ref_visitor(sp, proxy_mh.IsStatic(), proxy_mh.GetShorty(),
    396                                               proxy_mh.GetShortyLength(), &soa, &args);
    397 
    398   local_ref_visitor.VisitArguments();
    399   DCHECK_GT(args.size(), 0U) << PrettyMethod(proxy_method);
    400   args.erase(args.begin());
    401 
    402   // Convert proxy method into expected interface method.
    403   mirror::ArtMethod* interface_method = proxy_method->FindOverriddenMethod();
    404   DCHECK(interface_method != NULL) << PrettyMethod(proxy_method);
    405   DCHECK(!interface_method->IsProxyMethod()) << PrettyMethod(interface_method);
    406   jobject interface_method_jobj = soa.AddLocalReference<jobject>(interface_method);
    407 
    408   // All naked Object*s should now be in jobjects, so its safe to go into the main invoke code
    409   // that performs allocations.
    410   self->EndAssertNoThreadSuspension(old_cause);
    411   JValue result = InvokeProxyInvocationHandler(soa, proxy_mh.GetShorty(),
    412                                                rcvr_jobj, interface_method_jobj, args);
    413   return result.GetJ();
    414 }
    415 
    416 // Read object references held in arguments from quick frames and place in a JNI local references,
    417 // so they don't get garbage collected.
    418 class RememberFoGcArgumentVisitor : public QuickArgumentVisitor {
    419  public:
    420   RememberFoGcArgumentVisitor(mirror::ArtMethod** sp, bool is_static, const char* shorty,
    421                               uint32_t shorty_len, ScopedObjectAccessUnchecked* soa) :
    422     QuickArgumentVisitor(sp, is_static, shorty, shorty_len), soa_(soa) {}
    423 
    424   virtual void Visit() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    425     if (IsParamAReference()) {
    426       soa_->AddLocalReference<jobject>(*reinterpret_cast<mirror::Object**>(GetParamAddress()));
    427     }
    428   }
    429 
    430  private:
    431   ScopedObjectAccessUnchecked* soa_;
    432 
    433   DISALLOW_COPY_AND_ASSIGN(RememberFoGcArgumentVisitor);
    434 };
    435 
    436 // Lazily resolve a method for quick. Called by stub code.
    437 extern "C" const void* artQuickResolutionTrampoline(mirror::ArtMethod* called,
    438                                                     mirror::Object* receiver,
    439                                                     Thread* thread, mirror::ArtMethod** sp)
    440     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    441   FinishCalleeSaveFrameSetup(thread, sp, Runtime::kRefsAndArgs);
    442   // Start new JNI local reference state
    443   JNIEnvExt* env = thread->GetJniEnv();
    444   ScopedObjectAccessUnchecked soa(env);
    445   ScopedJniEnvLocalRefState env_state(env);
    446   const char* old_cause = thread->StartAssertNoThreadSuspension("Quick method resolution set up");
    447 
    448   // Compute details about the called method (avoid GCs)
    449   ClassLinker* linker = Runtime::Current()->GetClassLinker();
    450   mirror::ArtMethod* caller = QuickArgumentVisitor::GetCallingMethod(sp);
    451   InvokeType invoke_type;
    452   const DexFile* dex_file;
    453   uint32_t dex_method_idx;
    454   if (called->IsRuntimeMethod()) {
    455     uint32_t dex_pc = caller->ToDexPc(QuickArgumentVisitor::GetCallingPc(sp));
    456     const DexFile::CodeItem* code;
    457     {
    458       MethodHelper mh(caller);
    459       dex_file = &mh.GetDexFile();
    460       code = mh.GetCodeItem();
    461     }
    462     CHECK_LT(dex_pc, code->insns_size_in_code_units_);
    463     const Instruction* instr = Instruction::At(&code->insns_[dex_pc]);
    464     Instruction::Code instr_code = instr->Opcode();
    465     bool is_range;
    466     switch (instr_code) {
    467       case Instruction::INVOKE_DIRECT:
    468         invoke_type = kDirect;
    469         is_range = false;
    470         break;
    471       case Instruction::INVOKE_DIRECT_RANGE:
    472         invoke_type = kDirect;
    473         is_range = true;
    474         break;
    475       case Instruction::INVOKE_STATIC:
    476         invoke_type = kStatic;
    477         is_range = false;
    478         break;
    479       case Instruction::INVOKE_STATIC_RANGE:
    480         invoke_type = kStatic;
    481         is_range = true;
    482         break;
    483       case Instruction::INVOKE_SUPER:
    484         invoke_type = kSuper;
    485         is_range = false;
    486         break;
    487       case Instruction::INVOKE_SUPER_RANGE:
    488         invoke_type = kSuper;
    489         is_range = true;
    490         break;
    491       case Instruction::INVOKE_VIRTUAL:
    492         invoke_type = kVirtual;
    493         is_range = false;
    494         break;
    495       case Instruction::INVOKE_VIRTUAL_RANGE:
    496         invoke_type = kVirtual;
    497         is_range = true;
    498         break;
    499       case Instruction::INVOKE_INTERFACE:
    500         invoke_type = kInterface;
    501         is_range = false;
    502         break;
    503       case Instruction::INVOKE_INTERFACE_RANGE:
    504         invoke_type = kInterface;
    505         is_range = true;
    506         break;
    507       default:
    508         LOG(FATAL) << "Unexpected call into trampoline: " << instr->DumpString(NULL);
    509         // Avoid used uninitialized warnings.
    510         invoke_type = kDirect;
    511         is_range = false;
    512     }
    513     dex_method_idx = (is_range) ? instr->VRegB_3rc() : instr->VRegB_35c();
    514 
    515   } else {
    516     invoke_type = kStatic;
    517     dex_file = &MethodHelper(called).GetDexFile();
    518     dex_method_idx = called->GetDexMethodIndex();
    519   }
    520   uint32_t shorty_len;
    521   const char* shorty =
    522       dex_file->GetMethodShorty(dex_file->GetMethodId(dex_method_idx), &shorty_len);
    523   RememberFoGcArgumentVisitor visitor(sp, invoke_type == kStatic, shorty, shorty_len, &soa);
    524   visitor.VisitArguments();
    525   thread->EndAssertNoThreadSuspension(old_cause);
    526   // Resolve method filling in dex cache.
    527   if (called->IsRuntimeMethod()) {
    528     called = linker->ResolveMethod(dex_method_idx, caller, invoke_type);
    529   }
    530   const void* code = NULL;
    531   if (LIKELY(!thread->IsExceptionPending())) {
    532     // Incompatible class change should have been handled in resolve method.
    533     CHECK(!called->CheckIncompatibleClassChange(invoke_type));
    534     // Refine called method based on receiver.
    535     if (invoke_type == kVirtual) {
    536       called = receiver->GetClass()->FindVirtualMethodForVirtual(called);
    537     } else if (invoke_type == kInterface) {
    538       called = receiver->GetClass()->FindVirtualMethodForInterface(called);
    539     }
    540     // Ensure that the called method's class is initialized.
    541     mirror::Class* called_class = called->GetDeclaringClass();
    542     linker->EnsureInitialized(called_class, true, true);
    543     if (LIKELY(called_class->IsInitialized())) {
    544       code = called->GetEntryPointFromCompiledCode();
    545     } else if (called_class->IsInitializing()) {
    546       if (invoke_type == kStatic) {
    547         // Class is still initializing, go to oat and grab code (trampoline must be left in place
    548         // until class is initialized to stop races between threads).
    549         code = linker->GetOatCodeFor(called);
    550       } else {
    551         // No trampoline for non-static methods.
    552         code = called->GetEntryPointFromCompiledCode();
    553       }
    554     } else {
    555       DCHECK(called_class->IsErroneous());
    556     }
    557   }
    558   CHECK_EQ(code == NULL, thread->IsExceptionPending());
    559 #ifdef MOVING_GARBAGE_COLLECTOR
    560   // TODO: locally saved objects may have moved during a GC during resolution. Need to update the
    561   //       registers so that the stale objects aren't passed to the method we've resolved.
    562     UNIMPLEMENTED(WARNING);
    563 #endif
    564   // Place called method in callee-save frame to be placed as first argument to quick method.
    565   *sp = called;
    566   return code;
    567 }
    568 
    569 }  // namespace art
    570