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