Home | History | Annotate | Download | only in interpreter
      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 "interpreter.h"
     18 
     19 #include <limits>
     20 
     21 #include "common_throws.h"
     22 #include "interpreter_common.h"
     23 #include "interpreter_mterp_impl.h"
     24 #include "interpreter_switch_impl.h"
     25 #include "jvalue-inl.h"
     26 #include "mirror/string-inl.h"
     27 #include "scoped_thread_state_change-inl.h"
     28 #include "ScopedLocalRef.h"
     29 #include "stack.h"
     30 #include "unstarted_runtime.h"
     31 #include "mterp/mterp.h"
     32 #include "jit/jit.h"
     33 #include "jit/jit_code_cache.h"
     34 
     35 namespace art {
     36 namespace interpreter {
     37 
     38 ALWAYS_INLINE static ObjPtr<mirror::Object> ObjArg(uint32_t arg)
     39     REQUIRES_SHARED(Locks::mutator_lock_) {
     40   return ObjPtr<mirror::Object>(reinterpret_cast<mirror::Object*>(arg));
     41 }
     42 
     43 static void InterpreterJni(Thread* self,
     44                            ArtMethod* method,
     45                            const StringPiece& shorty,
     46                            ObjPtr<mirror::Object> receiver,
     47                            uint32_t* args,
     48                            JValue* result)
     49     REQUIRES_SHARED(Locks::mutator_lock_) {
     50   // TODO: The following enters JNI code using a typedef-ed function rather than the JNI compiler,
     51   //       it should be removed and JNI compiled stubs used instead.
     52   ScopedObjectAccessUnchecked soa(self);
     53   if (method->IsStatic()) {
     54     if (shorty == "L") {
     55       typedef jobject (fntype)(JNIEnv*, jclass);
     56       fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni());
     57       ScopedLocalRef<jclass> klass(soa.Env(),
     58                                    soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
     59       jobject jresult;
     60       {
     61         ScopedThreadStateChange tsc(self, kNative);
     62         jresult = fn(soa.Env(), klass.get());
     63       }
     64       result->SetL(soa.Decode<mirror::Object>(jresult));
     65     } else if (shorty == "V") {
     66       typedef void (fntype)(JNIEnv*, jclass);
     67       fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni());
     68       ScopedLocalRef<jclass> klass(soa.Env(),
     69                                    soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
     70       ScopedThreadStateChange tsc(self, kNative);
     71       fn(soa.Env(), klass.get());
     72     } else if (shorty == "Z") {
     73       typedef jboolean (fntype)(JNIEnv*, jclass);
     74       fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni());
     75       ScopedLocalRef<jclass> klass(soa.Env(),
     76                                    soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
     77       ScopedThreadStateChange tsc(self, kNative);
     78       result->SetZ(fn(soa.Env(), klass.get()));
     79     } else if (shorty == "BI") {
     80       typedef jbyte (fntype)(JNIEnv*, jclass, jint);
     81       fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni());
     82       ScopedLocalRef<jclass> klass(soa.Env(),
     83                                    soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
     84       ScopedThreadStateChange tsc(self, kNative);
     85       result->SetB(fn(soa.Env(), klass.get(), args[0]));
     86     } else if (shorty == "II") {
     87       typedef jint (fntype)(JNIEnv*, jclass, jint);
     88       fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni());
     89       ScopedLocalRef<jclass> klass(soa.Env(),
     90                                    soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
     91       ScopedThreadStateChange tsc(self, kNative);
     92       result->SetI(fn(soa.Env(), klass.get(), args[0]));
     93     } else if (shorty == "LL") {
     94       typedef jobject (fntype)(JNIEnv*, jclass, jobject);
     95       fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni());
     96       ScopedLocalRef<jclass> klass(soa.Env(),
     97                                    soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
     98       ScopedLocalRef<jobject> arg0(soa.Env(),
     99                                    soa.AddLocalReference<jobject>(ObjArg(args[0])));
    100       jobject jresult;
    101       {
    102         ScopedThreadStateChange tsc(self, kNative);
    103         jresult = fn(soa.Env(), klass.get(), arg0.get());
    104       }
    105       result->SetL(soa.Decode<mirror::Object>(jresult));
    106     } else if (shorty == "IIZ") {
    107       typedef jint (fntype)(JNIEnv*, jclass, jint, jboolean);
    108       fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni());
    109       ScopedLocalRef<jclass> klass(soa.Env(),
    110                                    soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
    111       ScopedThreadStateChange tsc(self, kNative);
    112       result->SetI(fn(soa.Env(), klass.get(), args[0], args[1]));
    113     } else if (shorty == "ILI") {
    114       typedef jint (fntype)(JNIEnv*, jclass, jobject, jint);
    115       fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(
    116           method->GetEntryPointFromJni()));
    117       ScopedLocalRef<jclass> klass(soa.Env(),
    118                                    soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
    119       ScopedLocalRef<jobject> arg0(soa.Env(),
    120                                    soa.AddLocalReference<jobject>(ObjArg(args[0])));
    121       ScopedThreadStateChange tsc(self, kNative);
    122       result->SetI(fn(soa.Env(), klass.get(), arg0.get(), args[1]));
    123     } else if (shorty == "SIZ") {
    124       typedef jshort (fntype)(JNIEnv*, jclass, jint, jboolean);
    125       fntype* const fn =
    126           reinterpret_cast<fntype*>(const_cast<void*>(method->GetEntryPointFromJni()));
    127       ScopedLocalRef<jclass> klass(soa.Env(),
    128                                    soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
    129       ScopedThreadStateChange tsc(self, kNative);
    130       result->SetS(fn(soa.Env(), klass.get(), args[0], args[1]));
    131     } else if (shorty == "VIZ") {
    132       typedef void (fntype)(JNIEnv*, jclass, jint, jboolean);
    133       fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni());
    134       ScopedLocalRef<jclass> klass(soa.Env(),
    135                                    soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
    136       ScopedThreadStateChange tsc(self, kNative);
    137       fn(soa.Env(), klass.get(), args[0], args[1]);
    138     } else if (shorty == "ZLL") {
    139       typedef jboolean (fntype)(JNIEnv*, jclass, jobject, jobject);
    140       fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni());
    141       ScopedLocalRef<jclass> klass(soa.Env(),
    142                                    soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
    143       ScopedLocalRef<jobject> arg0(soa.Env(),
    144                                    soa.AddLocalReference<jobject>(ObjArg(args[0])));
    145       ScopedLocalRef<jobject> arg1(soa.Env(),
    146                                    soa.AddLocalReference<jobject>(ObjArg(args[1])));
    147       ScopedThreadStateChange tsc(self, kNative);
    148       result->SetZ(fn(soa.Env(), klass.get(), arg0.get(), arg1.get()));
    149     } else if (shorty == "ZILL") {
    150       typedef jboolean (fntype)(JNIEnv*, jclass, jint, jobject, jobject);
    151       fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni());
    152       ScopedLocalRef<jclass> klass(soa.Env(),
    153                                    soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
    154       ScopedLocalRef<jobject> arg1(soa.Env(),
    155                                    soa.AddLocalReference<jobject>(ObjArg(args[1])));
    156       ScopedLocalRef<jobject> arg2(soa.Env(),
    157                                    soa.AddLocalReference<jobject>(ObjArg(args[2])));
    158       ScopedThreadStateChange tsc(self, kNative);
    159       result->SetZ(fn(soa.Env(), klass.get(), args[0], arg1.get(), arg2.get()));
    160     } else if (shorty == "VILII") {
    161       typedef void (fntype)(JNIEnv*, jclass, jint, jobject, jint, jint);
    162       fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni());
    163       ScopedLocalRef<jclass> klass(soa.Env(),
    164                                    soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
    165       ScopedLocalRef<jobject> arg1(soa.Env(),
    166                                    soa.AddLocalReference<jobject>(ObjArg(args[1])));
    167       ScopedThreadStateChange tsc(self, kNative);
    168       fn(soa.Env(), klass.get(), args[0], arg1.get(), args[2], args[3]);
    169     } else if (shorty == "VLILII") {
    170       typedef void (fntype)(JNIEnv*, jclass, jobject, jint, jobject, jint, jint);
    171       fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni());
    172       ScopedLocalRef<jclass> klass(soa.Env(),
    173                                    soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
    174       ScopedLocalRef<jobject> arg0(soa.Env(),
    175                                    soa.AddLocalReference<jobject>(ObjArg(args[0])));
    176       ScopedLocalRef<jobject> arg2(soa.Env(),
    177                                    soa.AddLocalReference<jobject>(ObjArg(args[2])));
    178       ScopedThreadStateChange tsc(self, kNative);
    179       fn(soa.Env(), klass.get(), arg0.get(), args[1], arg2.get(), args[3], args[4]);
    180     } else {
    181       LOG(FATAL) << "Do something with static native method: " << method->PrettyMethod()
    182           << " shorty: " << shorty;
    183     }
    184   } else {
    185     if (shorty == "L") {
    186       typedef jobject (fntype)(JNIEnv*, jobject);
    187       fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni());
    188       ScopedLocalRef<jobject> rcvr(soa.Env(),
    189                                    soa.AddLocalReference<jobject>(receiver));
    190       jobject jresult;
    191       {
    192         ScopedThreadStateChange tsc(self, kNative);
    193         jresult = fn(soa.Env(), rcvr.get());
    194       }
    195       result->SetL(soa.Decode<mirror::Object>(jresult));
    196     } else if (shorty == "V") {
    197       typedef void (fntype)(JNIEnv*, jobject);
    198       fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni());
    199       ScopedLocalRef<jobject> rcvr(soa.Env(),
    200                                    soa.AddLocalReference<jobject>(receiver));
    201       ScopedThreadStateChange tsc(self, kNative);
    202       fn(soa.Env(), rcvr.get());
    203     } else if (shorty == "LL") {
    204       typedef jobject (fntype)(JNIEnv*, jobject, jobject);
    205       fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni());
    206       ScopedLocalRef<jobject> rcvr(soa.Env(),
    207                                    soa.AddLocalReference<jobject>(receiver));
    208       ScopedLocalRef<jobject> arg0(soa.Env(),
    209                                    soa.AddLocalReference<jobject>(ObjArg(args[0])));
    210       jobject jresult;
    211       {
    212         ScopedThreadStateChange tsc(self, kNative);
    213         jresult = fn(soa.Env(), rcvr.get(), arg0.get());
    214       }
    215       result->SetL(soa.Decode<mirror::Object>(jresult));
    216       ScopedThreadStateChange tsc(self, kNative);
    217     } else if (shorty == "III") {
    218       typedef jint (fntype)(JNIEnv*, jobject, jint, jint);
    219       fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni());
    220       ScopedLocalRef<jobject> rcvr(soa.Env(),
    221                                    soa.AddLocalReference<jobject>(receiver));
    222       ScopedThreadStateChange tsc(self, kNative);
    223       result->SetI(fn(soa.Env(), rcvr.get(), args[0], args[1]));
    224     } else {
    225       LOG(FATAL) << "Do something with native method: " << method->PrettyMethod()
    226           << " shorty: " << shorty;
    227     }
    228   }
    229 }
    230 
    231 enum InterpreterImplKind {
    232   kSwitchImplKind,        // Switch-based interpreter implementation.
    233   kMterpImplKind          // Assembly interpreter
    234 };
    235 
    236 static constexpr InterpreterImplKind kInterpreterImplKind = kMterpImplKind;
    237 
    238 static inline JValue Execute(
    239     Thread* self,
    240     const DexFile::CodeItem* code_item,
    241     ShadowFrame& shadow_frame,
    242     JValue result_register,
    243     bool stay_in_interpreter = false) REQUIRES_SHARED(Locks::mutator_lock_) {
    244   DCHECK(!shadow_frame.GetMethod()->IsAbstract());
    245   DCHECK(!shadow_frame.GetMethod()->IsNative());
    246   if (LIKELY(shadow_frame.GetDexPC() == 0)) {  // Entering the method, but not via deoptimization.
    247     if (kIsDebugBuild) {
    248       self->AssertNoPendingException();
    249     }
    250     instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
    251     ArtMethod *method = shadow_frame.GetMethod();
    252 
    253     if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
    254       instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
    255                                         method, 0);
    256     }
    257 
    258     if (!stay_in_interpreter) {
    259       jit::Jit* jit = Runtime::Current()->GetJit();
    260       if (jit != nullptr) {
    261         jit->MethodEntered(self, shadow_frame.GetMethod());
    262         if (jit->CanInvokeCompiledCode(method)) {
    263           JValue result;
    264 
    265           // Pop the shadow frame before calling into compiled code.
    266           self->PopShadowFrame();
    267           ArtInterpreterToCompiledCodeBridge(self, nullptr, code_item, &shadow_frame, &result);
    268           // Push the shadow frame back as the caller will expect it.
    269           self->PushShadowFrame(&shadow_frame);
    270 
    271           return result;
    272         }
    273       }
    274     }
    275   }
    276 
    277   shadow_frame.GetMethod()->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self);
    278 
    279   // Lock counting is a special version of accessibility checks, and for simplicity and
    280   // reduction of template parameters, we gate it behind access-checks mode.
    281   ArtMethod* method = shadow_frame.GetMethod();
    282   DCHECK(!method->SkipAccessChecks() || !method->MustCountLocks());
    283 
    284   bool transaction_active = Runtime::Current()->IsActiveTransaction();
    285   if (LIKELY(method->SkipAccessChecks())) {
    286     // Enter the "without access check" interpreter.
    287     if (kInterpreterImplKind == kMterpImplKind) {
    288       if (transaction_active) {
    289         // No Mterp variant - just use the switch interpreter.
    290         return ExecuteSwitchImpl<false, true>(self, code_item, shadow_frame, result_register,
    291                                               false);
    292       } else if (UNLIKELY(!Runtime::Current()->IsStarted())) {
    293         return ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame, result_register,
    294                                                false);
    295       } else {
    296         while (true) {
    297           // Mterp does not support all instrumentation/debugging.
    298           if (MterpShouldSwitchInterpreters() != 0) {
    299             return ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame, result_register,
    300                                                    false);
    301           }
    302           bool returned = ExecuteMterpImpl(self, code_item, &shadow_frame, &result_register);
    303           if (returned) {
    304             return result_register;
    305           } else {
    306             // Mterp didn't like that instruction.  Single-step it with the reference interpreter.
    307             result_register = ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame,
    308                                                               result_register, true);
    309             if (shadow_frame.GetDexPC() == DexFile::kDexNoIndex) {
    310               // Single-stepped a return or an exception not handled locally.  Return to caller.
    311               return result_register;
    312             }
    313           }
    314         }
    315       }
    316     } else {
    317       DCHECK_EQ(kInterpreterImplKind, kSwitchImplKind);
    318       if (transaction_active) {
    319         return ExecuteSwitchImpl<false, true>(self, code_item, shadow_frame, result_register,
    320                                               false);
    321       } else {
    322         return ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame, result_register,
    323                                                false);
    324       }
    325     }
    326   } else {
    327     // Enter the "with access check" interpreter.
    328     if (kInterpreterImplKind == kMterpImplKind) {
    329       // No access check variants for Mterp.  Just use the switch version.
    330       if (transaction_active) {
    331         return ExecuteSwitchImpl<true, true>(self, code_item, shadow_frame, result_register,
    332                                              false);
    333       } else {
    334         return ExecuteSwitchImpl<true, false>(self, code_item, shadow_frame, result_register,
    335                                               false);
    336       }
    337     } else {
    338       DCHECK_EQ(kInterpreterImplKind, kSwitchImplKind);
    339       if (transaction_active) {
    340         return ExecuteSwitchImpl<true, true>(self, code_item, shadow_frame, result_register,
    341                                              false);
    342       } else {
    343         return ExecuteSwitchImpl<true, false>(self, code_item, shadow_frame, result_register,
    344                                               false);
    345       }
    346     }
    347   }
    348 }
    349 
    350 void EnterInterpreterFromInvoke(Thread* self,
    351                                 ArtMethod* method,
    352                                 ObjPtr<mirror::Object> receiver,
    353                                 uint32_t* args,
    354                                 JValue* result,
    355                                 bool stay_in_interpreter) {
    356   DCHECK_EQ(self, Thread::Current());
    357   bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks();
    358   if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) {
    359     ThrowStackOverflowError(self);
    360     return;
    361   }
    362 
    363   // This can happen if we are in forced interpreter mode and an obsolete method is called using
    364   // reflection.
    365   if (UNLIKELY(method->IsObsolete())) {
    366     ThrowInternalError("Attempting to invoke obsolete version of '%s'.",
    367                        method->PrettyMethod().c_str());
    368     return;
    369   }
    370 
    371   const char* old_cause = self->StartAssertNoThreadSuspension("EnterInterpreterFromInvoke");
    372   const DexFile::CodeItem* code_item = method->GetCodeItem();
    373   uint16_t num_regs;
    374   uint16_t num_ins;
    375   if (code_item != nullptr) {
    376     num_regs =  code_item->registers_size_;
    377     num_ins = code_item->ins_size_;
    378   } else if (!method->IsInvokable()) {
    379     self->EndAssertNoThreadSuspension(old_cause);
    380     method->ThrowInvocationTimeError();
    381     return;
    382   } else {
    383     DCHECK(method->IsNative());
    384     num_regs = num_ins = ArtMethod::NumArgRegisters(method->GetShorty());
    385     if (!method->IsStatic()) {
    386       num_regs++;
    387       num_ins++;
    388     }
    389   }
    390   // Set up shadow frame with matching number of reference slots to vregs.
    391   ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame();
    392   ShadowFrameAllocaUniquePtr shadow_frame_unique_ptr =
    393       CREATE_SHADOW_FRAME(num_regs, last_shadow_frame, method, /* dex pc */ 0);
    394   ShadowFrame* shadow_frame = shadow_frame_unique_ptr.get();
    395   self->PushShadowFrame(shadow_frame);
    396 
    397   size_t cur_reg = num_regs - num_ins;
    398   if (!method->IsStatic()) {
    399     CHECK(receiver != nullptr);
    400     shadow_frame->SetVRegReference(cur_reg, receiver.Ptr());
    401     ++cur_reg;
    402   }
    403   uint32_t shorty_len = 0;
    404   const char* shorty = method->GetShorty(&shorty_len);
    405   for (size_t shorty_pos = 0, arg_pos = 0; cur_reg < num_regs; ++shorty_pos, ++arg_pos, cur_reg++) {
    406     DCHECK_LT(shorty_pos + 1, shorty_len);
    407     switch (shorty[shorty_pos + 1]) {
    408       case 'L': {
    409         ObjPtr<mirror::Object> o =
    410             reinterpret_cast<StackReference<mirror::Object>*>(&args[arg_pos])->AsMirrorPtr();
    411         shadow_frame->SetVRegReference(cur_reg, o.Ptr());
    412         break;
    413       }
    414       case 'J': case 'D': {
    415         uint64_t wide_value = (static_cast<uint64_t>(args[arg_pos + 1]) << 32) | args[arg_pos];
    416         shadow_frame->SetVRegLong(cur_reg, wide_value);
    417         cur_reg++;
    418         arg_pos++;
    419         break;
    420       }
    421       default:
    422         shadow_frame->SetVReg(cur_reg, args[arg_pos]);
    423         break;
    424     }
    425   }
    426   self->EndAssertNoThreadSuspension(old_cause);
    427   // Do this after populating the shadow frame in case EnsureInitialized causes a GC.
    428   if (method->IsStatic() && UNLIKELY(!method->GetDeclaringClass()->IsInitialized())) {
    429     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
    430     StackHandleScope<1> hs(self);
    431     Handle<mirror::Class> h_class(hs.NewHandle(method->GetDeclaringClass()));
    432     if (UNLIKELY(!class_linker->EnsureInitialized(self, h_class, true, true))) {
    433       CHECK(self->IsExceptionPending());
    434       self->PopShadowFrame();
    435       return;
    436     }
    437   }
    438   if (LIKELY(!method->IsNative())) {
    439     JValue r = Execute(self, code_item, *shadow_frame, JValue(), stay_in_interpreter);
    440     if (result != nullptr) {
    441       *result = r;
    442     }
    443   } else {
    444     // We don't expect to be asked to interpret native code (which is entered via a JNI compiler
    445     // generated stub) except during testing and image writing.
    446     // Update args to be the args in the shadow frame since the input ones could hold stale
    447     // references pointers due to moving GC.
    448     args = shadow_frame->GetVRegArgs(method->IsStatic() ? 0 : 1);
    449     if (!Runtime::Current()->IsStarted()) {
    450       UnstartedRuntime::Jni(self, method, receiver.Ptr(), args, result);
    451     } else {
    452       InterpreterJni(self, method, shorty, receiver, args, result);
    453     }
    454   }
    455   self->PopShadowFrame();
    456 }
    457 
    458 static bool IsStringInit(const Instruction* instr, ArtMethod* caller)
    459     REQUIRES_SHARED(Locks::mutator_lock_) {
    460   if (instr->Opcode() == Instruction::INVOKE_DIRECT ||
    461       instr->Opcode() == Instruction::INVOKE_DIRECT_RANGE) {
    462     // Instead of calling ResolveMethod() which has suspend point and can trigger
    463     // GC, look up the callee method symbolically.
    464     uint16_t callee_method_idx = (instr->Opcode() == Instruction::INVOKE_DIRECT_RANGE) ?
    465         instr->VRegB_3rc() : instr->VRegB_35c();
    466     const DexFile* dex_file = caller->GetDexFile();
    467     const DexFile::MethodId& method_id = dex_file->GetMethodId(callee_method_idx);
    468     const char* class_name = dex_file->StringByTypeIdx(method_id.class_idx_);
    469     const char* method_name = dex_file->GetMethodName(method_id);
    470     // Compare method's class name and method name against string init.
    471     // It's ok since it's not allowed to create your own java/lang/String.
    472     // TODO: verify that assumption.
    473     if ((strcmp(class_name, "Ljava/lang/String;") == 0) &&
    474         (strcmp(method_name, "<init>") == 0)) {
    475       return true;
    476     }
    477   }
    478   return false;
    479 }
    480 
    481 static int16_t GetReceiverRegisterForStringInit(const Instruction* instr) {
    482   DCHECK(instr->Opcode() == Instruction::INVOKE_DIRECT_RANGE ||
    483          instr->Opcode() == Instruction::INVOKE_DIRECT);
    484   return (instr->Opcode() == Instruction::INVOKE_DIRECT_RANGE) ?
    485       instr->VRegC_3rc() : instr->VRegC_35c();
    486 }
    487 
    488 void EnterInterpreterFromDeoptimize(Thread* self,
    489                                     ShadowFrame* shadow_frame,
    490                                     bool from_code,
    491                                     JValue* ret_val)
    492     REQUIRES_SHARED(Locks::mutator_lock_) {
    493   JValue value;
    494   // Set value to last known result in case the shadow frame chain is empty.
    495   value.SetJ(ret_val->GetJ());
    496   // Are we executing the first shadow frame?
    497   bool first = true;
    498   while (shadow_frame != nullptr) {
    499     // We do not want to recover lock state for lock counting when deoptimizing. Currently,
    500     // the compiler should not have compiled a method that failed structured-locking checks.
    501     DCHECK(!shadow_frame->GetMethod()->MustCountLocks());
    502 
    503     self->SetTopOfShadowStack(shadow_frame);
    504     const DexFile::CodeItem* code_item = shadow_frame->GetMethod()->GetCodeItem();
    505     const uint32_t dex_pc = shadow_frame->GetDexPC();
    506     uint32_t new_dex_pc = dex_pc;
    507     if (UNLIKELY(self->IsExceptionPending())) {
    508       // If we deoptimize from the QuickExceptionHandler, we already reported the exception to
    509       // the instrumentation. To prevent from reporting it a second time, we simply pass a
    510       // null Instrumentation*.
    511       const instrumentation::Instrumentation* const instrumentation =
    512           first ? nullptr : Runtime::Current()->GetInstrumentation();
    513       uint32_t found_dex_pc = FindNextInstructionFollowingException(self, *shadow_frame, dex_pc,
    514                                                                     instrumentation);
    515       new_dex_pc = found_dex_pc;  // the dex pc of a matching catch handler
    516                                   // or DexFile::kDexNoIndex if there is none.
    517     } else if (!from_code) {
    518       // For the debugger and full deoptimization stack, we must go past the invoke
    519       // instruction, as it already executed.
    520       // TODO: should be tested more once b/17586779 is fixed.
    521       const Instruction* instr = Instruction::At(&code_item->insns_[dex_pc]);
    522       if (instr->IsInvoke()) {
    523         if (IsStringInit(instr, shadow_frame->GetMethod())) {
    524           uint16_t this_obj_vreg = GetReceiverRegisterForStringInit(instr);
    525           // Move the StringFactory.newStringFromChars() result into the register representing
    526           // "this object" when invoking the string constructor in the original dex instruction.
    527           // Also move the result into all aliases.
    528           DCHECK(value.GetL()->IsString());
    529           SetStringInitValueToAllAliases(shadow_frame, this_obj_vreg, value);
    530           // Calling string constructor in the original dex code doesn't generate a result value.
    531           value.SetJ(0);
    532         }
    533         new_dex_pc = dex_pc + instr->SizeInCodeUnits();
    534       } else if (instr->Opcode() == Instruction::NEW_INSTANCE) {
    535         // It's possible to deoptimize at a NEW_INSTANCE dex instruciton that's for a
    536         // java string, which is turned into a call into StringFactory.newEmptyString();
    537         // Move the StringFactory.newEmptyString() result into the destination register.
    538         DCHECK(value.GetL()->IsString());
    539         shadow_frame->SetVRegReference(instr->VRegA_21c(), value.GetL());
    540         // new-instance doesn't generate a result value.
    541         value.SetJ(0);
    542         // Skip the dex instruction since we essentially come back from an invocation.
    543         new_dex_pc = dex_pc + instr->SizeInCodeUnits();
    544         if (kIsDebugBuild) {
    545           ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
    546           // This is a suspend point. But it's ok since value has been set into shadow_frame.
    547           ObjPtr<mirror::Class> klass = class_linker->ResolveType(
    548               dex::TypeIndex(instr->VRegB_21c()), shadow_frame->GetMethod());
    549           DCHECK(klass->IsStringClass());
    550         }
    551       } else {
    552         CHECK(false) << "Unexpected instruction opcode " << instr->Opcode()
    553                      << " at dex_pc " << dex_pc
    554                      << " of method: " << ArtMethod::PrettyMethod(shadow_frame->GetMethod(), false);
    555       }
    556     } else {
    557       // Nothing to do, the dex_pc is the one at which the code requested
    558       // the deoptimization.
    559     }
    560     if (new_dex_pc != DexFile::kDexNoIndex) {
    561       shadow_frame->SetDexPC(new_dex_pc);
    562       value = Execute(self, code_item, *shadow_frame, value);
    563     }
    564     ShadowFrame* old_frame = shadow_frame;
    565     shadow_frame = shadow_frame->GetLink();
    566     ShadowFrame::DeleteDeoptimizedFrame(old_frame);
    567     // Following deoptimizations of shadow frames must pass the invoke instruction.
    568     from_code = false;
    569     first = false;
    570   }
    571   ret_val->SetJ(value.GetJ());
    572 }
    573 
    574 JValue EnterInterpreterFromEntryPoint(Thread* self, const DexFile::CodeItem* code_item,
    575                                       ShadowFrame* shadow_frame) {
    576   DCHECK_EQ(self, Thread::Current());
    577   bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks();
    578   if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) {
    579     ThrowStackOverflowError(self);
    580     return JValue();
    581   }
    582 
    583   jit::Jit* jit = Runtime::Current()->GetJit();
    584   if (jit != nullptr) {
    585     jit->NotifyCompiledCodeToInterpreterTransition(self, shadow_frame->GetMethod());
    586   }
    587   return Execute(self, code_item, *shadow_frame, JValue());
    588 }
    589 
    590 void ArtInterpreterToInterpreterBridge(Thread* self,
    591                                        const DexFile::CodeItem* code_item,
    592                                        ShadowFrame* shadow_frame,
    593                                        JValue* result) {
    594   bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks();
    595   if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) {
    596     ThrowStackOverflowError(self);
    597     return;
    598   }
    599 
    600   self->PushShadowFrame(shadow_frame);
    601   ArtMethod* method = shadow_frame->GetMethod();
    602   // Ensure static methods are initialized.
    603   const bool is_static = method->IsStatic();
    604   if (is_static) {
    605     ObjPtr<mirror::Class> declaring_class = method->GetDeclaringClass();
    606     if (UNLIKELY(!declaring_class->IsInitialized())) {
    607       StackHandleScope<1> hs(self);
    608       HandleWrapperObjPtr<mirror::Class> h_declaring_class(hs.NewHandleWrapper(&declaring_class));
    609       if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(
    610           self, h_declaring_class, true, true))) {
    611         DCHECK(self->IsExceptionPending());
    612         self->PopShadowFrame();
    613         return;
    614       }
    615       CHECK(h_declaring_class->IsInitializing());
    616     }
    617   }
    618 
    619   if (LIKELY(!shadow_frame->GetMethod()->IsNative())) {
    620     result->SetJ(Execute(self, code_item, *shadow_frame, JValue()).GetJ());
    621   } else {
    622     // We don't expect to be asked to interpret native code (which is entered via a JNI compiler
    623     // generated stub) except during testing and image writing.
    624     CHECK(!Runtime::Current()->IsStarted());
    625     ObjPtr<mirror::Object> receiver = is_static ? nullptr : shadow_frame->GetVRegReference(0);
    626     uint32_t* args = shadow_frame->GetVRegArgs(is_static ? 0 : 1);
    627     UnstartedRuntime::Jni(self, shadow_frame->GetMethod(), receiver.Ptr(), args, result);
    628   }
    629 
    630   self->PopShadowFrame();
    631 }
    632 
    633 void CheckInterpreterAsmConstants() {
    634   CheckMterpAsmConstants();
    635 }
    636 
    637 void InitInterpreterTls(Thread* self) {
    638   InitMterpTls(self);
    639 }
    640 
    641 }  // namespace interpreter
    642 }  // namespace art
    643