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 #if !defined(__clang__)
18 // Clang 3.4 fails to build the goto interpreter implementation.
19
20 #include "interpreter_common.h"
21 #include "safe_math.h"
22
23 namespace art {
24 namespace interpreter {
25
26 // In the following macros, we expect the following local variables exist:
27 // - "self": the current Thread*.
28 // - "inst" : the current Instruction*.
29 // - "inst_data" : the current instruction's first 16 bits.
30 // - "dex_pc": the current pc.
31 // - "shadow_frame": the current shadow frame.
32 // - "currentHandlersTable": the current table of pointer to each instruction handler.
33
34 // Advance to the next instruction and updates interpreter state.
35 #define ADVANCE(_offset) \
36 do { \
37 int32_t disp = static_cast<int32_t>(_offset); \
38 inst = inst->RelativeAt(disp); \
39 dex_pc = static_cast<uint32_t>(static_cast<int32_t>(dex_pc) + disp); \
40 shadow_frame.SetDexPC(dex_pc); \
41 TraceExecution(shadow_frame, inst, dex_pc); \
42 inst_data = inst->Fetch16(0); \
43 goto *currentHandlersTable[inst->Opcode(inst_data)]; \
44 } while (false)
45
46 #define HANDLE_PENDING_EXCEPTION() goto exception_pending_label
47
48 #define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _offset) \
49 do { \
50 if (UNLIKELY(_is_exception_pending)) { \
51 HANDLE_PENDING_EXCEPTION(); \
52 } else { \
53 ADVANCE(_offset); \
54 } \
55 } while (false)
56
57 #define UPDATE_HANDLER_TABLE() \
58 currentHandlersTable = handlersTable[ \
59 Runtime::Current()->GetInstrumentation()->GetInterpreterHandlerTable()]
60
61 #define BACKWARD_BRANCH_INSTRUMENTATION(offset) \
62 do { \
63 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); \
64 instrumentation->BackwardBranch(self, shadow_frame.GetMethod(), offset); \
65 } while (false)
66
67 #define UNREACHABLE_CODE_CHECK() \
68 do { \
69 if (kIsDebugBuild) { \
70 LOG(FATAL) << "We should not be here !"; \
71 UNREACHABLE(); \
72 } \
73 } while (false)
74
75 #define HANDLE_INSTRUCTION_START(opcode) op_##opcode: // NOLINT(whitespace/labels)
76 #define HANDLE_INSTRUCTION_END() UNREACHABLE_CODE_CHECK()
77
78 /**
79 * Interpreter based on computed goto tables.
80 *
81 * Each instruction is associated to a handler. This handler is responsible for executing the
82 * instruction and jump to the next instruction's handler.
83 * In order to limit the cost of instrumentation, we have two handler tables:
84 * - the "main" handler table: it contains handlers for normal execution of each instruction without
85 * handling of instrumentation.
86 * - the "alternative" handler table: it contains alternative handlers which first handle
87 * instrumentation before jumping to the corresponding "normal" instruction's handler.
88 *
89 * When instrumentation is active, the interpreter uses the "alternative" handler table. Otherwise
90 * it uses the "main" handler table.
91 *
92 * The current handler table is the handler table being used by the interpreter. It is updated:
93 * - on backward branch (goto, if and switch instructions)
94 * - after invoke
95 * - when an exception is thrown.
96 * This allows to support an attaching debugger to an already running application for instance.
97 *
98 * For a fast handler table update, handler tables are stored in an array of handler tables. Each
99 * handler table is represented by the InterpreterHandlerTable enum which allows to associate it
100 * to an index in this array of handler tables ((see Instrumentation::GetInterpreterHandlerTable).
101 *
102 * Here's the current layout of this array of handler tables:
103 *
104 * ---------------------+---------------+
105 * | NOP | (handler for NOP instruction)
106 * +---------------+
107 * "main" | MOVE | (handler for MOVE instruction)
108 * handler table +---------------+
109 * | ... |
110 * +---------------+
111 * | UNUSED_FF | (handler for UNUSED_FF instruction)
112 * ---------------------+---------------+
113 * | NOP | (alternative handler for NOP instruction)
114 * +---------------+
115 * "alternative" | MOVE | (alternative handler for MOVE instruction)
116 * handler table +---------------+
117 * | ... |
118 * +---------------+
119 * | UNUSED_FF | (alternative handler for UNUSED_FF instruction)
120 * ---------------------+---------------+
121 *
122 */
123 template<bool do_access_check, bool transaction_active>
ExecuteGotoImpl(Thread * self,const DexFile::CodeItem * code_item,ShadowFrame & shadow_frame,JValue result_register)124 JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame,
125 JValue result_register) {
126 // Define handler tables:
127 // - The main handler table contains execution handlers for each instruction.
128 // - The alternative handler table contains prelude handlers which check for thread suspend and
129 // manage instrumentation before jumping to the execution handler.
130 static const void* const handlersTable[instrumentation::kNumHandlerTables][kNumPackedOpcodes] = {
131 {
132 // Main handler table.
133 #define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&op_##code,
134 #include "dex_instruction_list.h"
135 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
136 #undef DEX_INSTRUCTION_LIST
137 #undef INSTRUCTION_HANDLER
138 }, {
139 // Alternative handler table.
140 #define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&alt_op_##code,
141 #include "dex_instruction_list.h"
142 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
143 #undef DEX_INSTRUCTION_LIST
144 #undef INSTRUCTION_HANDLER
145 }
146 };
147
148 constexpr bool do_assignability_check = do_access_check;
149 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
150 LOG(FATAL) << "Invalid shadow frame for interpreter use";
151 return JValue();
152 }
153 self->VerifyStack();
154
155 uint32_t dex_pc = shadow_frame.GetDexPC();
156 const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
157 uint16_t inst_data;
158 const void* const* currentHandlersTable;
159 UPDATE_HANDLER_TABLE();
160 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing.
161 if (kIsDebugBuild) {
162 self->AssertNoPendingException();
163 }
164 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
165 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
166 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
167 shadow_frame.GetMethod(), 0);
168 }
169 }
170
171 // Jump to first instruction.
172 ADVANCE(0);
173 UNREACHABLE_CODE_CHECK();
174
175 HANDLE_INSTRUCTION_START(NOP)
176 ADVANCE(1);
177 HANDLE_INSTRUCTION_END();
178
179 HANDLE_INSTRUCTION_START(MOVE)
180 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
181 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
182 ADVANCE(1);
183 HANDLE_INSTRUCTION_END();
184
185 HANDLE_INSTRUCTION_START(MOVE_FROM16)
186 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
187 shadow_frame.GetVReg(inst->VRegB_22x()));
188 ADVANCE(2);
189 HANDLE_INSTRUCTION_END();
190
191 HANDLE_INSTRUCTION_START(MOVE_16)
192 shadow_frame.SetVReg(inst->VRegA_32x(),
193 shadow_frame.GetVReg(inst->VRegB_32x()));
194 ADVANCE(3);
195 HANDLE_INSTRUCTION_END();
196
197 HANDLE_INSTRUCTION_START(MOVE_WIDE)
198 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
199 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
200 ADVANCE(1);
201 HANDLE_INSTRUCTION_END();
202
203 HANDLE_INSTRUCTION_START(MOVE_WIDE_FROM16)
204 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
205 shadow_frame.GetVRegLong(inst->VRegB_22x()));
206 ADVANCE(2);
207 HANDLE_INSTRUCTION_END();
208
209 HANDLE_INSTRUCTION_START(MOVE_WIDE_16)
210 shadow_frame.SetVRegLong(inst->VRegA_32x(),
211 shadow_frame.GetVRegLong(inst->VRegB_32x()));
212 ADVANCE(3);
213 HANDLE_INSTRUCTION_END();
214
215 HANDLE_INSTRUCTION_START(MOVE_OBJECT)
216 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
217 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
218 ADVANCE(1);
219 HANDLE_INSTRUCTION_END();
220
221 HANDLE_INSTRUCTION_START(MOVE_OBJECT_FROM16)
222 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
223 shadow_frame.GetVRegReference(inst->VRegB_22x()));
224 ADVANCE(2);
225 HANDLE_INSTRUCTION_END();
226
227 HANDLE_INSTRUCTION_START(MOVE_OBJECT_16)
228 shadow_frame.SetVRegReference(inst->VRegA_32x(),
229 shadow_frame.GetVRegReference(inst->VRegB_32x()));
230 ADVANCE(3);
231 HANDLE_INSTRUCTION_END();
232
233 HANDLE_INSTRUCTION_START(MOVE_RESULT)
234 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
235 ADVANCE(1);
236 HANDLE_INSTRUCTION_END();
237
238 HANDLE_INSTRUCTION_START(MOVE_RESULT_WIDE)
239 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
240 ADVANCE(1);
241 HANDLE_INSTRUCTION_END();
242
243 HANDLE_INSTRUCTION_START(MOVE_RESULT_OBJECT)
244 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
245 ADVANCE(1);
246 HANDLE_INSTRUCTION_END();
247
248 HANDLE_INSTRUCTION_START(MOVE_EXCEPTION) {
249 Throwable* exception = self->GetException();
250 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
251 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
252 self->ClearException();
253 ADVANCE(1);
254 }
255 HANDLE_INSTRUCTION_END();
256
257 HANDLE_INSTRUCTION_START(RETURN_VOID_NO_BARRIER) {
258 JValue result;
259 self->AllowThreadSuspension();
260 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
261 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
262 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
263 shadow_frame.GetMethod(), dex_pc,
264 result);
265 }
266 return result;
267 }
268 HANDLE_INSTRUCTION_END();
269
270 HANDLE_INSTRUCTION_START(RETURN_VOID) {
271 QuasiAtomic::ThreadFenceForConstructor();
272 JValue result;
273 self->AllowThreadSuspension();
274 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
275 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
276 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
277 shadow_frame.GetMethod(), dex_pc,
278 result);
279 }
280 return result;
281 }
282 HANDLE_INSTRUCTION_END();
283
284 HANDLE_INSTRUCTION_START(RETURN) {
285 JValue result;
286 result.SetJ(0);
287 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
288 self->AllowThreadSuspension();
289 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
290 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
291 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
292 shadow_frame.GetMethod(), dex_pc,
293 result);
294 }
295 return result;
296 }
297 HANDLE_INSTRUCTION_END();
298
299 HANDLE_INSTRUCTION_START(RETURN_WIDE) {
300 JValue result;
301 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
302 self->AllowThreadSuspension();
303 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
304 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
305 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
306 shadow_frame.GetMethod(), dex_pc,
307 result);
308 }
309 return result;
310 }
311 HANDLE_INSTRUCTION_END();
312
313 HANDLE_INSTRUCTION_START(RETURN_OBJECT) {
314 JValue result;
315 self->AllowThreadSuspension();
316 const uint8_t vreg_index = inst->VRegA_11x(inst_data);
317 Object* obj_result = shadow_frame.GetVRegReference(vreg_index);
318 if (do_assignability_check && obj_result != nullptr) {
319 Class* return_type = shadow_frame.GetMethod()->GetReturnType();
320 obj_result = shadow_frame.GetVRegReference(vreg_index);
321 if (return_type == nullptr) {
322 // Return the pending exception.
323 HANDLE_PENDING_EXCEPTION();
324 }
325 if (!obj_result->VerifierInstanceOf(return_type)) {
326 // This should never happen.
327 std::string temp1, temp2;
328 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
329 "Returning '%s' that is not instance of return type '%s'",
330 obj_result->GetClass()->GetDescriptor(&temp1),
331 return_type->GetDescriptor(&temp2));
332 HANDLE_PENDING_EXCEPTION();
333 }
334 }
335 result.SetL(obj_result);
336 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
337 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
338 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
339 shadow_frame.GetMethod(), dex_pc,
340 result);
341 }
342 return result;
343 }
344 HANDLE_INSTRUCTION_END();
345
346 HANDLE_INSTRUCTION_START(CONST_4) {
347 uint32_t dst = inst->VRegA_11n(inst_data);
348 int32_t val = inst->VRegB_11n(inst_data);
349 shadow_frame.SetVReg(dst, val);
350 if (val == 0) {
351 shadow_frame.SetVRegReference(dst, nullptr);
352 }
353 ADVANCE(1);
354 }
355 HANDLE_INSTRUCTION_END();
356
357 HANDLE_INSTRUCTION_START(CONST_16) {
358 uint32_t dst = inst->VRegA_21s(inst_data);
359 int32_t val = inst->VRegB_21s();
360 shadow_frame.SetVReg(dst, val);
361 if (val == 0) {
362 shadow_frame.SetVRegReference(dst, nullptr);
363 }
364 ADVANCE(2);
365 }
366 HANDLE_INSTRUCTION_END();
367
368 HANDLE_INSTRUCTION_START(CONST) {
369 uint32_t dst = inst->VRegA_31i(inst_data);
370 int32_t val = inst->VRegB_31i();
371 shadow_frame.SetVReg(dst, val);
372 if (val == 0) {
373 shadow_frame.SetVRegReference(dst, nullptr);
374 }
375 ADVANCE(3);
376 }
377 HANDLE_INSTRUCTION_END();
378
379 HANDLE_INSTRUCTION_START(CONST_HIGH16) {
380 uint32_t dst = inst->VRegA_21h(inst_data);
381 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
382 shadow_frame.SetVReg(dst, val);
383 if (val == 0) {
384 shadow_frame.SetVRegReference(dst, nullptr);
385 }
386 ADVANCE(2);
387 }
388 HANDLE_INSTRUCTION_END();
389
390 HANDLE_INSTRUCTION_START(CONST_WIDE_16)
391 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
392 ADVANCE(2);
393 HANDLE_INSTRUCTION_END();
394
395 HANDLE_INSTRUCTION_START(CONST_WIDE_32)
396 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
397 ADVANCE(3);
398 HANDLE_INSTRUCTION_END();
399
400 HANDLE_INSTRUCTION_START(CONST_WIDE)
401 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
402 ADVANCE(5);
403 HANDLE_INSTRUCTION_END();
404
405 HANDLE_INSTRUCTION_START(CONST_WIDE_HIGH16)
406 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
407 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
408 ADVANCE(2);
409 HANDLE_INSTRUCTION_END();
410
411 HANDLE_INSTRUCTION_START(CONST_STRING) {
412 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
413 if (UNLIKELY(s == nullptr)) {
414 HANDLE_PENDING_EXCEPTION();
415 } else {
416 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
417 ADVANCE(2);
418 }
419 }
420 HANDLE_INSTRUCTION_END();
421
422 HANDLE_INSTRUCTION_START(CONST_STRING_JUMBO) {
423 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
424 if (UNLIKELY(s == nullptr)) {
425 HANDLE_PENDING_EXCEPTION();
426 } else {
427 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
428 ADVANCE(3);
429 }
430 }
431 HANDLE_INSTRUCTION_END();
432
433 HANDLE_INSTRUCTION_START(CONST_CLASS) {
434 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
435 self, false, do_access_check);
436 if (UNLIKELY(c == nullptr)) {
437 HANDLE_PENDING_EXCEPTION();
438 } else {
439 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
440 ADVANCE(2);
441 }
442 }
443 HANDLE_INSTRUCTION_END();
444
445 HANDLE_INSTRUCTION_START(MONITOR_ENTER) {
446 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
447 if (UNLIKELY(obj == nullptr)) {
448 ThrowNullPointerExceptionFromInterpreter();
449 HANDLE_PENDING_EXCEPTION();
450 } else {
451 DoMonitorEnter(self, obj);
452 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
453 }
454 }
455 HANDLE_INSTRUCTION_END();
456
457 HANDLE_INSTRUCTION_START(MONITOR_EXIT) {
458 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
459 if (UNLIKELY(obj == nullptr)) {
460 ThrowNullPointerExceptionFromInterpreter();
461 HANDLE_PENDING_EXCEPTION();
462 } else {
463 DoMonitorExit(self, obj);
464 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
465 }
466 }
467 HANDLE_INSTRUCTION_END();
468
469 HANDLE_INSTRUCTION_START(CHECK_CAST) {
470 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
471 self, false, do_access_check);
472 if (UNLIKELY(c == nullptr)) {
473 HANDLE_PENDING_EXCEPTION();
474 } else {
475 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
476 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
477 ThrowClassCastException(c, obj->GetClass());
478 HANDLE_PENDING_EXCEPTION();
479 } else {
480 ADVANCE(2);
481 }
482 }
483 }
484 HANDLE_INSTRUCTION_END();
485
486 HANDLE_INSTRUCTION_START(INSTANCE_OF) {
487 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
488 self, false, do_access_check);
489 if (UNLIKELY(c == nullptr)) {
490 HANDLE_PENDING_EXCEPTION();
491 } else {
492 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
493 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
494 ADVANCE(2);
495 }
496 }
497 HANDLE_INSTRUCTION_END();
498
499 HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
500 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
501 if (UNLIKELY(array == nullptr)) {
502 ThrowNullPointerExceptionFromInterpreter();
503 HANDLE_PENDING_EXCEPTION();
504 } else {
505 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
506 ADVANCE(1);
507 }
508 }
509 HANDLE_INSTRUCTION_END();
510
511 HANDLE_INSTRUCTION_START(NEW_INSTANCE) {
512 Object* obj = nullptr;
513 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
514 self, false, do_access_check);
515 if (LIKELY(c != nullptr)) {
516 if (UNLIKELY(c->IsStringClass())) {
517 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
518 mirror::SetStringCountVisitor visitor(0);
519 obj = String::Alloc<true>(self, 0, allocator_type, visitor);
520 } else {
521 obj = AllocObjectFromCode<do_access_check, true>(
522 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
523 Runtime::Current()->GetHeap()->GetCurrentAllocator());
524 }
525 }
526 if (UNLIKELY(obj == nullptr)) {
527 HANDLE_PENDING_EXCEPTION();
528 } else {
529 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
530 // Don't allow finalizable objects to be allocated during a transaction since these can't be
531 // finalized without a started runtime.
532 if (transaction_active && obj->GetClass()->IsFinalizable()) {
533 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
534 PrettyTypeOf(obj).c_str());
535 HANDLE_PENDING_EXCEPTION();
536 }
537 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
538 ADVANCE(2);
539 }
540 }
541 HANDLE_INSTRUCTION_END();
542
543 HANDLE_INSTRUCTION_START(NEW_ARRAY) {
544 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
545 Object* obj = AllocArrayFromCode<do_access_check, true>(
546 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
547 Runtime::Current()->GetHeap()->GetCurrentAllocator());
548 if (UNLIKELY(obj == nullptr)) {
549 HANDLE_PENDING_EXCEPTION();
550 } else {
551 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
552 ADVANCE(2);
553 }
554 }
555 HANDLE_INSTRUCTION_END();
556
557 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) {
558 bool success =
559 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame,
560 self, &result_register);
561 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
562 }
563 HANDLE_INSTRUCTION_END();
564
565 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) {
566 bool success =
567 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
568 self, &result_register);
569 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
570 }
571 HANDLE_INSTRUCTION_END();
572
573 HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) {
574 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
575 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
576 const Instruction::ArrayDataPayload* payload =
577 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
578 bool success = FillArrayData(obj, payload);
579 if (transaction_active && success) {
580 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
581 }
582 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
583 }
584 HANDLE_INSTRUCTION_END();
585
586 HANDLE_INSTRUCTION_START(THROW) {
587 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
588 if (UNLIKELY(exception == nullptr)) {
589 ThrowNullPointerException("throw with null exception");
590 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
591 // This should never happen.
592 std::string temp;
593 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
594 "Throwing '%s' that is not instance of Throwable",
595 exception->GetClass()->GetDescriptor(&temp));
596 } else {
597 self->SetException(exception->AsThrowable());
598 }
599 HANDLE_PENDING_EXCEPTION();
600 }
601 HANDLE_INSTRUCTION_END();
602
603 HANDLE_INSTRUCTION_START(GOTO) {
604 int8_t offset = inst->VRegA_10t(inst_data);
605 if (IsBackwardBranch(offset)) {
606 BACKWARD_BRANCH_INSTRUMENTATION(offset);
607 if (UNLIKELY(self->TestAllFlags())) {
608 self->CheckSuspend();
609 UPDATE_HANDLER_TABLE();
610 }
611 }
612 ADVANCE(offset);
613 }
614 HANDLE_INSTRUCTION_END();
615
616 HANDLE_INSTRUCTION_START(GOTO_16) {
617 int16_t offset = inst->VRegA_20t();
618 if (IsBackwardBranch(offset)) {
619 BACKWARD_BRANCH_INSTRUMENTATION(offset);
620 if (UNLIKELY(self->TestAllFlags())) {
621 self->CheckSuspend();
622 UPDATE_HANDLER_TABLE();
623 }
624 }
625 ADVANCE(offset);
626 }
627 HANDLE_INSTRUCTION_END();
628
629 HANDLE_INSTRUCTION_START(GOTO_32) {
630 int32_t offset = inst->VRegA_30t();
631 if (IsBackwardBranch(offset)) {
632 BACKWARD_BRANCH_INSTRUMENTATION(offset);
633 if (UNLIKELY(self->TestAllFlags())) {
634 self->CheckSuspend();
635 UPDATE_HANDLER_TABLE();
636 }
637 }
638 ADVANCE(offset);
639 }
640 HANDLE_INSTRUCTION_END();
641
642 HANDLE_INSTRUCTION_START(PACKED_SWITCH) {
643 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
644 if (IsBackwardBranch(offset)) {
645 BACKWARD_BRANCH_INSTRUMENTATION(offset);
646 if (UNLIKELY(self->TestAllFlags())) {
647 self->CheckSuspend();
648 UPDATE_HANDLER_TABLE();
649 }
650 }
651 ADVANCE(offset);
652 }
653 HANDLE_INSTRUCTION_END();
654
655 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) {
656 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
657 if (IsBackwardBranch(offset)) {
658 BACKWARD_BRANCH_INSTRUMENTATION(offset);
659 if (UNLIKELY(self->TestAllFlags())) {
660 self->CheckSuspend();
661 UPDATE_HANDLER_TABLE();
662 }
663 }
664 ADVANCE(offset);
665 }
666 HANDLE_INSTRUCTION_END();
667
668 #if defined(__clang__)
669 #pragma clang diagnostic push
670 #pragma clang diagnostic ignored "-Wfloat-equal"
671 #endif
672
673 HANDLE_INSTRUCTION_START(CMPL_FLOAT) {
674 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
675 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
676 int32_t result;
677 if (val1 > val2) {
678 result = 1;
679 } else if (val1 == val2) {
680 result = 0;
681 } else {
682 result = -1;
683 }
684 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
685 ADVANCE(2);
686 }
687 HANDLE_INSTRUCTION_END();
688
689 HANDLE_INSTRUCTION_START(CMPG_FLOAT) {
690 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
691 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
692 int32_t result;
693 if (val1 < val2) {
694 result = -1;
695 } else if (val1 == val2) {
696 result = 0;
697 } else {
698 result = 1;
699 }
700 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
701 ADVANCE(2);
702 }
703 HANDLE_INSTRUCTION_END();
704
705 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) {
706 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
707 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
708 int32_t result;
709 if (val1 > val2) {
710 result = 1;
711 } else if (val1 == val2) {
712 result = 0;
713 } else {
714 result = -1;
715 }
716 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
717 ADVANCE(2);
718 }
719 HANDLE_INSTRUCTION_END();
720
721 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) {
722 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
723 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
724 int32_t result;
725 if (val1 < val2) {
726 result = -1;
727 } else if (val1 == val2) {
728 result = 0;
729 } else {
730 result = 1;
731 }
732 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
733 ADVANCE(2);
734 }
735 HANDLE_INSTRUCTION_END();
736
737 #if defined(__clang__)
738 #pragma clang diagnostic pop
739 #endif
740
741 HANDLE_INSTRUCTION_START(CMP_LONG) {
742 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
743 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
744 int32_t result;
745 if (val1 > val2) {
746 result = 1;
747 } else if (val1 == val2) {
748 result = 0;
749 } else {
750 result = -1;
751 }
752 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
753 ADVANCE(2);
754 }
755 HANDLE_INSTRUCTION_END();
756
757 HANDLE_INSTRUCTION_START(IF_EQ) {
758 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
759 int16_t offset = inst->VRegC_22t();
760 if (IsBackwardBranch(offset)) {
761 BACKWARD_BRANCH_INSTRUMENTATION(offset);
762 if (UNLIKELY(self->TestAllFlags())) {
763 self->CheckSuspend();
764 UPDATE_HANDLER_TABLE();
765 }
766 }
767 ADVANCE(offset);
768 } else {
769 ADVANCE(2);
770 }
771 }
772 HANDLE_INSTRUCTION_END();
773
774 HANDLE_INSTRUCTION_START(IF_NE) {
775 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
776 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
777 int16_t offset = inst->VRegC_22t();
778 if (IsBackwardBranch(offset)) {
779 BACKWARD_BRANCH_INSTRUMENTATION(offset);
780 if (UNLIKELY(self->TestAllFlags())) {
781 self->CheckSuspend();
782 UPDATE_HANDLER_TABLE();
783 }
784 }
785 ADVANCE(offset);
786 } else {
787 ADVANCE(2);
788 }
789 }
790 HANDLE_INSTRUCTION_END();
791
792 HANDLE_INSTRUCTION_START(IF_LT) {
793 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
794 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
795 int16_t offset = inst->VRegC_22t();
796 if (IsBackwardBranch(offset)) {
797 BACKWARD_BRANCH_INSTRUMENTATION(offset);
798 if (UNLIKELY(self->TestAllFlags())) {
799 self->CheckSuspend();
800 UPDATE_HANDLER_TABLE();
801 }
802 }
803 ADVANCE(offset);
804 } else {
805 ADVANCE(2);
806 }
807 }
808 HANDLE_INSTRUCTION_END();
809
810 HANDLE_INSTRUCTION_START(IF_GE) {
811 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
812 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
813 int16_t offset = inst->VRegC_22t();
814 if (IsBackwardBranch(offset)) {
815 BACKWARD_BRANCH_INSTRUMENTATION(offset);
816 if (UNLIKELY(self->TestAllFlags())) {
817 self->CheckSuspend();
818 UPDATE_HANDLER_TABLE();
819 }
820 }
821 ADVANCE(offset);
822 } else {
823 ADVANCE(2);
824 }
825 }
826 HANDLE_INSTRUCTION_END();
827
828 HANDLE_INSTRUCTION_START(IF_GT) {
829 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
830 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
831 int16_t offset = inst->VRegC_22t();
832 if (IsBackwardBranch(offset)) {
833 BACKWARD_BRANCH_INSTRUMENTATION(offset);
834 if (UNLIKELY(self->TestAllFlags())) {
835 self->CheckSuspend();
836 UPDATE_HANDLER_TABLE();
837 }
838 }
839 ADVANCE(offset);
840 } else {
841 ADVANCE(2);
842 }
843 }
844 HANDLE_INSTRUCTION_END();
845
846 HANDLE_INSTRUCTION_START(IF_LE) {
847 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
848 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
849 int16_t offset = inst->VRegC_22t();
850 if (IsBackwardBranch(offset)) {
851 BACKWARD_BRANCH_INSTRUMENTATION(offset);
852 if (UNLIKELY(self->TestAllFlags())) {
853 self->CheckSuspend();
854 UPDATE_HANDLER_TABLE();
855 }
856 }
857 ADVANCE(offset);
858 } else {
859 ADVANCE(2);
860 }
861 }
862 HANDLE_INSTRUCTION_END();
863
864 HANDLE_INSTRUCTION_START(IF_EQZ) {
865 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
866 int16_t offset = inst->VRegB_21t();
867 if (IsBackwardBranch(offset)) {
868 BACKWARD_BRANCH_INSTRUMENTATION(offset);
869 if (UNLIKELY(self->TestAllFlags())) {
870 self->CheckSuspend();
871 UPDATE_HANDLER_TABLE();
872 }
873 }
874 ADVANCE(offset);
875 } else {
876 ADVANCE(2);
877 }
878 }
879 HANDLE_INSTRUCTION_END();
880
881 HANDLE_INSTRUCTION_START(IF_NEZ) {
882 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
883 int16_t offset = inst->VRegB_21t();
884 if (IsBackwardBranch(offset)) {
885 BACKWARD_BRANCH_INSTRUMENTATION(offset);
886 if (UNLIKELY(self->TestAllFlags())) {
887 self->CheckSuspend();
888 UPDATE_HANDLER_TABLE();
889 }
890 }
891 ADVANCE(offset);
892 } else {
893 ADVANCE(2);
894 }
895 }
896 HANDLE_INSTRUCTION_END();
897
898 HANDLE_INSTRUCTION_START(IF_LTZ) {
899 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
900 int16_t offset = inst->VRegB_21t();
901 if (IsBackwardBranch(offset)) {
902 BACKWARD_BRANCH_INSTRUMENTATION(offset);
903 if (UNLIKELY(self->TestAllFlags())) {
904 self->CheckSuspend();
905 UPDATE_HANDLER_TABLE();
906 }
907 }
908 ADVANCE(offset);
909 } else {
910 ADVANCE(2);
911 }
912 }
913 HANDLE_INSTRUCTION_END();
914
915 HANDLE_INSTRUCTION_START(IF_GEZ) {
916 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
917 int16_t offset = inst->VRegB_21t();
918 if (IsBackwardBranch(offset)) {
919 BACKWARD_BRANCH_INSTRUMENTATION(offset);
920 if (UNLIKELY(self->TestAllFlags())) {
921 self->CheckSuspend();
922 UPDATE_HANDLER_TABLE();
923 }
924 }
925 ADVANCE(offset);
926 } else {
927 ADVANCE(2);
928 }
929 }
930 HANDLE_INSTRUCTION_END();
931
932 HANDLE_INSTRUCTION_START(IF_GTZ) {
933 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
934 int16_t offset = inst->VRegB_21t();
935 if (IsBackwardBranch(offset)) {
936 BACKWARD_BRANCH_INSTRUMENTATION(offset);
937 if (UNLIKELY(self->TestAllFlags())) {
938 self->CheckSuspend();
939 UPDATE_HANDLER_TABLE();
940 }
941 }
942 ADVANCE(offset);
943 } else {
944 ADVANCE(2);
945 }
946 }
947 HANDLE_INSTRUCTION_END();
948
949 HANDLE_INSTRUCTION_START(IF_LEZ) {
950 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
951 int16_t offset = inst->VRegB_21t();
952 if (IsBackwardBranch(offset)) {
953 BACKWARD_BRANCH_INSTRUMENTATION(offset);
954 if (UNLIKELY(self->TestAllFlags())) {
955 self->CheckSuspend();
956 UPDATE_HANDLER_TABLE();
957 }
958 }
959 ADVANCE(offset);
960 } else {
961 ADVANCE(2);
962 }
963 }
964 HANDLE_INSTRUCTION_END();
965
966 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
967 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
968 if (UNLIKELY(a == nullptr)) {
969 ThrowNullPointerExceptionFromInterpreter();
970 HANDLE_PENDING_EXCEPTION();
971 } else {
972 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
973 BooleanArray* array = a->AsBooleanArray();
974 if (LIKELY(array->CheckIsValidIndex(index))) {
975 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
976 ADVANCE(2);
977 } else {
978 HANDLE_PENDING_EXCEPTION();
979 }
980 }
981 }
982 HANDLE_INSTRUCTION_END();
983
984 HANDLE_INSTRUCTION_START(AGET_BYTE) {
985 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
986 if (UNLIKELY(a == nullptr)) {
987 ThrowNullPointerExceptionFromInterpreter();
988 HANDLE_PENDING_EXCEPTION();
989 } else {
990 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
991 ByteArray* array = a->AsByteArray();
992 if (LIKELY(array->CheckIsValidIndex(index))) {
993 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
994 ADVANCE(2);
995 } else {
996 HANDLE_PENDING_EXCEPTION();
997 }
998 }
999 }
1000 HANDLE_INSTRUCTION_END();
1001
1002 HANDLE_INSTRUCTION_START(AGET_CHAR) {
1003 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1004 if (UNLIKELY(a == nullptr)) {
1005 ThrowNullPointerExceptionFromInterpreter();
1006 HANDLE_PENDING_EXCEPTION();
1007 } else {
1008 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1009 CharArray* array = a->AsCharArray();
1010 if (LIKELY(array->CheckIsValidIndex(index))) {
1011 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
1012 ADVANCE(2);
1013 } else {
1014 HANDLE_PENDING_EXCEPTION();
1015 }
1016 }
1017 }
1018 HANDLE_INSTRUCTION_END();
1019
1020 HANDLE_INSTRUCTION_START(AGET_SHORT) {
1021 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1022 if (UNLIKELY(a == nullptr)) {
1023 ThrowNullPointerExceptionFromInterpreter();
1024 HANDLE_PENDING_EXCEPTION();
1025 } else {
1026 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1027 ShortArray* array = a->AsShortArray();
1028 if (LIKELY(array->CheckIsValidIndex(index))) {
1029 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
1030 ADVANCE(2);
1031 } else {
1032 HANDLE_PENDING_EXCEPTION();
1033 }
1034 }
1035 }
1036 HANDLE_INSTRUCTION_END();
1037
1038 HANDLE_INSTRUCTION_START(AGET) {
1039 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1040 if (UNLIKELY(a == nullptr)) {
1041 ThrowNullPointerExceptionFromInterpreter();
1042 HANDLE_PENDING_EXCEPTION();
1043 } else {
1044 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1045 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1046 auto* array = down_cast<IntArray*>(a);
1047 if (LIKELY(array->CheckIsValidIndex(index))) {
1048 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
1049 ADVANCE(2);
1050 } else {
1051 HANDLE_PENDING_EXCEPTION();
1052 }
1053 }
1054 }
1055 HANDLE_INSTRUCTION_END();
1056
1057 HANDLE_INSTRUCTION_START(AGET_WIDE) {
1058 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1059 if (UNLIKELY(a == nullptr)) {
1060 ThrowNullPointerExceptionFromInterpreter();
1061 HANDLE_PENDING_EXCEPTION();
1062 } else {
1063 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1064 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1065 auto* array = down_cast<LongArray*>(a);
1066 if (LIKELY(array->CheckIsValidIndex(index))) {
1067 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
1068 ADVANCE(2);
1069 } else {
1070 HANDLE_PENDING_EXCEPTION();
1071 }
1072 }
1073 }
1074 HANDLE_INSTRUCTION_END();
1075
1076 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
1077 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1078 if (UNLIKELY(a == nullptr)) {
1079 ThrowNullPointerExceptionFromInterpreter();
1080 HANDLE_PENDING_EXCEPTION();
1081 } else {
1082 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1083 ObjectArray<Object>* array = a->AsObjectArray<Object>();
1084 if (LIKELY(array->CheckIsValidIndex(index))) {
1085 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
1086 ADVANCE(2);
1087 } else {
1088 HANDLE_PENDING_EXCEPTION();
1089 }
1090 }
1091 }
1092 HANDLE_INSTRUCTION_END();
1093
1094 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
1095 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1096 if (UNLIKELY(a == nullptr)) {
1097 ThrowNullPointerExceptionFromInterpreter();
1098 HANDLE_PENDING_EXCEPTION();
1099 } else {
1100 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
1101 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1102 BooleanArray* array = a->AsBooleanArray();
1103 if (LIKELY(array->CheckIsValidIndex(index))) {
1104 array->SetWithoutChecks<transaction_active>(index, val);
1105 ADVANCE(2);
1106 } else {
1107 HANDLE_PENDING_EXCEPTION();
1108 }
1109 }
1110 }
1111 HANDLE_INSTRUCTION_END();
1112
1113 HANDLE_INSTRUCTION_START(APUT_BYTE) {
1114 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1115 if (UNLIKELY(a == nullptr)) {
1116 ThrowNullPointerExceptionFromInterpreter();
1117 HANDLE_PENDING_EXCEPTION();
1118 } else {
1119 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
1120 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1121 ByteArray* array = a->AsByteArray();
1122 if (LIKELY(array->CheckIsValidIndex(index))) {
1123 array->SetWithoutChecks<transaction_active>(index, val);
1124 ADVANCE(2);
1125 } else {
1126 HANDLE_PENDING_EXCEPTION();
1127 }
1128 }
1129 }
1130 HANDLE_INSTRUCTION_END();
1131
1132 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1133 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1134 if (UNLIKELY(a == nullptr)) {
1135 ThrowNullPointerExceptionFromInterpreter();
1136 HANDLE_PENDING_EXCEPTION();
1137 } else {
1138 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
1139 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1140 CharArray* array = a->AsCharArray();
1141 if (LIKELY(array->CheckIsValidIndex(index))) {
1142 array->SetWithoutChecks<transaction_active>(index, val);
1143 ADVANCE(2);
1144 } else {
1145 HANDLE_PENDING_EXCEPTION();
1146 }
1147 }
1148 }
1149 HANDLE_INSTRUCTION_END();
1150
1151 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1152 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1153 if (UNLIKELY(a == nullptr)) {
1154 ThrowNullPointerExceptionFromInterpreter();
1155 HANDLE_PENDING_EXCEPTION();
1156 } else {
1157 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
1158 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1159 ShortArray* array = a->AsShortArray();
1160 if (LIKELY(array->CheckIsValidIndex(index))) {
1161 array->SetWithoutChecks<transaction_active>(index, val);
1162 ADVANCE(2);
1163 } else {
1164 HANDLE_PENDING_EXCEPTION();
1165 }
1166 }
1167 }
1168 HANDLE_INSTRUCTION_END();
1169
1170 HANDLE_INSTRUCTION_START(APUT) {
1171 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1172 if (UNLIKELY(a == nullptr)) {
1173 ThrowNullPointerExceptionFromInterpreter();
1174 HANDLE_PENDING_EXCEPTION();
1175 } else {
1176 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
1177 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1178 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1179 auto* array = down_cast<IntArray*>(a);
1180 if (LIKELY(array->CheckIsValidIndex(index))) {
1181 array->SetWithoutChecks<transaction_active>(index, val);
1182 ADVANCE(2);
1183 } else {
1184 HANDLE_PENDING_EXCEPTION();
1185 }
1186 }
1187 }
1188 HANDLE_INSTRUCTION_END();
1189
1190 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1191 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1192 if (UNLIKELY(a == nullptr)) {
1193 ThrowNullPointerExceptionFromInterpreter();
1194 HANDLE_PENDING_EXCEPTION();
1195 } else {
1196 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
1197 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1198 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1199 auto* array = down_cast<LongArray*>(a);
1200 if (LIKELY(array->CheckIsValidIndex(index))) {
1201 array->SetWithoutChecks<transaction_active>(index, val);
1202 ADVANCE(2);
1203 } else {
1204 HANDLE_PENDING_EXCEPTION();
1205 }
1206 }
1207 }
1208 HANDLE_INSTRUCTION_END();
1209
1210 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1211 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1212 if (UNLIKELY(a == nullptr)) {
1213 ThrowNullPointerExceptionFromInterpreter();
1214 HANDLE_PENDING_EXCEPTION();
1215 } else {
1216 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1217 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
1218 ObjectArray<Object>* array = a->AsObjectArray<Object>();
1219 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
1220 array->SetWithoutChecks<transaction_active>(index, val);
1221 ADVANCE(2);
1222 } else {
1223 HANDLE_PENDING_EXCEPTION();
1224 }
1225 }
1226 }
1227 HANDLE_INSTRUCTION_END();
1228
1229 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
1230 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1231 self, shadow_frame, inst, inst_data);
1232 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1233 }
1234 HANDLE_INSTRUCTION_END();
1235
1236 HANDLE_INSTRUCTION_START(IGET_BYTE) {
1237 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1238 self, shadow_frame, inst, inst_data);
1239 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1240 }
1241 HANDLE_INSTRUCTION_END();
1242
1243 HANDLE_INSTRUCTION_START(IGET_CHAR) {
1244 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1245 self, shadow_frame, inst, inst_data);
1246 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1247 }
1248 HANDLE_INSTRUCTION_END();
1249
1250 HANDLE_INSTRUCTION_START(IGET_SHORT) {
1251 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1252 self, shadow_frame, inst, inst_data);
1253 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1254 }
1255 HANDLE_INSTRUCTION_END();
1256
1257 HANDLE_INSTRUCTION_START(IGET) {
1258 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1259 self, shadow_frame, inst, inst_data);
1260 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1261 }
1262 HANDLE_INSTRUCTION_END();
1263
1264 HANDLE_INSTRUCTION_START(IGET_WIDE) {
1265 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1266 self, shadow_frame, inst, inst_data);
1267 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1268 }
1269 HANDLE_INSTRUCTION_END();
1270
1271 HANDLE_INSTRUCTION_START(IGET_OBJECT) {
1272 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1273 self, shadow_frame, inst, inst_data);
1274 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1275 }
1276 HANDLE_INSTRUCTION_END();
1277
1278 HANDLE_INSTRUCTION_START(IGET_QUICK) {
1279 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
1280 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1281 }
1282 HANDLE_INSTRUCTION_END();
1283
1284 HANDLE_INSTRUCTION_START(IGET_BOOLEAN_QUICK) {
1285 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1286 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1287 }
1288 HANDLE_INSTRUCTION_END();
1289
1290 HANDLE_INSTRUCTION_START(IGET_BYTE_QUICK) {
1291 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1292 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1293 }
1294 HANDLE_INSTRUCTION_END();
1295
1296 HANDLE_INSTRUCTION_START(IGET_CHAR_QUICK) {
1297 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1298 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1299 }
1300 HANDLE_INSTRUCTION_END();
1301
1302 HANDLE_INSTRUCTION_START(IGET_SHORT_QUICK) {
1303 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1304 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1305 }
1306 HANDLE_INSTRUCTION_END();
1307
1308 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
1309 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
1310 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1311 }
1312 HANDLE_INSTRUCTION_END();
1313
1314 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) {
1315 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
1316 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1317 }
1318 HANDLE_INSTRUCTION_END();
1319
1320 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
1321 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1322 self, shadow_frame, inst, inst_data);
1323 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1324 }
1325 HANDLE_INSTRUCTION_END();
1326
1327 HANDLE_INSTRUCTION_START(SGET_BYTE) {
1328 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1329 self, shadow_frame, inst, inst_data);
1330 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1331 }
1332 HANDLE_INSTRUCTION_END();
1333
1334 HANDLE_INSTRUCTION_START(SGET_CHAR) {
1335 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1336 self, shadow_frame, inst, inst_data);
1337 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1338 }
1339 HANDLE_INSTRUCTION_END();
1340
1341 HANDLE_INSTRUCTION_START(SGET_SHORT) {
1342 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1343 self, shadow_frame, inst, inst_data);
1344 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1345 }
1346 HANDLE_INSTRUCTION_END();
1347
1348 HANDLE_INSTRUCTION_START(SGET) {
1349 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1350 self, shadow_frame, inst, inst_data);
1351 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1352 }
1353 HANDLE_INSTRUCTION_END();
1354
1355 HANDLE_INSTRUCTION_START(SGET_WIDE) {
1356 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1357 self, shadow_frame, inst, inst_data);
1358 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1359 }
1360 HANDLE_INSTRUCTION_END();
1361
1362 HANDLE_INSTRUCTION_START(SGET_OBJECT) {
1363 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1364 self, shadow_frame, inst, inst_data);
1365 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1366 }
1367 HANDLE_INSTRUCTION_END();
1368
1369 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) {
1370 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1371 transaction_active>(self, shadow_frame, inst, inst_data);
1372 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1373 }
1374 HANDLE_INSTRUCTION_END();
1375
1376 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
1377 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1378 transaction_active>(self, shadow_frame, inst, inst_data);
1379 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1380 }
1381 HANDLE_INSTRUCTION_END();
1382
1383 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
1384 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1385 transaction_active>(self, shadow_frame, inst, inst_data);
1386 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1387 }
1388 HANDLE_INSTRUCTION_END();
1389
1390 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
1391 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1392 transaction_active>(self, shadow_frame, inst, inst_data);
1393 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1394 }
1395 HANDLE_INSTRUCTION_END();
1396
1397 HANDLE_INSTRUCTION_START(IPUT) {
1398 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1399 transaction_active>(self, shadow_frame, inst, inst_data);
1400 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1401 }
1402 HANDLE_INSTRUCTION_END();
1403
1404 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
1405 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1406 transaction_active>(self, shadow_frame, inst, inst_data);
1407 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1408 }
1409 HANDLE_INSTRUCTION_END();
1410
1411 HANDLE_INSTRUCTION_START(IPUT_OBJECT) {
1412 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1413 transaction_active>(self, shadow_frame, inst, inst_data);
1414 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1415 }
1416 HANDLE_INSTRUCTION_END();
1417
1418 HANDLE_INSTRUCTION_START(IPUT_QUICK) {
1419 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1420 shadow_frame, inst, inst_data);
1421 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1422 }
1423 HANDLE_INSTRUCTION_END();
1424
1425 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN_QUICK) {
1426 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1427 shadow_frame, inst, inst_data);
1428 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1429 }
1430 HANDLE_INSTRUCTION_END();
1431
1432 HANDLE_INSTRUCTION_START(IPUT_BYTE_QUICK) {
1433 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1434 shadow_frame, inst, inst_data);
1435 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1436 }
1437 HANDLE_INSTRUCTION_END();
1438
1439 HANDLE_INSTRUCTION_START(IPUT_CHAR_QUICK) {
1440 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1441 shadow_frame, inst, inst_data);
1442 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1443 }
1444 HANDLE_INSTRUCTION_END();
1445
1446 HANDLE_INSTRUCTION_START(IPUT_SHORT_QUICK) {
1447 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1448 shadow_frame, inst, inst_data);
1449 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1450 }
1451 HANDLE_INSTRUCTION_END();
1452
1453 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
1454 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1455 shadow_frame, inst, inst_data);
1456 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1457 }
1458 HANDLE_INSTRUCTION_END();
1459
1460 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
1461 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1462 shadow_frame, inst, inst_data);
1463 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1464 }
1465 HANDLE_INSTRUCTION_END();
1466
1467 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
1468 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1469 transaction_active>(self, shadow_frame, inst, inst_data);
1470 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1471 }
1472 HANDLE_INSTRUCTION_END();
1473
1474 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
1475 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1476 transaction_active>(self, shadow_frame, inst, inst_data);
1477 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1478 }
1479 HANDLE_INSTRUCTION_END();
1480
1481 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
1482 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1483 transaction_active>(self, shadow_frame, inst, inst_data);
1484 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1485 }
1486 HANDLE_INSTRUCTION_END();
1487
1488 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
1489 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1490 transaction_active>(self, shadow_frame, inst, inst_data);
1491 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1492 }
1493 HANDLE_INSTRUCTION_END();
1494
1495 HANDLE_INSTRUCTION_START(SPUT) {
1496 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1497 transaction_active>(self, shadow_frame, inst, inst_data);
1498 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1499 }
1500 HANDLE_INSTRUCTION_END();
1501
1502 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
1503 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1504 transaction_active>(self, shadow_frame, inst, inst_data);
1505 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1506 }
1507 HANDLE_INSTRUCTION_END();
1508
1509 HANDLE_INSTRUCTION_START(SPUT_OBJECT) {
1510 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1511 transaction_active>(self, shadow_frame, inst, inst_data);
1512 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1513 }
1514 HANDLE_INSTRUCTION_END();
1515
1516 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) {
1517 bool success = DoInvoke<kVirtual, false, do_access_check>(
1518 self, shadow_frame, inst, inst_data, &result_register);
1519 UPDATE_HANDLER_TABLE();
1520 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1521 }
1522 HANDLE_INSTRUCTION_END();
1523
1524 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
1525 bool success = DoInvoke<kVirtual, true, do_access_check>(
1526 self, shadow_frame, inst, inst_data, &result_register);
1527 UPDATE_HANDLER_TABLE();
1528 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1529 }
1530 HANDLE_INSTRUCTION_END();
1531
1532 HANDLE_INSTRUCTION_START(INVOKE_SUPER) {
1533 bool success = DoInvoke<kSuper, false, do_access_check>(
1534 self, shadow_frame, inst, inst_data, &result_register);
1535 UPDATE_HANDLER_TABLE();
1536 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1537 }
1538 HANDLE_INSTRUCTION_END();
1539
1540 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) {
1541 bool success = DoInvoke<kSuper, true, do_access_check>(
1542 self, shadow_frame, inst, inst_data, &result_register);
1543 UPDATE_HANDLER_TABLE();
1544 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1545 }
1546 HANDLE_INSTRUCTION_END();
1547
1548 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) {
1549 bool success = DoInvoke<kDirect, false, do_access_check>(
1550 self, shadow_frame, inst, inst_data, &result_register);
1551 UPDATE_HANDLER_TABLE();
1552 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1553 }
1554 HANDLE_INSTRUCTION_END();
1555
1556 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) {
1557 bool success = DoInvoke<kDirect, true, do_access_check>(
1558 self, shadow_frame, inst, inst_data, &result_register);
1559 UPDATE_HANDLER_TABLE();
1560 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1561 }
1562 HANDLE_INSTRUCTION_END();
1563
1564 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) {
1565 bool success = DoInvoke<kInterface, false, do_access_check>(
1566 self, shadow_frame, inst, inst_data, &result_register);
1567 UPDATE_HANDLER_TABLE();
1568 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1569 }
1570 HANDLE_INSTRUCTION_END();
1571
1572 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) {
1573 bool success = DoInvoke<kInterface, true, do_access_check>(
1574 self, shadow_frame, inst, inst_data, &result_register);
1575 UPDATE_HANDLER_TABLE();
1576 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1577 }
1578 HANDLE_INSTRUCTION_END();
1579
1580 HANDLE_INSTRUCTION_START(INVOKE_STATIC) {
1581 bool success = DoInvoke<kStatic, false, do_access_check>(
1582 self, shadow_frame, inst, inst_data, &result_register);
1583 UPDATE_HANDLER_TABLE();
1584 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1585 }
1586 HANDLE_INSTRUCTION_END();
1587
1588 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) {
1589 bool success = DoInvoke<kStatic, true, do_access_check>(
1590 self, shadow_frame, inst, inst_data, &result_register);
1591 UPDATE_HANDLER_TABLE();
1592 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1593 }
1594 HANDLE_INSTRUCTION_END();
1595
1596 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) {
1597 bool success = DoInvokeVirtualQuick<false>(
1598 self, shadow_frame, inst, inst_data, &result_register);
1599 UPDATE_HANDLER_TABLE();
1600 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1601 }
1602 HANDLE_INSTRUCTION_END();
1603
1604 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) {
1605 bool success = DoInvokeVirtualQuick<true>(
1606 self, shadow_frame, inst, inst_data, &result_register);
1607 UPDATE_HANDLER_TABLE();
1608 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1609 }
1610 HANDLE_INSTRUCTION_END();
1611
1612 HANDLE_INSTRUCTION_START(NEG_INT)
1613 shadow_frame.SetVReg(
1614 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1615 ADVANCE(1);
1616 HANDLE_INSTRUCTION_END();
1617
1618 HANDLE_INSTRUCTION_START(NOT_INT)
1619 shadow_frame.SetVReg(
1620 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1621 ADVANCE(1);
1622 HANDLE_INSTRUCTION_END();
1623
1624 HANDLE_INSTRUCTION_START(NEG_LONG)
1625 shadow_frame.SetVRegLong(
1626 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1627 ADVANCE(1);
1628 HANDLE_INSTRUCTION_END();
1629
1630 HANDLE_INSTRUCTION_START(NOT_LONG)
1631 shadow_frame.SetVRegLong(
1632 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1633 ADVANCE(1);
1634 HANDLE_INSTRUCTION_END();
1635
1636 HANDLE_INSTRUCTION_START(NEG_FLOAT)
1637 shadow_frame.SetVRegFloat(
1638 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
1639 ADVANCE(1);
1640 HANDLE_INSTRUCTION_END();
1641
1642 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
1643 shadow_frame.SetVRegDouble(
1644 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
1645 ADVANCE(1);
1646 HANDLE_INSTRUCTION_END();
1647
1648 HANDLE_INSTRUCTION_START(INT_TO_LONG)
1649 shadow_frame.SetVRegLong(
1650 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1651 ADVANCE(1);
1652 HANDLE_INSTRUCTION_END();
1653
1654 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
1655 shadow_frame.SetVRegFloat(
1656 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1657 ADVANCE(1);
1658 HANDLE_INSTRUCTION_END();
1659
1660 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
1661 shadow_frame.SetVRegDouble(
1662 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
1663 ADVANCE(1);
1664 HANDLE_INSTRUCTION_END();
1665
1666 HANDLE_INSTRUCTION_START(LONG_TO_INT)
1667 shadow_frame.SetVReg(
1668 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1669 ADVANCE(1);
1670 HANDLE_INSTRUCTION_END();
1671
1672 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
1673 shadow_frame.SetVRegFloat(
1674 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1675 ADVANCE(1);
1676 HANDLE_INSTRUCTION_END();
1677
1678 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
1679 shadow_frame.SetVRegDouble(
1680 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
1681 ADVANCE(1);
1682 HANDLE_INSTRUCTION_END();
1683
1684 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
1685 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
1686 int32_t result = art_float_to_integral<int32_t, float>(val);
1687 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
1688 ADVANCE(1);
1689 }
1690 HANDLE_INSTRUCTION_END();
1691
1692 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
1693 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
1694 int64_t result = art_float_to_integral<int64_t, float>(val);
1695 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
1696 ADVANCE(1);
1697 }
1698 HANDLE_INSTRUCTION_END();
1699
1700 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
1701 shadow_frame.SetVRegDouble(
1702 inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
1703 ADVANCE(1);
1704 HANDLE_INSTRUCTION_END();
1705
1706 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
1707 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
1708 int32_t result = art_float_to_integral<int32_t, double>(val);
1709 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
1710 ADVANCE(1);
1711 }
1712 HANDLE_INSTRUCTION_END();
1713
1714 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
1715 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
1716 int64_t result = art_float_to_integral<int64_t, double>(val);
1717 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
1718 ADVANCE(1);
1719 }
1720 HANDLE_INSTRUCTION_END();
1721
1722 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
1723 shadow_frame.SetVRegFloat(
1724 inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
1725 ADVANCE(1);
1726 HANDLE_INSTRUCTION_END();
1727
1728 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
1729 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1730 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
1731 ADVANCE(1);
1732 HANDLE_INSTRUCTION_END();
1733
1734 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
1735 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1736 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
1737 ADVANCE(1);
1738 HANDLE_INSTRUCTION_END();
1739
1740 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
1741 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1742 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
1743 ADVANCE(1);
1744 HANDLE_INSTRUCTION_END();
1745
1746 HANDLE_INSTRUCTION_START(ADD_INT)
1747 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1748 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1749 shadow_frame.GetVReg(inst->VRegC_23x())));
1750 ADVANCE(2);
1751 HANDLE_INSTRUCTION_END();
1752
1753 HANDLE_INSTRUCTION_START(SUB_INT)
1754 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1755 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1756 shadow_frame.GetVReg(inst->VRegC_23x())));
1757 ADVANCE(2);
1758 HANDLE_INSTRUCTION_END();
1759
1760 HANDLE_INSTRUCTION_START(MUL_INT)
1761 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1762 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1763 shadow_frame.GetVReg(inst->VRegC_23x())));
1764 ADVANCE(2);
1765 HANDLE_INSTRUCTION_END();
1766
1767 HANDLE_INSTRUCTION_START(DIV_INT) {
1768 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1769 shadow_frame.GetVReg(inst->VRegB_23x()),
1770 shadow_frame.GetVReg(inst->VRegC_23x()));
1771 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1772 }
1773 HANDLE_INSTRUCTION_END();
1774
1775 HANDLE_INSTRUCTION_START(REM_INT) {
1776 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1777 shadow_frame.GetVReg(inst->VRegB_23x()),
1778 shadow_frame.GetVReg(inst->VRegC_23x()));
1779 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1780 }
1781 HANDLE_INSTRUCTION_END();
1782
1783 HANDLE_INSTRUCTION_START(SHL_INT)
1784 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1785 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1786 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1787 ADVANCE(2);
1788 HANDLE_INSTRUCTION_END();
1789
1790 HANDLE_INSTRUCTION_START(SHR_INT)
1791 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1792 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1793 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1794 ADVANCE(2);
1795 HANDLE_INSTRUCTION_END();
1796
1797 HANDLE_INSTRUCTION_START(USHR_INT)
1798 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1799 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1800 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1801 ADVANCE(2);
1802 HANDLE_INSTRUCTION_END();
1803
1804 HANDLE_INSTRUCTION_START(AND_INT)
1805 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1806 shadow_frame.GetVReg(inst->VRegB_23x()) &
1807 shadow_frame.GetVReg(inst->VRegC_23x()));
1808 ADVANCE(2);
1809 HANDLE_INSTRUCTION_END();
1810
1811 HANDLE_INSTRUCTION_START(OR_INT)
1812 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1813 shadow_frame.GetVReg(inst->VRegB_23x()) |
1814 shadow_frame.GetVReg(inst->VRegC_23x()));
1815 ADVANCE(2);
1816 HANDLE_INSTRUCTION_END();
1817
1818 HANDLE_INSTRUCTION_START(XOR_INT)
1819 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
1820 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1821 shadow_frame.GetVReg(inst->VRegC_23x()));
1822 ADVANCE(2);
1823 HANDLE_INSTRUCTION_END();
1824
1825 HANDLE_INSTRUCTION_START(ADD_LONG)
1826 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1827 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1828 shadow_frame.GetVRegLong(inst->VRegC_23x())));
1829 ADVANCE(2);
1830 HANDLE_INSTRUCTION_END();
1831
1832 HANDLE_INSTRUCTION_START(SUB_LONG)
1833 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1834 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1835 shadow_frame.GetVRegLong(inst->VRegC_23x())));
1836 ADVANCE(2);
1837 HANDLE_INSTRUCTION_END();
1838
1839 HANDLE_INSTRUCTION_START(MUL_LONG)
1840 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1841 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1842 shadow_frame.GetVRegLong(inst->VRegC_23x())));
1843 ADVANCE(2);
1844 HANDLE_INSTRUCTION_END();
1845
1846 HANDLE_INSTRUCTION_START(DIV_LONG) {
1847 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1848 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1849 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1850 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1851 }
1852 HANDLE_INSTRUCTION_END();
1853
1854 HANDLE_INSTRUCTION_START(REM_LONG) {
1855 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1856 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1857 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1858 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1859 }
1860 HANDLE_INSTRUCTION_END();
1861
1862 HANDLE_INSTRUCTION_START(AND_LONG)
1863 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1864 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1865 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1866 ADVANCE(2);
1867 HANDLE_INSTRUCTION_END();
1868
1869 HANDLE_INSTRUCTION_START(OR_LONG)
1870 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1871 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1872 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1873 ADVANCE(2);
1874 HANDLE_INSTRUCTION_END();
1875
1876 HANDLE_INSTRUCTION_START(XOR_LONG)
1877 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1878 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1879 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1880 ADVANCE(2);
1881 HANDLE_INSTRUCTION_END();
1882
1883 HANDLE_INSTRUCTION_START(SHL_LONG)
1884 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1885 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1886 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1887 ADVANCE(2);
1888 HANDLE_INSTRUCTION_END();
1889
1890 HANDLE_INSTRUCTION_START(SHR_LONG)
1891 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1892 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1893 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1894 ADVANCE(2);
1895 HANDLE_INSTRUCTION_END();
1896
1897 HANDLE_INSTRUCTION_START(USHR_LONG)
1898 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
1899 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1900 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1901 ADVANCE(2);
1902 HANDLE_INSTRUCTION_END();
1903
1904 HANDLE_INSTRUCTION_START(ADD_FLOAT)
1905 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
1906 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1907 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1908 ADVANCE(2);
1909 HANDLE_INSTRUCTION_END();
1910
1911 HANDLE_INSTRUCTION_START(SUB_FLOAT)
1912 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
1913 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1914 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1915 ADVANCE(2);
1916 HANDLE_INSTRUCTION_END();
1917
1918 HANDLE_INSTRUCTION_START(MUL_FLOAT)
1919 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
1920 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1921 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1922 ADVANCE(2);
1923 HANDLE_INSTRUCTION_END();
1924
1925 HANDLE_INSTRUCTION_START(DIV_FLOAT)
1926 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
1927 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1928 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1929 ADVANCE(2);
1930 HANDLE_INSTRUCTION_END();
1931
1932 HANDLE_INSTRUCTION_START(REM_FLOAT)
1933 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
1934 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1935 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1936 ADVANCE(2);
1937 HANDLE_INSTRUCTION_END();
1938
1939 HANDLE_INSTRUCTION_START(ADD_DOUBLE)
1940 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
1941 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1942 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1943 ADVANCE(2);
1944 HANDLE_INSTRUCTION_END();
1945
1946 HANDLE_INSTRUCTION_START(SUB_DOUBLE)
1947 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
1948 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1949 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1950 ADVANCE(2);
1951 HANDLE_INSTRUCTION_END();
1952
1953 HANDLE_INSTRUCTION_START(MUL_DOUBLE)
1954 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
1955 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1956 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1957 ADVANCE(2);
1958 HANDLE_INSTRUCTION_END();
1959
1960 HANDLE_INSTRUCTION_START(DIV_DOUBLE)
1961 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
1962 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1963 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1964 ADVANCE(2);
1965 HANDLE_INSTRUCTION_END();
1966
1967 HANDLE_INSTRUCTION_START(REM_DOUBLE)
1968 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
1969 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1970 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1971 ADVANCE(2);
1972 HANDLE_INSTRUCTION_END();
1973
1974 HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) {
1975 uint32_t vregA = inst->VRegA_12x(inst_data);
1976 shadow_frame.SetVReg(vregA,
1977 SafeAdd(shadow_frame.GetVReg(vregA),
1978 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
1979 ADVANCE(1);
1980 }
1981 HANDLE_INSTRUCTION_END();
1982
1983 HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) {
1984 uint32_t vregA = inst->VRegA_12x(inst_data);
1985 shadow_frame.SetVReg(vregA,
1986 SafeSub(shadow_frame.GetVReg(vregA),
1987 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
1988 ADVANCE(1);
1989 }
1990 HANDLE_INSTRUCTION_END();
1991
1992 HANDLE_INSTRUCTION_START(MUL_INT_2ADDR) {
1993 uint32_t vregA = inst->VRegA_12x(inst_data);
1994 shadow_frame.SetVReg(vregA,
1995 SafeMul(shadow_frame.GetVReg(vregA),
1996 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
1997 ADVANCE(1);
1998 }
1999 HANDLE_INSTRUCTION_END();
2000
2001 HANDLE_INSTRUCTION_START(DIV_INT_2ADDR) {
2002 uint32_t vregA = inst->VRegA_12x(inst_data);
2003 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
2004 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
2005 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2006 }
2007 HANDLE_INSTRUCTION_END();
2008
2009 HANDLE_INSTRUCTION_START(REM_INT_2ADDR) {
2010 uint32_t vregA = inst->VRegA_12x(inst_data);
2011 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
2012 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
2013 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2014 }
2015 HANDLE_INSTRUCTION_END();
2016
2017 HANDLE_INSTRUCTION_START(SHL_INT_2ADDR) {
2018 uint32_t vregA = inst->VRegA_12x(inst_data);
2019 shadow_frame.SetVReg(vregA,
2020 shadow_frame.GetVReg(vregA) <<
2021 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
2022 ADVANCE(1);
2023 }
2024 HANDLE_INSTRUCTION_END();
2025
2026 HANDLE_INSTRUCTION_START(SHR_INT_2ADDR) {
2027 uint32_t vregA = inst->VRegA_12x(inst_data);
2028 shadow_frame.SetVReg(vregA,
2029 shadow_frame.GetVReg(vregA) >>
2030 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
2031 ADVANCE(1);
2032 }
2033 HANDLE_INSTRUCTION_END();
2034
2035 HANDLE_INSTRUCTION_START(USHR_INT_2ADDR) {
2036 uint32_t vregA = inst->VRegA_12x(inst_data);
2037 shadow_frame.SetVReg(vregA,
2038 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
2039 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
2040 ADVANCE(1);
2041 }
2042 HANDLE_INSTRUCTION_END();
2043
2044 HANDLE_INSTRUCTION_START(AND_INT_2ADDR) {
2045 uint32_t vregA = inst->VRegA_12x(inst_data);
2046 shadow_frame.SetVReg(vregA,
2047 shadow_frame.GetVReg(vregA) &
2048 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
2049 ADVANCE(1);
2050 }
2051 HANDLE_INSTRUCTION_END();
2052
2053 HANDLE_INSTRUCTION_START(OR_INT_2ADDR) {
2054 uint32_t vregA = inst->VRegA_12x(inst_data);
2055 shadow_frame.SetVReg(vregA,
2056 shadow_frame.GetVReg(vregA) |
2057 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
2058 ADVANCE(1);
2059 }
2060 HANDLE_INSTRUCTION_END();
2061
2062 HANDLE_INSTRUCTION_START(XOR_INT_2ADDR) {
2063 uint32_t vregA = inst->VRegA_12x(inst_data);
2064 shadow_frame.SetVReg(vregA,
2065 shadow_frame.GetVReg(vregA) ^
2066 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
2067 ADVANCE(1);
2068 }
2069 HANDLE_INSTRUCTION_END();
2070
2071 HANDLE_INSTRUCTION_START(ADD_LONG_2ADDR) {
2072 uint32_t vregA = inst->VRegA_12x(inst_data);
2073 shadow_frame.SetVRegLong(vregA,
2074 SafeAdd(shadow_frame.GetVRegLong(vregA),
2075 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
2076 ADVANCE(1);
2077 }
2078 HANDLE_INSTRUCTION_END();
2079
2080 HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) {
2081 uint32_t vregA = inst->VRegA_12x(inst_data);
2082 shadow_frame.SetVRegLong(vregA,
2083 SafeSub(shadow_frame.GetVRegLong(vregA),
2084 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
2085 ADVANCE(1);
2086 }
2087 HANDLE_INSTRUCTION_END();
2088
2089 HANDLE_INSTRUCTION_START(MUL_LONG_2ADDR) {
2090 uint32_t vregA = inst->VRegA_12x(inst_data);
2091 shadow_frame.SetVRegLong(vregA,
2092 SafeMul(shadow_frame.GetVRegLong(vregA),
2093 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
2094 ADVANCE(1);
2095 }
2096 HANDLE_INSTRUCTION_END();
2097
2098 HANDLE_INSTRUCTION_START(DIV_LONG_2ADDR) {
2099 uint32_t vregA = inst->VRegA_12x(inst_data);
2100 bool success = DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
2101 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
2102 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2103 }
2104 HANDLE_INSTRUCTION_END();
2105
2106 HANDLE_INSTRUCTION_START(REM_LONG_2ADDR) {
2107 uint32_t vregA = inst->VRegA_12x(inst_data);
2108 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
2109 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
2110 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2111 }
2112 HANDLE_INSTRUCTION_END();
2113
2114 HANDLE_INSTRUCTION_START(AND_LONG_2ADDR) {
2115 uint32_t vregA = inst->VRegA_12x(inst_data);
2116 shadow_frame.SetVRegLong(vregA,
2117 shadow_frame.GetVRegLong(vregA) &
2118 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
2119 ADVANCE(1);
2120 }
2121 HANDLE_INSTRUCTION_END();
2122
2123 HANDLE_INSTRUCTION_START(OR_LONG_2ADDR) {
2124 uint32_t vregA = inst->VRegA_12x(inst_data);
2125 shadow_frame.SetVRegLong(vregA,
2126 shadow_frame.GetVRegLong(vregA) |
2127 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
2128 ADVANCE(1);
2129 }
2130 HANDLE_INSTRUCTION_END();
2131
2132 HANDLE_INSTRUCTION_START(XOR_LONG_2ADDR) {
2133 uint32_t vregA = inst->VRegA_12x(inst_data);
2134 shadow_frame.SetVRegLong(vregA,
2135 shadow_frame.GetVRegLong(vregA) ^
2136 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
2137 ADVANCE(1);
2138 }
2139 HANDLE_INSTRUCTION_END();
2140
2141 HANDLE_INSTRUCTION_START(SHL_LONG_2ADDR) {
2142 uint32_t vregA = inst->VRegA_12x(inst_data);
2143 shadow_frame.SetVRegLong(vregA,
2144 shadow_frame.GetVRegLong(vregA) <<
2145 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
2146 ADVANCE(1);
2147 }
2148 HANDLE_INSTRUCTION_END();
2149
2150 HANDLE_INSTRUCTION_START(SHR_LONG_2ADDR) {
2151 uint32_t vregA = inst->VRegA_12x(inst_data);
2152 shadow_frame.SetVRegLong(vregA,
2153 shadow_frame.GetVRegLong(vregA) >>
2154 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
2155 ADVANCE(1);
2156 }
2157 HANDLE_INSTRUCTION_END();
2158
2159 HANDLE_INSTRUCTION_START(USHR_LONG_2ADDR) {
2160 uint32_t vregA = inst->VRegA_12x(inst_data);
2161 shadow_frame.SetVRegLong(vregA,
2162 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
2163 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
2164 ADVANCE(1);
2165 }
2166 HANDLE_INSTRUCTION_END();
2167
2168 HANDLE_INSTRUCTION_START(ADD_FLOAT_2ADDR) {
2169 uint32_t vregA = inst->VRegA_12x(inst_data);
2170 shadow_frame.SetVRegFloat(vregA,
2171 shadow_frame.GetVRegFloat(vregA) +
2172 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
2173 ADVANCE(1);
2174 }
2175 HANDLE_INSTRUCTION_END();
2176
2177 HANDLE_INSTRUCTION_START(SUB_FLOAT_2ADDR) {
2178 uint32_t vregA = inst->VRegA_12x(inst_data);
2179 shadow_frame.SetVRegFloat(vregA,
2180 shadow_frame.GetVRegFloat(vregA) -
2181 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
2182 ADVANCE(1);
2183 }
2184 HANDLE_INSTRUCTION_END();
2185
2186 HANDLE_INSTRUCTION_START(MUL_FLOAT_2ADDR) {
2187 uint32_t vregA = inst->VRegA_12x(inst_data);
2188 shadow_frame.SetVRegFloat(vregA,
2189 shadow_frame.GetVRegFloat(vregA) *
2190 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
2191 ADVANCE(1);
2192 }
2193 HANDLE_INSTRUCTION_END();
2194
2195 HANDLE_INSTRUCTION_START(DIV_FLOAT_2ADDR) {
2196 uint32_t vregA = inst->VRegA_12x(inst_data);
2197 shadow_frame.SetVRegFloat(vregA,
2198 shadow_frame.GetVRegFloat(vregA) /
2199 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
2200 ADVANCE(1);
2201 }
2202 HANDLE_INSTRUCTION_END();
2203
2204 HANDLE_INSTRUCTION_START(REM_FLOAT_2ADDR) {
2205 uint32_t vregA = inst->VRegA_12x(inst_data);
2206 shadow_frame.SetVRegFloat(vregA,
2207 fmodf(shadow_frame.GetVRegFloat(vregA),
2208 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
2209 ADVANCE(1);
2210 }
2211 HANDLE_INSTRUCTION_END();
2212
2213 HANDLE_INSTRUCTION_START(ADD_DOUBLE_2ADDR) {
2214 uint32_t vregA = inst->VRegA_12x(inst_data);
2215 shadow_frame.SetVRegDouble(vregA,
2216 shadow_frame.GetVRegDouble(vregA) +
2217 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
2218 ADVANCE(1);
2219 }
2220 HANDLE_INSTRUCTION_END();
2221
2222 HANDLE_INSTRUCTION_START(SUB_DOUBLE_2ADDR) {
2223 uint32_t vregA = inst->VRegA_12x(inst_data);
2224 shadow_frame.SetVRegDouble(vregA,
2225 shadow_frame.GetVRegDouble(vregA) -
2226 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
2227 ADVANCE(1);
2228 }
2229 HANDLE_INSTRUCTION_END();
2230
2231 HANDLE_INSTRUCTION_START(MUL_DOUBLE_2ADDR) {
2232 uint32_t vregA = inst->VRegA_12x(inst_data);
2233 shadow_frame.SetVRegDouble(vregA,
2234 shadow_frame.GetVRegDouble(vregA) *
2235 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
2236 ADVANCE(1);
2237 }
2238 HANDLE_INSTRUCTION_END();
2239
2240 HANDLE_INSTRUCTION_START(DIV_DOUBLE_2ADDR) {
2241 uint32_t vregA = inst->VRegA_12x(inst_data);
2242 shadow_frame.SetVRegDouble(vregA,
2243 shadow_frame.GetVRegDouble(vregA) /
2244 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
2245 ADVANCE(1);
2246 }
2247 HANDLE_INSTRUCTION_END();
2248
2249 HANDLE_INSTRUCTION_START(REM_DOUBLE_2ADDR) {
2250 uint32_t vregA = inst->VRegA_12x(inst_data);
2251 shadow_frame.SetVRegDouble(vregA,
2252 fmod(shadow_frame.GetVRegDouble(vregA),
2253 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
2254 ADVANCE(1);
2255 }
2256 HANDLE_INSTRUCTION_END();
2257
2258 HANDLE_INSTRUCTION_START(ADD_INT_LIT16)
2259 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2260 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2261 inst->VRegC_22s()));
2262 ADVANCE(2);
2263 HANDLE_INSTRUCTION_END();
2264
2265 HANDLE_INSTRUCTION_START(RSUB_INT)
2266 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2267 SafeSub(inst->VRegC_22s(),
2268 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
2269 ADVANCE(2);
2270 HANDLE_INSTRUCTION_END();
2271
2272 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
2273 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2274 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2275 inst->VRegC_22s()));
2276 ADVANCE(2);
2277 HANDLE_INSTRUCTION_END();
2278
2279 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
2280 bool success = DoIntDivide(
2281 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2282 inst->VRegC_22s());
2283 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2284 }
2285 HANDLE_INSTRUCTION_END();
2286
2287 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
2288 bool success = DoIntRemainder(
2289 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2290 inst->VRegC_22s());
2291 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2292 }
2293 HANDLE_INSTRUCTION_END();
2294
2295 HANDLE_INSTRUCTION_START(AND_INT_LIT16)
2296 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2297 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
2298 inst->VRegC_22s());
2299 ADVANCE(2);
2300 HANDLE_INSTRUCTION_END();
2301
2302 HANDLE_INSTRUCTION_START(OR_INT_LIT16)
2303 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2304 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
2305 inst->VRegC_22s());
2306 ADVANCE(2);
2307 HANDLE_INSTRUCTION_END();
2308
2309 HANDLE_INSTRUCTION_START(XOR_INT_LIT16)
2310 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2311 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
2312 inst->VRegC_22s());
2313 ADVANCE(2);
2314 HANDLE_INSTRUCTION_END();
2315
2316 HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
2317 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2318 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()),
2319 inst->VRegC_22b()));
2320 ADVANCE(2);
2321 HANDLE_INSTRUCTION_END();
2322
2323 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
2324 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2325 SafeSub(inst->VRegC_22b(),
2326 shadow_frame.GetVReg(inst->VRegB_22b())));
2327 ADVANCE(2);
2328 HANDLE_INSTRUCTION_END();
2329
2330 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
2331 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2332 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()),
2333 inst->VRegC_22b()));
2334 ADVANCE(2);
2335 HANDLE_INSTRUCTION_END();
2336
2337 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
2338 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2339 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2340 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2341 }
2342 HANDLE_INSTRUCTION_END();
2343
2344 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
2345 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2346 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2347 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2348 }
2349 HANDLE_INSTRUCTION_END();
2350
2351 HANDLE_INSTRUCTION_START(AND_INT_LIT8)
2352 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2353 shadow_frame.GetVReg(inst->VRegB_22b()) &
2354 inst->VRegC_22b());
2355 ADVANCE(2);
2356 HANDLE_INSTRUCTION_END();
2357
2358 HANDLE_INSTRUCTION_START(OR_INT_LIT8)
2359 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2360 shadow_frame.GetVReg(inst->VRegB_22b()) |
2361 inst->VRegC_22b());
2362 ADVANCE(2);
2363 HANDLE_INSTRUCTION_END();
2364
2365 HANDLE_INSTRUCTION_START(XOR_INT_LIT8)
2366 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2367 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2368 inst->VRegC_22b());
2369 ADVANCE(2);
2370 HANDLE_INSTRUCTION_END();
2371
2372 HANDLE_INSTRUCTION_START(SHL_INT_LIT8)
2373 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2374 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2375 (inst->VRegC_22b() & 0x1f));
2376 ADVANCE(2);
2377 HANDLE_INSTRUCTION_END();
2378
2379 HANDLE_INSTRUCTION_START(SHR_INT_LIT8)
2380 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2381 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2382 (inst->VRegC_22b() & 0x1f));
2383 ADVANCE(2);
2384 HANDLE_INSTRUCTION_END();
2385
2386 HANDLE_INSTRUCTION_START(USHR_INT_LIT8)
2387 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
2388 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2389 (inst->VRegC_22b() & 0x1f));
2390 ADVANCE(2);
2391 HANDLE_INSTRUCTION_END();
2392
2393 HANDLE_INSTRUCTION_START(UNUSED_3E)
2394 UnexpectedOpcode(inst, shadow_frame);
2395 HANDLE_INSTRUCTION_END();
2396
2397 HANDLE_INSTRUCTION_START(UNUSED_3F)
2398 UnexpectedOpcode(inst, shadow_frame);
2399 HANDLE_INSTRUCTION_END();
2400
2401 HANDLE_INSTRUCTION_START(UNUSED_40)
2402 UnexpectedOpcode(inst, shadow_frame);
2403 HANDLE_INSTRUCTION_END();
2404
2405 HANDLE_INSTRUCTION_START(UNUSED_41)
2406 UnexpectedOpcode(inst, shadow_frame);
2407 HANDLE_INSTRUCTION_END();
2408
2409 HANDLE_INSTRUCTION_START(UNUSED_42)
2410 UnexpectedOpcode(inst, shadow_frame);
2411 HANDLE_INSTRUCTION_END();
2412
2413 HANDLE_INSTRUCTION_START(UNUSED_43)
2414 UnexpectedOpcode(inst, shadow_frame);
2415 HANDLE_INSTRUCTION_END();
2416
2417 HANDLE_INSTRUCTION_START(UNUSED_79)
2418 UnexpectedOpcode(inst, shadow_frame);
2419 HANDLE_INSTRUCTION_END();
2420
2421 HANDLE_INSTRUCTION_START(UNUSED_7A)
2422 UnexpectedOpcode(inst, shadow_frame);
2423 HANDLE_INSTRUCTION_END();
2424
2425 HANDLE_INSTRUCTION_START(UNUSED_F3)
2426 UnexpectedOpcode(inst, shadow_frame);
2427 HANDLE_INSTRUCTION_END();
2428
2429 HANDLE_INSTRUCTION_START(UNUSED_F4)
2430 UnexpectedOpcode(inst, shadow_frame);
2431 HANDLE_INSTRUCTION_END();
2432
2433 HANDLE_INSTRUCTION_START(UNUSED_F5)
2434 UnexpectedOpcode(inst, shadow_frame);
2435 HANDLE_INSTRUCTION_END();
2436
2437 HANDLE_INSTRUCTION_START(UNUSED_F6)
2438 UnexpectedOpcode(inst, shadow_frame);
2439 HANDLE_INSTRUCTION_END();
2440
2441 HANDLE_INSTRUCTION_START(UNUSED_F7)
2442 UnexpectedOpcode(inst, shadow_frame);
2443 HANDLE_INSTRUCTION_END();
2444
2445 HANDLE_INSTRUCTION_START(UNUSED_F8)
2446 UnexpectedOpcode(inst, shadow_frame);
2447 HANDLE_INSTRUCTION_END();
2448
2449 HANDLE_INSTRUCTION_START(UNUSED_F9)
2450 UnexpectedOpcode(inst, shadow_frame);
2451 HANDLE_INSTRUCTION_END();
2452
2453 HANDLE_INSTRUCTION_START(UNUSED_FA)
2454 UnexpectedOpcode(inst, shadow_frame);
2455 HANDLE_INSTRUCTION_END();
2456
2457 HANDLE_INSTRUCTION_START(UNUSED_FB)
2458 UnexpectedOpcode(inst, shadow_frame);
2459 HANDLE_INSTRUCTION_END();
2460
2461 HANDLE_INSTRUCTION_START(UNUSED_FC)
2462 UnexpectedOpcode(inst, shadow_frame);
2463 HANDLE_INSTRUCTION_END();
2464
2465 HANDLE_INSTRUCTION_START(UNUSED_FD)
2466 UnexpectedOpcode(inst, shadow_frame);
2467 HANDLE_INSTRUCTION_END();
2468
2469 HANDLE_INSTRUCTION_START(UNUSED_FE)
2470 UnexpectedOpcode(inst, shadow_frame);
2471 HANDLE_INSTRUCTION_END();
2472
2473 HANDLE_INSTRUCTION_START(UNUSED_FF)
2474 UnexpectedOpcode(inst, shadow_frame);
2475 HANDLE_INSTRUCTION_END();
2476
2477 exception_pending_label: {
2478 CHECK(self->IsExceptionPending());
2479 if (UNLIKELY(self->TestAllFlags())) {
2480 self->CheckSuspend();
2481 UPDATE_HANDLER_TABLE();
2482 }
2483 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
2484 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
2485 instrumentation);
2486 if (found_dex_pc == DexFile::kDexNoIndex) {
2487 return JValue(); /* Handled in caller. */
2488 } else {
2489 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2490 ADVANCE(displacement);
2491 }
2492 }
2493
2494 // Create alternative instruction handlers dedicated to instrumentation.
2495 // Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
2496 // Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
2497 // Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
2498 // compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
2499 // a constant condition that would remove the "if" statement so the test is free.
2500 #define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \
2501 alt_op_##code: { \
2502 Runtime* const runtime = Runtime::Current(); \
2503 const instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); \
2504 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
2505 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
2506 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \
2507 } \
2508 UPDATE_HANDLER_TABLE(); \
2509 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \
2510 }
2511 #include "dex_instruction_list.h"
2512 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2513 #undef DEX_INSTRUCTION_LIST
2514 #undef INSTRUMENTATION_INSTRUCTION_HANDLER
2515 } // NOLINT(readability/fn_size)
2516
2517 // Explicit definitions of ExecuteGotoImpl.
2518 template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
2519 JValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
2520 ShadowFrame& shadow_frame, JValue result_register);
2521 template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
2522 JValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
2523 ShadowFrame& shadow_frame, JValue result_register);
2524 template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2525 JValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
2526 ShadowFrame& shadow_frame, JValue result_register);
2527 template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2528 JValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
2529 ShadowFrame& shadow_frame, JValue result_register);
2530
2531 } // namespace interpreter
2532 } // namespace art
2533
2534 #endif
2535