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