• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_
18 #define ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_
19 
20 #include "interpreter_switch_impl.h"
21 
22 #include "base/enums.h"
23 #include "base/globals.h"
24 #include "base/memory_tool.h"
25 #include "base/quasi_atomic.h"
26 #include "dex/dex_file_types.h"
27 #include "dex/dex_instruction_list.h"
28 #include "experimental_flags.h"
29 #include "handle_scope.h"
30 #include "interpreter_common.h"
31 #include "interpreter/shadow_frame.h"
32 #include "jit/jit-inl.h"
33 #include "jvalue-inl.h"
34 #include "mirror/string-alloc-inl.h"
35 #include "mirror/throwable.h"
36 #include "monitor.h"
37 #include "nth_caller_visitor.h"
38 #include "safe_math.h"
39 #include "shadow_frame-inl.h"
40 #include "thread.h"
41 #include "verifier/method_verifier.h"
42 
43 namespace art {
44 namespace interpreter {
45 
46 // Short-lived helper class which executes single DEX bytecode.  It is inlined by compiler.
47 // Any relevant execution information is stored in the fields - it should be kept to minimum.
48 // All instance functions must be inlined so that the fields can be stored in registers.
49 //
50 // The function names must match the names from dex_instruction_list.h and have no arguments.
51 // Return value: The handlers must return false if the instruction throws or returns (exits).
52 //
53 template<bool do_access_check, bool transaction_active, Instruction::Format kFormat>
54 class InstructionHandler {
55  public:
56 #define HANDLER_ATTRIBUTES ALWAYS_INLINE FLATTEN WARN_UNUSED REQUIRES_SHARED(Locks::mutator_lock_)
57 
CheckTransactionAbort()58   HANDLER_ATTRIBUTES bool CheckTransactionAbort() {
59     if (transaction_active && Runtime::Current()->IsTransactionAborted()) {
60       // Transaction abort cannot be caught by catch handlers.
61       // Preserve the abort exception while doing non-standard return.
62       StackHandleScope<1u> hs(Self());
63       Handle<mirror::Throwable> abort_exception = hs.NewHandle(Self()->GetException());
64       DCHECK(abort_exception != nullptr);
65       DCHECK(abort_exception->GetClass()->DescriptorEquals(Transaction::kAbortExceptionDescriptor));
66       Self()->ClearException();
67       PerformNonStandardReturn<kMonitorState>(Self(),
68                                               shadow_frame_,
69                                               ctx_->result,
70                                               Instrumentation(),
71                                               Accessor().InsSize(),
72                                               inst_->GetDexPc(Insns()));
73       Self()->SetException(abort_exception.Get());
74       ExitInterpreterLoop();
75       return false;
76     }
77     return true;
78   }
79 
CheckForceReturn()80   HANDLER_ATTRIBUTES bool CheckForceReturn() {
81     if (shadow_frame_.GetForcePopFrame()) {
82       DCHECK(Runtime::Current()->AreNonStandardExitsEnabled());
83       PerformNonStandardReturn<kMonitorState>(Self(),
84                                               shadow_frame_,
85                                               ctx_->result,
86                                               Instrumentation(),
87                                               Accessor().InsSize(),
88                                               inst_->GetDexPc(Insns()));
89       ExitInterpreterLoop();
90       return false;
91     }
92     return true;
93   }
94 
HandlePendingException()95   HANDLER_ATTRIBUTES bool HandlePendingException() {
96     DCHECK(Self()->IsExceptionPending());
97     Self()->AllowThreadSuspension();
98     if (!CheckTransactionAbort()) {
99       return false;
100     }
101     if (!CheckForceReturn()) {
102       return false;
103     }
104     bool skip_event = shadow_frame_.GetSkipNextExceptionEvent();
105     shadow_frame_.SetSkipNextExceptionEvent(false);
106     if (!MoveToExceptionHandler(Self(), shadow_frame_, skip_event ? nullptr : Instrumentation())) {
107       /* Structured locking is to be enforced for abnormal termination, too. */
108       DoMonitorCheckOnExit<do_assignability_check>(Self(), &shadow_frame_);
109       ctx_->result = JValue(); /* Handled in caller. */
110       ExitInterpreterLoop();
111       return false;  // Return to caller.
112     }
113     if (!CheckForceReturn()) {
114       return false;
115     }
116     int32_t displacement =
117         static_cast<int32_t>(shadow_frame_.GetDexPC()) - static_cast<int32_t>(dex_pc_);
118     SetNextInstruction(inst_->RelativeAt(displacement));
119     return true;
120   }
121 
PossiblyHandlePendingExceptionOnInvoke(bool is_exception_pending)122   HANDLER_ATTRIBUTES bool PossiblyHandlePendingExceptionOnInvoke(bool is_exception_pending) {
123     if (UNLIKELY(shadow_frame_.GetForceRetryInstruction())) {
124       /* Don't need to do anything except clear the flag and exception. We leave the */
125       /* instruction the same so it will be re-executed on the next go-around.       */
126       DCHECK(inst_->IsInvoke());
127       shadow_frame_.SetForceRetryInstruction(false);
128       if (UNLIKELY(is_exception_pending)) {
129         DCHECK(Self()->IsExceptionPending());
130         if (kIsDebugBuild) {
131           LOG(WARNING) << "Suppressing exception for instruction-retry: "
132                        << Self()->GetException()->Dump();
133         }
134         Self()->ClearException();
135       }
136       SetNextInstruction(inst_);
137     } else if (UNLIKELY(is_exception_pending)) {
138       /* Should have succeeded. */
139       DCHECK(!shadow_frame_.GetForceRetryInstruction());
140       return false;  // Pending exception.
141     }
142     return true;
143   }
144 
145   // Code to run before each dex instruction.
Preamble()146   HANDLER_ATTRIBUTES bool Preamble() {
147     /* We need to put this before & after the instrumentation to avoid having to put in a */
148     /* post-script macro.                                                                 */
149     if (!CheckForceReturn()) {
150       return false;
151     }
152     if (UNLIKELY(Instrumentation()->HasDexPcListeners())) {
153       uint8_t opcode = inst_->Opcode(inst_data_);
154       bool is_move_result_object = (opcode == Instruction::MOVE_RESULT_OBJECT);
155       JValue* save_ref = is_move_result_object ? &ctx_->result_register : nullptr;
156       if (UNLIKELY(!DoDexPcMoveEvent(Self(),
157                                      Accessor(),
158                                      shadow_frame_,
159                                      DexPC(),
160                                      Instrumentation(),
161                                      save_ref))) {
162         DCHECK(Self()->IsExceptionPending());
163         // Do not raise exception event if it is caused by other instrumentation event.
164         shadow_frame_.SetSkipNextExceptionEvent(true);
165         return false;  // Pending exception.
166       }
167       if (!CheckForceReturn()) {
168         return false;
169       }
170     }
171     return true;
172   }
173 
174   // Unlike most other events the DexPcMovedEvent can be sent when there is a pending exception (if
175   // the next instruction is MOVE_EXCEPTION). This means it needs to be handled carefully to be able
176   // to detect exceptions thrown by the DexPcMovedEvent itself. These exceptions could be thrown by
177   // jvmti-agents while handling breakpoint or single step events. We had to move this into its own
178   // 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)179   NO_INLINE static bool DoDexPcMoveEvent(Thread* self,
180                                          const CodeItemDataAccessor& accessor,
181                                          const ShadowFrame& shadow_frame,
182                                          uint32_t dex_pc_,
183                                          const instrumentation::Instrumentation* instrumentation,
184                                          JValue* save_ref)
185       REQUIRES_SHARED(Locks::mutator_lock_) {
186     DCHECK(instrumentation->HasDexPcListeners());
187     StackHandleScope<2> hs(self);
188     Handle<mirror::Throwable> thr(hs.NewHandle(self->GetException()));
189     mirror::Object* null_obj = nullptr;
190     HandleWrapper<mirror::Object> h(
191         hs.NewHandleWrapper(LIKELY(save_ref == nullptr) ? &null_obj : save_ref->GetGCRoot()));
192     self->ClearException();
193     instrumentation->DexPcMovedEvent(self,
194                                      shadow_frame.GetThisObject(accessor.InsSize()),
195                                      shadow_frame.GetMethod(),
196                                      dex_pc_);
197     if (UNLIKELY(self->IsExceptionPending())) {
198       // We got a new exception in the dex-pc-moved event.
199       // We just let this exception replace the old one.
200       // TODO It would be good to add the old exception to the
201       // suppressed exceptions of the new one if possible.
202       return false;  // Pending exception.
203     }
204     if (UNLIKELY(!thr.IsNull())) {
205       self->SetException(thr.Get());
206     }
207     return true;
208   }
209 
HandleReturn(JValue result)210   HANDLER_ATTRIBUTES bool HandleReturn(JValue result) {
211     Self()->AllowThreadSuspension();
212     if (!DoMonitorCheckOnExit<do_assignability_check>(Self(), &shadow_frame_)) {
213       return false;
214     }
215     if (UNLIKELY(NeedsMethodExitEvent(Instrumentation()) &&
216                  !SendMethodExitEvents(Self(),
217                                        Instrumentation(),
218                                        shadow_frame_,
219                                        shadow_frame_.GetThisObject(Accessor().InsSize()),
220                                        shadow_frame_.GetMethod(),
221                                        inst_->GetDexPc(Insns()),
222                                        result))) {
223       DCHECK(Self()->IsExceptionPending());
224       // Do not raise exception event if it is caused by other instrumentation event.
225       shadow_frame_.SetSkipNextExceptionEvent(true);
226       return false;  // Pending exception.
227     }
228     ctx_->result = result;
229     ExitInterpreterLoop();
230     return false;
231   }
232 
HandleBranch(int32_t offset)233   HANDLER_ATTRIBUTES bool HandleBranch(int32_t offset) {
234     if (UNLIKELY(Self()->ObserveAsyncException())) {
235       return false;  // Pending exception.
236     }
237     if (UNLIKELY(Instrumentation()->HasBranchListeners())) {
238       Instrumentation()->Branch(Self(), shadow_frame_.GetMethod(), DexPC(), offset);
239     }
240     if (!transaction_active) {
241       // TODO: Do OSR only on back-edges and check if OSR code is ready here.
242       JValue result;
243       if (jit::Jit::MaybeDoOnStackReplacement(Self(),
244                                               shadow_frame_.GetMethod(),
245                                               DexPC(),
246                                               offset,
247                                               &result)) {
248         ctx_->result = result;
249         ExitInterpreterLoop();
250         return false;
251       }
252     }
253     SetNextInstruction(inst_->RelativeAt(offset));
254     if (offset <= 0) {  // Back-edge.
255       // Hotness update.
256       jit::Jit* jit = Runtime::Current()->GetJit();
257       if (jit != nullptr) {
258         jit->AddSamples(Self(), shadow_frame_.GetMethod(), 1, /*with_backedges=*/ true);
259       }
260       // Record new dex pc early to have consistent suspend point at loop header.
261       shadow_frame_.SetDexPC(next_->GetDexPc(Insns()));
262       Self()->AllowThreadSuspension();
263     }
264     return true;
265   }
266 
HandleIf(bool cond,int32_t offset)267   HANDLER_ATTRIBUTES bool HandleIf(bool cond, int32_t offset) {
268     return HandleBranch(cond ? offset : Instruction::SizeInCodeUnits(kFormat));
269   }
270 
271 #pragma clang diagnostic push
272 #pragma clang diagnostic ignored "-Wfloat-equal"
273 
274   template<typename T>
HandleCmpl(T val1,T val2)275   HANDLER_ATTRIBUTES bool HandleCmpl(T val1, T val2) {
276     int32_t result;
277     if (val1 > val2) {
278       result = 1;
279     } else if (val1 == val2) {
280       result = 0;
281     } else {
282       result = -1;
283     }
284     SetVReg(A(), result);
285     return true;
286   }
287 
288   // Returns the same result as the function above. It only differs for NaN values.
289   template<typename T>
HandleCmpg(T val1,T val2)290   HANDLER_ATTRIBUTES bool HandleCmpg(T val1, T val2) {
291     int32_t result;
292     if (val1 < val2) {
293       result = -1;
294     } else if (val1 == val2) {
295       result = 0;
296     } else {
297       result = 1;
298     }
299     SetVReg(A(), result);
300     return true;
301   }
302 
303 #pragma clang diagnostic pop
304 
HandleConstString()305   HANDLER_ATTRIBUTES bool HandleConstString() {
306     ObjPtr<mirror::String> s = ResolveString(Self(), shadow_frame_, dex::StringIndex(B()));
307     if (UNLIKELY(s == nullptr)) {
308       return false;  // Pending exception.
309     }
310     SetVRegReference(A(), s);
311     return true;
312   }
313 
314   template<typename ArrayType, typename SetVRegFn>
HandleAGet(SetVRegFn setVReg)315   HANDLER_ATTRIBUTES bool HandleAGet(SetVRegFn setVReg) {
316     ObjPtr<mirror::Object> a = GetVRegReference(B());
317     if (UNLIKELY(a == nullptr)) {
318       ThrowNullPointerExceptionFromInterpreter();
319       return false;  // Pending exception.
320     }
321     int32_t index = GetVReg(C());
322     ObjPtr<ArrayType> array = ObjPtr<ArrayType>::DownCast(a);
323     if (UNLIKELY(!array->CheckIsValidIndex(index))) {
324       return false;  // Pending exception.
325     }
326     (this->*setVReg)(A(), array->GetWithoutChecks(index));
327     return true;
328   }
329 
330   template<typename ArrayType, typename T>
HandleAPut(T value)331   HANDLER_ATTRIBUTES bool HandleAPut(T value) {
332     ObjPtr<mirror::Object> a = GetVRegReference(B());
333     if (UNLIKELY(a == nullptr)) {
334       ThrowNullPointerExceptionFromInterpreter();
335       return false;  // Pending exception.
336     }
337     int32_t index = GetVReg(C());
338     ObjPtr<ArrayType> array = ObjPtr<ArrayType>::DownCast(a);
339     if (UNLIKELY(!array->CheckIsValidIndex(index))) {
340       return false;  // Pending exception.
341     }
342     if (transaction_active && !CheckWriteConstraint(Self(), array)) {
343       return false;
344     }
345     array->template SetWithoutChecks<transaction_active>(index, value);
346     return true;
347   }
348 
349   template<FindFieldType find_type, Primitive::Type field_type>
HandleGet()350   HANDLER_ATTRIBUTES bool HandleGet() {
351     return DoFieldGet<find_type, field_type, do_access_check, transaction_active>(
352         Self(), shadow_frame_, inst_, inst_data_);
353   }
354 
355   template<FindFieldType find_type, Primitive::Type field_type>
HandlePut()356   HANDLER_ATTRIBUTES bool HandlePut() {
357     return DoFieldPut<find_type, field_type, do_access_check, transaction_active>(
358         Self(), shadow_frame_, inst_, inst_data_);
359   }
360 
361   template<InvokeType type, bool is_range>
HandleInvoke()362   HANDLER_ATTRIBUTES bool HandleInvoke() {
363     bool success = DoInvoke<type, is_range, do_access_check, /*is_mterp=*/ false>(
364         Self(), shadow_frame_, inst_, inst_data_, ResultRegister());
365     return PossiblyHandlePendingExceptionOnInvoke(!success);
366   }
367 
HandleUnused()368   HANDLER_ATTRIBUTES bool HandleUnused() {
369     UnexpectedOpcode(inst_, shadow_frame_);
370     return true;
371   }
372 
NOP()373   HANDLER_ATTRIBUTES bool NOP() {
374     return true;
375   }
376 
MOVE()377   HANDLER_ATTRIBUTES bool MOVE() {
378     SetVReg(A(), GetVReg(B()));
379     return true;
380   }
381 
MOVE_FROM16()382   HANDLER_ATTRIBUTES bool MOVE_FROM16() {
383     SetVReg(A(), GetVReg(B()));
384     return true;
385   }
386 
MOVE_16()387   HANDLER_ATTRIBUTES bool MOVE_16() {
388     SetVReg(A(), GetVReg(B()));
389     return true;
390   }
391 
MOVE_WIDE()392   HANDLER_ATTRIBUTES bool MOVE_WIDE() {
393     SetVRegLong(A(), GetVRegLong(B()));
394     return true;
395   }
396 
MOVE_WIDE_FROM16()397   HANDLER_ATTRIBUTES bool MOVE_WIDE_FROM16() {
398     SetVRegLong(A(), GetVRegLong(B()));
399     return true;
400   }
401 
MOVE_WIDE_16()402   HANDLER_ATTRIBUTES bool MOVE_WIDE_16() {
403     SetVRegLong(A(), GetVRegLong(B()));
404     return true;
405   }
406 
MOVE_OBJECT()407   HANDLER_ATTRIBUTES bool MOVE_OBJECT() {
408     SetVRegReference(A(), GetVRegReference(B()));
409     return true;
410   }
411 
MOVE_OBJECT_FROM16()412   HANDLER_ATTRIBUTES bool MOVE_OBJECT_FROM16() {
413     SetVRegReference(A(), GetVRegReference(B()));
414     return true;
415   }
416 
MOVE_OBJECT_16()417   HANDLER_ATTRIBUTES bool MOVE_OBJECT_16() {
418     SetVRegReference(A(), GetVRegReference(B()));
419     return true;
420   }
421 
MOVE_RESULT()422   HANDLER_ATTRIBUTES bool MOVE_RESULT() {
423     SetVReg(A(), ResultRegister()->GetI());
424     return true;
425   }
426 
MOVE_RESULT_WIDE()427   HANDLER_ATTRIBUTES bool MOVE_RESULT_WIDE() {
428     SetVRegLong(A(), ResultRegister()->GetJ());
429     return true;
430   }
431 
MOVE_RESULT_OBJECT()432   HANDLER_ATTRIBUTES bool MOVE_RESULT_OBJECT() {
433     SetVRegReference(A(), ResultRegister()->GetL());
434     return true;
435   }
436 
MOVE_EXCEPTION()437   HANDLER_ATTRIBUTES bool MOVE_EXCEPTION() {
438     ObjPtr<mirror::Throwable> exception = Self()->GetException();
439     DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
440     SetVRegReference(A(), exception);
441     Self()->ClearException();
442     return true;
443   }
444 
RETURN_VOID()445   HANDLER_ATTRIBUTES bool RETURN_VOID() {
446     QuasiAtomic::ThreadFenceForConstructor();
447     JValue result;
448     return HandleReturn(result);
449   }
450 
RETURN()451   HANDLER_ATTRIBUTES bool RETURN() {
452     JValue result;
453     result.SetJ(0);
454     result.SetI(GetVReg(A()));
455     return HandleReturn(result);
456   }
457 
RETURN_WIDE()458   HANDLER_ATTRIBUTES bool RETURN_WIDE() {
459     JValue result;
460     result.SetJ(GetVRegLong(A()));
461     return HandleReturn(result);
462   }
463 
RETURN_OBJECT()464   HANDLER_ATTRIBUTES bool RETURN_OBJECT() {
465     JValue result;
466     Self()->AllowThreadSuspension();
467     if (!DoMonitorCheckOnExit<do_assignability_check>(Self(), &shadow_frame_)) {
468       return false;
469     }
470     const size_t ref_idx = A();
471     ObjPtr<mirror::Object> obj_result = GetVRegReference(ref_idx);
472     if (do_assignability_check && obj_result != nullptr) {
473       ObjPtr<mirror::Class> return_type = shadow_frame_.GetMethod()->ResolveReturnType();
474       // Re-load since it might have moved.
475       obj_result = GetVRegReference(ref_idx);
476       if (return_type == nullptr) {
477         // Return the pending exception.
478         return false;  // Pending exception.
479       }
480       if (!obj_result->VerifierInstanceOf(return_type)) {
481         CHECK_LE(Runtime::Current()->GetTargetSdkVersion(), 29u);
482         // This should never happen.
483         std::string temp1, temp2;
484         Self()->ThrowNewExceptionF("Ljava/lang/InternalError;",
485                                    "Returning '%s' that is not instance of return type '%s'",
486                                    obj_result->GetClass()->GetDescriptor(&temp1),
487                                    return_type->GetDescriptor(&temp2));
488         return false;  // Pending exception.
489       }
490     }
491     StackHandleScope<1> hs(Self());
492     MutableHandle<mirror::Object> h_result(hs.NewHandle(obj_result));
493     result.SetL(obj_result);
494     if (UNLIKELY(NeedsMethodExitEvent(Instrumentation()) &&
495                  !SendMethodExitEvents(Self(),
496                                        Instrumentation(),
497                                        shadow_frame_,
498                                        shadow_frame_.GetThisObject(Accessor().InsSize()),
499                                        shadow_frame_.GetMethod(),
500                                        inst_->GetDexPc(Insns()),
501                                        h_result))) {
502       DCHECK(Self()->IsExceptionPending());
503       // Do not raise exception event if it is caused by other instrumentation event.
504       shadow_frame_.SetSkipNextExceptionEvent(true);
505       return false;  // Pending exception.
506     }
507     // Re-load since it might have moved or been replaced during the MethodExitEvent.
508     result.SetL(h_result.Get());
509     ctx_->result = result;
510     ExitInterpreterLoop();
511     return false;
512   }
513 
CONST_4()514   HANDLER_ATTRIBUTES bool CONST_4() {
515     SetVReg(A(), B());
516     return true;
517   }
518 
CONST_16()519   HANDLER_ATTRIBUTES bool CONST_16() {
520     SetVReg(A(), B());
521     return true;
522   }
523 
CONST()524   HANDLER_ATTRIBUTES bool CONST() {
525     SetVReg(A(), B());
526     return true;
527   }
528 
CONST_HIGH16()529   HANDLER_ATTRIBUTES bool CONST_HIGH16() {
530     SetVReg(A(), static_cast<int32_t>(B() << 16));
531     return true;
532   }
533 
CONST_WIDE_16()534   HANDLER_ATTRIBUTES bool CONST_WIDE_16() {
535     SetVRegLong(A(), B());
536     return true;
537   }
538 
CONST_WIDE_32()539   HANDLER_ATTRIBUTES bool CONST_WIDE_32() {
540     SetVRegLong(A(), B());
541     return true;
542   }
543 
CONST_WIDE()544   HANDLER_ATTRIBUTES bool CONST_WIDE() {
545     SetVRegLong(A(), inst_->WideVRegB());
546     return true;
547   }
548 
CONST_WIDE_HIGH16()549   HANDLER_ATTRIBUTES bool CONST_WIDE_HIGH16() {
550     SetVRegLong(A(), static_cast<uint64_t>(B()) << 48);
551     return true;
552   }
553 
CONST_STRING()554   HANDLER_ATTRIBUTES bool CONST_STRING() {
555     return HandleConstString();
556   }
557 
CONST_STRING_JUMBO()558   HANDLER_ATTRIBUTES bool CONST_STRING_JUMBO() {
559     return HandleConstString();
560   }
561 
CONST_CLASS()562   HANDLER_ATTRIBUTES bool CONST_CLASS() {
563     ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
564                                                      shadow_frame_.GetMethod(),
565                                                      Self(),
566                                                      false,
567                                                      do_access_check);
568     if (UNLIKELY(c == nullptr)) {
569       return false;  // Pending exception.
570     }
571     SetVRegReference(A(), c);
572     return true;
573   }
574 
CONST_METHOD_HANDLE()575   HANDLER_ATTRIBUTES bool CONST_METHOD_HANDLE() {
576     ClassLinker* cl = Runtime::Current()->GetClassLinker();
577     ObjPtr<mirror::MethodHandle> mh = cl->ResolveMethodHandle(Self(),
578                                                               B(),
579                                                               shadow_frame_.GetMethod());
580     if (UNLIKELY(mh == nullptr)) {
581       return false;  // Pending exception.
582     }
583     SetVRegReference(A(), mh);
584     return true;
585   }
586 
CONST_METHOD_TYPE()587   HANDLER_ATTRIBUTES bool CONST_METHOD_TYPE() {
588     ClassLinker* cl = Runtime::Current()->GetClassLinker();
589     ObjPtr<mirror::MethodType> mt = cl->ResolveMethodType(Self(),
590                                                           dex::ProtoIndex(B()),
591                                                           shadow_frame_.GetMethod());
592     if (UNLIKELY(mt == nullptr)) {
593       return false;  // Pending exception.
594     }
595     SetVRegReference(A(), mt);
596     return true;
597   }
598 
MONITOR_ENTER()599   HANDLER_ATTRIBUTES bool MONITOR_ENTER() {
600     if (UNLIKELY(Self()->ObserveAsyncException())) {
601       return false;  // Pending exception.
602     }
603     ObjPtr<mirror::Object> obj = GetVRegReference(A());
604     if (UNLIKELY(obj == nullptr)) {
605       ThrowNullPointerExceptionFromInterpreter();
606       return false;  // Pending exception.
607     }
608     DoMonitorEnter<do_assignability_check>(Self(), &shadow_frame_, obj);
609     return !Self()->IsExceptionPending();
610   }
611 
MONITOR_EXIT()612   HANDLER_ATTRIBUTES bool MONITOR_EXIT() {
613     if (UNLIKELY(Self()->ObserveAsyncException())) {
614       return false;  // Pending exception.
615     }
616     ObjPtr<mirror::Object> obj = GetVRegReference(A());
617     if (UNLIKELY(obj == nullptr)) {
618       ThrowNullPointerExceptionFromInterpreter();
619       return false;  // Pending exception.
620     }
621     DoMonitorExit<do_assignability_check>(Self(), &shadow_frame_, obj);
622     return !Self()->IsExceptionPending();
623   }
624 
CHECK_CAST()625   HANDLER_ATTRIBUTES bool CHECK_CAST() {
626     ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
627                                                      shadow_frame_.GetMethod(),
628                                                      Self(),
629                                                      false,
630                                                      do_access_check);
631     if (UNLIKELY(c == nullptr)) {
632       return false;  // Pending exception.
633     }
634     ObjPtr<mirror::Object> obj = GetVRegReference(A());
635     if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
636       ThrowClassCastException(c, obj->GetClass());
637       return false;  // Pending exception.
638     }
639     return true;
640   }
641 
INSTANCE_OF()642   HANDLER_ATTRIBUTES bool INSTANCE_OF() {
643     ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(C()),
644                                                      shadow_frame_.GetMethod(),
645                                                      Self(),
646                                                      false,
647                                                      do_access_check);
648     if (UNLIKELY(c == nullptr)) {
649       return false;  // Pending exception.
650     }
651     ObjPtr<mirror::Object> obj = GetVRegReference(B());
652     SetVReg(A(), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
653     return true;
654   }
655 
ARRAY_LENGTH()656   HANDLER_ATTRIBUTES bool ARRAY_LENGTH() {
657     ObjPtr<mirror::Object> array = GetVRegReference(B());
658     if (UNLIKELY(array == nullptr)) {
659       ThrowNullPointerExceptionFromInterpreter();
660       return false;  // Pending exception.
661     }
662     SetVReg(A(), array->AsArray()->GetLength());
663     return true;
664   }
665 
NEW_INSTANCE()666   HANDLER_ATTRIBUTES bool NEW_INSTANCE() {
667     ObjPtr<mirror::Object> obj = nullptr;
668     ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
669                                                      shadow_frame_.GetMethod(),
670                                                      Self(),
671                                                      false,
672                                                      do_access_check);
673     if (LIKELY(c != nullptr)) {
674       // Don't allow finalizable objects to be allocated during a transaction since these can't
675       // be finalized without a started runtime.
676       if (transaction_active && c->IsFinalizable()) {
677         AbortTransactionF(Self(),
678                           "Allocating finalizable object in transaction: %s",
679                           c->PrettyDescriptor().c_str());
680         return false;  // Pending exception.
681       }
682       gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
683       if (UNLIKELY(c->IsStringClass())) {
684         obj = mirror::String::AllocEmptyString(Self(), allocator_type);
685       } else {
686         obj = AllocObjectFromCode(c, Self(), allocator_type);
687       }
688     }
689     if (UNLIKELY(obj == nullptr)) {
690       return false;  // Pending exception.
691     }
692     obj->GetClass()->AssertInitializedOrInitializingInThread(Self());
693     SetVRegReference(A(), obj);
694     return true;
695   }
696 
NEW_ARRAY()697   HANDLER_ATTRIBUTES bool NEW_ARRAY() {
698     int32_t length = GetVReg(B());
699     ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check>(
700         dex::TypeIndex(C()),
701         length,
702         shadow_frame_.GetMethod(),
703         Self(),
704         Runtime::Current()->GetHeap()->GetCurrentAllocator());
705     if (UNLIKELY(obj == nullptr)) {
706       return false;  // Pending exception.
707     }
708     SetVRegReference(A(), obj);
709     return true;
710   }
711 
FILLED_NEW_ARRAY()712   HANDLER_ATTRIBUTES bool FILLED_NEW_ARRAY() {
713     return DoFilledNewArray<false, do_access_check, transaction_active>(
714         inst_, shadow_frame_, Self(), ResultRegister());
715   }
716 
FILLED_NEW_ARRAY_RANGE()717   HANDLER_ATTRIBUTES bool FILLED_NEW_ARRAY_RANGE() {
718     return DoFilledNewArray<true, do_access_check, transaction_active>(
719         inst_, shadow_frame_, Self(), ResultRegister());
720   }
721 
FILL_ARRAY_DATA()722   HANDLER_ATTRIBUTES bool FILL_ARRAY_DATA() {
723     const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst_) + B();
724     const Instruction::ArrayDataPayload* payload =
725         reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
726     ObjPtr<mirror::Object> obj = GetVRegReference(A());
727     if (!FillArrayData(obj, payload)) {
728       return false;  // Pending exception.
729     }
730     if (transaction_active) {
731       RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
732     }
733     return true;
734   }
735 
THROW()736   HANDLER_ATTRIBUTES bool THROW() {
737     if (UNLIKELY(Self()->ObserveAsyncException())) {
738       return false;  // Pending exception.
739     }
740     ObjPtr<mirror::Object> exception = GetVRegReference(A());
741     if (UNLIKELY(exception == nullptr)) {
742       ThrowNullPointerException();
743     } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
744       // This should never happen.
745       std::string temp;
746       Self()->ThrowNewExceptionF("Ljava/lang/InternalError;",
747                                  "Throwing '%s' that is not instance of Throwable",
748                                  exception->GetClass()->GetDescriptor(&temp));
749     } else {
750       Self()->SetException(exception->AsThrowable());
751     }
752     return false;  // Pending exception.
753   }
754 
GOTO()755   HANDLER_ATTRIBUTES bool GOTO() {
756     return HandleBranch(A());
757   }
758 
GOTO_16()759   HANDLER_ATTRIBUTES bool GOTO_16() {
760     return HandleBranch(A());
761   }
762 
GOTO_32()763   HANDLER_ATTRIBUTES bool GOTO_32() {
764     return HandleBranch(A());
765   }
766 
PACKED_SWITCH()767   HANDLER_ATTRIBUTES bool PACKED_SWITCH() {
768     return HandleBranch(DoPackedSwitch(inst_, shadow_frame_, inst_data_));
769   }
770 
SPARSE_SWITCH()771   HANDLER_ATTRIBUTES bool SPARSE_SWITCH() {
772     return HandleBranch(DoSparseSwitch(inst_, shadow_frame_, inst_data_));
773   }
774 
CMPL_FLOAT()775   HANDLER_ATTRIBUTES bool CMPL_FLOAT() {
776     return HandleCmpl<float>(GetVRegFloat(B()), GetVRegFloat(C()));
777   }
778 
CMPG_FLOAT()779   HANDLER_ATTRIBUTES bool CMPG_FLOAT() {
780     return HandleCmpg<float>(GetVRegFloat(B()), GetVRegFloat(C()));
781   }
782 
CMPL_DOUBLE()783   HANDLER_ATTRIBUTES bool CMPL_DOUBLE() {
784     return HandleCmpl<double>(GetVRegDouble(B()), GetVRegDouble(C()));
785   }
786 
CMPG_DOUBLE()787   HANDLER_ATTRIBUTES bool CMPG_DOUBLE() {
788     return HandleCmpg<double>(GetVRegDouble(B()), GetVRegDouble(C()));
789   }
790 
CMP_LONG()791   HANDLER_ATTRIBUTES bool CMP_LONG() {
792     return HandleCmpl<int64_t>(GetVRegLong(B()), GetVRegLong(C()));
793   }
794 
IF_EQ()795   HANDLER_ATTRIBUTES bool IF_EQ() {
796     return HandleIf(GetVReg(A()) == GetVReg(B()), C());
797   }
798 
IF_NE()799   HANDLER_ATTRIBUTES bool IF_NE() {
800     return HandleIf(GetVReg(A()) != GetVReg(B()), C());
801   }
802 
IF_LT()803   HANDLER_ATTRIBUTES bool IF_LT() {
804     return HandleIf(GetVReg(A()) < GetVReg(B()), C());
805   }
806 
IF_GE()807   HANDLER_ATTRIBUTES bool IF_GE() {
808     return HandleIf(GetVReg(A()) >= GetVReg(B()), C());
809   }
810 
IF_GT()811   HANDLER_ATTRIBUTES bool IF_GT() {
812     return HandleIf(GetVReg(A()) > GetVReg(B()), C());
813   }
814 
IF_LE()815   HANDLER_ATTRIBUTES bool IF_LE() {
816     return HandleIf(GetVReg(A()) <= GetVReg(B()), C());
817   }
818 
IF_EQZ()819   HANDLER_ATTRIBUTES bool IF_EQZ() {
820     return HandleIf(GetVReg(A()) == 0, B());
821   }
822 
IF_NEZ()823   HANDLER_ATTRIBUTES bool IF_NEZ() {
824     return HandleIf(GetVReg(A()) != 0, B());
825   }
826 
IF_LTZ()827   HANDLER_ATTRIBUTES bool IF_LTZ() {
828     return HandleIf(GetVReg(A()) < 0, B());
829   }
830 
IF_GEZ()831   HANDLER_ATTRIBUTES bool IF_GEZ() {
832     return HandleIf(GetVReg(A()) >= 0, B());
833   }
834 
IF_GTZ()835   HANDLER_ATTRIBUTES bool IF_GTZ() {
836     return HandleIf(GetVReg(A()) > 0, B());
837   }
838 
IF_LEZ()839   HANDLER_ATTRIBUTES bool IF_LEZ() {
840     return HandleIf(GetVReg(A()) <= 0, B());
841   }
842 
AGET_BOOLEAN()843   HANDLER_ATTRIBUTES bool AGET_BOOLEAN() {
844     return HandleAGet<mirror::BooleanArray>(&InstructionHandler::SetVReg);
845   }
846 
AGET_BYTE()847   HANDLER_ATTRIBUTES bool AGET_BYTE() {
848     return HandleAGet<mirror::ByteArray>(&InstructionHandler::SetVReg);
849   }
850 
AGET_CHAR()851   HANDLER_ATTRIBUTES bool AGET_CHAR() {
852     return HandleAGet<mirror::CharArray>(&InstructionHandler::SetVReg);
853   }
854 
AGET_SHORT()855   HANDLER_ATTRIBUTES bool AGET_SHORT() {
856     return HandleAGet<mirror::ShortArray>(&InstructionHandler::SetVReg);
857   }
858 
AGET()859   HANDLER_ATTRIBUTES bool AGET() {
860     return HandleAGet<mirror::IntArray>(&InstructionHandler::SetVReg);
861   }
862 
AGET_WIDE()863   HANDLER_ATTRIBUTES bool AGET_WIDE() {
864     return HandleAGet<mirror::LongArray>(&InstructionHandler::SetVRegLong);
865   }
866 
AGET_OBJECT()867   HANDLER_ATTRIBUTES bool AGET_OBJECT() {
868     return HandleAGet<mirror::ObjectArray<mirror::Object>>(&InstructionHandler::SetVRegReference);
869   }
870 
APUT_BOOLEAN()871   HANDLER_ATTRIBUTES bool APUT_BOOLEAN() {
872     return HandleAPut<mirror::BooleanArray>(GetVReg(A()));
873   }
874 
APUT_BYTE()875   HANDLER_ATTRIBUTES bool APUT_BYTE() {
876     return HandleAPut<mirror::ByteArray>(GetVReg(A()));
877   }
878 
APUT_CHAR()879   HANDLER_ATTRIBUTES bool APUT_CHAR() {
880     return HandleAPut<mirror::CharArray>(GetVReg(A()));
881   }
882 
APUT_SHORT()883   HANDLER_ATTRIBUTES bool APUT_SHORT() {
884     return HandleAPut<mirror::ShortArray>(GetVReg(A()));
885   }
886 
APUT()887   HANDLER_ATTRIBUTES bool APUT() {
888     return HandleAPut<mirror::IntArray>(GetVReg(A()));
889   }
890 
APUT_WIDE()891   HANDLER_ATTRIBUTES bool APUT_WIDE() {
892     return HandleAPut<mirror::LongArray>(GetVRegLong(A()));
893   }
894 
APUT_OBJECT()895   HANDLER_ATTRIBUTES bool APUT_OBJECT() {
896     ObjPtr<mirror::Object> a = GetVRegReference(B());
897     if (UNLIKELY(a == nullptr)) {
898       ThrowNullPointerExceptionFromInterpreter();
899       return false;  // Pending exception.
900     }
901     int32_t index = GetVReg(C());
902     ObjPtr<mirror::Object> val = GetVRegReference(A());
903     ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
904     if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
905       if (transaction_active &&
906           (!CheckWriteConstraint(Self(), array) || !CheckWriteValueConstraint(Self(), val))) {
907         return false;
908       }
909       array->SetWithoutChecks<transaction_active>(index, val);
910     } else {
911       return false;  // Pending exception.
912     }
913     return true;
914   }
915 
IGET_BOOLEAN()916   HANDLER_ATTRIBUTES bool IGET_BOOLEAN() {
917     return HandleGet<InstancePrimitiveRead, Primitive::kPrimBoolean>();
918   }
919 
IGET_BYTE()920   HANDLER_ATTRIBUTES bool IGET_BYTE() {
921     return HandleGet<InstancePrimitiveRead, Primitive::kPrimByte>();
922   }
923 
IGET_CHAR()924   HANDLER_ATTRIBUTES bool IGET_CHAR() {
925     return HandleGet<InstancePrimitiveRead, Primitive::kPrimChar>();
926   }
927 
IGET_SHORT()928   HANDLER_ATTRIBUTES bool IGET_SHORT() {
929     return HandleGet<InstancePrimitiveRead, Primitive::kPrimShort>();
930   }
931 
IGET()932   HANDLER_ATTRIBUTES bool IGET() {
933     return HandleGet<InstancePrimitiveRead, Primitive::kPrimInt>();
934   }
935 
IGET_WIDE()936   HANDLER_ATTRIBUTES bool IGET_WIDE() {
937     return HandleGet<InstancePrimitiveRead, Primitive::kPrimLong>();
938   }
939 
IGET_OBJECT()940   HANDLER_ATTRIBUTES bool IGET_OBJECT() {
941     return HandleGet<InstanceObjectRead, Primitive::kPrimNot>();
942   }
943 
SGET_BOOLEAN()944   HANDLER_ATTRIBUTES bool SGET_BOOLEAN() {
945     return HandleGet<StaticPrimitiveRead, Primitive::kPrimBoolean>();
946   }
947 
SGET_BYTE()948   HANDLER_ATTRIBUTES bool SGET_BYTE() {
949     return HandleGet<StaticPrimitiveRead, Primitive::kPrimByte>();
950   }
951 
SGET_CHAR()952   HANDLER_ATTRIBUTES bool SGET_CHAR() {
953     return HandleGet<StaticPrimitiveRead, Primitive::kPrimChar>();
954   }
955 
SGET_SHORT()956   HANDLER_ATTRIBUTES bool SGET_SHORT() {
957     return HandleGet<StaticPrimitiveRead, Primitive::kPrimShort>();
958   }
959 
SGET()960   HANDLER_ATTRIBUTES bool SGET() {
961     return HandleGet<StaticPrimitiveRead, Primitive::kPrimInt>();
962   }
963 
SGET_WIDE()964   HANDLER_ATTRIBUTES bool SGET_WIDE() {
965     return HandleGet<StaticPrimitiveRead, Primitive::kPrimLong>();
966   }
967 
SGET_OBJECT()968   HANDLER_ATTRIBUTES bool SGET_OBJECT() {
969     return HandleGet<StaticObjectRead, Primitive::kPrimNot>();
970   }
971 
IPUT_BOOLEAN()972   HANDLER_ATTRIBUTES bool IPUT_BOOLEAN() {
973     return HandlePut<InstancePrimitiveWrite, Primitive::kPrimBoolean>();
974   }
975 
IPUT_BYTE()976   HANDLER_ATTRIBUTES bool IPUT_BYTE() {
977     return HandlePut<InstancePrimitiveWrite, Primitive::kPrimByte>();
978   }
979 
IPUT_CHAR()980   HANDLER_ATTRIBUTES bool IPUT_CHAR() {
981     return HandlePut<InstancePrimitiveWrite, Primitive::kPrimChar>();
982   }
983 
IPUT_SHORT()984   HANDLER_ATTRIBUTES bool IPUT_SHORT() {
985     return HandlePut<InstancePrimitiveWrite, Primitive::kPrimShort>();
986   }
987 
IPUT()988   HANDLER_ATTRIBUTES bool IPUT() {
989     return HandlePut<InstancePrimitiveWrite, Primitive::kPrimInt>();
990   }
991 
IPUT_WIDE()992   HANDLER_ATTRIBUTES bool IPUT_WIDE() {
993     return HandlePut<InstancePrimitiveWrite, Primitive::kPrimLong>();
994   }
995 
IPUT_OBJECT()996   HANDLER_ATTRIBUTES bool IPUT_OBJECT() {
997     return HandlePut<InstanceObjectWrite, Primitive::kPrimNot>();
998   }
999 
SPUT_BOOLEAN()1000   HANDLER_ATTRIBUTES bool SPUT_BOOLEAN() {
1001     return HandlePut<StaticPrimitiveWrite, Primitive::kPrimBoolean>();
1002   }
1003 
SPUT_BYTE()1004   HANDLER_ATTRIBUTES bool SPUT_BYTE() {
1005     return HandlePut<StaticPrimitiveWrite, Primitive::kPrimByte>();
1006   }
1007 
SPUT_CHAR()1008   HANDLER_ATTRIBUTES bool SPUT_CHAR() {
1009     return HandlePut<StaticPrimitiveWrite, Primitive::kPrimChar>();
1010   }
1011 
SPUT_SHORT()1012   HANDLER_ATTRIBUTES bool SPUT_SHORT() {
1013     return HandlePut<StaticPrimitiveWrite, Primitive::kPrimShort>();
1014   }
1015 
SPUT()1016   HANDLER_ATTRIBUTES bool SPUT() {
1017     return HandlePut<StaticPrimitiveWrite, Primitive::kPrimInt>();
1018   }
1019 
SPUT_WIDE()1020   HANDLER_ATTRIBUTES bool SPUT_WIDE() {
1021     return HandlePut<StaticPrimitiveWrite, Primitive::kPrimLong>();
1022   }
1023 
SPUT_OBJECT()1024   HANDLER_ATTRIBUTES bool SPUT_OBJECT() {
1025     return HandlePut<StaticObjectWrite, Primitive::kPrimNot>();
1026   }
1027 
INVOKE_VIRTUAL()1028   HANDLER_ATTRIBUTES bool INVOKE_VIRTUAL() {
1029     return HandleInvoke<kVirtual, /*is_range=*/ false>();
1030   }
1031 
INVOKE_VIRTUAL_RANGE()1032   HANDLER_ATTRIBUTES bool INVOKE_VIRTUAL_RANGE() {
1033     return HandleInvoke<kVirtual, /*is_range=*/ true>();
1034   }
1035 
INVOKE_SUPER()1036   HANDLER_ATTRIBUTES bool INVOKE_SUPER() {
1037     return HandleInvoke<kSuper, /*is_range=*/ false>();
1038   }
1039 
INVOKE_SUPER_RANGE()1040   HANDLER_ATTRIBUTES bool INVOKE_SUPER_RANGE() {
1041     return HandleInvoke<kSuper, /*is_range=*/ true>();
1042   }
1043 
INVOKE_DIRECT()1044   HANDLER_ATTRIBUTES bool INVOKE_DIRECT() {
1045     return HandleInvoke<kDirect, /*is_range=*/ false>();
1046   }
1047 
INVOKE_DIRECT_RANGE()1048   HANDLER_ATTRIBUTES bool INVOKE_DIRECT_RANGE() {
1049     return HandleInvoke<kDirect, /*is_range=*/ true>();
1050   }
1051 
INVOKE_INTERFACE()1052   HANDLER_ATTRIBUTES bool INVOKE_INTERFACE() {
1053     return HandleInvoke<kInterface, /*is_range=*/ false>();
1054   }
1055 
INVOKE_INTERFACE_RANGE()1056   HANDLER_ATTRIBUTES bool INVOKE_INTERFACE_RANGE() {
1057     return HandleInvoke<kInterface, /*is_range=*/ true>();
1058   }
1059 
INVOKE_STATIC()1060   HANDLER_ATTRIBUTES bool INVOKE_STATIC() {
1061     return HandleInvoke<kStatic, /*is_range=*/ false>();
1062   }
1063 
INVOKE_STATIC_RANGE()1064   HANDLER_ATTRIBUTES bool INVOKE_STATIC_RANGE() {
1065     return HandleInvoke<kStatic, /*is_range=*/ true>();
1066   }
1067 
INVOKE_POLYMORPHIC()1068   HANDLER_ATTRIBUTES bool INVOKE_POLYMORPHIC() {
1069     DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1070     bool success = DoInvokePolymorphic</* is_range= */ false>(
1071         Self(), shadow_frame_, inst_, inst_data_, ResultRegister());
1072     return PossiblyHandlePendingExceptionOnInvoke(!success);
1073   }
1074 
INVOKE_POLYMORPHIC_RANGE()1075   HANDLER_ATTRIBUTES bool INVOKE_POLYMORPHIC_RANGE() {
1076     DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1077     bool success = DoInvokePolymorphic</* is_range= */ true>(
1078         Self(), shadow_frame_, inst_, inst_data_, ResultRegister());
1079     return PossiblyHandlePendingExceptionOnInvoke(!success);
1080   }
1081 
INVOKE_CUSTOM()1082   HANDLER_ATTRIBUTES bool INVOKE_CUSTOM() {
1083     DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1084     bool success = DoInvokeCustom</* is_range= */ false>(
1085         Self(), shadow_frame_, inst_, inst_data_, ResultRegister());
1086     return PossiblyHandlePendingExceptionOnInvoke(!success);
1087   }
1088 
INVOKE_CUSTOM_RANGE()1089   HANDLER_ATTRIBUTES bool INVOKE_CUSTOM_RANGE() {
1090     DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1091     bool success = DoInvokeCustom</* is_range= */ true>(
1092         Self(), shadow_frame_, inst_, inst_data_, ResultRegister());
1093     return PossiblyHandlePendingExceptionOnInvoke(!success);
1094   }
1095 
NEG_INT()1096   HANDLER_ATTRIBUTES bool NEG_INT() {
1097     SetVReg(A(), -GetVReg(B()));
1098     return true;
1099   }
1100 
NOT_INT()1101   HANDLER_ATTRIBUTES bool NOT_INT() {
1102     SetVReg(A(), ~GetVReg(B()));
1103     return true;
1104   }
1105 
NEG_LONG()1106   HANDLER_ATTRIBUTES bool NEG_LONG() {
1107     SetVRegLong(A(), -GetVRegLong(B()));
1108     return true;
1109   }
1110 
NOT_LONG()1111   HANDLER_ATTRIBUTES bool NOT_LONG() {
1112     SetVRegLong(A(), ~GetVRegLong(B()));
1113     return true;
1114   }
1115 
NEG_FLOAT()1116   HANDLER_ATTRIBUTES bool NEG_FLOAT() {
1117     SetVRegFloat(A(), -GetVRegFloat(B()));
1118     return true;
1119   }
1120 
NEG_DOUBLE()1121   HANDLER_ATTRIBUTES bool NEG_DOUBLE() {
1122     SetVRegDouble(A(), -GetVRegDouble(B()));
1123     return true;
1124   }
1125 
INT_TO_LONG()1126   HANDLER_ATTRIBUTES bool INT_TO_LONG() {
1127     SetVRegLong(A(), GetVReg(B()));
1128     return true;
1129   }
1130 
INT_TO_FLOAT()1131   HANDLER_ATTRIBUTES bool INT_TO_FLOAT() {
1132     SetVRegFloat(A(), GetVReg(B()));
1133     return true;
1134   }
1135 
INT_TO_DOUBLE()1136   HANDLER_ATTRIBUTES bool INT_TO_DOUBLE() {
1137     SetVRegDouble(A(), GetVReg(B()));
1138     return true;
1139   }
1140 
LONG_TO_INT()1141   HANDLER_ATTRIBUTES bool LONG_TO_INT() {
1142     SetVReg(A(), GetVRegLong(B()));
1143     return true;
1144   }
1145 
LONG_TO_FLOAT()1146   HANDLER_ATTRIBUTES bool LONG_TO_FLOAT() {
1147     SetVRegFloat(A(), GetVRegLong(B()));
1148     return true;
1149   }
1150 
LONG_TO_DOUBLE()1151   HANDLER_ATTRIBUTES bool LONG_TO_DOUBLE() {
1152     SetVRegDouble(A(), GetVRegLong(B()));
1153     return true;
1154   }
1155 
FLOAT_TO_INT()1156   HANDLER_ATTRIBUTES bool FLOAT_TO_INT() {
1157     SetVReg(A(), art_float_to_integral<int32_t, float>(GetVRegFloat(B())));
1158     return true;
1159   }
1160 
FLOAT_TO_LONG()1161   HANDLER_ATTRIBUTES bool FLOAT_TO_LONG() {
1162     SetVRegLong(A(), art_float_to_integral<int64_t, float>(GetVRegFloat(B())));
1163     return true;
1164   }
1165 
FLOAT_TO_DOUBLE()1166   HANDLER_ATTRIBUTES bool FLOAT_TO_DOUBLE() {
1167     SetVRegDouble(A(), GetVRegFloat(B()));
1168     return true;
1169   }
1170 
DOUBLE_TO_INT()1171   HANDLER_ATTRIBUTES bool DOUBLE_TO_INT() {
1172     SetVReg(A(), art_float_to_integral<int32_t, double>(GetVRegDouble(B())));
1173     return true;
1174   }
1175 
DOUBLE_TO_LONG()1176   HANDLER_ATTRIBUTES bool DOUBLE_TO_LONG() {
1177     SetVRegLong(A(), art_float_to_integral<int64_t, double>(GetVRegDouble(B())));
1178     return true;
1179   }
1180 
DOUBLE_TO_FLOAT()1181   HANDLER_ATTRIBUTES bool DOUBLE_TO_FLOAT() {
1182     SetVRegFloat(A(), GetVRegDouble(B()));
1183     return true;
1184   }
1185 
INT_TO_BYTE()1186   HANDLER_ATTRIBUTES bool INT_TO_BYTE() {
1187     SetVReg(A(), static_cast<int8_t>(GetVReg(B())));
1188     return true;
1189   }
1190 
INT_TO_CHAR()1191   HANDLER_ATTRIBUTES bool INT_TO_CHAR() {
1192     SetVReg(A(), static_cast<uint16_t>(GetVReg(B())));
1193     return true;
1194   }
1195 
INT_TO_SHORT()1196   HANDLER_ATTRIBUTES bool INT_TO_SHORT() {
1197     SetVReg(A(), static_cast<int16_t>(GetVReg(B())));
1198     return true;
1199   }
1200 
ADD_INT()1201   HANDLER_ATTRIBUTES bool ADD_INT() {
1202     SetVReg(A(), SafeAdd(GetVReg(B()), GetVReg(C())));
1203     return true;
1204   }
1205 
SUB_INT()1206   HANDLER_ATTRIBUTES bool SUB_INT() {
1207     SetVReg(A(), SafeSub(GetVReg(B()), GetVReg(C())));
1208     return true;
1209   }
1210 
MUL_INT()1211   HANDLER_ATTRIBUTES bool MUL_INT() {
1212     SetVReg(A(), SafeMul(GetVReg(B()), GetVReg(C())));
1213     return true;
1214   }
1215 
DIV_INT()1216   HANDLER_ATTRIBUTES bool DIV_INT() {
1217     return DoIntDivide(shadow_frame_, A(), GetVReg(B()), GetVReg(C()));
1218   }
1219 
REM_INT()1220   HANDLER_ATTRIBUTES bool REM_INT() {
1221     return DoIntRemainder(shadow_frame_, A(), GetVReg(B()), GetVReg(C()));
1222   }
1223 
SHL_INT()1224   HANDLER_ATTRIBUTES bool SHL_INT() {
1225     SetVReg(A(), GetVReg(B()) << (GetVReg(C()) & 0x1f));
1226     return true;
1227   }
1228 
SHR_INT()1229   HANDLER_ATTRIBUTES bool SHR_INT() {
1230     SetVReg(A(), GetVReg(B()) >> (GetVReg(C()) & 0x1f));
1231     return true;
1232   }
1233 
USHR_INT()1234   HANDLER_ATTRIBUTES bool USHR_INT() {
1235     SetVReg(A(), static_cast<uint32_t>(GetVReg(B())) >> (GetVReg(C()) & 0x1f));
1236     return true;
1237   }
1238 
AND_INT()1239   HANDLER_ATTRIBUTES bool AND_INT() {
1240     SetVReg(A(), GetVReg(B()) & GetVReg(C()));
1241     return true;
1242   }
1243 
OR_INT()1244   HANDLER_ATTRIBUTES bool OR_INT() {
1245     SetVReg(A(), GetVReg(B()) | GetVReg(C()));
1246     return true;
1247   }
1248 
XOR_INT()1249   HANDLER_ATTRIBUTES bool XOR_INT() {
1250     SetVReg(A(), GetVReg(B()) ^ GetVReg(C()));
1251     return true;
1252   }
1253 
ADD_LONG()1254   HANDLER_ATTRIBUTES bool ADD_LONG() {
1255     SetVRegLong(A(), SafeAdd(GetVRegLong(B()), GetVRegLong(C())));
1256     return true;
1257   }
1258 
SUB_LONG()1259   HANDLER_ATTRIBUTES bool SUB_LONG() {
1260     SetVRegLong(A(), SafeSub(GetVRegLong(B()), GetVRegLong(C())));
1261     return true;
1262   }
1263 
MUL_LONG()1264   HANDLER_ATTRIBUTES bool MUL_LONG() {
1265     SetVRegLong(A(), SafeMul(GetVRegLong(B()), GetVRegLong(C())));
1266     return true;
1267   }
1268 
DIV_LONG()1269   HANDLER_ATTRIBUTES bool DIV_LONG() {
1270     return DoLongDivide(shadow_frame_, A(), GetVRegLong(B()), GetVRegLong(C()));
1271   }
1272 
REM_LONG()1273   HANDLER_ATTRIBUTES bool REM_LONG() {
1274     return DoLongRemainder(shadow_frame_, A(), GetVRegLong(B()), GetVRegLong(C()));
1275   }
1276 
AND_LONG()1277   HANDLER_ATTRIBUTES bool AND_LONG() {
1278     SetVRegLong(A(), GetVRegLong(B()) & GetVRegLong(C()));
1279     return true;
1280   }
1281 
OR_LONG()1282   HANDLER_ATTRIBUTES bool OR_LONG() {
1283     SetVRegLong(A(), GetVRegLong(B()) | GetVRegLong(C()));
1284     return true;
1285   }
1286 
XOR_LONG()1287   HANDLER_ATTRIBUTES bool XOR_LONG() {
1288     SetVRegLong(A(), GetVRegLong(B()) ^ GetVRegLong(C()));
1289     return true;
1290   }
1291 
SHL_LONG()1292   HANDLER_ATTRIBUTES bool SHL_LONG() {
1293     SetVRegLong(A(), GetVRegLong(B()) << (GetVReg(C()) & 0x3f));
1294     return true;
1295   }
1296 
SHR_LONG()1297   HANDLER_ATTRIBUTES bool SHR_LONG() {
1298     SetVRegLong(A(), GetVRegLong(B()) >> (GetVReg(C()) & 0x3f));
1299     return true;
1300   }
1301 
USHR_LONG()1302   HANDLER_ATTRIBUTES bool USHR_LONG() {
1303     SetVRegLong(A(), static_cast<uint64_t>(GetVRegLong(B())) >> (GetVReg(C()) & 0x3f));
1304     return true;
1305   }
1306 
ADD_FLOAT()1307   HANDLER_ATTRIBUTES bool ADD_FLOAT() {
1308     SetVRegFloat(A(), GetVRegFloat(B()) + GetVRegFloat(C()));
1309     return true;
1310   }
1311 
SUB_FLOAT()1312   HANDLER_ATTRIBUTES bool SUB_FLOAT() {
1313     SetVRegFloat(A(), GetVRegFloat(B()) - GetVRegFloat(C()));
1314     return true;
1315   }
1316 
MUL_FLOAT()1317   HANDLER_ATTRIBUTES bool MUL_FLOAT() {
1318     SetVRegFloat(A(), GetVRegFloat(B()) * GetVRegFloat(C()));
1319     return true;
1320   }
1321 
DIV_FLOAT()1322   HANDLER_ATTRIBUTES bool DIV_FLOAT() {
1323     SetVRegFloat(A(), GetVRegFloat(B()) / GetVRegFloat(C()));
1324     return true;
1325   }
1326 
REM_FLOAT()1327   HANDLER_ATTRIBUTES bool REM_FLOAT() {
1328     SetVRegFloat(A(), fmodf(GetVRegFloat(B()), GetVRegFloat(C())));
1329     return true;
1330   }
1331 
ADD_DOUBLE()1332   HANDLER_ATTRIBUTES bool ADD_DOUBLE() {
1333     SetVRegDouble(A(), GetVRegDouble(B()) + GetVRegDouble(C()));
1334     return true;
1335   }
1336 
SUB_DOUBLE()1337   HANDLER_ATTRIBUTES bool SUB_DOUBLE() {
1338     SetVRegDouble(A(), GetVRegDouble(B()) - GetVRegDouble(C()));
1339     return true;
1340   }
1341 
MUL_DOUBLE()1342   HANDLER_ATTRIBUTES bool MUL_DOUBLE() {
1343     SetVRegDouble(A(), GetVRegDouble(B()) * GetVRegDouble(C()));
1344     return true;
1345   }
1346 
DIV_DOUBLE()1347   HANDLER_ATTRIBUTES bool DIV_DOUBLE() {
1348     SetVRegDouble(A(), GetVRegDouble(B()) / GetVRegDouble(C()));
1349     return true;
1350   }
1351 
REM_DOUBLE()1352   HANDLER_ATTRIBUTES bool REM_DOUBLE() {
1353     SetVRegDouble(A(), fmod(GetVRegDouble(B()), GetVRegDouble(C())));
1354     return true;
1355   }
1356 
ADD_INT_2ADDR()1357   HANDLER_ATTRIBUTES bool ADD_INT_2ADDR() {
1358     SetVReg(A(), SafeAdd(GetVReg(A()), GetVReg(B())));
1359     return true;
1360   }
1361 
SUB_INT_2ADDR()1362   HANDLER_ATTRIBUTES bool SUB_INT_2ADDR() {
1363     SetVReg(A(), SafeSub(GetVReg(A()), GetVReg(B())));
1364     return true;
1365   }
1366 
MUL_INT_2ADDR()1367   HANDLER_ATTRIBUTES bool MUL_INT_2ADDR() {
1368     SetVReg(A(), SafeMul(GetVReg(A()), GetVReg(B())));
1369     return true;
1370   }
1371 
DIV_INT_2ADDR()1372   HANDLER_ATTRIBUTES bool DIV_INT_2ADDR() {
1373     return DoIntDivide(shadow_frame_, A(), GetVReg(A()), GetVReg(B()));
1374   }
1375 
REM_INT_2ADDR()1376   HANDLER_ATTRIBUTES bool REM_INT_2ADDR() {
1377     return DoIntRemainder(shadow_frame_, A(), GetVReg(A()), GetVReg(B()));
1378   }
1379 
SHL_INT_2ADDR()1380   HANDLER_ATTRIBUTES bool SHL_INT_2ADDR() {
1381     SetVReg(A(), GetVReg(A()) << (GetVReg(B()) & 0x1f));
1382     return true;
1383   }
1384 
SHR_INT_2ADDR()1385   HANDLER_ATTRIBUTES bool SHR_INT_2ADDR() {
1386     SetVReg(A(), GetVReg(A()) >> (GetVReg(B()) & 0x1f));
1387     return true;
1388   }
1389 
USHR_INT_2ADDR()1390   HANDLER_ATTRIBUTES bool USHR_INT_2ADDR() {
1391     SetVReg(A(), static_cast<uint32_t>(GetVReg(A())) >> (GetVReg(B()) & 0x1f));
1392     return true;
1393   }
1394 
AND_INT_2ADDR()1395   HANDLER_ATTRIBUTES bool AND_INT_2ADDR() {
1396     SetVReg(A(), GetVReg(A()) & GetVReg(B()));
1397     return true;
1398   }
1399 
OR_INT_2ADDR()1400   HANDLER_ATTRIBUTES bool OR_INT_2ADDR() {
1401     SetVReg(A(), GetVReg(A()) | GetVReg(B()));
1402     return true;
1403   }
1404 
XOR_INT_2ADDR()1405   HANDLER_ATTRIBUTES bool XOR_INT_2ADDR() {
1406     SetVReg(A(), GetVReg(A()) ^ GetVReg(B()));
1407     return true;
1408   }
1409 
ADD_LONG_2ADDR()1410   HANDLER_ATTRIBUTES bool ADD_LONG_2ADDR() {
1411     SetVRegLong(A(), SafeAdd(GetVRegLong(A()), GetVRegLong(B())));
1412     return true;
1413   }
1414 
SUB_LONG_2ADDR()1415   HANDLER_ATTRIBUTES bool SUB_LONG_2ADDR() {
1416     SetVRegLong(A(), SafeSub(GetVRegLong(A()), GetVRegLong(B())));
1417     return true;
1418   }
1419 
MUL_LONG_2ADDR()1420   HANDLER_ATTRIBUTES bool MUL_LONG_2ADDR() {
1421     SetVRegLong(A(), SafeMul(GetVRegLong(A()), GetVRegLong(B())));
1422     return true;
1423   }
1424 
DIV_LONG_2ADDR()1425   HANDLER_ATTRIBUTES bool DIV_LONG_2ADDR() {
1426     return DoLongDivide(shadow_frame_, A(), GetVRegLong(A()), GetVRegLong(B()));
1427   }
1428 
REM_LONG_2ADDR()1429   HANDLER_ATTRIBUTES bool REM_LONG_2ADDR() {
1430     return DoLongRemainder(shadow_frame_, A(), GetVRegLong(A()), GetVRegLong(B()));
1431   }
1432 
AND_LONG_2ADDR()1433   HANDLER_ATTRIBUTES bool AND_LONG_2ADDR() {
1434     SetVRegLong(A(), GetVRegLong(A()) & GetVRegLong(B()));
1435     return true;
1436   }
1437 
OR_LONG_2ADDR()1438   HANDLER_ATTRIBUTES bool OR_LONG_2ADDR() {
1439     SetVRegLong(A(), GetVRegLong(A()) | GetVRegLong(B()));
1440     return true;
1441   }
1442 
XOR_LONG_2ADDR()1443   HANDLER_ATTRIBUTES bool XOR_LONG_2ADDR() {
1444     SetVRegLong(A(), GetVRegLong(A()) ^ GetVRegLong(B()));
1445     return true;
1446   }
1447 
SHL_LONG_2ADDR()1448   HANDLER_ATTRIBUTES bool SHL_LONG_2ADDR() {
1449     SetVRegLong(A(), GetVRegLong(A()) << (GetVReg(B()) & 0x3f));
1450     return true;
1451   }
1452 
SHR_LONG_2ADDR()1453   HANDLER_ATTRIBUTES bool SHR_LONG_2ADDR() {
1454     SetVRegLong(A(), GetVRegLong(A()) >> (GetVReg(B()) & 0x3f));
1455     return true;
1456   }
1457 
USHR_LONG_2ADDR()1458   HANDLER_ATTRIBUTES bool USHR_LONG_2ADDR() {
1459     SetVRegLong(A(), static_cast<uint64_t>(GetVRegLong(A())) >> (GetVReg(B()) & 0x3f));
1460     return true;
1461   }
1462 
ADD_FLOAT_2ADDR()1463   HANDLER_ATTRIBUTES bool ADD_FLOAT_2ADDR() {
1464     SetVRegFloat(A(), GetVRegFloat(A()) + GetVRegFloat(B()));
1465     return true;
1466   }
1467 
SUB_FLOAT_2ADDR()1468   HANDLER_ATTRIBUTES bool SUB_FLOAT_2ADDR() {
1469     SetVRegFloat(A(), GetVRegFloat(A()) - GetVRegFloat(B()));
1470     return true;
1471   }
1472 
MUL_FLOAT_2ADDR()1473   HANDLER_ATTRIBUTES bool MUL_FLOAT_2ADDR() {
1474     SetVRegFloat(A(), GetVRegFloat(A()) * GetVRegFloat(B()));
1475     return true;
1476   }
1477 
DIV_FLOAT_2ADDR()1478   HANDLER_ATTRIBUTES bool DIV_FLOAT_2ADDR() {
1479     SetVRegFloat(A(), GetVRegFloat(A()) / GetVRegFloat(B()));
1480     return true;
1481   }
1482 
REM_FLOAT_2ADDR()1483   HANDLER_ATTRIBUTES bool REM_FLOAT_2ADDR() {
1484     SetVRegFloat(A(), fmodf(GetVRegFloat(A()), GetVRegFloat(B())));
1485     return true;
1486   }
1487 
ADD_DOUBLE_2ADDR()1488   HANDLER_ATTRIBUTES bool ADD_DOUBLE_2ADDR() {
1489     SetVRegDouble(A(), GetVRegDouble(A()) + GetVRegDouble(B()));
1490     return true;
1491   }
1492 
SUB_DOUBLE_2ADDR()1493   HANDLER_ATTRIBUTES bool SUB_DOUBLE_2ADDR() {
1494     SetVRegDouble(A(), GetVRegDouble(A()) - GetVRegDouble(B()));
1495     return true;
1496   }
1497 
MUL_DOUBLE_2ADDR()1498   HANDLER_ATTRIBUTES bool MUL_DOUBLE_2ADDR() {
1499     SetVRegDouble(A(), GetVRegDouble(A()) * GetVRegDouble(B()));
1500     return true;
1501   }
1502 
DIV_DOUBLE_2ADDR()1503   HANDLER_ATTRIBUTES bool DIV_DOUBLE_2ADDR() {
1504     SetVRegDouble(A(), GetVRegDouble(A()) / GetVRegDouble(B()));
1505     return true;
1506   }
1507 
REM_DOUBLE_2ADDR()1508   HANDLER_ATTRIBUTES bool REM_DOUBLE_2ADDR() {
1509     SetVRegDouble(A(), fmod(GetVRegDouble(A()), GetVRegDouble(B())));
1510     return true;
1511   }
1512 
ADD_INT_LIT16()1513   HANDLER_ATTRIBUTES bool ADD_INT_LIT16() {
1514     SetVReg(A(), SafeAdd(GetVReg(B()), C()));
1515     return true;
1516   }
1517 
RSUB_INT()1518   HANDLER_ATTRIBUTES bool RSUB_INT() {
1519     SetVReg(A(), SafeSub(C(), GetVReg(B())));
1520     return true;
1521   }
1522 
MUL_INT_LIT16()1523   HANDLER_ATTRIBUTES bool MUL_INT_LIT16() {
1524     SetVReg(A(), SafeMul(GetVReg(B()), C()));
1525     return true;
1526   }
1527 
DIV_INT_LIT16()1528   HANDLER_ATTRIBUTES bool DIV_INT_LIT16() {
1529     return DoIntDivide(shadow_frame_, A(), GetVReg(B()), C());
1530   }
1531 
REM_INT_LIT16()1532   HANDLER_ATTRIBUTES bool REM_INT_LIT16() {
1533     return DoIntRemainder(shadow_frame_, A(), GetVReg(B()), C());
1534   }
1535 
AND_INT_LIT16()1536   HANDLER_ATTRIBUTES bool AND_INT_LIT16() {
1537     SetVReg(A(), GetVReg(B()) & C());
1538     return true;
1539   }
1540 
OR_INT_LIT16()1541   HANDLER_ATTRIBUTES bool OR_INT_LIT16() {
1542     SetVReg(A(), GetVReg(B()) | C());
1543     return true;
1544   }
1545 
XOR_INT_LIT16()1546   HANDLER_ATTRIBUTES bool XOR_INT_LIT16() {
1547     SetVReg(A(), GetVReg(B()) ^ C());
1548     return true;
1549   }
1550 
ADD_INT_LIT8()1551   HANDLER_ATTRIBUTES bool ADD_INT_LIT8() {
1552     SetVReg(A(), SafeAdd(GetVReg(B()), C()));
1553     return true;
1554   }
1555 
RSUB_INT_LIT8()1556   HANDLER_ATTRIBUTES bool RSUB_INT_LIT8() {
1557     SetVReg(A(), SafeSub(C(), GetVReg(B())));
1558     return true;
1559   }
1560 
MUL_INT_LIT8()1561   HANDLER_ATTRIBUTES bool MUL_INT_LIT8() {
1562     SetVReg(A(), SafeMul(GetVReg(B()), C()));
1563     return true;
1564   }
1565 
DIV_INT_LIT8()1566   HANDLER_ATTRIBUTES bool DIV_INT_LIT8() {
1567     return DoIntDivide(shadow_frame_, A(), GetVReg(B()), C());
1568   }
1569 
REM_INT_LIT8()1570   HANDLER_ATTRIBUTES bool REM_INT_LIT8() {
1571     return DoIntRemainder(shadow_frame_, A(), GetVReg(B()), C());
1572   }
1573 
AND_INT_LIT8()1574   HANDLER_ATTRIBUTES bool AND_INT_LIT8() {
1575     SetVReg(A(), GetVReg(B()) & C());
1576     return true;
1577   }
1578 
OR_INT_LIT8()1579   HANDLER_ATTRIBUTES bool OR_INT_LIT8() {
1580     SetVReg(A(), GetVReg(B()) | C());
1581     return true;
1582   }
1583 
XOR_INT_LIT8()1584   HANDLER_ATTRIBUTES bool XOR_INT_LIT8() {
1585     SetVReg(A(), GetVReg(B()) ^ C());
1586     return true;
1587   }
1588 
SHL_INT_LIT8()1589   HANDLER_ATTRIBUTES bool SHL_INT_LIT8() {
1590     SetVReg(A(), GetVReg(B()) << (C() & 0x1f));
1591     return true;
1592   }
1593 
SHR_INT_LIT8()1594   HANDLER_ATTRIBUTES bool SHR_INT_LIT8() {
1595     SetVReg(A(), GetVReg(B()) >> (C() & 0x1f));
1596     return true;
1597   }
1598 
USHR_INT_LIT8()1599   HANDLER_ATTRIBUTES bool USHR_INT_LIT8() {
1600     SetVReg(A(), static_cast<uint32_t>(GetVReg(B())) >> (C() & 0x1f));
1601     return true;
1602   }
1603 
UNUSED_3E()1604   HANDLER_ATTRIBUTES bool UNUSED_3E() {
1605     return HandleUnused();
1606   }
1607 
UNUSED_3F()1608   HANDLER_ATTRIBUTES bool UNUSED_3F() {
1609     return HandleUnused();
1610   }
1611 
UNUSED_40()1612   HANDLER_ATTRIBUTES bool UNUSED_40() {
1613     return HandleUnused();
1614   }
1615 
UNUSED_41()1616   HANDLER_ATTRIBUTES bool UNUSED_41() {
1617     return HandleUnused();
1618   }
1619 
UNUSED_42()1620   HANDLER_ATTRIBUTES bool UNUSED_42() {
1621     return HandleUnused();
1622   }
1623 
UNUSED_43()1624   HANDLER_ATTRIBUTES bool UNUSED_43() {
1625     return HandleUnused();
1626   }
1627 
UNUSED_73()1628   HANDLER_ATTRIBUTES bool UNUSED_73() {
1629     return HandleUnused();
1630   }
1631 
UNUSED_79()1632   HANDLER_ATTRIBUTES bool UNUSED_79() {
1633     return HandleUnused();
1634   }
1635 
UNUSED_7A()1636   HANDLER_ATTRIBUTES bool UNUSED_7A() {
1637     return HandleUnused();
1638   }
1639 
UNUSED_E3()1640   HANDLER_ATTRIBUTES bool UNUSED_E3() {
1641     return HandleUnused();
1642   }
1643 
UNUSED_E4()1644   HANDLER_ATTRIBUTES bool UNUSED_E4() {
1645     return HandleUnused();
1646   }
1647 
UNUSED_E5()1648   HANDLER_ATTRIBUTES bool UNUSED_E5() {
1649     return HandleUnused();
1650   }
1651 
UNUSED_E6()1652   HANDLER_ATTRIBUTES bool UNUSED_E6() {
1653     return HandleUnused();
1654   }
1655 
UNUSED_E7()1656   HANDLER_ATTRIBUTES bool UNUSED_E7() {
1657     return HandleUnused();
1658   }
1659 
UNUSED_E8()1660   HANDLER_ATTRIBUTES bool UNUSED_E8() {
1661     return HandleUnused();
1662   }
1663 
UNUSED_E9()1664   HANDLER_ATTRIBUTES bool UNUSED_E9() {
1665     return HandleUnused();
1666   }
1667 
UNUSED_EA()1668   HANDLER_ATTRIBUTES bool UNUSED_EA() {
1669     return HandleUnused();
1670   }
1671 
UNUSED_EB()1672   HANDLER_ATTRIBUTES bool UNUSED_EB() {
1673     return HandleUnused();
1674   }
1675 
UNUSED_EC()1676   HANDLER_ATTRIBUTES bool UNUSED_EC() {
1677     return HandleUnused();
1678   }
1679 
UNUSED_ED()1680   HANDLER_ATTRIBUTES bool UNUSED_ED() {
1681     return HandleUnused();
1682   }
1683 
UNUSED_EE()1684   HANDLER_ATTRIBUTES bool UNUSED_EE() {
1685     return HandleUnused();
1686   }
1687 
UNUSED_EF()1688   HANDLER_ATTRIBUTES bool UNUSED_EF() {
1689     return HandleUnused();
1690   }
1691 
UNUSED_F0()1692   HANDLER_ATTRIBUTES bool UNUSED_F0() {
1693     return HandleUnused();
1694   }
1695 
UNUSED_F1()1696   HANDLER_ATTRIBUTES bool UNUSED_F1() {
1697     return HandleUnused();
1698   }
1699 
UNUSED_F2()1700   HANDLER_ATTRIBUTES bool UNUSED_F2() {
1701     return HandleUnused();
1702   }
1703 
UNUSED_F3()1704   HANDLER_ATTRIBUTES bool UNUSED_F3() {
1705     return HandleUnused();
1706   }
1707 
UNUSED_F4()1708   HANDLER_ATTRIBUTES bool UNUSED_F4() {
1709     return HandleUnused();
1710   }
1711 
UNUSED_F5()1712   HANDLER_ATTRIBUTES bool UNUSED_F5() {
1713     return HandleUnused();
1714   }
1715 
UNUSED_F6()1716   HANDLER_ATTRIBUTES bool UNUSED_F6() {
1717     return HandleUnused();
1718   }
1719 
UNUSED_F7()1720   HANDLER_ATTRIBUTES bool UNUSED_F7() {
1721     return HandleUnused();
1722   }
1723 
UNUSED_F8()1724   HANDLER_ATTRIBUTES bool UNUSED_F8() {
1725     return HandleUnused();
1726   }
1727 
UNUSED_F9()1728   HANDLER_ATTRIBUTES bool UNUSED_F9() {
1729     return HandleUnused();
1730   }
1731 
InstructionHandler(SwitchImplContext * ctx,const instrumentation::Instrumentation * instrumentation,Thread * self,ShadowFrame & shadow_frame,uint16_t dex_pc,const Instruction * inst,uint16_t inst_data,const Instruction * & next,bool & exit_interpreter_loop)1732   ALWAYS_INLINE InstructionHandler(SwitchImplContext* ctx,
1733                                    const instrumentation::Instrumentation* instrumentation,
1734                                    Thread* self,
1735                                    ShadowFrame& shadow_frame,
1736                                    uint16_t dex_pc,
1737                                    const Instruction* inst,
1738                                    uint16_t inst_data,
1739                                    const Instruction*& next,
1740                                    bool& exit_interpreter_loop)
1741     : ctx_(ctx),
1742       instrumentation_(instrumentation),
1743       self_(self),
1744       shadow_frame_(shadow_frame),
1745       dex_pc_(dex_pc),
1746       inst_(inst),
1747       inst_data_(inst_data),
1748       next_(next),
1749       exit_interpreter_loop_(exit_interpreter_loop) {
1750   }
1751 
1752  private:
1753   static constexpr bool do_assignability_check = do_access_check;
1754   static constexpr MonitorState kMonitorState =
1755       do_assignability_check ? MonitorState::kCountingMonitors : MonitorState::kNormalMonitors;
1756 
Accessor()1757   ALWAYS_INLINE const CodeItemDataAccessor& Accessor() { return ctx_->accessor; }
Insns()1758   ALWAYS_INLINE const uint16_t* Insns() { return ctx_->accessor.Insns(); }
ResultRegister()1759   ALWAYS_INLINE JValue* ResultRegister() { return &ctx_->result_register; }
1760 
Self()1761   ALWAYS_INLINE Thread* Self() {
1762     DCHECK_EQ(self_, Thread::Current());
1763     return self_;
1764   }
1765 
DexPC()1766   ALWAYS_INLINE int32_t DexPC() {
1767     DCHECK_EQ(dex_pc_, shadow_frame_.GetDexPC());
1768     return dex_pc_;
1769   }
1770 
Instrumentation()1771   ALWAYS_INLINE const instrumentation::Instrumentation* Instrumentation() {
1772     return instrumentation_;
1773   }
1774 
A()1775   ALWAYS_INLINE int32_t A() { return inst_->VRegA(kFormat, inst_data_); }
B()1776   ALWAYS_INLINE int32_t B() { return inst_->VRegB(kFormat, inst_data_); }
C()1777   ALWAYS_INLINE int32_t C() { return inst_->VRegC(kFormat); }
1778 
GetVReg(size_t i)1779   int32_t GetVReg(size_t i) const { return shadow_frame_.GetVReg(i); }
GetVRegLong(size_t i)1780   int64_t GetVRegLong(size_t i) const { return shadow_frame_.GetVRegLong(i); }
GetVRegFloat(size_t i)1781   float GetVRegFloat(size_t i) const { return shadow_frame_.GetVRegFloat(i); }
GetVRegDouble(size_t i)1782   double GetVRegDouble(size_t i) const { return shadow_frame_.GetVRegDouble(i); }
GetVRegReference(size_t i)1783   ObjPtr<mirror::Object> GetVRegReference(size_t i) const REQUIRES_SHARED(Locks::mutator_lock_) {
1784     return shadow_frame_.GetVRegReference(i);
1785   }
1786 
SetVReg(size_t i,int32_t val)1787   void SetVReg(size_t i, int32_t val) { shadow_frame_.SetVReg(i, val); }
SetVRegLong(size_t i,int64_t val)1788   void SetVRegLong(size_t i, int64_t val) { shadow_frame_.SetVRegLong(i, val); }
SetVRegFloat(size_t i,float val)1789   void SetVRegFloat(size_t i, float val) { shadow_frame_.SetVRegFloat(i, val); }
SetVRegDouble(size_t i,double val)1790   void SetVRegDouble(size_t i, double val) { shadow_frame_.SetVRegDouble(i, val); }
SetVRegReference(size_t i,ObjPtr<mirror::Object> val)1791   void SetVRegReference(size_t i, ObjPtr<mirror::Object> val)
1792       REQUIRES_SHARED(Locks::mutator_lock_) {
1793     shadow_frame_.SetVRegReference(i, val);
1794   }
1795 
1796   // Set the next instruction to be executed.  It is the 'fall-through' instruction by default.
SetNextInstruction(const Instruction * next_inst)1797   ALWAYS_INLINE void SetNextInstruction(const Instruction* next_inst) {
1798     DCHECK_LT(next_inst->GetDexPc(Insns()), Accessor().InsnsSizeInCodeUnits());
1799     next_ = next_inst;
1800   }
1801 
1802   // Stop interpreting the current method. (return statement, debugger-forced return, OSR, ...)
ExitInterpreterLoop()1803   ALWAYS_INLINE void ExitInterpreterLoop() {
1804     exit_interpreter_loop_ = true;
1805   }
1806 
1807   SwitchImplContext* const ctx_;
1808   const instrumentation::Instrumentation* const instrumentation_;
1809   Thread* const self_;
1810   ShadowFrame& shadow_frame_;
1811   uint32_t const dex_pc_;
1812   const Instruction* const inst_;
1813   uint16_t const inst_data_;
1814   const Instruction*& next_;
1815 
1816   bool& exit_interpreter_loop_;
1817 };
1818 
1819 // Don't inline in ASAN. It would create massive stack frame.
1820 #if defined(ADDRESS_SANITIZER) || defined(HWADDRESS_SANITIZER)
1821 #define ASAN_NO_INLINE NO_INLINE
1822 #else
1823 #define ASAN_NO_INLINE ALWAYS_INLINE
1824 #endif
1825 
1826 #define OPCODE_CASE(OPCODE, OPCODE_NAME, NAME, FORMAT, i, a, e, v)                                \
1827 template<bool do_access_check, bool transaction_active>                                           \
1828 ASAN_NO_INLINE static bool OP_##OPCODE_NAME(                                                      \
1829     SwitchImplContext* ctx,                                                                       \
1830     const instrumentation::Instrumentation* instrumentation,                                      \
1831     Thread* self,                                                                                 \
1832     ShadowFrame& shadow_frame,                                                                    \
1833     uint16_t dex_pc,                                                                              \
1834     const Instruction* inst,                                                                      \
1835     uint16_t inst_data,                                                                           \
1836     const Instruction*& next,                                                                     \
1837     bool& exit) REQUIRES_SHARED(Locks::mutator_lock_) {                                           \
1838   InstructionHandler<do_access_check, transaction_active, Instruction::FORMAT> handler(           \
1839       ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, next, exit);             \
1840   return LIKELY(handler.OPCODE_NAME());                                                           \
1841 }
DEX_INSTRUCTION_LIST(OPCODE_CASE)1842 DEX_INSTRUCTION_LIST(OPCODE_CASE)
1843 #undef OPCODE_CASE
1844 
1845 template<bool do_access_check, bool transaction_active>
1846 void ExecuteSwitchImplCpp(SwitchImplContext* ctx) {
1847   Thread* self = ctx->self;
1848   const CodeItemDataAccessor& accessor = ctx->accessor;
1849   ShadowFrame& shadow_frame = ctx->shadow_frame;
1850   self->VerifyStack();
1851 
1852   uint32_t dex_pc = shadow_frame.GetDexPC();
1853   const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
1854   const uint16_t* const insns = accessor.Insns();
1855   const Instruction* next = Instruction::At(insns + dex_pc);
1856 
1857   DCHECK(!shadow_frame.GetForceRetryInstruction())
1858       << "Entered interpreter from invoke without retry instruction being handled!";
1859 
1860   bool const interpret_one_instruction = ctx->interpret_one_instruction;
1861   while (true) {
1862     const Instruction* const inst = next;
1863     dex_pc = inst->GetDexPc(insns);
1864     shadow_frame.SetDexPC(dex_pc);
1865     TraceExecution(shadow_frame, inst, dex_pc);
1866     uint16_t inst_data = inst->Fetch16(0);
1867     bool exit = false;
1868     bool success;  // Moved outside to keep frames small under asan.
1869     if (InstructionHandler<do_access_check, transaction_active, Instruction::kInvalidFormat>(
1870             ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, next, exit).
1871             Preamble()) {
1872       DCHECK_EQ(self->IsExceptionPending(), inst->Opcode(inst_data) == Instruction::MOVE_EXCEPTION);
1873       switch (inst->Opcode(inst_data)) {
1874 #define OPCODE_CASE(OPCODE, OPCODE_NAME, NAME, FORMAT, i, a, e, v)                                \
1875         case OPCODE: {                                                                            \
1876           next = inst->RelativeAt(Instruction::SizeInCodeUnits(Instruction::FORMAT));             \
1877           success = OP_##OPCODE_NAME<do_access_check, transaction_active>(                        \
1878               ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, next, exit);     \
1879           if (success && LIKELY(!interpret_one_instruction)) {                                    \
1880             continue;                                                                             \
1881           }                                                                                       \
1882           break;                                                                                  \
1883         }
1884   DEX_INSTRUCTION_LIST(OPCODE_CASE)
1885 #undef OPCODE_CASE
1886       }
1887     }
1888     if (exit) {
1889       shadow_frame.SetDexPC(dex::kDexNoIndex);
1890       return;  // Return statement or debugger forced exit.
1891     }
1892     if (self->IsExceptionPending()) {
1893       if (!InstructionHandler<do_access_check, transaction_active, Instruction::kInvalidFormat>(
1894               ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, next, exit).
1895               HandlePendingException()) {
1896         shadow_frame.SetDexPC(dex::kDexNoIndex);
1897         return;  // Locally unhandled exception - return to caller.
1898       }
1899       // Continue execution in the catch block.
1900     }
1901     if (interpret_one_instruction) {
1902       shadow_frame.SetDexPC(next->GetDexPc(insns));  // Record where we stopped.
1903       ctx->result = ctx->result_register;
1904       return;
1905     }
1906   }
1907 }  // NOLINT(readability/fn_size)
1908 
1909 }  // namespace interpreter
1910 }  // namespace art
1911 
1912 #endif  // ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_
1913