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