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