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