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