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