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