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 "base/stl_util.h"  // MakeUnique
18 #include "experimental_flags.h"
19 #include "interpreter_common.h"
20 #include "jit/jit.h"
21 #include "safe_math.h"
22 
23 #include <memory>  // std::unique_ptr
24 
25 namespace art {
26 namespace interpreter {
27 
28 #define HANDLE_PENDING_EXCEPTION()                                                              \
29   do {                                                                                          \
30     DCHECK(self->IsExceptionPending());                                                         \
31     self->AllowThreadSuspension();                                                              \
32     uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame,           \
33                                                                   inst->GetDexPc(insns),        \
34                                                                   instrumentation);             \
35     if (found_dex_pc == DexFile::kDexNoIndex) {                                                 \
36       /* Structured locking is to be enforced for abnormal termination, too. */                 \
37       DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame);                        \
38       if (interpret_one_instruction) {                                                          \
39         /* Signal mterp to return to caller */                                                  \
40         shadow_frame.SetDexPC(DexFile::kDexNoIndex);                                            \
41       }                                                                                         \
42       return JValue(); /* Handled in caller. */                                                 \
43     } else {                                                                                    \
44       int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc); \
45       inst = inst->RelativeAt(displacement);                                                    \
46     }                                                                                           \
47   } while (false)
48 
49 #define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function)  \
50   do {                                                                            \
51     if (UNLIKELY(_is_exception_pending)) {                                        \
52       HANDLE_PENDING_EXCEPTION();                                                 \
53     } else {                                                                      \
54       inst = inst->_next_function();                                              \
55     }                                                                             \
56   } while (false)
57 
58 #define HANDLE_MONITOR_CHECKS()                                                                   \
59   if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) {                       \
60     HANDLE_PENDING_EXCEPTION();                                                                   \
61   }
62 
63 // Code to run before each dex instruction.
64 #define PREAMBLE()                                                                              \
65   do {                                                                                          \
66     if (UNLIKELY(instrumentation->HasDexPcListeners())) {                                       \
67       instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),  \
68                                        shadow_frame.GetMethod(), dex_pc);                       \
69     }                                                                                           \
70   } while (false)
71 
72 #define BRANCH_INSTRUMENTATION(offset)                                                         \
73   do {                                                                                         \
74     if (UNLIKELY(instrumentation->HasBranchListeners())) {                                     \
75       instrumentation->Branch(self, method, dex_pc, offset);                                   \
76     }                                                                                          \
77     JValue result;                                                                             \
78     if (jit::Jit::MaybeDoOnStackReplacement(self, method, dex_pc, offset, &result)) {          \
79       if (interpret_one_instruction) {                                                         \
80         /* OSR has completed execution of the method.  Signal mterp to return to caller */     \
81         shadow_frame.SetDexPC(DexFile::kDexNoIndex);                                           \
82       }                                                                                        \
83       return result;                                                                           \
84     }                                                                                          \
85   } while (false)
86 
87 #define HOTNESS_UPDATE()                                                                       \
88   do {                                                                                         \
89     if (jit != nullptr) {                                                                      \
90       jit->AddSamples(self, method, 1, /*with_backedges*/ true);                               \
91     }                                                                                          \
92   } while (false)
93 
IsExperimentalInstructionEnabled(const Instruction * inst)94 static bool IsExperimentalInstructionEnabled(const Instruction *inst) {
95   DCHECK(inst->IsExperimental());
96   return Runtime::Current()->AreExperimentalFlagsEnabled(ExperimentalFlags::kLambdas);
97 }
98 
99 template<bool do_access_check, bool transaction_active>
ExecuteSwitchImpl(Thread * self,const DexFile::CodeItem * code_item,ShadowFrame & shadow_frame,JValue result_register,bool interpret_one_instruction)100 JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item,
101                          ShadowFrame& shadow_frame, JValue result_register,
102                          bool interpret_one_instruction) {
103   constexpr bool do_assignability_check = do_access_check;
104   if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
105     LOG(FATAL) << "Invalid shadow frame for interpreter use";
106     return JValue();
107   }
108   self->VerifyStack();
109 
110   uint32_t dex_pc = shadow_frame.GetDexPC();
111   const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
112   const uint16_t* const insns = code_item->insns_;
113   const Instruction* inst = Instruction::At(insns + dex_pc);
114   uint16_t inst_data;
115   ArtMethod* method = shadow_frame.GetMethod();
116   jit::Jit* jit = Runtime::Current()->GetJit();
117 
118   // TODO: collapse capture-variable+create-lambda into one opcode, then we won't need
119   // to keep this live for the scope of the entire function call.
120   std::unique_ptr<lambda::ClosureBuilder> lambda_closure_builder;
121   size_t lambda_captured_variable_index = 0;
122   do {
123     dex_pc = inst->GetDexPc(insns);
124     shadow_frame.SetDexPC(dex_pc);
125     TraceExecution(shadow_frame, inst, dex_pc);
126     inst_data = inst->Fetch16(0);
127     switch (inst->Opcode(inst_data)) {
128       case Instruction::NOP:
129         PREAMBLE();
130         inst = inst->Next_1xx();
131         break;
132       case Instruction::MOVE:
133         PREAMBLE();
134         shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
135                              shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
136         inst = inst->Next_1xx();
137         break;
138       case Instruction::MOVE_FROM16:
139         PREAMBLE();
140         shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
141                              shadow_frame.GetVReg(inst->VRegB_22x()));
142         inst = inst->Next_2xx();
143         break;
144       case Instruction::MOVE_16:
145         PREAMBLE();
146         shadow_frame.SetVReg(inst->VRegA_32x(),
147                              shadow_frame.GetVReg(inst->VRegB_32x()));
148         inst = inst->Next_3xx();
149         break;
150       case Instruction::MOVE_WIDE:
151         PREAMBLE();
152         shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
153                                  shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
154         inst = inst->Next_1xx();
155         break;
156       case Instruction::MOVE_WIDE_FROM16:
157         PREAMBLE();
158         shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
159                                  shadow_frame.GetVRegLong(inst->VRegB_22x()));
160         inst = inst->Next_2xx();
161         break;
162       case Instruction::MOVE_WIDE_16:
163         PREAMBLE();
164         shadow_frame.SetVRegLong(inst->VRegA_32x(),
165                                  shadow_frame.GetVRegLong(inst->VRegB_32x()));
166         inst = inst->Next_3xx();
167         break;
168       case Instruction::MOVE_OBJECT:
169         PREAMBLE();
170         shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
171                                       shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
172         inst = inst->Next_1xx();
173         break;
174       case Instruction::MOVE_OBJECT_FROM16:
175         PREAMBLE();
176         shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
177                                       shadow_frame.GetVRegReference(inst->VRegB_22x()));
178         inst = inst->Next_2xx();
179         break;
180       case Instruction::MOVE_OBJECT_16:
181         PREAMBLE();
182         shadow_frame.SetVRegReference(inst->VRegA_32x(),
183                                       shadow_frame.GetVRegReference(inst->VRegB_32x()));
184         inst = inst->Next_3xx();
185         break;
186       case Instruction::MOVE_RESULT:
187         PREAMBLE();
188         shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
189         inst = inst->Next_1xx();
190         break;
191       case Instruction::MOVE_RESULT_WIDE:
192         PREAMBLE();
193         shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
194         inst = inst->Next_1xx();
195         break;
196       case Instruction::MOVE_RESULT_OBJECT:
197         PREAMBLE();
198         shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
199         inst = inst->Next_1xx();
200         break;
201       case Instruction::MOVE_EXCEPTION: {
202         PREAMBLE();
203         Throwable* exception = self->GetException();
204         DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
205         shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
206         self->ClearException();
207         inst = inst->Next_1xx();
208         break;
209       }
210       case Instruction::RETURN_VOID_NO_BARRIER: {
211         PREAMBLE();
212         JValue result;
213         self->AllowThreadSuspension();
214         HANDLE_MONITOR_CHECKS();
215         if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
216           instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
217                                            shadow_frame.GetMethod(), inst->GetDexPc(insns),
218                                            result);
219         }
220         if (interpret_one_instruction) {
221           /* Signal mterp to return to caller */
222           shadow_frame.SetDexPC(DexFile::kDexNoIndex);
223         }
224         return result;
225       }
226       case Instruction::RETURN_VOID: {
227         PREAMBLE();
228         QuasiAtomic::ThreadFenceForConstructor();
229         JValue result;
230         self->AllowThreadSuspension();
231         HANDLE_MONITOR_CHECKS();
232         if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
233           instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
234                                            shadow_frame.GetMethod(), inst->GetDexPc(insns),
235                                            result);
236         }
237         if (interpret_one_instruction) {
238           /* Signal mterp to return to caller */
239           shadow_frame.SetDexPC(DexFile::kDexNoIndex);
240         }
241         return result;
242       }
243       case Instruction::RETURN: {
244         PREAMBLE();
245         JValue result;
246         result.SetJ(0);
247         result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
248         self->AllowThreadSuspension();
249         HANDLE_MONITOR_CHECKS();
250         if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
251           instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
252                                            shadow_frame.GetMethod(), inst->GetDexPc(insns),
253                                            result);
254         }
255         if (interpret_one_instruction) {
256           /* Signal mterp to return to caller */
257           shadow_frame.SetDexPC(DexFile::kDexNoIndex);
258         }
259         return result;
260       }
261       case Instruction::RETURN_WIDE: {
262         PREAMBLE();
263         JValue result;
264         result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
265         self->AllowThreadSuspension();
266         HANDLE_MONITOR_CHECKS();
267         if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
268           instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
269                                            shadow_frame.GetMethod(), inst->GetDexPc(insns),
270                                            result);
271         }
272         if (interpret_one_instruction) {
273           /* Signal mterp to return to caller */
274           shadow_frame.SetDexPC(DexFile::kDexNoIndex);
275         }
276         return result;
277       }
278       case Instruction::RETURN_OBJECT: {
279         PREAMBLE();
280         JValue result;
281         self->AllowThreadSuspension();
282         HANDLE_MONITOR_CHECKS();
283         const size_t ref_idx = inst->VRegA_11x(inst_data);
284         Object* obj_result = shadow_frame.GetVRegReference(ref_idx);
285         if (do_assignability_check && obj_result != nullptr) {
286           size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
287           Class* return_type = shadow_frame.GetMethod()->GetReturnType(true /* resolve */,
288                                                                        pointer_size);
289           // Re-load since it might have moved.
290           obj_result = shadow_frame.GetVRegReference(ref_idx);
291           if (return_type == nullptr) {
292             // Return the pending exception.
293             HANDLE_PENDING_EXCEPTION();
294           }
295           if (!obj_result->VerifierInstanceOf(return_type)) {
296             // This should never happen.
297             std::string temp1, temp2;
298             self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
299                                      "Returning '%s' that is not instance of return type '%s'",
300                                      obj_result->GetClass()->GetDescriptor(&temp1),
301                                      return_type->GetDescriptor(&temp2));
302             HANDLE_PENDING_EXCEPTION();
303           }
304         }
305         result.SetL(obj_result);
306         if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
307           instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
308                                            shadow_frame.GetMethod(), inst->GetDexPc(insns),
309                                            result);
310         }
311         if (interpret_one_instruction) {
312           /* Signal mterp to return to caller */
313           shadow_frame.SetDexPC(DexFile::kDexNoIndex);
314         }
315         return result;
316       }
317       case Instruction::CONST_4: {
318         PREAMBLE();
319         uint4_t dst = inst->VRegA_11n(inst_data);
320         int4_t val = inst->VRegB_11n(inst_data);
321         shadow_frame.SetVReg(dst, val);
322         if (val == 0) {
323           shadow_frame.SetVRegReference(dst, nullptr);
324         }
325         inst = inst->Next_1xx();
326         break;
327       }
328       case Instruction::CONST_16: {
329         PREAMBLE();
330         uint8_t dst = inst->VRegA_21s(inst_data);
331         int16_t val = inst->VRegB_21s();
332         shadow_frame.SetVReg(dst, val);
333         if (val == 0) {
334           shadow_frame.SetVRegReference(dst, nullptr);
335         }
336         inst = inst->Next_2xx();
337         break;
338       }
339       case Instruction::CONST: {
340         PREAMBLE();
341         uint8_t dst = inst->VRegA_31i(inst_data);
342         int32_t val = inst->VRegB_31i();
343         shadow_frame.SetVReg(dst, val);
344         if (val == 0) {
345           shadow_frame.SetVRegReference(dst, nullptr);
346         }
347         inst = inst->Next_3xx();
348         break;
349       }
350       case Instruction::CONST_HIGH16: {
351         PREAMBLE();
352         uint8_t dst = inst->VRegA_21h(inst_data);
353         int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
354         shadow_frame.SetVReg(dst, val);
355         if (val == 0) {
356           shadow_frame.SetVRegReference(dst, nullptr);
357         }
358         inst = inst->Next_2xx();
359         break;
360       }
361       case Instruction::CONST_WIDE_16:
362         PREAMBLE();
363         shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
364         inst = inst->Next_2xx();
365         break;
366       case Instruction::CONST_WIDE_32:
367         PREAMBLE();
368         shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
369         inst = inst->Next_3xx();
370         break;
371       case Instruction::CONST_WIDE:
372         PREAMBLE();
373         shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
374         inst = inst->Next_51l();
375         break;
376       case Instruction::CONST_WIDE_HIGH16:
377         PREAMBLE();
378         shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
379                                  static_cast<uint64_t>(inst->VRegB_21h()) << 48);
380         inst = inst->Next_2xx();
381         break;
382       case Instruction::CONST_STRING: {
383         PREAMBLE();
384         String* s = ResolveString(self, shadow_frame,  inst->VRegB_21c());
385         if (UNLIKELY(s == nullptr)) {
386           HANDLE_PENDING_EXCEPTION();
387         } else {
388           shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
389           inst = inst->Next_2xx();
390         }
391         break;
392       }
393       case Instruction::CONST_STRING_JUMBO: {
394         PREAMBLE();
395         String* s = ResolveString(self, shadow_frame,  inst->VRegB_31c());
396         if (UNLIKELY(s == nullptr)) {
397           HANDLE_PENDING_EXCEPTION();
398         } else {
399           shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
400           inst = inst->Next_3xx();
401         }
402         break;
403       }
404       case Instruction::CONST_CLASS: {
405         PREAMBLE();
406         Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
407                                           self, false, do_access_check);
408         if (UNLIKELY(c == nullptr)) {
409           HANDLE_PENDING_EXCEPTION();
410         } else {
411           shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
412           inst = inst->Next_2xx();
413         }
414         break;
415       }
416       case Instruction::MONITOR_ENTER: {
417         PREAMBLE();
418         Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
419         if (UNLIKELY(obj == nullptr)) {
420           ThrowNullPointerExceptionFromInterpreter();
421           HANDLE_PENDING_EXCEPTION();
422         } else {
423           DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
424           POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
425         }
426         break;
427       }
428       case Instruction::MONITOR_EXIT: {
429         PREAMBLE();
430         Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
431         if (UNLIKELY(obj == nullptr)) {
432           ThrowNullPointerExceptionFromInterpreter();
433           HANDLE_PENDING_EXCEPTION();
434         } else {
435           DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
436           POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
437         }
438         break;
439       }
440       case Instruction::CHECK_CAST: {
441         PREAMBLE();
442         Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
443                                           self, false, do_access_check);
444         if (UNLIKELY(c == nullptr)) {
445           HANDLE_PENDING_EXCEPTION();
446         } else {
447           Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
448           if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
449             ThrowClassCastException(c, obj->GetClass());
450             HANDLE_PENDING_EXCEPTION();
451           } else {
452             inst = inst->Next_2xx();
453           }
454         }
455         break;
456       }
457       case Instruction::INSTANCE_OF: {
458         PREAMBLE();
459         Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
460                                           self, false, do_access_check);
461         if (UNLIKELY(c == nullptr)) {
462           HANDLE_PENDING_EXCEPTION();
463         } else {
464           Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
465           shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
466                                (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
467           inst = inst->Next_2xx();
468         }
469         break;
470       }
471       case Instruction::ARRAY_LENGTH:  {
472         PREAMBLE();
473         Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
474         if (UNLIKELY(array == nullptr)) {
475           ThrowNullPointerExceptionFromInterpreter();
476           HANDLE_PENDING_EXCEPTION();
477         } else {
478           shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
479           inst = inst->Next_1xx();
480         }
481         break;
482       }
483       case Instruction::NEW_INSTANCE: {
484         PREAMBLE();
485         Object* obj = nullptr;
486         Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
487                                           self, false, do_access_check);
488         if (LIKELY(c != nullptr)) {
489           if (UNLIKELY(c->IsStringClass())) {
490             gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
491             mirror::SetStringCountVisitor visitor(0);
492             obj = String::Alloc<true>(self, 0, allocator_type, visitor);
493           } else {
494             obj = AllocObjectFromCode<do_access_check, true>(
495               inst->VRegB_21c(), shadow_frame.GetMethod(), self,
496               Runtime::Current()->GetHeap()->GetCurrentAllocator());
497           }
498         }
499         if (UNLIKELY(obj == nullptr)) {
500           HANDLE_PENDING_EXCEPTION();
501         } else {
502           obj->GetClass()->AssertInitializedOrInitializingInThread(self);
503           // Don't allow finalizable objects to be allocated during a transaction since these can't
504           // be finalized without a started runtime.
505           if (transaction_active && obj->GetClass()->IsFinalizable()) {
506             AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
507                               PrettyTypeOf(obj).c_str());
508             HANDLE_PENDING_EXCEPTION();
509             break;
510           }
511           shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
512           inst = inst->Next_2xx();
513         }
514         break;
515       }
516       case Instruction::NEW_ARRAY: {
517         PREAMBLE();
518         int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
519         Object* obj = AllocArrayFromCode<do_access_check, true>(
520             inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
521             Runtime::Current()->GetHeap()->GetCurrentAllocator());
522         if (UNLIKELY(obj == nullptr)) {
523           HANDLE_PENDING_EXCEPTION();
524         } else {
525           shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
526           inst = inst->Next_2xx();
527         }
528         break;
529       }
530       case Instruction::FILLED_NEW_ARRAY: {
531         PREAMBLE();
532         bool success =
533             DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
534                                                                          &result_register);
535         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
536         break;
537       }
538       case Instruction::FILLED_NEW_ARRAY_RANGE: {
539         PREAMBLE();
540         bool success =
541             DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
542                                                                         self, &result_register);
543         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
544         break;
545       }
546       case Instruction::FILL_ARRAY_DATA: {
547         PREAMBLE();
548         const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
549         const Instruction::ArrayDataPayload* payload =
550             reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
551         Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
552         bool success = FillArrayData(obj, payload);
553         if (!success) {
554           HANDLE_PENDING_EXCEPTION();
555           break;
556         }
557         if (transaction_active) {
558           RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
559         }
560         inst = inst->Next_3xx();
561         break;
562       }
563       case Instruction::THROW: {
564         PREAMBLE();
565         Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
566         if (UNLIKELY(exception == nullptr)) {
567           ThrowNullPointerException("throw with null exception");
568         } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
569           // This should never happen.
570           std::string temp;
571           self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
572                                    "Throwing '%s' that is not instance of Throwable",
573                                    exception->GetClass()->GetDescriptor(&temp));
574         } else {
575           self->SetException(exception->AsThrowable());
576         }
577         HANDLE_PENDING_EXCEPTION();
578         break;
579       }
580       case Instruction::GOTO: {
581         PREAMBLE();
582         int8_t offset = inst->VRegA_10t(inst_data);
583         BRANCH_INSTRUMENTATION(offset);
584         if (IsBackwardBranch(offset)) {
585           HOTNESS_UPDATE();
586           self->AllowThreadSuspension();
587         }
588         inst = inst->RelativeAt(offset);
589         break;
590       }
591       case Instruction::GOTO_16: {
592         PREAMBLE();
593         int16_t offset = inst->VRegA_20t();
594         BRANCH_INSTRUMENTATION(offset);
595         if (IsBackwardBranch(offset)) {
596           HOTNESS_UPDATE();
597           self->AllowThreadSuspension();
598         }
599         inst = inst->RelativeAt(offset);
600         break;
601       }
602       case Instruction::GOTO_32: {
603         PREAMBLE();
604         int32_t offset = inst->VRegA_30t();
605         BRANCH_INSTRUMENTATION(offset);
606         if (IsBackwardBranch(offset)) {
607           HOTNESS_UPDATE();
608           self->AllowThreadSuspension();
609         }
610         inst = inst->RelativeAt(offset);
611         break;
612       }
613       case Instruction::PACKED_SWITCH: {
614         PREAMBLE();
615         int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
616         BRANCH_INSTRUMENTATION(offset);
617         if (IsBackwardBranch(offset)) {
618           HOTNESS_UPDATE();
619           self->AllowThreadSuspension();
620         }
621         inst = inst->RelativeAt(offset);
622         break;
623       }
624       case Instruction::SPARSE_SWITCH: {
625         PREAMBLE();
626         int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
627         BRANCH_INSTRUMENTATION(offset);
628         if (IsBackwardBranch(offset)) {
629           HOTNESS_UPDATE();
630           self->AllowThreadSuspension();
631         }
632         inst = inst->RelativeAt(offset);
633         break;
634       }
635 
636 #if defined(__clang__)
637 #pragma clang diagnostic push
638 #pragma clang diagnostic ignored "-Wfloat-equal"
639 #endif
640 
641       case Instruction::CMPL_FLOAT: {
642         PREAMBLE();
643         float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
644         float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
645         int32_t result;
646         if (val1 > val2) {
647           result = 1;
648         } else if (val1 == val2) {
649           result = 0;
650         } else {
651           result = -1;
652         }
653         shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
654         inst = inst->Next_2xx();
655         break;
656       }
657       case Instruction::CMPG_FLOAT: {
658         PREAMBLE();
659         float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
660         float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
661         int32_t result;
662         if (val1 < val2) {
663           result = -1;
664         } else if (val1 == val2) {
665           result = 0;
666         } else {
667           result = 1;
668         }
669         shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
670         inst = inst->Next_2xx();
671         break;
672       }
673       case Instruction::CMPL_DOUBLE: {
674         PREAMBLE();
675         double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
676         double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
677         int32_t result;
678         if (val1 > val2) {
679           result = 1;
680         } else if (val1 == val2) {
681           result = 0;
682         } else {
683           result = -1;
684         }
685         shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
686         inst = inst->Next_2xx();
687         break;
688       }
689 
690       case Instruction::CMPG_DOUBLE: {
691         PREAMBLE();
692         double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
693         double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
694         int32_t result;
695         if (val1 < val2) {
696           result = -1;
697         } else if (val1 == val2) {
698           result = 0;
699         } else {
700           result = 1;
701         }
702         shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
703         inst = inst->Next_2xx();
704         break;
705       }
706 
707 #if defined(__clang__)
708 #pragma clang diagnostic pop
709 #endif
710 
711       case Instruction::CMP_LONG: {
712         PREAMBLE();
713         int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
714         int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
715         int32_t result;
716         if (val1 > val2) {
717           result = 1;
718         } else if (val1 == val2) {
719           result = 0;
720         } else {
721           result = -1;
722         }
723         shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
724         inst = inst->Next_2xx();
725         break;
726       }
727       case Instruction::IF_EQ: {
728         PREAMBLE();
729         if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) ==
730             shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
731           int16_t offset = inst->VRegC_22t();
732           BRANCH_INSTRUMENTATION(offset);
733           if (IsBackwardBranch(offset)) {
734             HOTNESS_UPDATE();
735             self->AllowThreadSuspension();
736           }
737           inst = inst->RelativeAt(offset);
738         } else {
739           BRANCH_INSTRUMENTATION(2);
740           inst = inst->Next_2xx();
741         }
742         break;
743       }
744       case Instruction::IF_NE: {
745         PREAMBLE();
746         if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
747             shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
748           int16_t offset = inst->VRegC_22t();
749           BRANCH_INSTRUMENTATION(offset);
750           if (IsBackwardBranch(offset)) {
751             HOTNESS_UPDATE();
752             self->AllowThreadSuspension();
753           }
754           inst = inst->RelativeAt(offset);
755         } else {
756           BRANCH_INSTRUMENTATION(2);
757           inst = inst->Next_2xx();
758         }
759         break;
760       }
761       case Instruction::IF_LT: {
762         PREAMBLE();
763         if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
764             shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
765           int16_t offset = inst->VRegC_22t();
766           BRANCH_INSTRUMENTATION(offset);
767           if (IsBackwardBranch(offset)) {
768             HOTNESS_UPDATE();
769             self->AllowThreadSuspension();
770           }
771           inst = inst->RelativeAt(offset);
772         } else {
773           BRANCH_INSTRUMENTATION(2);
774           inst = inst->Next_2xx();
775         }
776         break;
777       }
778       case Instruction::IF_GE: {
779         PREAMBLE();
780         if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
781             shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
782           int16_t offset = inst->VRegC_22t();
783           BRANCH_INSTRUMENTATION(offset);
784           if (IsBackwardBranch(offset)) {
785             HOTNESS_UPDATE();
786             self->AllowThreadSuspension();
787           }
788           inst = inst->RelativeAt(offset);
789         } else {
790           BRANCH_INSTRUMENTATION(2);
791           inst = inst->Next_2xx();
792         }
793         break;
794       }
795       case Instruction::IF_GT: {
796         PREAMBLE();
797         if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
798         shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
799           int16_t offset = inst->VRegC_22t();
800           BRANCH_INSTRUMENTATION(offset);
801           if (IsBackwardBranch(offset)) {
802             HOTNESS_UPDATE();
803             self->AllowThreadSuspension();
804           }
805           inst = inst->RelativeAt(offset);
806         } else {
807           BRANCH_INSTRUMENTATION(2);
808           inst = inst->Next_2xx();
809         }
810         break;
811       }
812       case Instruction::IF_LE: {
813         PREAMBLE();
814         if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
815             shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
816           int16_t offset = inst->VRegC_22t();
817           BRANCH_INSTRUMENTATION(offset);
818           if (IsBackwardBranch(offset)) {
819             HOTNESS_UPDATE();
820             self->AllowThreadSuspension();
821           }
822           inst = inst->RelativeAt(offset);
823         } else {
824           BRANCH_INSTRUMENTATION(2);
825           inst = inst->Next_2xx();
826         }
827         break;
828       }
829       case Instruction::IF_EQZ: {
830         PREAMBLE();
831         if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
832           int16_t offset = inst->VRegB_21t();
833           BRANCH_INSTRUMENTATION(offset);
834           if (IsBackwardBranch(offset)) {
835             HOTNESS_UPDATE();
836             self->AllowThreadSuspension();
837           }
838           inst = inst->RelativeAt(offset);
839         } else {
840           BRANCH_INSTRUMENTATION(2);
841           inst = inst->Next_2xx();
842         }
843         break;
844       }
845       case Instruction::IF_NEZ: {
846         PREAMBLE();
847         if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
848           int16_t offset = inst->VRegB_21t();
849           BRANCH_INSTRUMENTATION(offset);
850           if (IsBackwardBranch(offset)) {
851             HOTNESS_UPDATE();
852             self->AllowThreadSuspension();
853           }
854           inst = inst->RelativeAt(offset);
855         } else {
856           BRANCH_INSTRUMENTATION(2);
857           inst = inst->Next_2xx();
858         }
859         break;
860       }
861       case Instruction::IF_LTZ: {
862         PREAMBLE();
863         if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
864           int16_t offset = inst->VRegB_21t();
865           BRANCH_INSTRUMENTATION(offset);
866           if (IsBackwardBranch(offset)) {
867             HOTNESS_UPDATE();
868             self->AllowThreadSuspension();
869           }
870           inst = inst->RelativeAt(offset);
871         } else {
872           BRANCH_INSTRUMENTATION(2);
873           inst = inst->Next_2xx();
874         }
875         break;
876       }
877       case Instruction::IF_GEZ: {
878         PREAMBLE();
879         if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
880           int16_t offset = inst->VRegB_21t();
881           BRANCH_INSTRUMENTATION(offset);
882           if (IsBackwardBranch(offset)) {
883             HOTNESS_UPDATE();
884             self->AllowThreadSuspension();
885           }
886           inst = inst->RelativeAt(offset);
887         } else {
888           BRANCH_INSTRUMENTATION(2);
889           inst = inst->Next_2xx();
890         }
891         break;
892       }
893       case Instruction::IF_GTZ: {
894         PREAMBLE();
895         if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
896           int16_t offset = inst->VRegB_21t();
897           BRANCH_INSTRUMENTATION(offset);
898           if (IsBackwardBranch(offset)) {
899             HOTNESS_UPDATE();
900             self->AllowThreadSuspension();
901           }
902           inst = inst->RelativeAt(offset);
903         } else {
904           BRANCH_INSTRUMENTATION(2);
905           inst = inst->Next_2xx();
906         }
907         break;
908       }
909       case Instruction::IF_LEZ:  {
910         PREAMBLE();
911         if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
912           int16_t offset = inst->VRegB_21t();
913           BRANCH_INSTRUMENTATION(offset);
914           if (IsBackwardBranch(offset)) {
915             HOTNESS_UPDATE();
916             self->AllowThreadSuspension();
917           }
918           inst = inst->RelativeAt(offset);
919         } else {
920           BRANCH_INSTRUMENTATION(2);
921           inst = inst->Next_2xx();
922         }
923         break;
924       }
925       case Instruction::AGET_BOOLEAN: {
926         PREAMBLE();
927         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
928         if (UNLIKELY(a == nullptr)) {
929           ThrowNullPointerExceptionFromInterpreter();
930           HANDLE_PENDING_EXCEPTION();
931           break;
932         }
933         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
934         BooleanArray* array = a->AsBooleanArray();
935         if (array->CheckIsValidIndex(index)) {
936           shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
937           inst = inst->Next_2xx();
938         } else {
939           HANDLE_PENDING_EXCEPTION();
940         }
941         break;
942       }
943       case Instruction::AGET_BYTE: {
944         PREAMBLE();
945         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
946         if (UNLIKELY(a == nullptr)) {
947           ThrowNullPointerExceptionFromInterpreter();
948           HANDLE_PENDING_EXCEPTION();
949           break;
950         }
951         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
952         ByteArray* array = a->AsByteArray();
953         if (array->CheckIsValidIndex(index)) {
954           shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
955           inst = inst->Next_2xx();
956         } else {
957           HANDLE_PENDING_EXCEPTION();
958         }
959         break;
960       }
961       case Instruction::AGET_CHAR: {
962         PREAMBLE();
963         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
964         if (UNLIKELY(a == nullptr)) {
965           ThrowNullPointerExceptionFromInterpreter();
966           HANDLE_PENDING_EXCEPTION();
967           break;
968         }
969         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
970         CharArray* array = a->AsCharArray();
971         if (array->CheckIsValidIndex(index)) {
972           shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
973           inst = inst->Next_2xx();
974         } else {
975           HANDLE_PENDING_EXCEPTION();
976         }
977         break;
978       }
979       case Instruction::AGET_SHORT: {
980         PREAMBLE();
981         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
982         if (UNLIKELY(a == nullptr)) {
983           ThrowNullPointerExceptionFromInterpreter();
984           HANDLE_PENDING_EXCEPTION();
985           break;
986         }
987         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
988         ShortArray* array = a->AsShortArray();
989         if (array->CheckIsValidIndex(index)) {
990           shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
991           inst = inst->Next_2xx();
992         } else {
993           HANDLE_PENDING_EXCEPTION();
994         }
995         break;
996       }
997       case Instruction::AGET: {
998         PREAMBLE();
999         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1000         if (UNLIKELY(a == nullptr)) {
1001           ThrowNullPointerExceptionFromInterpreter();
1002           HANDLE_PENDING_EXCEPTION();
1003           break;
1004         }
1005         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1006         DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1007         auto* array = down_cast<IntArray*>(a);
1008         if (array->CheckIsValidIndex(index)) {
1009           shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
1010           inst = inst->Next_2xx();
1011         } else {
1012           HANDLE_PENDING_EXCEPTION();
1013         }
1014         break;
1015       }
1016       case Instruction::AGET_WIDE:  {
1017         PREAMBLE();
1018         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1019         if (UNLIKELY(a == nullptr)) {
1020           ThrowNullPointerExceptionFromInterpreter();
1021           HANDLE_PENDING_EXCEPTION();
1022           break;
1023         }
1024         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1025         DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1026         auto* array = down_cast<LongArray*>(a);
1027         if (array->CheckIsValidIndex(index)) {
1028           shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
1029           inst = inst->Next_2xx();
1030         } else {
1031           HANDLE_PENDING_EXCEPTION();
1032         }
1033         break;
1034       }
1035       case Instruction::AGET_OBJECT: {
1036         PREAMBLE();
1037         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1038         if (UNLIKELY(a == nullptr)) {
1039           ThrowNullPointerExceptionFromInterpreter();
1040           HANDLE_PENDING_EXCEPTION();
1041           break;
1042         }
1043         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1044         ObjectArray<Object>* array = a->AsObjectArray<Object>();
1045         if (array->CheckIsValidIndex(index)) {
1046           shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
1047           inst = inst->Next_2xx();
1048         } else {
1049           HANDLE_PENDING_EXCEPTION();
1050         }
1051         break;
1052       }
1053       case Instruction::APUT_BOOLEAN: {
1054         PREAMBLE();
1055         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1056         if (UNLIKELY(a == nullptr)) {
1057           ThrowNullPointerExceptionFromInterpreter();
1058           HANDLE_PENDING_EXCEPTION();
1059           break;
1060         }
1061         uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
1062         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1063         BooleanArray* array = a->AsBooleanArray();
1064         if (array->CheckIsValidIndex(index)) {
1065           array->SetWithoutChecks<transaction_active>(index, val);
1066           inst = inst->Next_2xx();
1067         } else {
1068           HANDLE_PENDING_EXCEPTION();
1069         }
1070         break;
1071       }
1072       case Instruction::APUT_BYTE: {
1073         PREAMBLE();
1074         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1075         if (UNLIKELY(a == nullptr)) {
1076           ThrowNullPointerExceptionFromInterpreter();
1077           HANDLE_PENDING_EXCEPTION();
1078           break;
1079         }
1080         int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
1081         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1082         ByteArray* array = a->AsByteArray();
1083         if (array->CheckIsValidIndex(index)) {
1084           array->SetWithoutChecks<transaction_active>(index, val);
1085           inst = inst->Next_2xx();
1086         } else {
1087           HANDLE_PENDING_EXCEPTION();
1088         }
1089         break;
1090       }
1091       case Instruction::APUT_CHAR: {
1092         PREAMBLE();
1093         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1094         if (UNLIKELY(a == nullptr)) {
1095           ThrowNullPointerExceptionFromInterpreter();
1096           HANDLE_PENDING_EXCEPTION();
1097           break;
1098         }
1099         uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
1100         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1101         CharArray* array = a->AsCharArray();
1102         if (array->CheckIsValidIndex(index)) {
1103           array->SetWithoutChecks<transaction_active>(index, val);
1104           inst = inst->Next_2xx();
1105         } else {
1106           HANDLE_PENDING_EXCEPTION();
1107         }
1108         break;
1109       }
1110       case Instruction::APUT_SHORT: {
1111         PREAMBLE();
1112         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1113         if (UNLIKELY(a == nullptr)) {
1114           ThrowNullPointerExceptionFromInterpreter();
1115           HANDLE_PENDING_EXCEPTION();
1116           break;
1117         }
1118         int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
1119         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1120         ShortArray* array = a->AsShortArray();
1121         if (array->CheckIsValidIndex(index)) {
1122           array->SetWithoutChecks<transaction_active>(index, val);
1123           inst = inst->Next_2xx();
1124         } else {
1125           HANDLE_PENDING_EXCEPTION();
1126         }
1127         break;
1128       }
1129       case Instruction::APUT: {
1130         PREAMBLE();
1131         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1132         if (UNLIKELY(a == nullptr)) {
1133           ThrowNullPointerExceptionFromInterpreter();
1134           HANDLE_PENDING_EXCEPTION();
1135           break;
1136         }
1137         int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
1138         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1139         DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1140         auto* array = down_cast<IntArray*>(a);
1141         if (array->CheckIsValidIndex(index)) {
1142           array->SetWithoutChecks<transaction_active>(index, val);
1143           inst = inst->Next_2xx();
1144         } else {
1145           HANDLE_PENDING_EXCEPTION();
1146         }
1147         break;
1148       }
1149       case Instruction::APUT_WIDE: {
1150         PREAMBLE();
1151         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1152         if (UNLIKELY(a == nullptr)) {
1153           ThrowNullPointerExceptionFromInterpreter();
1154           HANDLE_PENDING_EXCEPTION();
1155           break;
1156         }
1157         int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
1158         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1159         DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1160         LongArray* array = down_cast<LongArray*>(a);
1161         if (array->CheckIsValidIndex(index)) {
1162           array->SetWithoutChecks<transaction_active>(index, val);
1163           inst = inst->Next_2xx();
1164         } else {
1165           HANDLE_PENDING_EXCEPTION();
1166         }
1167         break;
1168       }
1169       case Instruction::APUT_OBJECT: {
1170         PREAMBLE();
1171         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1172         if (UNLIKELY(a == nullptr)) {
1173           ThrowNullPointerExceptionFromInterpreter();
1174           HANDLE_PENDING_EXCEPTION();
1175           break;
1176         }
1177         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1178         Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
1179         ObjectArray<Object>* array = a->AsObjectArray<Object>();
1180         if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
1181           array->SetWithoutChecks<transaction_active>(index, val);
1182           inst = inst->Next_2xx();
1183         } else {
1184           HANDLE_PENDING_EXCEPTION();
1185         }
1186         break;
1187       }
1188       case Instruction::IGET_BOOLEAN: {
1189         PREAMBLE();
1190         bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1191             self, shadow_frame, inst, inst_data);
1192         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1193         break;
1194       }
1195       case Instruction::IGET_BYTE: {
1196         PREAMBLE();
1197         bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1198             self, shadow_frame, inst, inst_data);
1199         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1200         break;
1201       }
1202       case Instruction::IGET_CHAR: {
1203         PREAMBLE();
1204         bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1205             self, shadow_frame, inst, inst_data);
1206         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1207         break;
1208       }
1209       case Instruction::IGET_SHORT: {
1210         PREAMBLE();
1211         bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1212             self, shadow_frame, inst, inst_data);
1213         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1214         break;
1215       }
1216       case Instruction::IGET: {
1217         PREAMBLE();
1218         bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1219             self, shadow_frame, inst, inst_data);
1220         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1221         break;
1222       }
1223       case Instruction::IGET_WIDE: {
1224         PREAMBLE();
1225         bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1226             self, shadow_frame, inst, inst_data);
1227         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1228         break;
1229       }
1230       case Instruction::IGET_OBJECT: {
1231         PREAMBLE();
1232         bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1233             self, shadow_frame, inst, inst_data);
1234         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1235         break;
1236       }
1237       case Instruction::IGET_QUICK: {
1238         PREAMBLE();
1239         bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
1240         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1241         break;
1242       }
1243       case Instruction::IGET_WIDE_QUICK: {
1244         PREAMBLE();
1245         bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
1246         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1247         break;
1248       }
1249       case Instruction::IGET_OBJECT_QUICK: {
1250         PREAMBLE();
1251         bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
1252         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1253         break;
1254       }
1255       case Instruction::IGET_BOOLEAN_QUICK: {
1256         PREAMBLE();
1257         bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1258         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1259         break;
1260       }
1261       case Instruction::IGET_BYTE_QUICK: {
1262         PREAMBLE();
1263         bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1264         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1265         break;
1266       }
1267       case Instruction::IGET_CHAR_QUICK: {
1268         PREAMBLE();
1269         bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1270         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1271         break;
1272       }
1273       case Instruction::IGET_SHORT_QUICK: {
1274         PREAMBLE();
1275         bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1276         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1277         break;
1278       }
1279       case Instruction::SGET_BOOLEAN: {
1280         PREAMBLE();
1281         bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1282             self, shadow_frame, inst, inst_data);
1283         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1284         break;
1285       }
1286       case Instruction::SGET_BYTE: {
1287         PREAMBLE();
1288         bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1289             self, shadow_frame, inst, inst_data);
1290         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1291         break;
1292       }
1293       case Instruction::SGET_CHAR: {
1294         PREAMBLE();
1295         bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1296             self, shadow_frame, inst, inst_data);
1297         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1298         break;
1299       }
1300       case Instruction::SGET_SHORT: {
1301         PREAMBLE();
1302         bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1303             self, shadow_frame, inst, inst_data);
1304         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1305         break;
1306       }
1307       case Instruction::SGET: {
1308         PREAMBLE();
1309         bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1310             self, shadow_frame, inst, inst_data);
1311         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1312         break;
1313       }
1314       case Instruction::SGET_WIDE: {
1315         PREAMBLE();
1316         bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1317             self, shadow_frame, inst, inst_data);
1318         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1319         break;
1320       }
1321       case Instruction::SGET_OBJECT: {
1322         PREAMBLE();
1323         bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1324             self, shadow_frame, inst, inst_data);
1325         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1326         break;
1327       }
1328       case Instruction::IPUT_BOOLEAN: {
1329         PREAMBLE();
1330         bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1331             transaction_active>(self, shadow_frame, inst, inst_data);
1332         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1333         break;
1334       }
1335       case Instruction::IPUT_BYTE: {
1336         PREAMBLE();
1337         bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1338             transaction_active>(self, shadow_frame, inst, inst_data);
1339         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1340         break;
1341       }
1342       case Instruction::IPUT_CHAR: {
1343         PREAMBLE();
1344         bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1345             transaction_active>(self, shadow_frame, inst, inst_data);
1346         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1347         break;
1348       }
1349       case Instruction::IPUT_SHORT: {
1350         PREAMBLE();
1351         bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1352             transaction_active>(self, shadow_frame, inst, inst_data);
1353         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1354         break;
1355       }
1356       case Instruction::IPUT: {
1357         PREAMBLE();
1358         bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1359             transaction_active>(self, shadow_frame, inst, inst_data);
1360         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1361         break;
1362       }
1363       case Instruction::IPUT_WIDE: {
1364         PREAMBLE();
1365         bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1366             transaction_active>(self, shadow_frame, inst, inst_data);
1367         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1368         break;
1369       }
1370       case Instruction::IPUT_OBJECT: {
1371         PREAMBLE();
1372         bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1373             transaction_active>(self, shadow_frame, inst, inst_data);
1374         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1375         break;
1376       }
1377       case Instruction::IPUT_QUICK: {
1378         PREAMBLE();
1379         bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1380             shadow_frame, inst, inst_data);
1381         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1382         break;
1383       }
1384       case Instruction::IPUT_BOOLEAN_QUICK: {
1385         PREAMBLE();
1386         bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1387             shadow_frame, inst, inst_data);
1388         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1389         break;
1390       }
1391       case Instruction::IPUT_BYTE_QUICK: {
1392         PREAMBLE();
1393         bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1394             shadow_frame, inst, inst_data);
1395         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1396         break;
1397       }
1398       case Instruction::IPUT_CHAR_QUICK: {
1399         PREAMBLE();
1400         bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1401             shadow_frame, inst, inst_data);
1402         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1403         break;
1404       }
1405       case Instruction::IPUT_SHORT_QUICK: {
1406         PREAMBLE();
1407         bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1408             shadow_frame, inst, inst_data);
1409         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1410         break;
1411       }
1412       case Instruction::IPUT_WIDE_QUICK: {
1413         PREAMBLE();
1414         bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1415             shadow_frame, inst, inst_data);
1416         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1417         break;
1418       }
1419       case Instruction::IPUT_OBJECT_QUICK: {
1420         PREAMBLE();
1421         bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1422             shadow_frame, inst, inst_data);
1423         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1424         break;
1425       }
1426       case Instruction::SPUT_BOOLEAN: {
1427         PREAMBLE();
1428         bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1429             transaction_active>(self, shadow_frame, inst, inst_data);
1430         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1431         break;
1432       }
1433       case Instruction::SPUT_BYTE: {
1434         PREAMBLE();
1435         bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1436             transaction_active>(self, shadow_frame, inst, inst_data);
1437         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1438         break;
1439       }
1440       case Instruction::SPUT_CHAR: {
1441         PREAMBLE();
1442         bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1443             transaction_active>(self, shadow_frame, inst, inst_data);
1444         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1445         break;
1446       }
1447       case Instruction::SPUT_SHORT: {
1448         PREAMBLE();
1449         bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1450             transaction_active>(self, shadow_frame, inst, inst_data);
1451         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1452         break;
1453       }
1454       case Instruction::SPUT: {
1455         PREAMBLE();
1456         bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1457             transaction_active>(self, shadow_frame, inst, inst_data);
1458         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1459         break;
1460       }
1461       case Instruction::SPUT_WIDE: {
1462         PREAMBLE();
1463         bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1464             transaction_active>(self, shadow_frame, inst, inst_data);
1465         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1466         break;
1467       }
1468       case Instruction::SPUT_OBJECT: {
1469         PREAMBLE();
1470         bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1471             transaction_active>(self, shadow_frame, inst, inst_data);
1472         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1473         break;
1474       }
1475       case Instruction::INVOKE_VIRTUAL: {
1476         PREAMBLE();
1477         bool success = DoInvoke<kVirtual, false, do_access_check>(
1478             self, shadow_frame, inst, inst_data, &result_register);
1479         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1480         break;
1481       }
1482       case Instruction::INVOKE_VIRTUAL_RANGE: {
1483         PREAMBLE();
1484         bool success = DoInvoke<kVirtual, true, do_access_check>(
1485             self, shadow_frame, inst, inst_data, &result_register);
1486         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1487         break;
1488       }
1489       case Instruction::INVOKE_SUPER: {
1490         PREAMBLE();
1491         bool success = DoInvoke<kSuper, false, do_access_check>(
1492             self, shadow_frame, inst, inst_data, &result_register);
1493         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1494         break;
1495       }
1496       case Instruction::INVOKE_SUPER_RANGE: {
1497         PREAMBLE();
1498         bool success = DoInvoke<kSuper, true, do_access_check>(
1499             self, shadow_frame, inst, inst_data, &result_register);
1500         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1501         break;
1502       }
1503       case Instruction::INVOKE_DIRECT: {
1504         PREAMBLE();
1505         bool success = DoInvoke<kDirect, false, do_access_check>(
1506             self, shadow_frame, inst, inst_data, &result_register);
1507         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1508         break;
1509       }
1510       case Instruction::INVOKE_DIRECT_RANGE: {
1511         PREAMBLE();
1512         bool success = DoInvoke<kDirect, true, do_access_check>(
1513             self, shadow_frame, inst, inst_data, &result_register);
1514         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1515         break;
1516       }
1517       case Instruction::INVOKE_INTERFACE: {
1518         PREAMBLE();
1519         bool success = DoInvoke<kInterface, false, do_access_check>(
1520             self, shadow_frame, inst, inst_data, &result_register);
1521         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1522         break;
1523       }
1524       case Instruction::INVOKE_INTERFACE_RANGE: {
1525         PREAMBLE();
1526         bool success = DoInvoke<kInterface, true, do_access_check>(
1527             self, shadow_frame, inst, inst_data, &result_register);
1528         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1529         break;
1530       }
1531       case Instruction::INVOKE_STATIC: {
1532         PREAMBLE();
1533         bool success = DoInvoke<kStatic, false, do_access_check>(
1534             self, shadow_frame, inst, inst_data, &result_register);
1535         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1536         break;
1537       }
1538       case Instruction::INVOKE_STATIC_RANGE: {
1539         PREAMBLE();
1540         bool success = DoInvoke<kStatic, true, do_access_check>(
1541             self, shadow_frame, inst, inst_data, &result_register);
1542         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1543         break;
1544       }
1545       case Instruction::INVOKE_VIRTUAL_QUICK: {
1546         PREAMBLE();
1547         bool success = DoInvokeVirtualQuick<false>(
1548             self, shadow_frame, inst, inst_data, &result_register);
1549         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1550         break;
1551       }
1552       case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1553         PREAMBLE();
1554         bool success = DoInvokeVirtualQuick<true>(
1555             self, shadow_frame, inst, inst_data, &result_register);
1556         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1557         break;
1558       }
1559       case Instruction::NEG_INT:
1560         PREAMBLE();
1561         shadow_frame.SetVReg(
1562             inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1563         inst = inst->Next_1xx();
1564         break;
1565       case Instruction::NOT_INT:
1566         PREAMBLE();
1567         shadow_frame.SetVReg(
1568             inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1569         inst = inst->Next_1xx();
1570         break;
1571       case Instruction::NEG_LONG:
1572         PREAMBLE();
1573         shadow_frame.SetVRegLong(
1574             inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1575         inst = inst->Next_1xx();
1576         break;
1577       case Instruction::NOT_LONG:
1578         PREAMBLE();
1579         shadow_frame.SetVRegLong(
1580             inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1581         inst = inst->Next_1xx();
1582         break;
1583       case Instruction::NEG_FLOAT:
1584         PREAMBLE();
1585         shadow_frame.SetVRegFloat(
1586             inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
1587         inst = inst->Next_1xx();
1588         break;
1589       case Instruction::NEG_DOUBLE:
1590         PREAMBLE();
1591         shadow_frame.SetVRegDouble(
1592             inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
1593         inst = inst->Next_1xx();
1594         break;
1595       case Instruction::INT_TO_LONG:
1596         PREAMBLE();
1597         shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1598                                  shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1599         inst = inst->Next_1xx();
1600         break;
1601       case Instruction::INT_TO_FLOAT:
1602         PREAMBLE();
1603         shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1604                                   shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1605         inst = inst->Next_1xx();
1606         break;
1607       case Instruction::INT_TO_DOUBLE:
1608         PREAMBLE();
1609         shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1610                                    shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1611         inst = inst->Next_1xx();
1612         break;
1613       case Instruction::LONG_TO_INT:
1614         PREAMBLE();
1615         shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1616                              shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1617         inst = inst->Next_1xx();
1618         break;
1619       case Instruction::LONG_TO_FLOAT:
1620         PREAMBLE();
1621         shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1622                                   shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1623         inst = inst->Next_1xx();
1624         break;
1625       case Instruction::LONG_TO_DOUBLE:
1626         PREAMBLE();
1627         shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1628                                    shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1629         inst = inst->Next_1xx();
1630         break;
1631       case Instruction::FLOAT_TO_INT: {
1632         PREAMBLE();
1633         float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
1634         int32_t result = art_float_to_integral<int32_t, float>(val);
1635         shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
1636         inst = inst->Next_1xx();
1637         break;
1638       }
1639       case Instruction::FLOAT_TO_LONG: {
1640         PREAMBLE();
1641         float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
1642         int64_t result = art_float_to_integral<int64_t, float>(val);
1643         shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
1644         inst = inst->Next_1xx();
1645         break;
1646       }
1647       case Instruction::FLOAT_TO_DOUBLE:
1648         PREAMBLE();
1649         shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1650                                    shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
1651         inst = inst->Next_1xx();
1652         break;
1653       case Instruction::DOUBLE_TO_INT: {
1654         PREAMBLE();
1655         double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
1656         int32_t result = art_float_to_integral<int32_t, double>(val);
1657         shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
1658         inst = inst->Next_1xx();
1659         break;
1660       }
1661       case Instruction::DOUBLE_TO_LONG: {
1662         PREAMBLE();
1663         double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
1664         int64_t result = art_float_to_integral<int64_t, double>(val);
1665         shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
1666         inst = inst->Next_1xx();
1667         break;
1668       }
1669       case Instruction::DOUBLE_TO_FLOAT:
1670         PREAMBLE();
1671         shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1672                                   shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
1673         inst = inst->Next_1xx();
1674         break;
1675       case Instruction::INT_TO_BYTE:
1676         PREAMBLE();
1677         shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1678             shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
1679         inst = inst->Next_1xx();
1680         break;
1681       case Instruction::INT_TO_CHAR:
1682         PREAMBLE();
1683         shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1684             shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
1685         inst = inst->Next_1xx();
1686         break;
1687       case Instruction::INT_TO_SHORT:
1688         PREAMBLE();
1689         shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1690             shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
1691         inst = inst->Next_1xx();
1692         break;
1693       case Instruction::ADD_INT: {
1694         PREAMBLE();
1695         shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1696                              SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1697                                      shadow_frame.GetVReg(inst->VRegC_23x())));
1698         inst = inst->Next_2xx();
1699         break;
1700       }
1701       case Instruction::SUB_INT:
1702         PREAMBLE();
1703         shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1704                              SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1705                                      shadow_frame.GetVReg(inst->VRegC_23x())));
1706         inst = inst->Next_2xx();
1707         break;
1708       case Instruction::MUL_INT:
1709         PREAMBLE();
1710         shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1711                              SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1712                                      shadow_frame.GetVReg(inst->VRegC_23x())));
1713         inst = inst->Next_2xx();
1714         break;
1715       case Instruction::DIV_INT: {
1716         PREAMBLE();
1717         bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1718                                    shadow_frame.GetVReg(inst->VRegB_23x()),
1719                                    shadow_frame.GetVReg(inst->VRegC_23x()));
1720         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1721         break;
1722       }
1723       case Instruction::REM_INT: {
1724         PREAMBLE();
1725         bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1726                                       shadow_frame.GetVReg(inst->VRegB_23x()),
1727                                       shadow_frame.GetVReg(inst->VRegC_23x()));
1728         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1729         break;
1730       }
1731       case Instruction::SHL_INT:
1732         PREAMBLE();
1733         shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1734                              shadow_frame.GetVReg(inst->VRegB_23x()) <<
1735                              (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1736         inst = inst->Next_2xx();
1737         break;
1738       case Instruction::SHR_INT:
1739         PREAMBLE();
1740         shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1741                              shadow_frame.GetVReg(inst->VRegB_23x()) >>
1742                              (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1743         inst = inst->Next_2xx();
1744         break;
1745       case Instruction::USHR_INT:
1746         PREAMBLE();
1747         shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1748                              static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1749                              (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1750         inst = inst->Next_2xx();
1751         break;
1752       case Instruction::AND_INT:
1753         PREAMBLE();
1754         shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1755                              shadow_frame.GetVReg(inst->VRegB_23x()) &
1756                              shadow_frame.GetVReg(inst->VRegC_23x()));
1757         inst = inst->Next_2xx();
1758         break;
1759       case Instruction::OR_INT:
1760         PREAMBLE();
1761         shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1762                              shadow_frame.GetVReg(inst->VRegB_23x()) |
1763                              shadow_frame.GetVReg(inst->VRegC_23x()));
1764         inst = inst->Next_2xx();
1765         break;
1766       case Instruction::XOR_INT:
1767         PREAMBLE();
1768         shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1769                              shadow_frame.GetVReg(inst->VRegB_23x()) ^
1770                              shadow_frame.GetVReg(inst->VRegC_23x()));
1771         inst = inst->Next_2xx();
1772         break;
1773       case Instruction::ADD_LONG:
1774         PREAMBLE();
1775         shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1776                                  SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1777                                          shadow_frame.GetVRegLong(inst->VRegC_23x())));
1778         inst = inst->Next_2xx();
1779         break;
1780       case Instruction::SUB_LONG:
1781         PREAMBLE();
1782         shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1783                                  SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1784                                          shadow_frame.GetVRegLong(inst->VRegC_23x())));
1785         inst = inst->Next_2xx();
1786         break;
1787       case Instruction::MUL_LONG:
1788         PREAMBLE();
1789         shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1790                                  SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1791                                          shadow_frame.GetVRegLong(inst->VRegC_23x())));
1792         inst = inst->Next_2xx();
1793         break;
1794       case Instruction::DIV_LONG:
1795         PREAMBLE();
1796         DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1797                      shadow_frame.GetVRegLong(inst->VRegB_23x()),
1798                      shadow_frame.GetVRegLong(inst->VRegC_23x()));
1799         POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1800         break;
1801       case Instruction::REM_LONG:
1802         PREAMBLE();
1803         DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1804                         shadow_frame.GetVRegLong(inst->VRegB_23x()),
1805                         shadow_frame.GetVRegLong(inst->VRegC_23x()));
1806         POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1807         break;
1808       case Instruction::AND_LONG:
1809         PREAMBLE();
1810         shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1811                                  shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1812                                  shadow_frame.GetVRegLong(inst->VRegC_23x()));
1813         inst = inst->Next_2xx();
1814         break;
1815       case Instruction::OR_LONG:
1816         PREAMBLE();
1817         shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1818                                  shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1819                                  shadow_frame.GetVRegLong(inst->VRegC_23x()));
1820         inst = inst->Next_2xx();
1821         break;
1822       case Instruction::XOR_LONG:
1823         PREAMBLE();
1824         shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1825                                  shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1826                                  shadow_frame.GetVRegLong(inst->VRegC_23x()));
1827         inst = inst->Next_2xx();
1828         break;
1829       case Instruction::SHL_LONG:
1830         PREAMBLE();
1831         shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1832                                  shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1833                                  (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1834         inst = inst->Next_2xx();
1835         break;
1836       case Instruction::SHR_LONG:
1837         PREAMBLE();
1838         shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1839                                  shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1840                                  (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1841         inst = inst->Next_2xx();
1842         break;
1843       case Instruction::USHR_LONG:
1844         PREAMBLE();
1845         shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1846                                  static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1847                                  (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1848         inst = inst->Next_2xx();
1849         break;
1850       case Instruction::ADD_FLOAT:
1851         PREAMBLE();
1852         shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
1853                                   shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1854                                   shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1855         inst = inst->Next_2xx();
1856         break;
1857       case Instruction::SUB_FLOAT:
1858         PREAMBLE();
1859         shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
1860                                   shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1861                                   shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1862         inst = inst->Next_2xx();
1863         break;
1864       case Instruction::MUL_FLOAT:
1865         PREAMBLE();
1866         shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
1867                                   shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1868                                   shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1869         inst = inst->Next_2xx();
1870         break;
1871       case Instruction::DIV_FLOAT:
1872         PREAMBLE();
1873         shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
1874                                   shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1875                                   shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1876         inst = inst->Next_2xx();
1877         break;
1878       case Instruction::REM_FLOAT:
1879         PREAMBLE();
1880         shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
1881                                   fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1882                                         shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1883         inst = inst->Next_2xx();
1884         break;
1885       case Instruction::ADD_DOUBLE:
1886         PREAMBLE();
1887         shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
1888                                    shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1889                                    shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1890         inst = inst->Next_2xx();
1891         break;
1892       case Instruction::SUB_DOUBLE:
1893         PREAMBLE();
1894         shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
1895                                    shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1896                                    shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1897         inst = inst->Next_2xx();
1898         break;
1899       case Instruction::MUL_DOUBLE:
1900         PREAMBLE();
1901         shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
1902                                    shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1903                                    shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1904         inst = inst->Next_2xx();
1905         break;
1906       case Instruction::DIV_DOUBLE:
1907         PREAMBLE();
1908         shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
1909                                    shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1910                                    shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1911         inst = inst->Next_2xx();
1912         break;
1913       case Instruction::REM_DOUBLE:
1914         PREAMBLE();
1915         shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
1916                                    fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1917                                         shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1918         inst = inst->Next_2xx();
1919         break;
1920       case Instruction::ADD_INT_2ADDR: {
1921         PREAMBLE();
1922         uint4_t vregA = inst->VRegA_12x(inst_data);
1923         shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
1924                                             shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
1925         inst = inst->Next_1xx();
1926         break;
1927       }
1928       case Instruction::SUB_INT_2ADDR: {
1929         PREAMBLE();
1930         uint4_t vregA = inst->VRegA_12x(inst_data);
1931         shadow_frame.SetVReg(vregA,
1932                              SafeSub(shadow_frame.GetVReg(vregA),
1933                                      shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
1934         inst = inst->Next_1xx();
1935         break;
1936       }
1937       case Instruction::MUL_INT_2ADDR: {
1938         PREAMBLE();
1939         uint4_t vregA = inst->VRegA_12x(inst_data);
1940         shadow_frame.SetVReg(vregA,
1941                              SafeMul(shadow_frame.GetVReg(vregA),
1942                                      shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
1943         inst = inst->Next_1xx();
1944         break;
1945       }
1946       case Instruction::DIV_INT_2ADDR: {
1947         PREAMBLE();
1948         uint4_t vregA = inst->VRegA_12x(inst_data);
1949         bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
1950                                    shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1951         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1952         break;
1953       }
1954       case Instruction::REM_INT_2ADDR: {
1955         PREAMBLE();
1956         uint4_t vregA = inst->VRegA_12x(inst_data);
1957         bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
1958                                       shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1959         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1960         break;
1961       }
1962       case Instruction::SHL_INT_2ADDR: {
1963         PREAMBLE();
1964         uint4_t vregA = inst->VRegA_12x(inst_data);
1965         shadow_frame.SetVReg(vregA,
1966                              shadow_frame.GetVReg(vregA) <<
1967                              (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
1968         inst = inst->Next_1xx();
1969         break;
1970       }
1971       case Instruction::SHR_INT_2ADDR: {
1972         PREAMBLE();
1973         uint4_t vregA = inst->VRegA_12x(inst_data);
1974         shadow_frame.SetVReg(vregA,
1975                              shadow_frame.GetVReg(vregA) >>
1976                              (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
1977         inst = inst->Next_1xx();
1978         break;
1979       }
1980       case Instruction::USHR_INT_2ADDR: {
1981         PREAMBLE();
1982         uint4_t vregA = inst->VRegA_12x(inst_data);
1983         shadow_frame.SetVReg(vregA,
1984                              static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
1985                              (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
1986         inst = inst->Next_1xx();
1987         break;
1988       }
1989       case Instruction::AND_INT_2ADDR: {
1990         PREAMBLE();
1991         uint4_t vregA = inst->VRegA_12x(inst_data);
1992         shadow_frame.SetVReg(vregA,
1993                              shadow_frame.GetVReg(vregA) &
1994                              shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1995         inst = inst->Next_1xx();
1996         break;
1997       }
1998       case Instruction::OR_INT_2ADDR: {
1999         PREAMBLE();
2000         uint4_t vregA = inst->VRegA_12x(inst_data);
2001         shadow_frame.SetVReg(vregA,
2002                              shadow_frame.GetVReg(vregA) |
2003                              shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
2004         inst = inst->Next_1xx();
2005         break;
2006       }
2007       case Instruction::XOR_INT_2ADDR: {
2008         PREAMBLE();
2009         uint4_t vregA = inst->VRegA_12x(inst_data);
2010         shadow_frame.SetVReg(vregA,
2011                              shadow_frame.GetVReg(vregA) ^
2012                              shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
2013         inst = inst->Next_1xx();
2014         break;
2015       }
2016       case Instruction::ADD_LONG_2ADDR: {
2017         PREAMBLE();
2018         uint4_t vregA = inst->VRegA_12x(inst_data);
2019         shadow_frame.SetVRegLong(vregA,
2020                                  SafeAdd(shadow_frame.GetVRegLong(vregA),
2021                                          shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
2022         inst = inst->Next_1xx();
2023         break;
2024       }
2025       case Instruction::SUB_LONG_2ADDR: {
2026         PREAMBLE();
2027         uint4_t vregA = inst->VRegA_12x(inst_data);
2028         shadow_frame.SetVRegLong(vregA,
2029                                  SafeSub(shadow_frame.GetVRegLong(vregA),
2030                                          shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
2031         inst = inst->Next_1xx();
2032         break;
2033       }
2034       case Instruction::MUL_LONG_2ADDR: {
2035         PREAMBLE();
2036         uint4_t vregA = inst->VRegA_12x(inst_data);
2037         shadow_frame.SetVRegLong(vregA,
2038                                  SafeMul(shadow_frame.GetVRegLong(vregA),
2039                                          shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
2040         inst = inst->Next_1xx();
2041         break;
2042       }
2043       case Instruction::DIV_LONG_2ADDR: {
2044         PREAMBLE();
2045         uint4_t vregA = inst->VRegA_12x(inst_data);
2046         DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
2047                     shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
2048         POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2049         break;
2050       }
2051       case Instruction::REM_LONG_2ADDR: {
2052         PREAMBLE();
2053         uint4_t vregA = inst->VRegA_12x(inst_data);
2054         DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
2055                         shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
2056         POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2057         break;
2058       }
2059       case Instruction::AND_LONG_2ADDR: {
2060         PREAMBLE();
2061         uint4_t vregA = inst->VRegA_12x(inst_data);
2062         shadow_frame.SetVRegLong(vregA,
2063                                  shadow_frame.GetVRegLong(vregA) &
2064                                  shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
2065         inst = inst->Next_1xx();
2066         break;
2067       }
2068       case Instruction::OR_LONG_2ADDR: {
2069         PREAMBLE();
2070         uint4_t vregA = inst->VRegA_12x(inst_data);
2071         shadow_frame.SetVRegLong(vregA,
2072                                  shadow_frame.GetVRegLong(vregA) |
2073                                  shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
2074         inst = inst->Next_1xx();
2075         break;
2076       }
2077       case Instruction::XOR_LONG_2ADDR: {
2078         PREAMBLE();
2079         uint4_t vregA = inst->VRegA_12x(inst_data);
2080         shadow_frame.SetVRegLong(vregA,
2081                                  shadow_frame.GetVRegLong(vregA) ^
2082                                  shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
2083         inst = inst->Next_1xx();
2084         break;
2085       }
2086       case Instruction::SHL_LONG_2ADDR: {
2087         PREAMBLE();
2088         uint4_t vregA = inst->VRegA_12x(inst_data);
2089         shadow_frame.SetVRegLong(vregA,
2090                                  shadow_frame.GetVRegLong(vregA) <<
2091                                  (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
2092         inst = inst->Next_1xx();
2093         break;
2094       }
2095       case Instruction::SHR_LONG_2ADDR: {
2096         PREAMBLE();
2097         uint4_t vregA = inst->VRegA_12x(inst_data);
2098         shadow_frame.SetVRegLong(vregA,
2099                                  shadow_frame.GetVRegLong(vregA) >>
2100                                  (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
2101         inst = inst->Next_1xx();
2102         break;
2103       }
2104       case Instruction::USHR_LONG_2ADDR: {
2105         PREAMBLE();
2106         uint4_t vregA = inst->VRegA_12x(inst_data);
2107         shadow_frame.SetVRegLong(vregA,
2108                                  static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
2109                                  (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
2110         inst = inst->Next_1xx();
2111         break;
2112       }
2113       case Instruction::ADD_FLOAT_2ADDR: {
2114         PREAMBLE();
2115         uint4_t vregA = inst->VRegA_12x(inst_data);
2116         shadow_frame.SetVRegFloat(vregA,
2117                                   shadow_frame.GetVRegFloat(vregA) +
2118                                   shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
2119         inst = inst->Next_1xx();
2120         break;
2121       }
2122       case Instruction::SUB_FLOAT_2ADDR: {
2123         PREAMBLE();
2124         uint4_t vregA = inst->VRegA_12x(inst_data);
2125         shadow_frame.SetVRegFloat(vregA,
2126                                   shadow_frame.GetVRegFloat(vregA) -
2127                                   shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
2128         inst = inst->Next_1xx();
2129         break;
2130       }
2131       case Instruction::MUL_FLOAT_2ADDR: {
2132         PREAMBLE();
2133         uint4_t vregA = inst->VRegA_12x(inst_data);
2134         shadow_frame.SetVRegFloat(vregA,
2135                                   shadow_frame.GetVRegFloat(vregA) *
2136                                   shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
2137         inst = inst->Next_1xx();
2138         break;
2139       }
2140       case Instruction::DIV_FLOAT_2ADDR: {
2141         PREAMBLE();
2142         uint4_t vregA = inst->VRegA_12x(inst_data);
2143         shadow_frame.SetVRegFloat(vregA,
2144                                   shadow_frame.GetVRegFloat(vregA) /
2145                                   shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
2146         inst = inst->Next_1xx();
2147         break;
2148       }
2149       case Instruction::REM_FLOAT_2ADDR: {
2150         PREAMBLE();
2151         uint4_t vregA = inst->VRegA_12x(inst_data);
2152         shadow_frame.SetVRegFloat(vregA,
2153                                   fmodf(shadow_frame.GetVRegFloat(vregA),
2154                                         shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
2155         inst = inst->Next_1xx();
2156         break;
2157       }
2158       case Instruction::ADD_DOUBLE_2ADDR: {
2159         PREAMBLE();
2160         uint4_t vregA = inst->VRegA_12x(inst_data);
2161         shadow_frame.SetVRegDouble(vregA,
2162                                    shadow_frame.GetVRegDouble(vregA) +
2163                                    shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
2164         inst = inst->Next_1xx();
2165         break;
2166       }
2167       case Instruction::SUB_DOUBLE_2ADDR: {
2168         PREAMBLE();
2169         uint4_t vregA = inst->VRegA_12x(inst_data);
2170         shadow_frame.SetVRegDouble(vregA,
2171                                    shadow_frame.GetVRegDouble(vregA) -
2172                                    shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
2173         inst = inst->Next_1xx();
2174         break;
2175       }
2176       case Instruction::MUL_DOUBLE_2ADDR: {
2177         PREAMBLE();
2178         uint4_t vregA = inst->VRegA_12x(inst_data);
2179         shadow_frame.SetVRegDouble(vregA,
2180                                    shadow_frame.GetVRegDouble(vregA) *
2181                                    shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
2182         inst = inst->Next_1xx();
2183         break;
2184       }
2185       case Instruction::DIV_DOUBLE_2ADDR: {
2186         PREAMBLE();
2187         uint4_t vregA = inst->VRegA_12x(inst_data);
2188         shadow_frame.SetVRegDouble(vregA,
2189                                    shadow_frame.GetVRegDouble(vregA) /
2190                                    shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
2191         inst = inst->Next_1xx();
2192         break;
2193       }
2194       case Instruction::REM_DOUBLE_2ADDR: {
2195         PREAMBLE();
2196         uint4_t vregA = inst->VRegA_12x(inst_data);
2197         shadow_frame.SetVRegDouble(vregA,
2198                                    fmod(shadow_frame.GetVRegDouble(vregA),
2199                                         shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
2200         inst = inst->Next_1xx();
2201         break;
2202       }
2203       case Instruction::ADD_INT_LIT16:
2204         PREAMBLE();
2205         shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2206                              SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2207                                      inst->VRegC_22s()));
2208         inst = inst->Next_2xx();
2209         break;
2210       case Instruction::RSUB_INT_LIT16:
2211         PREAMBLE();
2212         shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2213                              SafeSub(inst->VRegC_22s(),
2214                                      shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
2215         inst = inst->Next_2xx();
2216         break;
2217       case Instruction::MUL_INT_LIT16:
2218         PREAMBLE();
2219         shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2220                              SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2221                                      inst->VRegC_22s()));
2222         inst = inst->Next_2xx();
2223         break;
2224       case Instruction::DIV_INT_LIT16: {
2225         PREAMBLE();
2226         bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
2227                                    shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2228                                    inst->VRegC_22s());
2229         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2230         break;
2231       }
2232       case Instruction::REM_INT_LIT16: {
2233         PREAMBLE();
2234         bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
2235                                       shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2236                                       inst->VRegC_22s());
2237         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2238         break;
2239       }
2240       case Instruction::AND_INT_LIT16:
2241         PREAMBLE();
2242         shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2243                              shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
2244                              inst->VRegC_22s());
2245         inst = inst->Next_2xx();
2246         break;
2247       case Instruction::OR_INT_LIT16:
2248         PREAMBLE();
2249         shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2250                              shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
2251                              inst->VRegC_22s());
2252         inst = inst->Next_2xx();
2253         break;
2254       case Instruction::XOR_INT_LIT16:
2255         PREAMBLE();
2256         shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2257                              shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
2258                              inst->VRegC_22s());
2259         inst = inst->Next_2xx();
2260         break;
2261       case Instruction::ADD_INT_LIT8:
2262         PREAMBLE();
2263         shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2264                              SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
2265         inst = inst->Next_2xx();
2266         break;
2267       case Instruction::RSUB_INT_LIT8:
2268         PREAMBLE();
2269         shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2270                              SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
2271         inst = inst->Next_2xx();
2272         break;
2273       case Instruction::MUL_INT_LIT8:
2274         PREAMBLE();
2275         shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2276                              SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
2277         inst = inst->Next_2xx();
2278         break;
2279       case Instruction::DIV_INT_LIT8: {
2280         PREAMBLE();
2281         bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2282                                    shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2283         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2284         break;
2285       }
2286       case Instruction::REM_INT_LIT8: {
2287         PREAMBLE();
2288         bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2289                                       shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2290         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2291         break;
2292       }
2293       case Instruction::AND_INT_LIT8:
2294         PREAMBLE();
2295         shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2296                              shadow_frame.GetVReg(inst->VRegB_22b()) &
2297                              inst->VRegC_22b());
2298         inst = inst->Next_2xx();
2299         break;
2300       case Instruction::OR_INT_LIT8:
2301         PREAMBLE();
2302         shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2303                              shadow_frame.GetVReg(inst->VRegB_22b()) |
2304                              inst->VRegC_22b());
2305         inst = inst->Next_2xx();
2306         break;
2307       case Instruction::XOR_INT_LIT8:
2308         PREAMBLE();
2309         shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2310                              shadow_frame.GetVReg(inst->VRegB_22b()) ^
2311                              inst->VRegC_22b());
2312         inst = inst->Next_2xx();
2313         break;
2314       case Instruction::SHL_INT_LIT8:
2315         PREAMBLE();
2316         shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2317                              shadow_frame.GetVReg(inst->VRegB_22b()) <<
2318                              (inst->VRegC_22b() & 0x1f));
2319         inst = inst->Next_2xx();
2320         break;
2321       case Instruction::SHR_INT_LIT8:
2322         PREAMBLE();
2323         shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2324                              shadow_frame.GetVReg(inst->VRegB_22b()) >>
2325                              (inst->VRegC_22b() & 0x1f));
2326         inst = inst->Next_2xx();
2327         break;
2328       case Instruction::USHR_INT_LIT8:
2329         PREAMBLE();
2330         shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2331                              static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2332                              (inst->VRegC_22b() & 0x1f));
2333         inst = inst->Next_2xx();
2334         break;
2335       case Instruction::INVOKE_LAMBDA: {
2336         if (!IsExperimentalInstructionEnabled(inst)) {
2337           UnexpectedOpcode(inst, shadow_frame);
2338         }
2339 
2340         PREAMBLE();
2341         bool success = DoInvokeLambda<do_access_check>(self, shadow_frame, inst, inst_data,
2342                                                        &result_register);
2343         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2344         break;
2345       }
2346       case Instruction::CAPTURE_VARIABLE: {
2347         if (!IsExperimentalInstructionEnabled(inst)) {
2348           UnexpectedOpcode(inst, shadow_frame);
2349         }
2350 
2351         if (lambda_closure_builder == nullptr) {
2352           lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2353         }
2354 
2355         PREAMBLE();
2356         bool success = DoCaptureVariable<do_access_check>(self,
2357                                                           inst,
2358                                                           /*inout*/shadow_frame,
2359                                                           /*inout*/lambda_closure_builder.get());
2360         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2361         break;
2362       }
2363       case Instruction::CREATE_LAMBDA: {
2364         if (!IsExperimentalInstructionEnabled(inst)) {
2365           UnexpectedOpcode(inst, shadow_frame);
2366         }
2367 
2368         PREAMBLE();
2369 
2370         if (lambda_closure_builder == nullptr) {
2371           // DoCreateLambda always needs a ClosureBuilder, even if it has 0 captured variables.
2372           lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2373         }
2374 
2375         // TODO: these allocations should not leak, and the lambda method should not be local.
2376         lambda::Closure* lambda_closure =
2377             reinterpret_cast<lambda::Closure*>(alloca(lambda_closure_builder->GetSize()));
2378         bool success = DoCreateLambda<do_access_check>(self,
2379                                                        inst,
2380                                                        /*inout*/shadow_frame,
2381                                                        /*inout*/lambda_closure_builder.get(),
2382                                                        /*inout*/lambda_closure);
2383         lambda_closure_builder.reset(nullptr);  // reset state of variables captured
2384         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2385         break;
2386       }
2387       case Instruction::LIBERATE_VARIABLE: {
2388         if (!IsExperimentalInstructionEnabled(inst)) {
2389           UnexpectedOpcode(inst, shadow_frame);
2390         }
2391 
2392         PREAMBLE();
2393         bool success = DoLiberateVariable<do_access_check>(self,
2394                                                            inst,
2395                                                            lambda_captured_variable_index,
2396                                                            /*inout*/shadow_frame);
2397         // Temporarily only allow sequences of 'liberate-variable, liberate-variable, ...'
2398         lambda_captured_variable_index++;
2399         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2400         break;
2401       }
2402       case Instruction::UNUSED_F4: {
2403         if (!IsExperimentalInstructionEnabled(inst)) {
2404           UnexpectedOpcode(inst, shadow_frame);
2405         }
2406 
2407         CHECK(false);  // TODO(iam): Implement opcodes for lambdas
2408         break;
2409       }
2410       case Instruction::BOX_LAMBDA: {
2411         if (!IsExperimentalInstructionEnabled(inst)) {
2412           UnexpectedOpcode(inst, shadow_frame);
2413         }
2414 
2415         PREAMBLE();
2416         bool success = DoBoxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2417         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2418         break;
2419       }
2420       case Instruction::UNBOX_LAMBDA: {
2421         if (!IsExperimentalInstructionEnabled(inst)) {
2422           UnexpectedOpcode(inst, shadow_frame);
2423         }
2424 
2425         PREAMBLE();
2426         bool success = DoUnboxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2427         POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2428         break;
2429       }
2430       case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
2431       case Instruction::UNUSED_FA ... Instruction::UNUSED_FF:
2432       case Instruction::UNUSED_79:
2433       case Instruction::UNUSED_7A:
2434         UnexpectedOpcode(inst, shadow_frame);
2435     }
2436   } while (!interpret_one_instruction);
2437   // Record where we stopped.
2438   shadow_frame.SetDexPC(inst->GetDexPc(insns));
2439   return result_register;
2440 }  // NOLINT(readability/fn_size)
2441 
2442 // Explicit definitions of ExecuteSwitchImpl.
2443 template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
2444 JValue ExecuteSwitchImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
2445                                       ShadowFrame& shadow_frame, JValue result_register,
2446                                       bool interpret_one_instruction);
2447 template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
2448 JValue ExecuteSwitchImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
2449                                        ShadowFrame& shadow_frame, JValue result_register,
2450                                        bool interpret_one_instruction);
2451 template SHARED_REQUIRES(Locks::mutator_lock_)
2452 JValue ExecuteSwitchImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
2453                                      ShadowFrame& shadow_frame, JValue result_register,
2454                                      bool interpret_one_instruction);
2455 template SHARED_REQUIRES(Locks::mutator_lock_)
2456 JValue ExecuteSwitchImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
2457                                       ShadowFrame& shadow_frame, JValue result_register,
2458                                       bool interpret_one_instruction);
2459 
2460 }  // namespace interpreter
2461 }  // namespace art
2462