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