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 #ifndef ART_RUNTIME_INTERPRETER_INTERPRETER_COMMON_H_
     18 #define ART_RUNTIME_INTERPRETER_INTERPRETER_COMMON_H_
     19 
     20 #include "interpreter.h"
     21 
     22 #include <math.h>
     23 
     24 #include <iostream>
     25 #include <sstream>
     26 
     27 #include "art_field-inl.h"
     28 #include "art_method-inl.h"
     29 #include "base/logging.h"
     30 #include "base/macros.h"
     31 #include "class_linker-inl.h"
     32 #include "common_throws.h"
     33 #include "dex_file-inl.h"
     34 #include "dex_instruction-inl.h"
     35 #include "entrypoints/entrypoint_utils-inl.h"
     36 #include "handle_scope-inl.h"
     37 #include "jit/jit.h"
     38 #include "lambda/art_lambda_method.h"
     39 #include "lambda/box_table.h"
     40 #include "lambda/closure.h"
     41 #include "lambda/closure_builder-inl.h"
     42 #include "lambda/leaking_allocator.h"
     43 #include "lambda/shorty_field_type.h"
     44 #include "mirror/class-inl.h"
     45 #include "mirror/method.h"
     46 #include "mirror/object-inl.h"
     47 #include "mirror/object_array-inl.h"
     48 #include "mirror/string-inl.h"
     49 #include "stack.h"
     50 #include "thread.h"
     51 #include "well_known_classes.h"
     52 
     53 using ::art::ArtMethod;
     54 using ::art::mirror::Array;
     55 using ::art::mirror::BooleanArray;
     56 using ::art::mirror::ByteArray;
     57 using ::art::mirror::CharArray;
     58 using ::art::mirror::Class;
     59 using ::art::mirror::ClassLoader;
     60 using ::art::mirror::IntArray;
     61 using ::art::mirror::LongArray;
     62 using ::art::mirror::Object;
     63 using ::art::mirror::ObjectArray;
     64 using ::art::mirror::ShortArray;
     65 using ::art::mirror::String;
     66 using ::art::mirror::Throwable;
     67 
     68 namespace art {
     69 namespace interpreter {
     70 
     71 // External references to all interpreter implementations.
     72 
     73 template<bool do_access_check, bool transaction_active>
     74 extern JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item,
     75                                 ShadowFrame& shadow_frame, JValue result_register,
     76                                 bool interpret_one_instruction);
     77 
     78 template<bool do_access_check, bool transaction_active>
     79 extern JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item,
     80                               ShadowFrame& shadow_frame, JValue result_register);
     81 
     82 // Mterp does not support transactions or access check, thus no templated versions.
     83 extern "C" bool ExecuteMterpImpl(Thread* self, const DexFile::CodeItem* code_item,
     84                                  ShadowFrame* shadow_frame, JValue* result_register);
     85 
     86 void ThrowNullPointerExceptionFromInterpreter()
     87     SHARED_REQUIRES(Locks::mutator_lock_);
     88 
     89 template <bool kMonitorCounting>
     90 static inline void DoMonitorEnter(Thread* self,
     91                                   ShadowFrame* frame,
     92                                   Object* ref)
     93     NO_THREAD_SAFETY_ANALYSIS
     94     REQUIRES(!Roles::uninterruptible_) {
     95   StackHandleScope<1> hs(self);
     96   Handle<Object> h_ref(hs.NewHandle(ref));
     97   h_ref->MonitorEnter(self);
     98   if (kMonitorCounting && frame->GetMethod()->MustCountLocks()) {
     99     frame->GetLockCountData().AddMonitor(self, h_ref.Get());
    100   }
    101 }
    102 
    103 template <bool kMonitorCounting>
    104 static inline void DoMonitorExit(Thread* self,
    105                                  ShadowFrame* frame,
    106                                  Object* ref)
    107     NO_THREAD_SAFETY_ANALYSIS
    108     REQUIRES(!Roles::uninterruptible_) {
    109   StackHandleScope<1> hs(self);
    110   Handle<Object> h_ref(hs.NewHandle(ref));
    111   h_ref->MonitorExit(self);
    112   if (kMonitorCounting && frame->GetMethod()->MustCountLocks()) {
    113     frame->GetLockCountData().RemoveMonitorOrThrow(self, h_ref.Get());
    114   }
    115 }
    116 
    117 template <bool kMonitorCounting>
    118 static inline bool DoMonitorCheckOnExit(Thread* self, ShadowFrame* frame)
    119     NO_THREAD_SAFETY_ANALYSIS
    120     REQUIRES(!Roles::uninterruptible_) {
    121   if (kMonitorCounting && frame->GetMethod()->MustCountLocks()) {
    122     return frame->GetLockCountData().CheckAllMonitorsReleasedOrThrow(self);
    123   }
    124   return true;
    125 }
    126 
    127 void AbortTransactionF(Thread* self, const char* fmt, ...)
    128     __attribute__((__format__(__printf__, 2, 3)))
    129     SHARED_REQUIRES(Locks::mutator_lock_);
    130 
    131 void AbortTransactionV(Thread* self, const char* fmt, va_list args)
    132     SHARED_REQUIRES(Locks::mutator_lock_);
    133 
    134 void RecordArrayElementsInTransaction(mirror::Array* array, int32_t count)
    135     SHARED_REQUIRES(Locks::mutator_lock_);
    136 
    137 // Invokes the given method. This is part of the invocation support and is used by DoInvoke and
    138 // DoInvokeVirtualQuick functions.
    139 // Returns true on success, otherwise throws an exception and returns false.
    140 template<bool is_range, bool do_assignability_check>
    141 bool DoCall(ArtMethod* called_method, Thread* self, ShadowFrame& shadow_frame,
    142             const Instruction* inst, uint16_t inst_data, JValue* result);
    143 
    144 // Invokes the given lambda closure. This is part of the invocation support and is used by
    145 // DoLambdaInvoke functions.
    146 // Returns true on success, otherwise throws an exception and returns false.
    147 template<bool is_range, bool do_assignability_check>
    148 bool DoLambdaCall(ArtMethod* called_method, Thread* self, ShadowFrame& shadow_frame,
    149                   const Instruction* inst, uint16_t inst_data, JValue* result);
    150 
    151 // Validates that the art method corresponding to a lambda method target
    152 // is semantically valid:
    153 //
    154 // Must be ACC_STATIC and ACC_LAMBDA. Must be a concrete managed implementation
    155 // (i.e. not native, not proxy, not abstract, ...).
    156 //
    157 // If the validation fails, return false and raise an exception.
    158 static inline bool IsValidLambdaTargetOrThrow(ArtMethod* called_method)
    159     SHARED_REQUIRES(Locks::mutator_lock_) {
    160   bool success = false;
    161 
    162   if (UNLIKELY(called_method == nullptr)) {
    163     // The shadow frame should already be pushed, so we don't need to update it.
    164   } else if (UNLIKELY(!called_method->IsInvokable())) {
    165     called_method->ThrowInvocationTimeError();
    166     // We got an error.
    167     // TODO(iam): Also handle the case when the method is non-static, what error do we throw?
    168     // TODO(iam): Also make sure that ACC_LAMBDA is set.
    169   } else if (UNLIKELY(called_method->GetCodeItem() == nullptr)) {
    170     // Method could be native, proxy method, etc. Lambda targets have to be concrete impls,
    171     // so don't allow this.
    172   } else {
    173     success = true;
    174   }
    175 
    176   return success;
    177 }
    178 
    179 // Write out the 'Closure*' into vreg and vreg+1, as if it was a jlong.
    180 static inline void WriteLambdaClosureIntoVRegs(ShadowFrame& shadow_frame,
    181                                                const lambda::Closure& lambda_closure,
    182                                                uint32_t vreg) {
    183   // Split the method into a lo and hi 32 bits so we can encode them into 2 virtual registers.
    184   uint32_t closure_lo = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(&lambda_closure));
    185   uint32_t closure_hi = static_cast<uint32_t>(reinterpret_cast<uint64_t>(&lambda_closure)
    186                                                     >> BitSizeOf<uint32_t>());
    187   // Use uint64_t instead of uintptr_t to allow shifting past the max on 32-bit.
    188   static_assert(sizeof(uint64_t) >= sizeof(uintptr_t), "Impossible");
    189 
    190   DCHECK_NE(closure_lo | closure_hi, 0u);
    191 
    192   shadow_frame.SetVReg(vreg, closure_lo);
    193   shadow_frame.SetVReg(vreg + 1, closure_hi);
    194 }
    195 
    196 // Handles create-lambda instructions.
    197 // Returns true on success, otherwise throws an exception and returns false.
    198 // (Exceptions are thrown by creating a new exception and then being put in the thread TLS)
    199 //
    200 // The closure must be allocated big enough to hold the data, and should not be
    201 // pre-initialized. It is initialized with the actual captured variables as a side-effect,
    202 // although this should be unimportant to the caller since this function also handles storing it to
    203 // the ShadowFrame.
    204 //
    205 // As a work-in-progress implementation, this shoves the ArtMethod object corresponding
    206 // to the target dex method index into the target register vA and vA + 1.
    207 template<bool do_access_check>
    208 static inline bool DoCreateLambda(Thread* self,
    209                                   const Instruction* inst,
    210                                   /*inout*/ShadowFrame& shadow_frame,
    211                                   /*inout*/lambda::ClosureBuilder* closure_builder,
    212                                   /*inout*/lambda::Closure* uninitialized_closure) {
    213   DCHECK(closure_builder != nullptr);
    214   DCHECK(uninitialized_closure != nullptr);
    215   DCHECK_ALIGNED(uninitialized_closure, alignof(lambda::Closure));
    216 
    217   using lambda::ArtLambdaMethod;
    218   using lambda::LeakingAllocator;
    219 
    220   /*
    221    * create-lambda is opcode 0x21c
    222    * - vA is the target register where the closure will be stored into
    223    *   (also stores into vA + 1)
    224    * - vB is the method index which will be the target for a later invoke-lambda
    225    */
    226   const uint32_t method_idx = inst->VRegB_21c();
    227   mirror::Object* receiver = nullptr;  // Always static. (see 'kStatic')
    228   ArtMethod* sf_method = shadow_frame.GetMethod();
    229   ArtMethod* const called_method = FindMethodFromCode<kStatic, do_access_check>(
    230       method_idx, &receiver, sf_method, self);
    231 
    232   uint32_t vreg_dest_closure = inst->VRegA_21c();
    233 
    234   if (UNLIKELY(!IsValidLambdaTargetOrThrow(called_method))) {
    235     CHECK(self->IsExceptionPending());
    236     shadow_frame.SetVReg(vreg_dest_closure, 0u);
    237     shadow_frame.SetVReg(vreg_dest_closure + 1, 0u);
    238     return false;
    239   }
    240 
    241   ArtLambdaMethod* initialized_lambda_method;
    242   // Initialize the ArtLambdaMethod with the right data.
    243   {
    244     // Allocate enough memory to store a well-aligned ArtLambdaMethod.
    245     // This is not the final type yet since the data starts out uninitialized.
    246     LeakingAllocator::AlignedMemoryStorage<ArtLambdaMethod>* uninitialized_lambda_method =
    247             LeakingAllocator::AllocateMemory<ArtLambdaMethod>(self);
    248 
    249     std::string captured_variables_shorty = closure_builder->GetCapturedVariableShortyTypes();
    250     std::string captured_variables_long_type_desc;
    251 
    252     // Synthesize a long type descriptor from the short one.
    253     for (char shorty : captured_variables_shorty) {
    254       lambda::ShortyFieldType shorty_field_type(shorty);
    255       if (shorty_field_type.IsObject()) {
    256         // Not the true type, but good enough until we implement verifier support.
    257         captured_variables_long_type_desc += "Ljava/lang/Object;";
    258         UNIMPLEMENTED(FATAL) << "create-lambda with an object captured variable";
    259       } else if (shorty_field_type.IsLambda()) {
    260         // Not the true type, but good enough until we implement verifier support.
    261         captured_variables_long_type_desc += "Ljava/lang/Runnable;";
    262         UNIMPLEMENTED(FATAL) << "create-lambda with a lambda captured variable";
    263       } else {
    264         // The primitive types have the same length shorty or not, so this is always correct.
    265         DCHECK(shorty_field_type.IsPrimitive());
    266         captured_variables_long_type_desc += shorty_field_type;
    267       }
    268     }
    269 
    270     // Copy strings to dynamically allocated storage. This leaks, but that's ok. Fix it later.
    271     // TODO: Strings need to come from the DexFile, so they won't need their own allocations.
    272     char* captured_variables_type_desc = LeakingAllocator::MakeFlexibleInstance<char>(
    273         self,
    274         captured_variables_long_type_desc.size() + 1);
    275     strcpy(captured_variables_type_desc, captured_variables_long_type_desc.c_str());
    276     char* captured_variables_shorty_copy = LeakingAllocator::MakeFlexibleInstance<char>(
    277         self,
    278         captured_variables_shorty.size() + 1);
    279     strcpy(captured_variables_shorty_copy, captured_variables_shorty.c_str());
    280 
    281     // After initialization, the object at the storage is well-typed. Use strong type going forward.
    282     initialized_lambda_method =
    283         new (uninitialized_lambda_method) ArtLambdaMethod(called_method,
    284                                                           captured_variables_type_desc,
    285                                                           captured_variables_shorty_copy,
    286                                                           true);  // innate lambda
    287   }
    288 
    289   // Write all the closure captured variables and the closure header into the closure.
    290   lambda::Closure* initialized_closure =
    291       closure_builder->CreateInPlace(uninitialized_closure, initialized_lambda_method);
    292 
    293   WriteLambdaClosureIntoVRegs(/*inout*/shadow_frame, *initialized_closure, vreg_dest_closure);
    294   return true;
    295 }
    296 
    297 // Reads out the 'ArtMethod*' stored inside of vreg and vreg+1
    298 //
    299 // Validates that the art method points to a valid lambda function, otherwise throws
    300 // an exception and returns null.
    301 // (Exceptions are thrown by creating a new exception and then being put in the thread TLS)
    302 static inline lambda::Closure* ReadLambdaClosureFromVRegsOrThrow(ShadowFrame& shadow_frame,
    303                                                                  uint32_t vreg)
    304     SHARED_REQUIRES(Locks::mutator_lock_) {
    305   // Lambda closures take up a consecutive pair of 2 virtual registers.
    306   // On 32-bit the high bits are always 0.
    307   uint32_t vc_value_lo = shadow_frame.GetVReg(vreg);
    308   uint32_t vc_value_hi = shadow_frame.GetVReg(vreg + 1);
    309 
    310   uint64_t vc_value_ptr = (static_cast<uint64_t>(vc_value_hi) << BitSizeOf<uint32_t>())
    311                            | vc_value_lo;
    312 
    313   // Use uint64_t instead of uintptr_t to allow left-shifting past the max on 32-bit.
    314   static_assert(sizeof(uint64_t) >= sizeof(uintptr_t), "Impossible");
    315   lambda::Closure* const lambda_closure = reinterpret_cast<lambda::Closure*>(vc_value_ptr);
    316   DCHECK_ALIGNED(lambda_closure, alignof(lambda::Closure));
    317 
    318   // Guard against the user passing a null closure, which is odd but (sadly) semantically valid.
    319   if (UNLIKELY(lambda_closure == nullptr)) {
    320     ThrowNullPointerExceptionFromInterpreter();
    321     return nullptr;
    322   } else if (UNLIKELY(!IsValidLambdaTargetOrThrow(lambda_closure->GetTargetMethod()))) {
    323     // Sanity check against data corruption.
    324     return nullptr;
    325   }
    326 
    327   return lambda_closure;
    328 }
    329 
    330 // Forward declaration for lock annotations. See below for documentation.
    331 template <bool do_access_check>
    332 static inline const char* GetStringDataByDexStringIndexOrThrow(ShadowFrame& shadow_frame,
    333                                                                uint32_t string_idx)
    334     SHARED_REQUIRES(Locks::mutator_lock_);
    335 
    336 // Find the c-string data corresponding to a dex file's string index.
    337 // Otherwise, returns null if not found and throws a VerifyError.
    338 //
    339 // Note that with do_access_check=false, we never return null because the verifier
    340 // must guard against invalid string indices.
    341 // (Exceptions are thrown by creating a new exception and then being put in the thread TLS)
    342 template <bool do_access_check>
    343 static inline const char* GetStringDataByDexStringIndexOrThrow(ShadowFrame& shadow_frame,
    344                                                                uint32_t string_idx) {
    345   ArtMethod* method = shadow_frame.GetMethod();
    346   const DexFile* dex_file = method->GetDexFile();
    347 
    348   mirror::Class* declaring_class = method->GetDeclaringClass();
    349   if (!do_access_check) {
    350     // MethodVerifier refuses methods with string_idx out of bounds.
    351     DCHECK_LT(string_idx, declaring_class->GetDexCache()->NumStrings());
    352   } else {
    353     // Access checks enabled: perform string index bounds ourselves.
    354     if (string_idx >= dex_file->GetHeader().string_ids_size_) {
    355       ThrowVerifyError(declaring_class, "String index '%" PRIu32 "' out of bounds",
    356                        string_idx);
    357       return nullptr;
    358     }
    359   }
    360 
    361   const char* type_string = dex_file->StringDataByIdx(string_idx);
    362 
    363   if (UNLIKELY(type_string == nullptr)) {
    364     CHECK_EQ(false, do_access_check)
    365         << " verifier should've caught invalid string index " << string_idx;
    366     CHECK_EQ(true, do_access_check)
    367         << " string idx size check should've caught invalid string index " << string_idx;
    368   }
    369 
    370   return type_string;
    371 }
    372 
    373 // Handles capture-variable instructions.
    374 // Returns true on success, otherwise throws an exception and returns false.
    375 // (Exceptions are thrown by creating a new exception and then being put in the thread TLS)
    376 template<bool do_access_check>
    377 static inline bool DoCaptureVariable(Thread* self,
    378                                      const Instruction* inst,
    379                                      /*inout*/ShadowFrame& shadow_frame,
    380                                      /*inout*/lambda::ClosureBuilder* closure_builder) {
    381   DCHECK(closure_builder != nullptr);
    382   using lambda::ShortyFieldType;
    383   /*
    384    * capture-variable is opcode 0xf6, fmt 0x21c
    385    * - vA is the source register of the variable that will be captured
    386    * - vB is the string ID of the variable's type that will be captured
    387    */
    388   const uint32_t source_vreg = inst->VRegA_21c();
    389   const uint32_t string_idx = inst->VRegB_21c();
    390   // TODO: this should be a proper [type id] instead of a [string ID] pointing to a type.
    391 
    392   const char* type_string = GetStringDataByDexStringIndexOrThrow<do_access_check>(shadow_frame,
    393                                                                                   string_idx);
    394   if (UNLIKELY(type_string == nullptr)) {
    395     CHECK(self->IsExceptionPending());
    396     return false;
    397   }
    398 
    399   char type_first_letter = type_string[0];
    400   ShortyFieldType shorty_type;
    401   if (do_access_check &&
    402       UNLIKELY(!ShortyFieldType::MaybeCreate(type_first_letter, /*out*/&shorty_type))) {  // NOLINT: [whitespace/comma] [3]
    403     ThrowVerifyError(shadow_frame.GetMethod()->GetDeclaringClass(),
    404                      "capture-variable vB must be a valid type");
    405     return false;
    406   } else {
    407     // Already verified that the type is valid.
    408     shorty_type = ShortyFieldType(type_first_letter);
    409   }
    410 
    411   const size_t captured_variable_count = closure_builder->GetCaptureCount();
    412 
    413   // Note: types are specified explicitly so that the closure is packed tightly.
    414   switch (shorty_type) {
    415     case ShortyFieldType::kBoolean: {
    416       uint32_t primitive_narrow_value = shadow_frame.GetVReg(source_vreg);
    417       closure_builder->CaptureVariablePrimitive<bool>(primitive_narrow_value);
    418       break;
    419     }
    420     case ShortyFieldType::kByte: {
    421       uint32_t primitive_narrow_value = shadow_frame.GetVReg(source_vreg);
    422       closure_builder->CaptureVariablePrimitive<int8_t>(primitive_narrow_value);
    423       break;
    424     }
    425     case ShortyFieldType::kChar: {
    426       uint32_t primitive_narrow_value = shadow_frame.GetVReg(source_vreg);
    427       closure_builder->CaptureVariablePrimitive<uint16_t>(primitive_narrow_value);
    428       break;
    429     }
    430     case ShortyFieldType::kShort: {
    431       uint32_t primitive_narrow_value = shadow_frame.GetVReg(source_vreg);
    432       closure_builder->CaptureVariablePrimitive<int16_t>(primitive_narrow_value);
    433       break;
    434     }
    435     case ShortyFieldType::kInt: {
    436       uint32_t primitive_narrow_value = shadow_frame.GetVReg(source_vreg);
    437       closure_builder->CaptureVariablePrimitive<int32_t>(primitive_narrow_value);
    438       break;
    439     }
    440     case ShortyFieldType::kDouble: {
    441       closure_builder->CaptureVariablePrimitive(shadow_frame.GetVRegDouble(source_vreg));
    442       break;
    443     }
    444     case ShortyFieldType::kFloat: {
    445       closure_builder->CaptureVariablePrimitive(shadow_frame.GetVRegFloat(source_vreg));
    446       break;
    447     }
    448     case ShortyFieldType::kLambda: {
    449       UNIMPLEMENTED(FATAL) << " capture-variable with type kLambda";
    450       // TODO: Capturing lambdas recursively will be done at a later time.
    451       UNREACHABLE();
    452     }
    453     case ShortyFieldType::kLong: {
    454       closure_builder->CaptureVariablePrimitive(shadow_frame.GetVRegLong(source_vreg));
    455       break;
    456     }
    457     case ShortyFieldType::kObject: {
    458       closure_builder->CaptureVariableObject(shadow_frame.GetVRegReference(source_vreg));
    459       UNIMPLEMENTED(FATAL) << " capture-variable with type kObject";
    460       // TODO: finish implementing this. disabled for now since we can't track lambda refs for GC.
    461       UNREACHABLE();
    462     }
    463 
    464     default:
    465       LOG(FATAL) << "Invalid shorty type value " << shorty_type;
    466       UNREACHABLE();
    467   }
    468 
    469   DCHECK_EQ(captured_variable_count + 1, closure_builder->GetCaptureCount());
    470 
    471   return true;
    472 }
    473 
    474 // Handles capture-variable instructions.
    475 // Returns true on success, otherwise throws an exception and returns false.
    476 // (Exceptions are thrown by creating a new exception and then being put in the thread TLS)
    477 template<bool do_access_check>
    478 static inline bool DoLiberateVariable(Thread* self,
    479                                      const Instruction* inst,
    480                                      size_t captured_variable_index,
    481                                      /*inout*/ShadowFrame& shadow_frame) {
    482   using lambda::ShortyFieldType;
    483   /*
    484    * liberate-variable is opcode 0xf7, fmt 0x22c
    485    * - vA is the destination register
    486    * - vB is the register with the lambda closure in it
    487    * - vC is the string ID which needs to be a valid field type descriptor
    488    */
    489 
    490   const uint32_t dest_vreg = inst->VRegA_22c();
    491   const uint32_t closure_vreg = inst->VRegB_22c();
    492   const uint32_t string_idx = inst->VRegC_22c();
    493   // TODO: this should be a proper [type id] instead of a [string ID] pointing to a type.
    494 
    495 
    496   // Synthesize a long type descriptor from a shorty type descriptor list.
    497   // TODO: Fix the dex encoding to contain the long and short type descriptors.
    498   const char* type_string = GetStringDataByDexStringIndexOrThrow<do_access_check>(shadow_frame,
    499                                                                                   string_idx);
    500   if (UNLIKELY(do_access_check && type_string == nullptr)) {
    501     CHECK(self->IsExceptionPending());
    502     shadow_frame.SetVReg(dest_vreg, 0);
    503     return false;
    504   }
    505 
    506   char type_first_letter = type_string[0];
    507   ShortyFieldType shorty_type;
    508   if (do_access_check &&
    509       UNLIKELY(!ShortyFieldType::MaybeCreate(type_first_letter, /*out*/&shorty_type))) {  // NOLINT: [whitespace/comma] [3]
    510     ThrowVerifyError(shadow_frame.GetMethod()->GetDeclaringClass(),
    511                      "liberate-variable vC must be a valid type");
    512     shadow_frame.SetVReg(dest_vreg, 0);
    513     return false;
    514   } else {
    515     // Already verified that the type is valid.
    516     shorty_type = ShortyFieldType(type_first_letter);
    517   }
    518 
    519   // Check for closure being null *after* the type check.
    520   // This way we can access the type info in case we fail later, to know how many vregs to clear.
    521   const lambda::Closure* lambda_closure =
    522       ReadLambdaClosureFromVRegsOrThrow(/*inout*/shadow_frame, closure_vreg);
    523 
    524   // Failed lambda target runtime check, an exception was raised.
    525   if (UNLIKELY(lambda_closure == nullptr)) {
    526     CHECK(self->IsExceptionPending());
    527 
    528     // Clear the destination vreg(s) to be safe.
    529     shadow_frame.SetVReg(dest_vreg, 0);
    530     if (shorty_type.IsPrimitiveWide() || shorty_type.IsLambda()) {
    531       shadow_frame.SetVReg(dest_vreg + 1, 0);
    532     }
    533     return false;
    534   }
    535 
    536   if (do_access_check &&
    537       UNLIKELY(captured_variable_index >= lambda_closure->GetNumberOfCapturedVariables())) {
    538     ThrowVerifyError(shadow_frame.GetMethod()->GetDeclaringClass(),
    539                      "liberate-variable captured variable index %zu out of bounds",
    540                      lambda_closure->GetNumberOfCapturedVariables());
    541     // Clear the destination vreg(s) to be safe.
    542     shadow_frame.SetVReg(dest_vreg, 0);
    543     if (shorty_type.IsPrimitiveWide() || shorty_type.IsLambda()) {
    544       shadow_frame.SetVReg(dest_vreg + 1, 0);
    545     }
    546     return false;
    547   }
    548 
    549   // Verify that the runtime type of the captured-variable matches the requested dex type.
    550   if (do_access_check) {
    551     ShortyFieldType actual_type = lambda_closure->GetCapturedShortyType(captured_variable_index);
    552     if (actual_type != shorty_type) {
    553       ThrowVerifyError(shadow_frame.GetMethod()->GetDeclaringClass(),
    554                      "cannot liberate-variable of runtime type '%c' to dex type '%c'",
    555                      static_cast<char>(actual_type),
    556                      static_cast<char>(shorty_type));
    557 
    558       shadow_frame.SetVReg(dest_vreg, 0);
    559       if (shorty_type.IsPrimitiveWide() || shorty_type.IsLambda()) {
    560         shadow_frame.SetVReg(dest_vreg + 1, 0);
    561       }
    562       return false;
    563     }
    564 
    565     if (actual_type.IsLambda() || actual_type.IsObject()) {
    566       UNIMPLEMENTED(FATAL) << "liberate-variable type checks needs to "
    567                            << "parse full type descriptor for objects and lambdas";
    568     }
    569   }
    570 
    571   // Unpack the captured variable from the closure into the correct type, then save it to the vreg.
    572   if (shorty_type.IsPrimitiveNarrow()) {
    573     uint32_t primitive_narrow_value =
    574         lambda_closure->GetCapturedPrimitiveNarrow(captured_variable_index);
    575     shadow_frame.SetVReg(dest_vreg, primitive_narrow_value);
    576   } else if (shorty_type.IsPrimitiveWide()) {
    577       uint64_t primitive_wide_value =
    578           lambda_closure->GetCapturedPrimitiveWide(captured_variable_index);
    579       shadow_frame.SetVRegLong(dest_vreg, static_cast<int64_t>(primitive_wide_value));
    580   } else if (shorty_type.IsObject()) {
    581     mirror::Object* unpacked_object =
    582         lambda_closure->GetCapturedObject(captured_variable_index);
    583     shadow_frame.SetVRegReference(dest_vreg, unpacked_object);
    584 
    585     UNIMPLEMENTED(FATAL) << "liberate-variable cannot unpack objects yet";
    586   } else if (shorty_type.IsLambda()) {
    587     UNIMPLEMENTED(FATAL) << "liberate-variable cannot unpack lambdas yet";
    588   } else {
    589     LOG(FATAL) << "unreachable";
    590     UNREACHABLE();
    591   }
    592 
    593   return true;
    594 }
    595 
    596 template<bool do_access_check>
    597 static inline bool DoInvokeLambda(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst,
    598                                   uint16_t inst_data, JValue* result) {
    599   /*
    600    * invoke-lambda is opcode 0x25
    601    *
    602    * - vC is the closure register (both vC and vC + 1 will be used to store the closure).
    603    * - vB is the number of additional registers up to |{vD,vE,vF,vG}| (4)
    604    * - the rest of the registers are always var-args
    605    *
    606    * - reading var-args for 0x25 gets us vD,vE,vF,vG (but not vB)
    607    */
    608   uint32_t vreg_closure = inst->VRegC_25x();
    609   const lambda::Closure* lambda_closure =
    610       ReadLambdaClosureFromVRegsOrThrow(shadow_frame, vreg_closure);
    611 
    612   // Failed lambda target runtime check, an exception was raised.
    613   if (UNLIKELY(lambda_closure == nullptr)) {
    614     CHECK(self->IsExceptionPending());
    615     result->SetJ(0);
    616     return false;
    617   }
    618 
    619   ArtMethod* const called_method = lambda_closure->GetTargetMethod();
    620   // Invoke a non-range lambda
    621   return DoLambdaCall<false, do_access_check>(called_method, self, shadow_frame, inst, inst_data,
    622                                               result);
    623 }
    624 
    625 // Handles invoke-XXX/range instructions (other than invoke-lambda[-range]).
    626 // Returns true on success, otherwise throws an exception and returns false.
    627 template<InvokeType type, bool is_range, bool do_access_check>
    628 static inline bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst,
    629                             uint16_t inst_data, JValue* result) {
    630   const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
    631   const uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c();
    632   Object* receiver = (type == kStatic) ? nullptr : shadow_frame.GetVRegReference(vregC);
    633   ArtMethod* sf_method = shadow_frame.GetMethod();
    634   ArtMethod* const called_method = FindMethodFromCode<type, do_access_check>(
    635       method_idx, &receiver, sf_method, self);
    636   // The shadow frame should already be pushed, so we don't need to update it.
    637   if (UNLIKELY(called_method == nullptr)) {
    638     CHECK(self->IsExceptionPending());
    639     result->SetJ(0);
    640     return false;
    641   } else if (UNLIKELY(!called_method->IsInvokable())) {
    642     called_method->ThrowInvocationTimeError();
    643     result->SetJ(0);
    644     return false;
    645   } else {
    646     jit::Jit* jit = Runtime::Current()->GetJit();
    647     if (jit != nullptr) {
    648       if (type == kVirtual || type == kInterface) {
    649         jit->InvokeVirtualOrInterface(
    650             self, receiver, sf_method, shadow_frame.GetDexPC(), called_method);
    651       }
    652       jit->AddSamples(self, sf_method, 1, /*with_backedges*/false);
    653     }
    654     // TODO: Remove the InvokeVirtualOrInterface instrumentation, as it was only used by the JIT.
    655     if (type == kVirtual || type == kInterface) {
    656       instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
    657       if (UNLIKELY(instrumentation->HasInvokeVirtualOrInterfaceListeners())) {
    658         instrumentation->InvokeVirtualOrInterface(
    659             self, receiver, sf_method, shadow_frame.GetDexPC(), called_method);
    660       }
    661     }
    662     return DoCall<is_range, do_access_check>(called_method, self, shadow_frame, inst, inst_data,
    663                                              result);
    664   }
    665 }
    666 
    667 // Handles invoke-virtual-quick and invoke-virtual-quick-range instructions.
    668 // Returns true on success, otherwise throws an exception and returns false.
    669 template<bool is_range>
    670 static inline bool DoInvokeVirtualQuick(Thread* self, ShadowFrame& shadow_frame,
    671                                         const Instruction* inst, uint16_t inst_data,
    672                                         JValue* result) {
    673   const uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c();
    674   Object* const receiver = shadow_frame.GetVRegReference(vregC);
    675   if (UNLIKELY(receiver == nullptr)) {
    676     // We lost the reference to the method index so we cannot get a more
    677     // precised exception message.
    678     ThrowNullPointerExceptionFromDexPC();
    679     return false;
    680   }
    681   const uint32_t vtable_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
    682   CHECK(receiver->GetClass()->ShouldHaveEmbeddedVTable());
    683   ArtMethod* const called_method = receiver->GetClass()->GetEmbeddedVTableEntry(
    684       vtable_idx, sizeof(void*));
    685   if (UNLIKELY(called_method == nullptr)) {
    686     CHECK(self->IsExceptionPending());
    687     result->SetJ(0);
    688     return false;
    689   } else if (UNLIKELY(!called_method->IsInvokable())) {
    690     called_method->ThrowInvocationTimeError();
    691     result->SetJ(0);
    692     return false;
    693   } else {
    694     jit::Jit* jit = Runtime::Current()->GetJit();
    695     if (jit != nullptr) {
    696       jit->InvokeVirtualOrInterface(
    697           self, receiver, shadow_frame.GetMethod(), shadow_frame.GetDexPC(), called_method);
    698       jit->AddSamples(self, shadow_frame.GetMethod(), 1, /*with_backedges*/false);
    699     }
    700     instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
    701     // TODO: Remove the InvokeVirtualOrInterface instrumentation, as it was only used by the JIT.
    702     if (UNLIKELY(instrumentation->HasInvokeVirtualOrInterfaceListeners())) {
    703       instrumentation->InvokeVirtualOrInterface(
    704           self, receiver, shadow_frame.GetMethod(), shadow_frame.GetDexPC(), called_method);
    705     }
    706     // No need to check since we've been quickened.
    707     return DoCall<is_range, false>(called_method, self, shadow_frame, inst, inst_data, result);
    708   }
    709 }
    710 
    711 // Handles iget-XXX and sget-XXX instructions.
    712 // Returns true on success, otherwise throws an exception and returns false.
    713 template<FindFieldType find_type, Primitive::Type field_type, bool do_access_check>
    714 bool DoFieldGet(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst,
    715                 uint16_t inst_data) SHARED_REQUIRES(Locks::mutator_lock_);
    716 
    717 // Handles iget-quick, iget-wide-quick and iget-object-quick instructions.
    718 // Returns true on success, otherwise throws an exception and returns false.
    719 template<Primitive::Type field_type>
    720 bool DoIGetQuick(ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data)
    721     SHARED_REQUIRES(Locks::mutator_lock_);
    722 
    723 // Handles iput-XXX and sput-XXX instructions.
    724 // Returns true on success, otherwise throws an exception and returns false.
    725 template<FindFieldType find_type, Primitive::Type field_type, bool do_access_check,
    726          bool transaction_active>
    727 bool DoFieldPut(Thread* self, const ShadowFrame& shadow_frame, const Instruction* inst,
    728                 uint16_t inst_data) SHARED_REQUIRES(Locks::mutator_lock_);
    729 
    730 // Handles iput-quick, iput-wide-quick and iput-object-quick instructions.
    731 // Returns true on success, otherwise throws an exception and returns false.
    732 template<Primitive::Type field_type, bool transaction_active>
    733 bool DoIPutQuick(const ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data)
    734     SHARED_REQUIRES(Locks::mutator_lock_);
    735 
    736 
    737 // Handles string resolution for const-string and const-string-jumbo instructions. Also ensures the
    738 // java.lang.String class is initialized.
    739 static inline String* ResolveString(Thread* self, ShadowFrame& shadow_frame, uint32_t string_idx)
    740     SHARED_REQUIRES(Locks::mutator_lock_) {
    741   Class* java_lang_string_class = String::GetJavaLangString();
    742   if (UNLIKELY(!java_lang_string_class->IsInitialized())) {
    743     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
    744     StackHandleScope<1> hs(self);
    745     Handle<mirror::Class> h_class(hs.NewHandle(java_lang_string_class));
    746     if (UNLIKELY(!class_linker->EnsureInitialized(self, h_class, true, true))) {
    747       DCHECK(self->IsExceptionPending());
    748       return nullptr;
    749     }
    750   }
    751   ArtMethod* method = shadow_frame.GetMethod();
    752   mirror::Class* declaring_class = method->GetDeclaringClass();
    753   // MethodVerifier refuses methods with string_idx out of bounds.
    754   DCHECK_LT(string_idx, declaring_class->GetDexCache()->NumStrings());
    755   mirror::String* s = declaring_class->GetDexCacheStrings()[string_idx].Read();
    756   if (UNLIKELY(s == nullptr)) {
    757     StackHandleScope<1> hs(self);
    758     Handle<mirror::DexCache> dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
    759     s = Runtime::Current()->GetClassLinker()->ResolveString(*method->GetDexFile(), string_idx,
    760                                                             dex_cache);
    761   }
    762   return s;
    763 }
    764 
    765 // Handles div-int, div-int/2addr, div-int/li16 and div-int/lit8 instructions.
    766 // Returns true on success, otherwise throws a java.lang.ArithmeticException and return false.
    767 static inline bool DoIntDivide(ShadowFrame& shadow_frame, size_t result_reg,
    768                                int32_t dividend, int32_t divisor)
    769     SHARED_REQUIRES(Locks::mutator_lock_) {
    770   constexpr int32_t kMinInt = std::numeric_limits<int32_t>::min();
    771   if (UNLIKELY(divisor == 0)) {
    772     ThrowArithmeticExceptionDivideByZero();
    773     return false;
    774   }
    775   if (UNLIKELY(dividend == kMinInt && divisor == -1)) {
    776     shadow_frame.SetVReg(result_reg, kMinInt);
    777   } else {
    778     shadow_frame.SetVReg(result_reg, dividend / divisor);
    779   }
    780   return true;
    781 }
    782 
    783 // Handles rem-int, rem-int/2addr, rem-int/li16 and rem-int/lit8 instructions.
    784 // Returns true on success, otherwise throws a java.lang.ArithmeticException and return false.
    785 static inline bool DoIntRemainder(ShadowFrame& shadow_frame, size_t result_reg,
    786                                   int32_t dividend, int32_t divisor)
    787     SHARED_REQUIRES(Locks::mutator_lock_) {
    788   constexpr int32_t kMinInt = std::numeric_limits<int32_t>::min();
    789   if (UNLIKELY(divisor == 0)) {
    790     ThrowArithmeticExceptionDivideByZero();
    791     return false;
    792   }
    793   if (UNLIKELY(dividend == kMinInt && divisor == -1)) {
    794     shadow_frame.SetVReg(result_reg, 0);
    795   } else {
    796     shadow_frame.SetVReg(result_reg, dividend % divisor);
    797   }
    798   return true;
    799 }
    800 
    801 // Handles div-long and div-long-2addr instructions.
    802 // Returns true on success, otherwise throws a java.lang.ArithmeticException and return false.
    803 static inline bool DoLongDivide(ShadowFrame& shadow_frame, size_t result_reg,
    804                                 int64_t dividend, int64_t divisor)
    805     SHARED_REQUIRES(Locks::mutator_lock_) {
    806   const int64_t kMinLong = std::numeric_limits<int64_t>::min();
    807   if (UNLIKELY(divisor == 0)) {
    808     ThrowArithmeticExceptionDivideByZero();
    809     return false;
    810   }
    811   if (UNLIKELY(dividend == kMinLong && divisor == -1)) {
    812     shadow_frame.SetVRegLong(result_reg, kMinLong);
    813   } else {
    814     shadow_frame.SetVRegLong(result_reg, dividend / divisor);
    815   }
    816   return true;
    817 }
    818 
    819 // Handles rem-long and rem-long-2addr instructions.
    820 // Returns true on success, otherwise throws a java.lang.ArithmeticException and return false.
    821 static inline bool DoLongRemainder(ShadowFrame& shadow_frame, size_t result_reg,
    822                                    int64_t dividend, int64_t divisor)
    823     SHARED_REQUIRES(Locks::mutator_lock_) {
    824   const int64_t kMinLong = std::numeric_limits<int64_t>::min();
    825   if (UNLIKELY(divisor == 0)) {
    826     ThrowArithmeticExceptionDivideByZero();
    827     return false;
    828   }
    829   if (UNLIKELY(dividend == kMinLong && divisor == -1)) {
    830     shadow_frame.SetVRegLong(result_reg, 0);
    831   } else {
    832     shadow_frame.SetVRegLong(result_reg, dividend % divisor);
    833   }
    834   return true;
    835 }
    836 
    837 // Handles filled-new-array and filled-new-array-range instructions.
    838 // Returns true on success, otherwise throws an exception and returns false.
    839 template <bool is_range, bool do_access_check, bool transaction_active>
    840 bool DoFilledNewArray(const Instruction* inst, const ShadowFrame& shadow_frame,
    841                       Thread* self, JValue* result);
    842 
    843 // Handles packed-switch instruction.
    844 // Returns the branch offset to the next instruction to execute.
    845 static inline int32_t DoPackedSwitch(const Instruction* inst, const ShadowFrame& shadow_frame,
    846                                      uint16_t inst_data)
    847     SHARED_REQUIRES(Locks::mutator_lock_) {
    848   DCHECK(inst->Opcode() == Instruction::PACKED_SWITCH);
    849   const uint16_t* switch_data = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
    850   int32_t test_val = shadow_frame.GetVReg(inst->VRegA_31t(inst_data));
    851   DCHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kPackedSwitchSignature));
    852   uint16_t size = switch_data[1];
    853   if (size == 0) {
    854     // Empty packed switch, move forward by 3 (size of PACKED_SWITCH).
    855     return 3;
    856   }
    857   const int32_t* keys = reinterpret_cast<const int32_t*>(&switch_data[2]);
    858   DCHECK_ALIGNED(keys, 4);
    859   int32_t first_key = keys[0];
    860   const int32_t* targets = reinterpret_cast<const int32_t*>(&switch_data[4]);
    861   DCHECK_ALIGNED(targets, 4);
    862   int32_t index = test_val - first_key;
    863   if (index >= 0 && index < size) {
    864     return targets[index];
    865   } else {
    866     // No corresponding value: move forward by 3 (size of PACKED_SWITCH).
    867     return 3;
    868   }
    869 }
    870 
    871 // Handles sparse-switch instruction.
    872 // Returns the branch offset to the next instruction to execute.
    873 static inline int32_t DoSparseSwitch(const Instruction* inst, const ShadowFrame& shadow_frame,
    874                                      uint16_t inst_data)
    875     SHARED_REQUIRES(Locks::mutator_lock_) {
    876   DCHECK(inst->Opcode() == Instruction::SPARSE_SWITCH);
    877   const uint16_t* switch_data = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
    878   int32_t test_val = shadow_frame.GetVReg(inst->VRegA_31t(inst_data));
    879   DCHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kSparseSwitchSignature));
    880   uint16_t size = switch_data[1];
    881   // Return length of SPARSE_SWITCH if size is 0.
    882   if (size == 0) {
    883     return 3;
    884   }
    885   const int32_t* keys = reinterpret_cast<const int32_t*>(&switch_data[2]);
    886   DCHECK_ALIGNED(keys, 4);
    887   const int32_t* entries = keys + size;
    888   DCHECK_ALIGNED(entries, 4);
    889   int lo = 0;
    890   int hi = size - 1;
    891   while (lo <= hi) {
    892     int mid = (lo + hi) / 2;
    893     int32_t foundVal = keys[mid];
    894     if (test_val < foundVal) {
    895       hi = mid - 1;
    896     } else if (test_val > foundVal) {
    897       lo = mid + 1;
    898     } else {
    899       return entries[mid];
    900     }
    901   }
    902   // No corresponding value: move forward by 3 (size of SPARSE_SWITCH).
    903   return 3;
    904 }
    905 
    906 template <bool _do_check>
    907 static inline bool DoBoxLambda(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst,
    908                                uint16_t inst_data) SHARED_REQUIRES(Locks::mutator_lock_) {
    909   /*
    910    * box-lambda vA, vB /// opcode 0xf8, format 22x
    911    * - vA is the target register where the Object representation of the closure will be stored into
    912    * - vB is a closure (made by create-lambda)
    913    *   (also reads vB + 1)
    914    */
    915   uint32_t vreg_target_object = inst->VRegA_22x(inst_data);
    916   uint32_t vreg_source_closure = inst->VRegB_22x();
    917 
    918   lambda::Closure* lambda_closure = ReadLambdaClosureFromVRegsOrThrow(shadow_frame,
    919                                                                       vreg_source_closure);
    920 
    921   // Failed lambda target runtime check, an exception was raised.
    922   if (UNLIKELY(lambda_closure == nullptr)) {
    923     CHECK(self->IsExceptionPending());
    924     return false;
    925   }
    926 
    927   mirror::Object* closure_as_object =
    928       Runtime::Current()->GetLambdaBoxTable()->BoxLambda(lambda_closure);
    929 
    930   // Failed to box the lambda, an exception was raised.
    931   if (UNLIKELY(closure_as_object == nullptr)) {
    932     CHECK(self->IsExceptionPending());
    933     return false;
    934   }
    935 
    936   shadow_frame.SetVRegReference(vreg_target_object, closure_as_object);
    937   return true;
    938 }
    939 
    940 template <bool _do_check> SHARED_REQUIRES(Locks::mutator_lock_)
    941 static inline bool DoUnboxLambda(Thread* self,
    942                                  ShadowFrame& shadow_frame,
    943                                  const Instruction* inst,
    944                                  uint16_t inst_data) {
    945   /*
    946    * unbox-lambda vA, vB, [type id] /// opcode 0xf9, format 22c
    947    * - vA is the target register where the closure will be written into
    948    *   (also writes vA + 1)
    949    * - vB is the Object representation of the closure (made by box-lambda)
    950    */
    951   uint32_t vreg_target_closure = inst->VRegA_22c(inst_data);
    952   uint32_t vreg_source_object = inst->VRegB_22c();
    953 
    954   // Raise NullPointerException if object is null
    955   mirror::Object* boxed_closure_object = shadow_frame.GetVRegReference(vreg_source_object);
    956   if (UNLIKELY(boxed_closure_object == nullptr)) {
    957     ThrowNullPointerExceptionFromInterpreter();
    958     return false;
    959   }
    960 
    961   lambda::Closure* unboxed_closure = nullptr;
    962   // Raise an exception if unboxing fails.
    963   if (!Runtime::Current()->GetLambdaBoxTable()->UnboxLambda(boxed_closure_object,
    964                                                             /*out*/&unboxed_closure)) {
    965     CHECK(self->IsExceptionPending());
    966     return false;
    967   }
    968 
    969   DCHECK(unboxed_closure != nullptr);
    970   WriteLambdaClosureIntoVRegs(/*inout*/shadow_frame, *unboxed_closure, vreg_target_closure);
    971   return true;
    972 }
    973 
    974 uint32_t FindNextInstructionFollowingException(Thread* self, ShadowFrame& shadow_frame,
    975     uint32_t dex_pc, const instrumentation::Instrumentation* instrumentation)
    976         SHARED_REQUIRES(Locks::mutator_lock_);
    977 
    978 NO_RETURN void UnexpectedOpcode(const Instruction* inst, const ShadowFrame& shadow_frame)
    979   __attribute__((cold))
    980   SHARED_REQUIRES(Locks::mutator_lock_);
    981 
    982 static inline bool TraceExecutionEnabled() {
    983   // Return true if you want TraceExecution invocation before each bytecode execution.
    984   return false;
    985 }
    986 
    987 static inline void TraceExecution(const ShadowFrame& shadow_frame, const Instruction* inst,
    988                                   const uint32_t dex_pc)
    989     SHARED_REQUIRES(Locks::mutator_lock_) {
    990   if (TraceExecutionEnabled()) {
    991 #define TRACE_LOG std::cerr
    992     std::ostringstream oss;
    993     oss << PrettyMethod(shadow_frame.GetMethod())
    994         << StringPrintf("\n0x%x: ", dex_pc)
    995         << inst->DumpString(shadow_frame.GetMethod()->GetDexFile()) << "\n";
    996     for (uint32_t i = 0; i < shadow_frame.NumberOfVRegs(); ++i) {
    997       uint32_t raw_value = shadow_frame.GetVReg(i);
    998       Object* ref_value = shadow_frame.GetVRegReference(i);
    999       oss << StringPrintf(" vreg%u=0x%08X", i, raw_value);
   1000       if (ref_value != nullptr) {
   1001         if (ref_value->GetClass()->IsStringClass() &&
   1002             ref_value->AsString()->GetValue() != nullptr) {
   1003           oss << "/java.lang.String \"" << ref_value->AsString()->ToModifiedUtf8() << "\"";
   1004         } else {
   1005           oss << "/" << PrettyTypeOf(ref_value);
   1006         }
   1007       }
   1008     }
   1009     TRACE_LOG << oss.str() << "\n";
   1010 #undef TRACE_LOG
   1011   }
   1012 }
   1013 
   1014 static inline bool IsBackwardBranch(int32_t branch_offset) {
   1015   return branch_offset <= 0;
   1016 }
   1017 
   1018 void ArtInterpreterToCompiledCodeBridge(Thread* self,
   1019                                         ArtMethod* caller,
   1020                                         const DexFile::CodeItem* code_item,
   1021                                         ShadowFrame* shadow_frame,
   1022                                         JValue* result);
   1023 
   1024 // Set string value created from StringFactory.newStringFromXXX() into all aliases of
   1025 // StringFactory.newEmptyString().
   1026 void SetStringInitValueToAllAliases(ShadowFrame* shadow_frame,
   1027                                     uint16_t this_obj_vreg,
   1028                                     JValue result);
   1029 
   1030 // Explicitly instantiate all DoInvoke functions.
   1031 #define EXPLICIT_DO_INVOKE_TEMPLATE_DECL(_type, _is_range, _do_check)                      \
   1032   template SHARED_REQUIRES(Locks::mutator_lock_)                                     \
   1033   bool DoInvoke<_type, _is_range, _do_check>(Thread* self, ShadowFrame& shadow_frame,      \
   1034                                              const Instruction* inst, uint16_t inst_data,  \
   1035                                              JValue* result)
   1036 
   1037 #define EXPLICIT_DO_INVOKE_ALL_TEMPLATE_DECL(_type)       \
   1038   EXPLICIT_DO_INVOKE_TEMPLATE_DECL(_type, false, false);  \
   1039   EXPLICIT_DO_INVOKE_TEMPLATE_DECL(_type, false, true);   \
   1040   EXPLICIT_DO_INVOKE_TEMPLATE_DECL(_type, true, false);   \
   1041   EXPLICIT_DO_INVOKE_TEMPLATE_DECL(_type, true, true);
   1042 
   1043 EXPLICIT_DO_INVOKE_ALL_TEMPLATE_DECL(kStatic)      // invoke-static/range.
   1044 EXPLICIT_DO_INVOKE_ALL_TEMPLATE_DECL(kDirect)      // invoke-direct/range.
   1045 EXPLICIT_DO_INVOKE_ALL_TEMPLATE_DECL(kVirtual)     // invoke-virtual/range.
   1046 EXPLICIT_DO_INVOKE_ALL_TEMPLATE_DECL(kSuper)       // invoke-super/range.
   1047 EXPLICIT_DO_INVOKE_ALL_TEMPLATE_DECL(kInterface)   // invoke-interface/range.
   1048 #undef EXPLICIT_DO_INVOKE_ALL_TEMPLATE_DECL
   1049 #undef EXPLICIT_DO_INVOKE_TEMPLATE_DECL
   1050 
   1051 // Explicitly instantiate all DoInvokeVirtualQuick functions.
   1052 #define EXPLICIT_DO_INVOKE_VIRTUAL_QUICK_TEMPLATE_DECL(_is_range)                    \
   1053   template SHARED_REQUIRES(Locks::mutator_lock_)                               \
   1054   bool DoInvokeVirtualQuick<_is_range>(Thread* self, ShadowFrame& shadow_frame,      \
   1055                                        const Instruction* inst, uint16_t inst_data,  \
   1056                                        JValue* result)
   1057 
   1058 EXPLICIT_DO_INVOKE_VIRTUAL_QUICK_TEMPLATE_DECL(false);  // invoke-virtual-quick.
   1059 EXPLICIT_DO_INVOKE_VIRTUAL_QUICK_TEMPLATE_DECL(true);   // invoke-virtual-quick-range.
   1060 #undef EXPLICIT_INSTANTIATION_DO_INVOKE_VIRTUAL_QUICK
   1061 
   1062 // Explicitly instantiate all DoCreateLambda functions.
   1063 #define EXPLICIT_DO_CREATE_LAMBDA_DECL(_do_check)                                                 \
   1064 template SHARED_REQUIRES(Locks::mutator_lock_)                                                    \
   1065 bool DoCreateLambda<_do_check>(Thread* self,                                                      \
   1066                                const Instruction* inst,                                           \
   1067                                /*inout*/ShadowFrame& shadow_frame,                                \
   1068                                /*inout*/lambda::ClosureBuilder* closure_builder,                  \
   1069                                /*inout*/lambda::Closure* uninitialized_closure);
   1070 
   1071 EXPLICIT_DO_CREATE_LAMBDA_DECL(false);  // create-lambda
   1072 EXPLICIT_DO_CREATE_LAMBDA_DECL(true);   // create-lambda
   1073 #undef EXPLICIT_DO_CREATE_LAMBDA_DECL
   1074 
   1075 // Explicitly instantiate all DoInvokeLambda functions.
   1076 #define EXPLICIT_DO_INVOKE_LAMBDA_DECL(_do_check)                                    \
   1077 template SHARED_REQUIRES(Locks::mutator_lock_)                                 \
   1078 bool DoInvokeLambda<_do_check>(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst, \
   1079                                uint16_t inst_data, JValue* result);
   1080 
   1081 EXPLICIT_DO_INVOKE_LAMBDA_DECL(false);  // invoke-lambda
   1082 EXPLICIT_DO_INVOKE_LAMBDA_DECL(true);   // invoke-lambda
   1083 #undef EXPLICIT_DO_INVOKE_LAMBDA_DECL
   1084 
   1085 // Explicitly instantiate all DoBoxLambda functions.
   1086 #define EXPLICIT_DO_BOX_LAMBDA_DECL(_do_check)                                                \
   1087 template SHARED_REQUIRES(Locks::mutator_lock_)                                          \
   1088 bool DoBoxLambda<_do_check>(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst, \
   1089                             uint16_t inst_data);
   1090 
   1091 EXPLICIT_DO_BOX_LAMBDA_DECL(false);  // box-lambda
   1092 EXPLICIT_DO_BOX_LAMBDA_DECL(true);   // box-lambda
   1093 #undef EXPLICIT_DO_BOX_LAMBDA_DECL
   1094 
   1095 // Explicitly instantiate all DoUnBoxLambda functions.
   1096 #define EXPLICIT_DO_UNBOX_LAMBDA_DECL(_do_check)                                                \
   1097 template SHARED_REQUIRES(Locks::mutator_lock_)                                            \
   1098 bool DoUnboxLambda<_do_check>(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst, \
   1099                               uint16_t inst_data);
   1100 
   1101 EXPLICIT_DO_UNBOX_LAMBDA_DECL(false);  // unbox-lambda
   1102 EXPLICIT_DO_UNBOX_LAMBDA_DECL(true);   // unbox-lambda
   1103 #undef EXPLICIT_DO_BOX_LAMBDA_DECL
   1104 
   1105 // Explicitly instantiate all DoCaptureVariable functions.
   1106 #define EXPLICIT_DO_CAPTURE_VARIABLE_DECL(_do_check)                                    \
   1107 template SHARED_REQUIRES(Locks::mutator_lock_)                                          \
   1108 bool DoCaptureVariable<_do_check>(Thread* self,                                         \
   1109                                   const Instruction* inst,                              \
   1110                                   ShadowFrame& shadow_frame,                            \
   1111                                   lambda::ClosureBuilder* closure_builder);
   1112 
   1113 EXPLICIT_DO_CAPTURE_VARIABLE_DECL(false);  // capture-variable
   1114 EXPLICIT_DO_CAPTURE_VARIABLE_DECL(true);   // capture-variable
   1115 #undef EXPLICIT_DO_CREATE_LAMBDA_DECL
   1116 
   1117 // Explicitly instantiate all DoLiberateVariable functions.
   1118 #define EXPLICIT_DO_LIBERATE_VARIABLE_DECL(_do_check)                                   \
   1119 template SHARED_REQUIRES(Locks::mutator_lock_)                                          \
   1120 bool DoLiberateVariable<_do_check>(Thread* self,                                        \
   1121                                    const Instruction* inst,                             \
   1122                                    size_t captured_variable_index,                      \
   1123                                    ShadowFrame& shadow_frame);                          \
   1124 
   1125 EXPLICIT_DO_LIBERATE_VARIABLE_DECL(false);  // liberate-variable
   1126 EXPLICIT_DO_LIBERATE_VARIABLE_DECL(true);   // liberate-variable
   1127 #undef EXPLICIT_DO_LIBERATE_LAMBDA_DECL
   1128 }  // namespace interpreter
   1129 }  // namespace art
   1130 
   1131 #endif  // ART_RUNTIME_INTERPRETER_INTERPRETER_COMMON_H_
   1132