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