1/* 2 * Copyright (C) 2016 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 "instruction_builder.h" 18 19#include "art_method-inl.h" 20#include "bytecode_utils.h" 21#include "class_linker.h" 22#include "dex_instruction-inl.h" 23#include "driver/compiler_options.h" 24#include "imtable-inl.h" 25#include "sharpening.h" 26#include "scoped_thread_state_change-inl.h" 27 28namespace art { 29 30void HInstructionBuilder::MaybeRecordStat(MethodCompilationStat compilation_stat) { 31 if (compilation_stats_ != nullptr) { 32 compilation_stats_->RecordStat(compilation_stat); 33 } 34} 35 36HBasicBlock* HInstructionBuilder::FindBlockStartingAt(uint32_t dex_pc) const { 37 return block_builder_->GetBlockAt(dex_pc); 38} 39 40inline ArenaVector<HInstruction*>* HInstructionBuilder::GetLocalsFor(HBasicBlock* block) { 41 ArenaVector<HInstruction*>* locals = &locals_for_[block->GetBlockId()]; 42 const size_t vregs = graph_->GetNumberOfVRegs(); 43 if (locals->size() == vregs) { 44 return locals; 45 } 46 return GetLocalsForWithAllocation(block, locals, vregs); 47} 48 49ArenaVector<HInstruction*>* HInstructionBuilder::GetLocalsForWithAllocation( 50 HBasicBlock* block, 51 ArenaVector<HInstruction*>* locals, 52 const size_t vregs) { 53 DCHECK_NE(locals->size(), vregs); 54 locals->resize(vregs, nullptr); 55 if (block->IsCatchBlock()) { 56 // We record incoming inputs of catch phis at throwing instructions and 57 // must therefore eagerly create the phis. Phis for undefined vregs will 58 // be deleted when the first throwing instruction with the vreg undefined 59 // is encountered. Unused phis will be removed by dead phi analysis. 60 for (size_t i = 0; i < vregs; ++i) { 61 // No point in creating the catch phi if it is already undefined at 62 // the first throwing instruction. 63 HInstruction* current_local_value = (*current_locals_)[i]; 64 if (current_local_value != nullptr) { 65 HPhi* phi = new (arena_) HPhi( 66 arena_, 67 i, 68 0, 69 current_local_value->GetType()); 70 block->AddPhi(phi); 71 (*locals)[i] = phi; 72 } 73 } 74 } 75 return locals; 76} 77 78inline HInstruction* HInstructionBuilder::ValueOfLocalAt(HBasicBlock* block, size_t local) { 79 ArenaVector<HInstruction*>* locals = GetLocalsFor(block); 80 return (*locals)[local]; 81} 82 83void HInstructionBuilder::InitializeBlockLocals() { 84 current_locals_ = GetLocalsFor(current_block_); 85 86 if (current_block_->IsCatchBlock()) { 87 // Catch phis were already created and inputs collected from throwing sites. 88 if (kIsDebugBuild) { 89 // Make sure there was at least one throwing instruction which initialized 90 // locals (guaranteed by HGraphBuilder) and that all try blocks have been 91 // visited already (from HTryBoundary scoping and reverse post order). 92 bool catch_block_visited = false; 93 for (HBasicBlock* current : graph_->GetReversePostOrder()) { 94 if (current == current_block_) { 95 catch_block_visited = true; 96 } else if (current->IsTryBlock()) { 97 const HTryBoundary& try_entry = current->GetTryCatchInformation()->GetTryEntry(); 98 if (try_entry.HasExceptionHandler(*current_block_)) { 99 DCHECK(!catch_block_visited) << "Catch block visited before its try block."; 100 } 101 } 102 } 103 DCHECK_EQ(current_locals_->size(), graph_->GetNumberOfVRegs()) 104 << "No instructions throwing into a live catch block."; 105 } 106 } else if (current_block_->IsLoopHeader()) { 107 // If the block is a loop header, we know we only have visited the pre header 108 // because we are visiting in reverse post order. We create phis for all initialized 109 // locals from the pre header. Their inputs will be populated at the end of 110 // the analysis. 111 for (size_t local = 0; local < current_locals_->size(); ++local) { 112 HInstruction* incoming = 113 ValueOfLocalAt(current_block_->GetLoopInformation()->GetPreHeader(), local); 114 if (incoming != nullptr) { 115 HPhi* phi = new (arena_) HPhi( 116 arena_, 117 local, 118 0, 119 incoming->GetType()); 120 current_block_->AddPhi(phi); 121 (*current_locals_)[local] = phi; 122 } 123 } 124 125 // Save the loop header so that the last phase of the analysis knows which 126 // blocks need to be updated. 127 loop_headers_.push_back(current_block_); 128 } else if (current_block_->GetPredecessors().size() > 0) { 129 // All predecessors have already been visited because we are visiting in reverse post order. 130 // We merge the values of all locals, creating phis if those values differ. 131 for (size_t local = 0; local < current_locals_->size(); ++local) { 132 bool one_predecessor_has_no_value = false; 133 bool is_different = false; 134 HInstruction* value = ValueOfLocalAt(current_block_->GetPredecessors()[0], local); 135 136 for (HBasicBlock* predecessor : current_block_->GetPredecessors()) { 137 HInstruction* current = ValueOfLocalAt(predecessor, local); 138 if (current == nullptr) { 139 one_predecessor_has_no_value = true; 140 break; 141 } else if (current != value) { 142 is_different = true; 143 } 144 } 145 146 if (one_predecessor_has_no_value) { 147 // If one predecessor has no value for this local, we trust the verifier has 148 // successfully checked that there is a store dominating any read after this block. 149 continue; 150 } 151 152 if (is_different) { 153 HInstruction* first_input = ValueOfLocalAt(current_block_->GetPredecessors()[0], local); 154 HPhi* phi = new (arena_) HPhi( 155 arena_, 156 local, 157 current_block_->GetPredecessors().size(), 158 first_input->GetType()); 159 for (size_t i = 0; i < current_block_->GetPredecessors().size(); i++) { 160 HInstruction* pred_value = ValueOfLocalAt(current_block_->GetPredecessors()[i], local); 161 phi->SetRawInputAt(i, pred_value); 162 } 163 current_block_->AddPhi(phi); 164 value = phi; 165 } 166 (*current_locals_)[local] = value; 167 } 168 } 169} 170 171void HInstructionBuilder::PropagateLocalsToCatchBlocks() { 172 const HTryBoundary& try_entry = current_block_->GetTryCatchInformation()->GetTryEntry(); 173 for (HBasicBlock* catch_block : try_entry.GetExceptionHandlers()) { 174 ArenaVector<HInstruction*>* handler_locals = GetLocalsFor(catch_block); 175 DCHECK_EQ(handler_locals->size(), current_locals_->size()); 176 for (size_t vreg = 0, e = current_locals_->size(); vreg < e; ++vreg) { 177 HInstruction* handler_value = (*handler_locals)[vreg]; 178 if (handler_value == nullptr) { 179 // Vreg was undefined at a previously encountered throwing instruction 180 // and the catch phi was deleted. Do not record the local value. 181 continue; 182 } 183 DCHECK(handler_value->IsPhi()); 184 185 HInstruction* local_value = (*current_locals_)[vreg]; 186 if (local_value == nullptr) { 187 // This is the first instruction throwing into `catch_block` where 188 // `vreg` is undefined. Delete the catch phi. 189 catch_block->RemovePhi(handler_value->AsPhi()); 190 (*handler_locals)[vreg] = nullptr; 191 } else { 192 // Vreg has been defined at all instructions throwing into `catch_block` 193 // encountered so far. Record the local value in the catch phi. 194 handler_value->AsPhi()->AddInput(local_value); 195 } 196 } 197 } 198} 199 200void HInstructionBuilder::AppendInstruction(HInstruction* instruction) { 201 current_block_->AddInstruction(instruction); 202 InitializeInstruction(instruction); 203} 204 205void HInstructionBuilder::InsertInstructionAtTop(HInstruction* instruction) { 206 if (current_block_->GetInstructions().IsEmpty()) { 207 current_block_->AddInstruction(instruction); 208 } else { 209 current_block_->InsertInstructionBefore(instruction, current_block_->GetFirstInstruction()); 210 } 211 InitializeInstruction(instruction); 212} 213 214void HInstructionBuilder::InitializeInstruction(HInstruction* instruction) { 215 if (instruction->NeedsEnvironment()) { 216 HEnvironment* environment = new (arena_) HEnvironment( 217 arena_, 218 current_locals_->size(), 219 graph_->GetArtMethod(), 220 instruction->GetDexPc(), 221 instruction); 222 environment->CopyFrom(*current_locals_); 223 instruction->SetRawEnvironment(environment); 224 } 225} 226 227HInstruction* HInstructionBuilder::LoadNullCheckedLocal(uint32_t register_index, uint32_t dex_pc) { 228 HInstruction* ref = LoadLocal(register_index, Primitive::kPrimNot); 229 if (!ref->CanBeNull()) { 230 return ref; 231 } 232 233 HNullCheck* null_check = new (arena_) HNullCheck(ref, dex_pc); 234 AppendInstruction(null_check); 235 return null_check; 236} 237 238void HInstructionBuilder::SetLoopHeaderPhiInputs() { 239 for (size_t i = loop_headers_.size(); i > 0; --i) { 240 HBasicBlock* block = loop_headers_[i - 1]; 241 for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { 242 HPhi* phi = it.Current()->AsPhi(); 243 size_t vreg = phi->GetRegNumber(); 244 for (HBasicBlock* predecessor : block->GetPredecessors()) { 245 HInstruction* value = ValueOfLocalAt(predecessor, vreg); 246 if (value == nullptr) { 247 // Vreg is undefined at this predecessor. Mark it dead and leave with 248 // fewer inputs than predecessors. SsaChecker will fail if not removed. 249 phi->SetDead(); 250 break; 251 } else { 252 phi->AddInput(value); 253 } 254 } 255 } 256 } 257} 258 259static bool IsBlockPopulated(HBasicBlock* block) { 260 if (block->IsLoopHeader()) { 261 // Suspend checks were inserted into loop headers during building of dominator tree. 262 DCHECK(block->GetFirstInstruction()->IsSuspendCheck()); 263 return block->GetFirstInstruction() != block->GetLastInstruction(); 264 } else { 265 return !block->GetInstructions().IsEmpty(); 266 } 267} 268 269bool HInstructionBuilder::Build() { 270 locals_for_.resize(graph_->GetBlocks().size(), 271 ArenaVector<HInstruction*>(arena_->Adapter(kArenaAllocGraphBuilder))); 272 273 // Find locations where we want to generate extra stackmaps for native debugging. 274 // This allows us to generate the info only at interesting points (for example, 275 // at start of java statement) rather than before every dex instruction. 276 const bool native_debuggable = compiler_driver_ != nullptr && 277 compiler_driver_->GetCompilerOptions().GetNativeDebuggable(); 278 ArenaBitVector* native_debug_info_locations = nullptr; 279 if (native_debuggable) { 280 const uint32_t num_instructions = code_item_.insns_size_in_code_units_; 281 native_debug_info_locations = new (arena_) ArenaBitVector (arena_, num_instructions, false); 282 FindNativeDebugInfoLocations(native_debug_info_locations); 283 } 284 285 for (HBasicBlock* block : graph_->GetReversePostOrder()) { 286 current_block_ = block; 287 uint32_t block_dex_pc = current_block_->GetDexPc(); 288 289 InitializeBlockLocals(); 290 291 if (current_block_->IsEntryBlock()) { 292 InitializeParameters(); 293 AppendInstruction(new (arena_) HSuspendCheck(0u)); 294 AppendInstruction(new (arena_) HGoto(0u)); 295 continue; 296 } else if (current_block_->IsExitBlock()) { 297 AppendInstruction(new (arena_) HExit()); 298 continue; 299 } else if (current_block_->IsLoopHeader()) { 300 HSuspendCheck* suspend_check = new (arena_) HSuspendCheck(current_block_->GetDexPc()); 301 current_block_->GetLoopInformation()->SetSuspendCheck(suspend_check); 302 // This is slightly odd because the loop header might not be empty (TryBoundary). 303 // But we're still creating the environment with locals from the top of the block. 304 InsertInstructionAtTop(suspend_check); 305 } 306 307 if (block_dex_pc == kNoDexPc || current_block_ != block_builder_->GetBlockAt(block_dex_pc)) { 308 // Synthetic block that does not need to be populated. 309 DCHECK(IsBlockPopulated(current_block_)); 310 continue; 311 } 312 313 DCHECK(!IsBlockPopulated(current_block_)); 314 315 for (CodeItemIterator it(code_item_, block_dex_pc); !it.Done(); it.Advance()) { 316 if (current_block_ == nullptr) { 317 // The previous instruction ended this block. 318 break; 319 } 320 321 uint32_t dex_pc = it.CurrentDexPc(); 322 if (dex_pc != block_dex_pc && FindBlockStartingAt(dex_pc) != nullptr) { 323 // This dex_pc starts a new basic block. 324 break; 325 } 326 327 if (current_block_->IsTryBlock() && IsThrowingDexInstruction(it.CurrentInstruction())) { 328 PropagateLocalsToCatchBlocks(); 329 } 330 331 if (native_debuggable && native_debug_info_locations->IsBitSet(dex_pc)) { 332 AppendInstruction(new (arena_) HNativeDebugInfo(dex_pc)); 333 } 334 335 if (!ProcessDexInstruction(it.CurrentInstruction(), dex_pc)) { 336 return false; 337 } 338 } 339 340 if (current_block_ != nullptr) { 341 // Branching instructions clear current_block, so we know the last 342 // instruction of the current block is not a branching instruction. 343 // We add an unconditional Goto to the next block. 344 DCHECK_EQ(current_block_->GetSuccessors().size(), 1u); 345 AppendInstruction(new (arena_) HGoto()); 346 } 347 } 348 349 SetLoopHeaderPhiInputs(); 350 351 return true; 352} 353 354void HInstructionBuilder::FindNativeDebugInfoLocations(ArenaBitVector* locations) { 355 // The callback gets called when the line number changes. 356 // In other words, it marks the start of new java statement. 357 struct Callback { 358 static bool Position(void* ctx, const DexFile::PositionInfo& entry) { 359 static_cast<ArenaBitVector*>(ctx)->SetBit(entry.address_); 360 return false; 361 } 362 }; 363 dex_file_->DecodeDebugPositionInfo(&code_item_, Callback::Position, locations); 364 // Instruction-specific tweaks. 365 const Instruction* const begin = Instruction::At(code_item_.insns_); 366 const Instruction* const end = begin->RelativeAt(code_item_.insns_size_in_code_units_); 367 for (const Instruction* inst = begin; inst < end; inst = inst->Next()) { 368 switch (inst->Opcode()) { 369 case Instruction::MOVE_EXCEPTION: { 370 // Stop in native debugger after the exception has been moved. 371 // The compiler also expects the move at the start of basic block so 372 // we do not want to interfere by inserting native-debug-info before it. 373 locations->ClearBit(inst->GetDexPc(code_item_.insns_)); 374 const Instruction* next = inst->Next(); 375 if (next < end) { 376 locations->SetBit(next->GetDexPc(code_item_.insns_)); 377 } 378 break; 379 } 380 default: 381 break; 382 } 383 } 384} 385 386HInstruction* HInstructionBuilder::LoadLocal(uint32_t reg_number, Primitive::Type type) const { 387 HInstruction* value = (*current_locals_)[reg_number]; 388 DCHECK(value != nullptr); 389 390 // If the operation requests a specific type, we make sure its input is of that type. 391 if (type != value->GetType()) { 392 if (Primitive::IsFloatingPointType(type)) { 393 value = ssa_builder_->GetFloatOrDoubleEquivalent(value, type); 394 } else if (type == Primitive::kPrimNot) { 395 value = ssa_builder_->GetReferenceTypeEquivalent(value); 396 } 397 DCHECK(value != nullptr); 398 } 399 400 return value; 401} 402 403void HInstructionBuilder::UpdateLocal(uint32_t reg_number, HInstruction* stored_value) { 404 Primitive::Type stored_type = stored_value->GetType(); 405 DCHECK_NE(stored_type, Primitive::kPrimVoid); 406 407 // Storing into vreg `reg_number` may implicitly invalidate the surrounding 408 // registers. Consider the following cases: 409 // (1) Storing a wide value must overwrite previous values in both `reg_number` 410 // and `reg_number+1`. We store `nullptr` in `reg_number+1`. 411 // (2) If vreg `reg_number-1` holds a wide value, writing into `reg_number` 412 // must invalidate it. We store `nullptr` in `reg_number-1`. 413 // Consequently, storing a wide value into the high vreg of another wide value 414 // will invalidate both `reg_number-1` and `reg_number+1`. 415 416 if (reg_number != 0) { 417 HInstruction* local_low = (*current_locals_)[reg_number - 1]; 418 if (local_low != nullptr && Primitive::Is64BitType(local_low->GetType())) { 419 // The vreg we are storing into was previously the high vreg of a pair. 420 // We need to invalidate its low vreg. 421 DCHECK((*current_locals_)[reg_number] == nullptr); 422 (*current_locals_)[reg_number - 1] = nullptr; 423 } 424 } 425 426 (*current_locals_)[reg_number] = stored_value; 427 if (Primitive::Is64BitType(stored_type)) { 428 // We are storing a pair. Invalidate the instruction in the high vreg. 429 (*current_locals_)[reg_number + 1] = nullptr; 430 } 431} 432 433void HInstructionBuilder::InitializeParameters() { 434 DCHECK(current_block_->IsEntryBlock()); 435 436 // dex_compilation_unit_ is null only when unit testing. 437 if (dex_compilation_unit_ == nullptr) { 438 return; 439 } 440 441 const char* shorty = dex_compilation_unit_->GetShorty(); 442 uint16_t number_of_parameters = graph_->GetNumberOfInVRegs(); 443 uint16_t locals_index = graph_->GetNumberOfLocalVRegs(); 444 uint16_t parameter_index = 0; 445 446 const DexFile::MethodId& referrer_method_id = 447 dex_file_->GetMethodId(dex_compilation_unit_->GetDexMethodIndex()); 448 if (!dex_compilation_unit_->IsStatic()) { 449 // Add the implicit 'this' argument, not expressed in the signature. 450 HParameterValue* parameter = new (arena_) HParameterValue(*dex_file_, 451 referrer_method_id.class_idx_, 452 parameter_index++, 453 Primitive::kPrimNot, 454 true); 455 AppendInstruction(parameter); 456 UpdateLocal(locals_index++, parameter); 457 number_of_parameters--; 458 } 459 460 const DexFile::ProtoId& proto = dex_file_->GetMethodPrototype(referrer_method_id); 461 const DexFile::TypeList* arg_types = dex_file_->GetProtoParameters(proto); 462 for (int i = 0, shorty_pos = 1; i < number_of_parameters; i++) { 463 HParameterValue* parameter = new (arena_) HParameterValue( 464 *dex_file_, 465 arg_types->GetTypeItem(shorty_pos - 1).type_idx_, 466 parameter_index++, 467 Primitive::GetType(shorty[shorty_pos]), 468 false); 469 ++shorty_pos; 470 AppendInstruction(parameter); 471 // Store the parameter value in the local that the dex code will use 472 // to reference that parameter. 473 UpdateLocal(locals_index++, parameter); 474 if (Primitive::Is64BitType(parameter->GetType())) { 475 i++; 476 locals_index++; 477 parameter_index++; 478 } 479 } 480} 481 482template<typename T> 483void HInstructionBuilder::If_22t(const Instruction& instruction, uint32_t dex_pc) { 484 HInstruction* first = LoadLocal(instruction.VRegA(), Primitive::kPrimInt); 485 HInstruction* second = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); 486 T* comparison = new (arena_) T(first, second, dex_pc); 487 AppendInstruction(comparison); 488 AppendInstruction(new (arena_) HIf(comparison, dex_pc)); 489 current_block_ = nullptr; 490} 491 492template<typename T> 493void HInstructionBuilder::If_21t(const Instruction& instruction, uint32_t dex_pc) { 494 HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt); 495 T* comparison = new (arena_) T(value, graph_->GetIntConstant(0, dex_pc), dex_pc); 496 AppendInstruction(comparison); 497 AppendInstruction(new (arena_) HIf(comparison, dex_pc)); 498 current_block_ = nullptr; 499} 500 501template<typename T> 502void HInstructionBuilder::Unop_12x(const Instruction& instruction, 503 Primitive::Type type, 504 uint32_t dex_pc) { 505 HInstruction* first = LoadLocal(instruction.VRegB(), type); 506 AppendInstruction(new (arena_) T(type, first, dex_pc)); 507 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 508} 509 510void HInstructionBuilder::Conversion_12x(const Instruction& instruction, 511 Primitive::Type input_type, 512 Primitive::Type result_type, 513 uint32_t dex_pc) { 514 HInstruction* first = LoadLocal(instruction.VRegB(), input_type); 515 AppendInstruction(new (arena_) HTypeConversion(result_type, first, dex_pc)); 516 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 517} 518 519template<typename T> 520void HInstructionBuilder::Binop_23x(const Instruction& instruction, 521 Primitive::Type type, 522 uint32_t dex_pc) { 523 HInstruction* first = LoadLocal(instruction.VRegB(), type); 524 HInstruction* second = LoadLocal(instruction.VRegC(), type); 525 AppendInstruction(new (arena_) T(type, first, second, dex_pc)); 526 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 527} 528 529template<typename T> 530void HInstructionBuilder::Binop_23x_shift(const Instruction& instruction, 531 Primitive::Type type, 532 uint32_t dex_pc) { 533 HInstruction* first = LoadLocal(instruction.VRegB(), type); 534 HInstruction* second = LoadLocal(instruction.VRegC(), Primitive::kPrimInt); 535 AppendInstruction(new (arena_) T(type, first, second, dex_pc)); 536 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 537} 538 539void HInstructionBuilder::Binop_23x_cmp(const Instruction& instruction, 540 Primitive::Type type, 541 ComparisonBias bias, 542 uint32_t dex_pc) { 543 HInstruction* first = LoadLocal(instruction.VRegB(), type); 544 HInstruction* second = LoadLocal(instruction.VRegC(), type); 545 AppendInstruction(new (arena_) HCompare(type, first, second, bias, dex_pc)); 546 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 547} 548 549template<typename T> 550void HInstructionBuilder::Binop_12x_shift(const Instruction& instruction, 551 Primitive::Type type, 552 uint32_t dex_pc) { 553 HInstruction* first = LoadLocal(instruction.VRegA(), type); 554 HInstruction* second = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); 555 AppendInstruction(new (arena_) T(type, first, second, dex_pc)); 556 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 557} 558 559template<typename T> 560void HInstructionBuilder::Binop_12x(const Instruction& instruction, 561 Primitive::Type type, 562 uint32_t dex_pc) { 563 HInstruction* first = LoadLocal(instruction.VRegA(), type); 564 HInstruction* second = LoadLocal(instruction.VRegB(), type); 565 AppendInstruction(new (arena_) T(type, first, second, dex_pc)); 566 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 567} 568 569template<typename T> 570void HInstructionBuilder::Binop_22s(const Instruction& instruction, bool reverse, uint32_t dex_pc) { 571 HInstruction* first = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); 572 HInstruction* second = graph_->GetIntConstant(instruction.VRegC_22s(), dex_pc); 573 if (reverse) { 574 std::swap(first, second); 575 } 576 AppendInstruction(new (arena_) T(Primitive::kPrimInt, first, second, dex_pc)); 577 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 578} 579 580template<typename T> 581void HInstructionBuilder::Binop_22b(const Instruction& instruction, bool reverse, uint32_t dex_pc) { 582 HInstruction* first = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); 583 HInstruction* second = graph_->GetIntConstant(instruction.VRegC_22b(), dex_pc); 584 if (reverse) { 585 std::swap(first, second); 586 } 587 AppendInstruction(new (arena_) T(Primitive::kPrimInt, first, second, dex_pc)); 588 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 589} 590 591static bool RequiresConstructorBarrier(const DexCompilationUnit* cu, CompilerDriver* driver) { 592 // Can be null in unit tests only. 593 if (UNLIKELY(cu == nullptr)) { 594 return false; 595 } 596 597 Thread* self = Thread::Current(); 598 return cu->IsConstructor() 599 && driver->RequiresConstructorBarrier(self, cu->GetDexFile(), cu->GetClassDefIndex()); 600} 601 602// Returns true if `block` has only one successor which starts at the next 603// dex_pc after `instruction` at `dex_pc`. 604static bool IsFallthroughInstruction(const Instruction& instruction, 605 uint32_t dex_pc, 606 HBasicBlock* block) { 607 uint32_t next_dex_pc = dex_pc + instruction.SizeInCodeUnits(); 608 return block->GetSingleSuccessor()->GetDexPc() == next_dex_pc; 609} 610 611void HInstructionBuilder::BuildSwitch(const Instruction& instruction, uint32_t dex_pc) { 612 HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt); 613 DexSwitchTable table(instruction, dex_pc); 614 615 if (table.GetNumEntries() == 0) { 616 // Empty Switch. Code falls through to the next block. 617 DCHECK(IsFallthroughInstruction(instruction, dex_pc, current_block_)); 618 AppendInstruction(new (arena_) HGoto(dex_pc)); 619 } else if (table.ShouldBuildDecisionTree()) { 620 for (DexSwitchTableIterator it(table); !it.Done(); it.Advance()) { 621 HInstruction* case_value = graph_->GetIntConstant(it.CurrentKey(), dex_pc); 622 HEqual* comparison = new (arena_) HEqual(value, case_value, dex_pc); 623 AppendInstruction(comparison); 624 AppendInstruction(new (arena_) HIf(comparison, dex_pc)); 625 626 if (!it.IsLast()) { 627 current_block_ = FindBlockStartingAt(it.GetDexPcForCurrentIndex()); 628 } 629 } 630 } else { 631 AppendInstruction( 632 new (arena_) HPackedSwitch(table.GetEntryAt(0), table.GetNumEntries(), value, dex_pc)); 633 } 634 635 current_block_ = nullptr; 636} 637 638void HInstructionBuilder::BuildReturn(const Instruction& instruction, 639 Primitive::Type type, 640 uint32_t dex_pc) { 641 if (type == Primitive::kPrimVoid) { 642 // This may insert additional redundant constructor fences from the super constructors. 643 // TODO: remove redundant constructor fences (b/36656456). 644 if (RequiresConstructorBarrier(dex_compilation_unit_, compiler_driver_)) { 645 AppendInstruction(new (arena_) HMemoryBarrier(kStoreStore, dex_pc)); 646 } 647 AppendInstruction(new (arena_) HReturnVoid(dex_pc)); 648 } else { 649 HInstruction* value = LoadLocal(instruction.VRegA(), type); 650 AppendInstruction(new (arena_) HReturn(value, dex_pc)); 651 } 652 current_block_ = nullptr; 653} 654 655static InvokeType GetInvokeTypeFromOpCode(Instruction::Code opcode) { 656 switch (opcode) { 657 case Instruction::INVOKE_STATIC: 658 case Instruction::INVOKE_STATIC_RANGE: 659 return kStatic; 660 case Instruction::INVOKE_DIRECT: 661 case Instruction::INVOKE_DIRECT_RANGE: 662 return kDirect; 663 case Instruction::INVOKE_VIRTUAL: 664 case Instruction::INVOKE_VIRTUAL_QUICK: 665 case Instruction::INVOKE_VIRTUAL_RANGE: 666 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: 667 return kVirtual; 668 case Instruction::INVOKE_INTERFACE: 669 case Instruction::INVOKE_INTERFACE_RANGE: 670 return kInterface; 671 case Instruction::INVOKE_SUPER_RANGE: 672 case Instruction::INVOKE_SUPER: 673 return kSuper; 674 default: 675 LOG(FATAL) << "Unexpected invoke opcode: " << opcode; 676 UNREACHABLE(); 677 } 678} 679 680ArtMethod* HInstructionBuilder::ResolveMethod(uint16_t method_idx, InvokeType invoke_type) { 681 ScopedObjectAccess soa(Thread::Current()); 682 StackHandleScope<2> hs(soa.Self()); 683 684 ClassLinker* class_linker = dex_compilation_unit_->GetClassLinker(); 685 Handle<mirror::ClassLoader> class_loader = dex_compilation_unit_->GetClassLoader(); 686 Handle<mirror::Class> compiling_class(hs.NewHandle(GetCompilingClass())); 687 // We fetch the referenced class eagerly (that is, the class pointed by in the MethodId 688 // at method_idx), as `CanAccessResolvedMethod` expects it be be in the dex cache. 689 Handle<mirror::Class> methods_class(hs.NewHandle(class_linker->ResolveReferencedClassOfMethod( 690 method_idx, dex_compilation_unit_->GetDexCache(), class_loader))); 691 692 if (UNLIKELY(methods_class == nullptr)) { 693 // Clean up any exception left by type resolution. 694 soa.Self()->ClearException(); 695 return nullptr; 696 } 697 698 ArtMethod* resolved_method = class_linker->ResolveMethod<ClassLinker::kForceICCECheck>( 699 *dex_compilation_unit_->GetDexFile(), 700 method_idx, 701 dex_compilation_unit_->GetDexCache(), 702 class_loader, 703 /* referrer */ nullptr, 704 invoke_type); 705 706 if (UNLIKELY(resolved_method == nullptr)) { 707 // Clean up any exception left by type resolution. 708 soa.Self()->ClearException(); 709 return nullptr; 710 } 711 712 // Check access. The class linker has a fast path for looking into the dex cache 713 // and does not check the access if it hits it. 714 if (compiling_class == nullptr) { 715 if (!resolved_method->IsPublic()) { 716 return nullptr; 717 } 718 } else if (!compiling_class->CanAccessResolvedMethod(resolved_method->GetDeclaringClass(), 719 resolved_method, 720 dex_compilation_unit_->GetDexCache().Get(), 721 method_idx)) { 722 return nullptr; 723 } 724 725 // We have to special case the invoke-super case, as ClassLinker::ResolveMethod does not. 726 // We need to look at the referrer's super class vtable. We need to do this to know if we need to 727 // make this an invoke-unresolved to handle cross-dex invokes or abstract super methods, both of 728 // which require runtime handling. 729 if (invoke_type == kSuper) { 730 if (compiling_class == nullptr) { 731 // We could not determine the method's class we need to wait until runtime. 732 DCHECK(Runtime::Current()->IsAotCompiler()); 733 return nullptr; 734 } 735 if (!methods_class->IsAssignableFrom(compiling_class.Get())) { 736 // We cannot statically determine the target method. The runtime will throw a 737 // NoSuchMethodError on this one. 738 return nullptr; 739 } 740 ArtMethod* actual_method; 741 if (methods_class->IsInterface()) { 742 actual_method = methods_class->FindVirtualMethodForInterfaceSuper( 743 resolved_method, class_linker->GetImagePointerSize()); 744 } else { 745 uint16_t vtable_index = resolved_method->GetMethodIndex(); 746 actual_method = compiling_class->GetSuperClass()->GetVTableEntry( 747 vtable_index, class_linker->GetImagePointerSize()); 748 } 749 if (actual_method != resolved_method && 750 !IsSameDexFile(*actual_method->GetDexFile(), *dex_compilation_unit_->GetDexFile())) { 751 // The back-end code generator relies on this check in order to ensure that it will not 752 // attempt to read the dex_cache with a dex_method_index that is not from the correct 753 // dex_file. If we didn't do this check then the dex_method_index will not be updated in the 754 // builder, which means that the code-generator (and compiler driver during sharpening and 755 // inliner, maybe) might invoke an incorrect method. 756 // TODO: The actual method could still be referenced in the current dex file, so we 757 // could try locating it. 758 // TODO: Remove the dex_file restriction. 759 return nullptr; 760 } 761 if (!actual_method->IsInvokable()) { 762 // Fail if the actual method cannot be invoked. Otherwise, the runtime resolution stub 763 // could resolve the callee to the wrong method. 764 return nullptr; 765 } 766 resolved_method = actual_method; 767 } 768 769 // Check for incompatible class changes. The class linker has a fast path for 770 // looking into the dex cache and does not check incompatible class changes if it hits it. 771 if (resolved_method->CheckIncompatibleClassChange(invoke_type)) { 772 return nullptr; 773 } 774 775 return resolved_method; 776} 777 778static bool IsStringConstructor(ArtMethod* method) { 779 ScopedObjectAccess soa(Thread::Current()); 780 return method->GetDeclaringClass()->IsStringClass() && method->IsConstructor(); 781} 782 783bool HInstructionBuilder::BuildInvoke(const Instruction& instruction, 784 uint32_t dex_pc, 785 uint32_t method_idx, 786 uint32_t number_of_vreg_arguments, 787 bool is_range, 788 uint32_t* args, 789 uint32_t register_index) { 790 InvokeType invoke_type = GetInvokeTypeFromOpCode(instruction.Opcode()); 791 const char* descriptor = dex_file_->GetMethodShorty(method_idx); 792 Primitive::Type return_type = Primitive::GetType(descriptor[0]); 793 794 // Remove the return type from the 'proto'. 795 size_t number_of_arguments = strlen(descriptor) - 1; 796 if (invoke_type != kStatic) { // instance call 797 // One extra argument for 'this'. 798 number_of_arguments++; 799 } 800 801 ArtMethod* resolved_method = ResolveMethod(method_idx, invoke_type); 802 803 if (UNLIKELY(resolved_method == nullptr)) { 804 MaybeRecordStat(MethodCompilationStat::kUnresolvedMethod); 805 HInvoke* invoke = new (arena_) HInvokeUnresolved(arena_, 806 number_of_arguments, 807 return_type, 808 dex_pc, 809 method_idx, 810 invoke_type); 811 return HandleInvoke(invoke, 812 number_of_vreg_arguments, 813 args, 814 register_index, 815 is_range, 816 descriptor, 817 nullptr, /* clinit_check */ 818 true /* is_unresolved */); 819 } 820 821 // Replace calls to String.<init> with StringFactory. 822 if (IsStringConstructor(resolved_method)) { 823 uint32_t string_init_entry_point = WellKnownClasses::StringInitToEntryPoint(resolved_method); 824 HInvokeStaticOrDirect::DispatchInfo dispatch_info = { 825 HInvokeStaticOrDirect::MethodLoadKind::kStringInit, 826 HInvokeStaticOrDirect::CodePtrLocation::kCallArtMethod, 827 dchecked_integral_cast<uint64_t>(string_init_entry_point) 828 }; 829 MethodReference target_method(dex_file_, method_idx); 830 HInvoke* invoke = new (arena_) HInvokeStaticOrDirect( 831 arena_, 832 number_of_arguments - 1, 833 Primitive::kPrimNot /*return_type */, 834 dex_pc, 835 method_idx, 836 nullptr, 837 dispatch_info, 838 invoke_type, 839 target_method, 840 HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit); 841 return HandleStringInit(invoke, 842 number_of_vreg_arguments, 843 args, 844 register_index, 845 is_range, 846 descriptor); 847 } 848 849 // Potential class initialization check, in the case of a static method call. 850 HClinitCheck* clinit_check = nullptr; 851 HInvoke* invoke = nullptr; 852 if (invoke_type == kDirect || invoke_type == kStatic || invoke_type == kSuper) { 853 // By default, consider that the called method implicitly requires 854 // an initialization check of its declaring method. 855 HInvokeStaticOrDirect::ClinitCheckRequirement clinit_check_requirement 856 = HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit; 857 ScopedObjectAccess soa(Thread::Current()); 858 if (invoke_type == kStatic) { 859 clinit_check = ProcessClinitCheckForInvoke( 860 dex_pc, resolved_method, &clinit_check_requirement); 861 } else if (invoke_type == kSuper) { 862 if (IsSameDexFile(*resolved_method->GetDexFile(), *dex_compilation_unit_->GetDexFile())) { 863 // Update the method index to the one resolved. Note that this may be a no-op if 864 // we resolved to the method referenced by the instruction. 865 method_idx = resolved_method->GetDexMethodIndex(); 866 } 867 } 868 869 HInvokeStaticOrDirect::DispatchInfo dispatch_info = { 870 HInvokeStaticOrDirect::MethodLoadKind::kDexCacheViaMethod, 871 HInvokeStaticOrDirect::CodePtrLocation::kCallArtMethod, 872 0u 873 }; 874 MethodReference target_method(resolved_method->GetDexFile(), 875 resolved_method->GetDexMethodIndex()); 876 invoke = new (arena_) HInvokeStaticOrDirect(arena_, 877 number_of_arguments, 878 return_type, 879 dex_pc, 880 method_idx, 881 resolved_method, 882 dispatch_info, 883 invoke_type, 884 target_method, 885 clinit_check_requirement); 886 } else if (invoke_type == kVirtual) { 887 ScopedObjectAccess soa(Thread::Current()); // Needed for the method index 888 invoke = new (arena_) HInvokeVirtual(arena_, 889 number_of_arguments, 890 return_type, 891 dex_pc, 892 method_idx, 893 resolved_method, 894 resolved_method->GetMethodIndex()); 895 } else { 896 DCHECK_EQ(invoke_type, kInterface); 897 ScopedObjectAccess soa(Thread::Current()); // Needed for the IMT index. 898 invoke = new (arena_) HInvokeInterface(arena_, 899 number_of_arguments, 900 return_type, 901 dex_pc, 902 method_idx, 903 resolved_method, 904 ImTable::GetImtIndex(resolved_method)); 905 } 906 907 return HandleInvoke(invoke, 908 number_of_vreg_arguments, 909 args, 910 register_index, 911 is_range, 912 descriptor, 913 clinit_check, 914 false /* is_unresolved */); 915} 916 917bool HInstructionBuilder::BuildInvokePolymorphic(const Instruction& instruction ATTRIBUTE_UNUSED, 918 uint32_t dex_pc, 919 uint32_t method_idx, 920 uint32_t proto_idx, 921 uint32_t number_of_vreg_arguments, 922 bool is_range, 923 uint32_t* args, 924 uint32_t register_index) { 925 const char* descriptor = dex_file_->GetShorty(proto_idx); 926 DCHECK_EQ(1 + ArtMethod::NumArgRegisters(descriptor), number_of_vreg_arguments); 927 Primitive::Type return_type = Primitive::GetType(descriptor[0]); 928 size_t number_of_arguments = strlen(descriptor); 929 HInvoke* invoke = new (arena_) HInvokePolymorphic(arena_, 930 number_of_arguments, 931 return_type, 932 dex_pc, 933 method_idx); 934 return HandleInvoke(invoke, 935 number_of_vreg_arguments, 936 args, 937 register_index, 938 is_range, 939 descriptor, 940 nullptr /* clinit_check */, 941 false /* is_unresolved */); 942} 943 944bool HInstructionBuilder::BuildNewInstance(dex::TypeIndex type_index, uint32_t dex_pc) { 945 ScopedObjectAccess soa(Thread::Current()); 946 947 HLoadClass* load_class = BuildLoadClass(type_index, dex_pc); 948 949 HInstruction* cls = load_class; 950 Handle<mirror::Class> klass = load_class->GetClass(); 951 952 if (!IsInitialized(klass)) { 953 cls = new (arena_) HClinitCheck(load_class, dex_pc); 954 AppendInstruction(cls); 955 } 956 957 // Only the access check entrypoint handles the finalizable class case. If we 958 // need access checks, then we haven't resolved the method and the class may 959 // again be finalizable. 960 QuickEntrypointEnum entrypoint = kQuickAllocObjectInitialized; 961 if (load_class->NeedsAccessCheck() || klass->IsFinalizable() || !klass->IsInstantiable()) { 962 entrypoint = kQuickAllocObjectWithChecks; 963 } 964 965 // Consider classes we haven't resolved as potentially finalizable. 966 bool finalizable = (klass == nullptr) || klass->IsFinalizable(); 967 968 AppendInstruction(new (arena_) HNewInstance( 969 cls, 970 dex_pc, 971 type_index, 972 *dex_compilation_unit_->GetDexFile(), 973 finalizable, 974 entrypoint)); 975 return true; 976} 977 978static bool IsSubClass(mirror::Class* to_test, mirror::Class* super_class) 979 REQUIRES_SHARED(Locks::mutator_lock_) { 980 return to_test != nullptr && !to_test->IsInterface() && to_test->IsSubClass(super_class); 981} 982 983bool HInstructionBuilder::IsInitialized(Handle<mirror::Class> cls) const { 984 if (cls == nullptr) { 985 return false; 986 } 987 988 // `CanAssumeClassIsLoaded` will return true if we're JITting, or will 989 // check whether the class is in an image for the AOT compilation. 990 if (cls->IsInitialized() && 991 compiler_driver_->CanAssumeClassIsLoaded(cls.Get())) { 992 return true; 993 } 994 995 if (IsSubClass(GetOutermostCompilingClass(), cls.Get())) { 996 return true; 997 } 998 999 // TODO: We should walk over the inlined methods, but we don't pass 1000 // that information to the builder. 1001 if (IsSubClass(GetCompilingClass(), cls.Get())) { 1002 return true; 1003 } 1004 1005 return false; 1006} 1007 1008HClinitCheck* HInstructionBuilder::ProcessClinitCheckForInvoke( 1009 uint32_t dex_pc, 1010 ArtMethod* resolved_method, 1011 HInvokeStaticOrDirect::ClinitCheckRequirement* clinit_check_requirement) { 1012 Handle<mirror::Class> klass = handles_->NewHandle(resolved_method->GetDeclaringClass()); 1013 1014 HClinitCheck* clinit_check = nullptr; 1015 if (IsInitialized(klass)) { 1016 *clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kNone; 1017 } else { 1018 HLoadClass* cls = BuildLoadClass(klass->GetDexTypeIndex(), 1019 klass->GetDexFile(), 1020 klass, 1021 dex_pc, 1022 /* needs_access_check */ false); 1023 if (cls != nullptr) { 1024 *clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kExplicit; 1025 clinit_check = new (arena_) HClinitCheck(cls, dex_pc); 1026 AppendInstruction(clinit_check); 1027 } 1028 } 1029 return clinit_check; 1030} 1031 1032bool HInstructionBuilder::SetupInvokeArguments(HInvoke* invoke, 1033 uint32_t number_of_vreg_arguments, 1034 uint32_t* args, 1035 uint32_t register_index, 1036 bool is_range, 1037 const char* descriptor, 1038 size_t start_index, 1039 size_t* argument_index) { 1040 uint32_t descriptor_index = 1; // Skip the return type. 1041 1042 for (size_t i = start_index; 1043 // Make sure we don't go over the expected arguments or over the number of 1044 // dex registers given. If the instruction was seen as dead by the verifier, 1045 // it hasn't been properly checked. 1046 (i < number_of_vreg_arguments) && (*argument_index < invoke->GetNumberOfArguments()); 1047 i++, (*argument_index)++) { 1048 Primitive::Type type = Primitive::GetType(descriptor[descriptor_index++]); 1049 bool is_wide = (type == Primitive::kPrimLong) || (type == Primitive::kPrimDouble); 1050 if (!is_range 1051 && is_wide 1052 && ((i + 1 == number_of_vreg_arguments) || (args[i] + 1 != args[i + 1]))) { 1053 // Longs and doubles should be in pairs, that is, sequential registers. The verifier should 1054 // reject any class where this is violated. However, the verifier only does these checks 1055 // on non trivially dead instructions, so we just bailout the compilation. 1056 VLOG(compiler) << "Did not compile " 1057 << dex_file_->PrettyMethod(dex_compilation_unit_->GetDexMethodIndex()) 1058 << " because of non-sequential dex register pair in wide argument"; 1059 MaybeRecordStat(MethodCompilationStat::kNotCompiledMalformedOpcode); 1060 return false; 1061 } 1062 HInstruction* arg = LoadLocal(is_range ? register_index + i : args[i], type); 1063 invoke->SetArgumentAt(*argument_index, arg); 1064 if (is_wide) { 1065 i++; 1066 } 1067 } 1068 1069 if (*argument_index != invoke->GetNumberOfArguments()) { 1070 VLOG(compiler) << "Did not compile " 1071 << dex_file_->PrettyMethod(dex_compilation_unit_->GetDexMethodIndex()) 1072 << " because of wrong number of arguments in invoke instruction"; 1073 MaybeRecordStat(MethodCompilationStat::kNotCompiledMalformedOpcode); 1074 return false; 1075 } 1076 1077 if (invoke->IsInvokeStaticOrDirect() && 1078 HInvokeStaticOrDirect::NeedsCurrentMethodInput( 1079 invoke->AsInvokeStaticOrDirect()->GetMethodLoadKind())) { 1080 invoke->SetArgumentAt(*argument_index, graph_->GetCurrentMethod()); 1081 (*argument_index)++; 1082 } 1083 1084 return true; 1085} 1086 1087bool HInstructionBuilder::HandleInvoke(HInvoke* invoke, 1088 uint32_t number_of_vreg_arguments, 1089 uint32_t* args, 1090 uint32_t register_index, 1091 bool is_range, 1092 const char* descriptor, 1093 HClinitCheck* clinit_check, 1094 bool is_unresolved) { 1095 DCHECK(!invoke->IsInvokeStaticOrDirect() || !invoke->AsInvokeStaticOrDirect()->IsStringInit()); 1096 1097 size_t start_index = 0; 1098 size_t argument_index = 0; 1099 if (invoke->GetInvokeType() != InvokeType::kStatic) { // Instance call. 1100 uint32_t obj_reg = is_range ? register_index : args[0]; 1101 HInstruction* arg = is_unresolved 1102 ? LoadLocal(obj_reg, Primitive::kPrimNot) 1103 : LoadNullCheckedLocal(obj_reg, invoke->GetDexPc()); 1104 invoke->SetArgumentAt(0, arg); 1105 start_index = 1; 1106 argument_index = 1; 1107 } 1108 1109 if (!SetupInvokeArguments(invoke, 1110 number_of_vreg_arguments, 1111 args, 1112 register_index, 1113 is_range, 1114 descriptor, 1115 start_index, 1116 &argument_index)) { 1117 return false; 1118 } 1119 1120 if (clinit_check != nullptr) { 1121 // Add the class initialization check as last input of `invoke`. 1122 DCHECK(invoke->IsInvokeStaticOrDirect()); 1123 DCHECK(invoke->AsInvokeStaticOrDirect()->GetClinitCheckRequirement() 1124 == HInvokeStaticOrDirect::ClinitCheckRequirement::kExplicit); 1125 invoke->SetArgumentAt(argument_index, clinit_check); 1126 argument_index++; 1127 } 1128 1129 AppendInstruction(invoke); 1130 latest_result_ = invoke; 1131 1132 return true; 1133} 1134 1135bool HInstructionBuilder::HandleStringInit(HInvoke* invoke, 1136 uint32_t number_of_vreg_arguments, 1137 uint32_t* args, 1138 uint32_t register_index, 1139 bool is_range, 1140 const char* descriptor) { 1141 DCHECK(invoke->IsInvokeStaticOrDirect()); 1142 DCHECK(invoke->AsInvokeStaticOrDirect()->IsStringInit()); 1143 1144 size_t start_index = 1; 1145 size_t argument_index = 0; 1146 if (!SetupInvokeArguments(invoke, 1147 number_of_vreg_arguments, 1148 args, 1149 register_index, 1150 is_range, 1151 descriptor, 1152 start_index, 1153 &argument_index)) { 1154 return false; 1155 } 1156 1157 AppendInstruction(invoke); 1158 1159 // This is a StringFactory call, not an actual String constructor. Its result 1160 // replaces the empty String pre-allocated by NewInstance. 1161 uint32_t orig_this_reg = is_range ? register_index : args[0]; 1162 HInstruction* arg_this = LoadLocal(orig_this_reg, Primitive::kPrimNot); 1163 1164 // Replacing the NewInstance might render it redundant. Keep a list of these 1165 // to be visited once it is clear whether it is has remaining uses. 1166 if (arg_this->IsNewInstance()) { 1167 ssa_builder_->AddUninitializedString(arg_this->AsNewInstance()); 1168 } else { 1169 DCHECK(arg_this->IsPhi()); 1170 // NewInstance is not the direct input of the StringFactory call. It might 1171 // be redundant but optimizing this case is not worth the effort. 1172 } 1173 1174 // Walk over all vregs and replace any occurrence of `arg_this` with `invoke`. 1175 for (size_t vreg = 0, e = current_locals_->size(); vreg < e; ++vreg) { 1176 if ((*current_locals_)[vreg] == arg_this) { 1177 (*current_locals_)[vreg] = invoke; 1178 } 1179 } 1180 1181 return true; 1182} 1183 1184static Primitive::Type GetFieldAccessType(const DexFile& dex_file, uint16_t field_index) { 1185 const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index); 1186 const char* type = dex_file.GetFieldTypeDescriptor(field_id); 1187 return Primitive::GetType(type[0]); 1188} 1189 1190bool HInstructionBuilder::BuildInstanceFieldAccess(const Instruction& instruction, 1191 uint32_t dex_pc, 1192 bool is_put) { 1193 uint32_t source_or_dest_reg = instruction.VRegA_22c(); 1194 uint32_t obj_reg = instruction.VRegB_22c(); 1195 uint16_t field_index; 1196 if (instruction.IsQuickened()) { 1197 if (!CanDecodeQuickenedInfo()) { 1198 return false; 1199 } 1200 field_index = LookupQuickenedInfo(dex_pc); 1201 } else { 1202 field_index = instruction.VRegC_22c(); 1203 } 1204 1205 ScopedObjectAccess soa(Thread::Current()); 1206 ArtField* resolved_field = ResolveField(field_index, /* is_static */ false, is_put); 1207 1208 // Generate an explicit null check on the reference, unless the field access 1209 // is unresolved. In that case, we rely on the runtime to perform various 1210 // checks first, followed by a null check. 1211 HInstruction* object = (resolved_field == nullptr) 1212 ? LoadLocal(obj_reg, Primitive::kPrimNot) 1213 : LoadNullCheckedLocal(obj_reg, dex_pc); 1214 1215 Primitive::Type field_type = (resolved_field == nullptr) 1216 ? GetFieldAccessType(*dex_file_, field_index) 1217 : resolved_field->GetTypeAsPrimitiveType(); 1218 if (is_put) { 1219 HInstruction* value = LoadLocal(source_or_dest_reg, field_type); 1220 HInstruction* field_set = nullptr; 1221 if (resolved_field == nullptr) { 1222 MaybeRecordStat(MethodCompilationStat::kUnresolvedField); 1223 field_set = new (arena_) HUnresolvedInstanceFieldSet(object, 1224 value, 1225 field_type, 1226 field_index, 1227 dex_pc); 1228 } else { 1229 uint16_t class_def_index = resolved_field->GetDeclaringClass()->GetDexClassDefIndex(); 1230 field_set = new (arena_) HInstanceFieldSet(object, 1231 value, 1232 resolved_field, 1233 field_type, 1234 resolved_field->GetOffset(), 1235 resolved_field->IsVolatile(), 1236 field_index, 1237 class_def_index, 1238 *dex_file_, 1239 dex_pc); 1240 } 1241 AppendInstruction(field_set); 1242 } else { 1243 HInstruction* field_get = nullptr; 1244 if (resolved_field == nullptr) { 1245 MaybeRecordStat(MethodCompilationStat::kUnresolvedField); 1246 field_get = new (arena_) HUnresolvedInstanceFieldGet(object, 1247 field_type, 1248 field_index, 1249 dex_pc); 1250 } else { 1251 uint16_t class_def_index = resolved_field->GetDeclaringClass()->GetDexClassDefIndex(); 1252 field_get = new (arena_) HInstanceFieldGet(object, 1253 resolved_field, 1254 field_type, 1255 resolved_field->GetOffset(), 1256 resolved_field->IsVolatile(), 1257 field_index, 1258 class_def_index, 1259 *dex_file_, 1260 dex_pc); 1261 } 1262 AppendInstruction(field_get); 1263 UpdateLocal(source_or_dest_reg, field_get); 1264 } 1265 1266 return true; 1267} 1268 1269static mirror::Class* GetClassFrom(CompilerDriver* driver, 1270 const DexCompilationUnit& compilation_unit) { 1271 ScopedObjectAccess soa(Thread::Current()); 1272 Handle<mirror::ClassLoader> class_loader = compilation_unit.GetClassLoader(); 1273 Handle<mirror::DexCache> dex_cache = compilation_unit.GetDexCache(); 1274 1275 return driver->ResolveCompilingMethodsClass(soa, dex_cache, class_loader, &compilation_unit); 1276} 1277 1278mirror::Class* HInstructionBuilder::GetOutermostCompilingClass() const { 1279 return GetClassFrom(compiler_driver_, *outer_compilation_unit_); 1280} 1281 1282mirror::Class* HInstructionBuilder::GetCompilingClass() const { 1283 return GetClassFrom(compiler_driver_, *dex_compilation_unit_); 1284} 1285 1286bool HInstructionBuilder::IsOutermostCompilingClass(dex::TypeIndex type_index) const { 1287 ScopedObjectAccess soa(Thread::Current()); 1288 StackHandleScope<2> hs(soa.Self()); 1289 Handle<mirror::DexCache> dex_cache = dex_compilation_unit_->GetDexCache(); 1290 Handle<mirror::ClassLoader> class_loader = dex_compilation_unit_->GetClassLoader(); 1291 Handle<mirror::Class> cls(hs.NewHandle(compiler_driver_->ResolveClass( 1292 soa, dex_cache, class_loader, type_index, dex_compilation_unit_))); 1293 Handle<mirror::Class> outer_class(hs.NewHandle(GetOutermostCompilingClass())); 1294 1295 // GetOutermostCompilingClass returns null when the class is unresolved 1296 // (e.g. if it derives from an unresolved class). This is bogus knowing that 1297 // we are compiling it. 1298 // When this happens we cannot establish a direct relation between the current 1299 // class and the outer class, so we return false. 1300 // (Note that this is only used for optimizing invokes and field accesses) 1301 return (cls != nullptr) && (outer_class.Get() == cls.Get()); 1302} 1303 1304void HInstructionBuilder::BuildUnresolvedStaticFieldAccess(const Instruction& instruction, 1305 uint32_t dex_pc, 1306 bool is_put, 1307 Primitive::Type field_type) { 1308 uint32_t source_or_dest_reg = instruction.VRegA_21c(); 1309 uint16_t field_index = instruction.VRegB_21c(); 1310 1311 if (is_put) { 1312 HInstruction* value = LoadLocal(source_or_dest_reg, field_type); 1313 AppendInstruction( 1314 new (arena_) HUnresolvedStaticFieldSet(value, field_type, field_index, dex_pc)); 1315 } else { 1316 AppendInstruction(new (arena_) HUnresolvedStaticFieldGet(field_type, field_index, dex_pc)); 1317 UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction()); 1318 } 1319} 1320 1321ArtField* HInstructionBuilder::ResolveField(uint16_t field_idx, bool is_static, bool is_put) { 1322 ScopedObjectAccess soa(Thread::Current()); 1323 StackHandleScope<2> hs(soa.Self()); 1324 1325 ClassLinker* class_linker = dex_compilation_unit_->GetClassLinker(); 1326 Handle<mirror::ClassLoader> class_loader = dex_compilation_unit_->GetClassLoader(); 1327 Handle<mirror::Class> compiling_class(hs.NewHandle(GetCompilingClass())); 1328 1329 ArtField* resolved_field = class_linker->ResolveField(*dex_compilation_unit_->GetDexFile(), 1330 field_idx, 1331 dex_compilation_unit_->GetDexCache(), 1332 class_loader, 1333 is_static); 1334 1335 if (UNLIKELY(resolved_field == nullptr)) { 1336 // Clean up any exception left by type resolution. 1337 soa.Self()->ClearException(); 1338 return nullptr; 1339 } 1340 1341 // Check static/instance. The class linker has a fast path for looking into the dex cache 1342 // and does not check static/instance if it hits it. 1343 if (UNLIKELY(resolved_field->IsStatic() != is_static)) { 1344 return nullptr; 1345 } 1346 1347 // Check access. 1348 if (compiling_class == nullptr) { 1349 if (!resolved_field->IsPublic()) { 1350 return nullptr; 1351 } 1352 } else if (!compiling_class->CanAccessResolvedField(resolved_field->GetDeclaringClass(), 1353 resolved_field, 1354 dex_compilation_unit_->GetDexCache().Get(), 1355 field_idx)) { 1356 return nullptr; 1357 } 1358 1359 if (is_put && 1360 resolved_field->IsFinal() && 1361 (compiling_class.Get() != resolved_field->GetDeclaringClass())) { 1362 // Final fields can only be updated within their own class. 1363 // TODO: Only allow it in constructors. b/34966607. 1364 return nullptr; 1365 } 1366 1367 return resolved_field; 1368} 1369 1370bool HInstructionBuilder::BuildStaticFieldAccess(const Instruction& instruction, 1371 uint32_t dex_pc, 1372 bool is_put) { 1373 uint32_t source_or_dest_reg = instruction.VRegA_21c(); 1374 uint16_t field_index = instruction.VRegB_21c(); 1375 1376 ScopedObjectAccess soa(Thread::Current()); 1377 ArtField* resolved_field = ResolveField(field_index, /* is_static */ true, is_put); 1378 1379 if (resolved_field == nullptr) { 1380 MaybeRecordStat(MethodCompilationStat::kUnresolvedField); 1381 Primitive::Type field_type = GetFieldAccessType(*dex_file_, field_index); 1382 BuildUnresolvedStaticFieldAccess(instruction, dex_pc, is_put, field_type); 1383 return true; 1384 } 1385 1386 Primitive::Type field_type = resolved_field->GetTypeAsPrimitiveType(); 1387 1388 Handle<mirror::Class> klass = handles_->NewHandle(resolved_field->GetDeclaringClass()); 1389 HLoadClass* constant = BuildLoadClass(klass->GetDexTypeIndex(), 1390 klass->GetDexFile(), 1391 klass, 1392 dex_pc, 1393 /* needs_access_check */ false); 1394 1395 if (constant == nullptr) { 1396 // The class cannot be referenced from this compiled code. Generate 1397 // an unresolved access. 1398 MaybeRecordStat(MethodCompilationStat::kUnresolvedFieldNotAFastAccess); 1399 BuildUnresolvedStaticFieldAccess(instruction, dex_pc, is_put, field_type); 1400 return true; 1401 } 1402 1403 HInstruction* cls = constant; 1404 if (!IsInitialized(klass)) { 1405 cls = new (arena_) HClinitCheck(constant, dex_pc); 1406 AppendInstruction(cls); 1407 } 1408 1409 uint16_t class_def_index = klass->GetDexClassDefIndex(); 1410 if (is_put) { 1411 // We need to keep the class alive before loading the value. 1412 HInstruction* value = LoadLocal(source_or_dest_reg, field_type); 1413 DCHECK_EQ(HPhi::ToPhiType(value->GetType()), HPhi::ToPhiType(field_type)); 1414 AppendInstruction(new (arena_) HStaticFieldSet(cls, 1415 value, 1416 resolved_field, 1417 field_type, 1418 resolved_field->GetOffset(), 1419 resolved_field->IsVolatile(), 1420 field_index, 1421 class_def_index, 1422 *dex_file_, 1423 dex_pc)); 1424 } else { 1425 AppendInstruction(new (arena_) HStaticFieldGet(cls, 1426 resolved_field, 1427 field_type, 1428 resolved_field->GetOffset(), 1429 resolved_field->IsVolatile(), 1430 field_index, 1431 class_def_index, 1432 *dex_file_, 1433 dex_pc)); 1434 UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction()); 1435 } 1436 return true; 1437} 1438 1439void HInstructionBuilder::BuildCheckedDivRem(uint16_t out_vreg, 1440 uint16_t first_vreg, 1441 int64_t second_vreg_or_constant, 1442 uint32_t dex_pc, 1443 Primitive::Type type, 1444 bool second_is_constant, 1445 bool isDiv) { 1446 DCHECK(type == Primitive::kPrimInt || type == Primitive::kPrimLong); 1447 1448 HInstruction* first = LoadLocal(first_vreg, type); 1449 HInstruction* second = nullptr; 1450 if (second_is_constant) { 1451 if (type == Primitive::kPrimInt) { 1452 second = graph_->GetIntConstant(second_vreg_or_constant, dex_pc); 1453 } else { 1454 second = graph_->GetLongConstant(second_vreg_or_constant, dex_pc); 1455 } 1456 } else { 1457 second = LoadLocal(second_vreg_or_constant, type); 1458 } 1459 1460 if (!second_is_constant 1461 || (type == Primitive::kPrimInt && second->AsIntConstant()->GetValue() == 0) 1462 || (type == Primitive::kPrimLong && second->AsLongConstant()->GetValue() == 0)) { 1463 second = new (arena_) HDivZeroCheck(second, dex_pc); 1464 AppendInstruction(second); 1465 } 1466 1467 if (isDiv) { 1468 AppendInstruction(new (arena_) HDiv(type, first, second, dex_pc)); 1469 } else { 1470 AppendInstruction(new (arena_) HRem(type, first, second, dex_pc)); 1471 } 1472 UpdateLocal(out_vreg, current_block_->GetLastInstruction()); 1473} 1474 1475void HInstructionBuilder::BuildArrayAccess(const Instruction& instruction, 1476 uint32_t dex_pc, 1477 bool is_put, 1478 Primitive::Type anticipated_type) { 1479 uint8_t source_or_dest_reg = instruction.VRegA_23x(); 1480 uint8_t array_reg = instruction.VRegB_23x(); 1481 uint8_t index_reg = instruction.VRegC_23x(); 1482 1483 HInstruction* object = LoadNullCheckedLocal(array_reg, dex_pc); 1484 HInstruction* length = new (arena_) HArrayLength(object, dex_pc); 1485 AppendInstruction(length); 1486 HInstruction* index = LoadLocal(index_reg, Primitive::kPrimInt); 1487 index = new (arena_) HBoundsCheck(index, length, dex_pc); 1488 AppendInstruction(index); 1489 if (is_put) { 1490 HInstruction* value = LoadLocal(source_or_dest_reg, anticipated_type); 1491 // TODO: Insert a type check node if the type is Object. 1492 HArraySet* aset = new (arena_) HArraySet(object, index, value, anticipated_type, dex_pc); 1493 ssa_builder_->MaybeAddAmbiguousArraySet(aset); 1494 AppendInstruction(aset); 1495 } else { 1496 HArrayGet* aget = new (arena_) HArrayGet(object, index, anticipated_type, dex_pc); 1497 ssa_builder_->MaybeAddAmbiguousArrayGet(aget); 1498 AppendInstruction(aget); 1499 UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction()); 1500 } 1501 graph_->SetHasBoundsChecks(true); 1502} 1503 1504void HInstructionBuilder::BuildFilledNewArray(uint32_t dex_pc, 1505 dex::TypeIndex type_index, 1506 uint32_t number_of_vreg_arguments, 1507 bool is_range, 1508 uint32_t* args, 1509 uint32_t register_index) { 1510 HInstruction* length = graph_->GetIntConstant(number_of_vreg_arguments, dex_pc); 1511 HLoadClass* cls = BuildLoadClass(type_index, dex_pc); 1512 HInstruction* object = new (arena_) HNewArray(cls, length, dex_pc); 1513 AppendInstruction(object); 1514 1515 const char* descriptor = dex_file_->StringByTypeIdx(type_index); 1516 DCHECK_EQ(descriptor[0], '[') << descriptor; 1517 char primitive = descriptor[1]; 1518 DCHECK(primitive == 'I' 1519 || primitive == 'L' 1520 || primitive == '[') << descriptor; 1521 bool is_reference_array = (primitive == 'L') || (primitive == '['); 1522 Primitive::Type type = is_reference_array ? Primitive::kPrimNot : Primitive::kPrimInt; 1523 1524 for (size_t i = 0; i < number_of_vreg_arguments; ++i) { 1525 HInstruction* value = LoadLocal(is_range ? register_index + i : args[i], type); 1526 HInstruction* index = graph_->GetIntConstant(i, dex_pc); 1527 HArraySet* aset = new (arena_) HArraySet(object, index, value, type, dex_pc); 1528 ssa_builder_->MaybeAddAmbiguousArraySet(aset); 1529 AppendInstruction(aset); 1530 } 1531 latest_result_ = object; 1532} 1533 1534template <typename T> 1535void HInstructionBuilder::BuildFillArrayData(HInstruction* object, 1536 const T* data, 1537 uint32_t element_count, 1538 Primitive::Type anticipated_type, 1539 uint32_t dex_pc) { 1540 for (uint32_t i = 0; i < element_count; ++i) { 1541 HInstruction* index = graph_->GetIntConstant(i, dex_pc); 1542 HInstruction* value = graph_->GetIntConstant(data[i], dex_pc); 1543 HArraySet* aset = new (arena_) HArraySet(object, index, value, anticipated_type, dex_pc); 1544 ssa_builder_->MaybeAddAmbiguousArraySet(aset); 1545 AppendInstruction(aset); 1546 } 1547} 1548 1549void HInstructionBuilder::BuildFillArrayData(const Instruction& instruction, uint32_t dex_pc) { 1550 HInstruction* array = LoadNullCheckedLocal(instruction.VRegA_31t(), dex_pc); 1551 1552 int32_t payload_offset = instruction.VRegB_31t() + dex_pc; 1553 const Instruction::ArrayDataPayload* payload = 1554 reinterpret_cast<const Instruction::ArrayDataPayload*>(code_item_.insns_ + payload_offset); 1555 const uint8_t* data = payload->data; 1556 uint32_t element_count = payload->element_count; 1557 1558 if (element_count == 0u) { 1559 // For empty payload we emit only the null check above. 1560 return; 1561 } 1562 1563 HInstruction* length = new (arena_) HArrayLength(array, dex_pc); 1564 AppendInstruction(length); 1565 1566 // Implementation of this DEX instruction seems to be that the bounds check is 1567 // done before doing any stores. 1568 HInstruction* last_index = graph_->GetIntConstant(payload->element_count - 1, dex_pc); 1569 AppendInstruction(new (arena_) HBoundsCheck(last_index, length, dex_pc)); 1570 1571 switch (payload->element_width) { 1572 case 1: 1573 BuildFillArrayData(array, 1574 reinterpret_cast<const int8_t*>(data), 1575 element_count, 1576 Primitive::kPrimByte, 1577 dex_pc); 1578 break; 1579 case 2: 1580 BuildFillArrayData(array, 1581 reinterpret_cast<const int16_t*>(data), 1582 element_count, 1583 Primitive::kPrimShort, 1584 dex_pc); 1585 break; 1586 case 4: 1587 BuildFillArrayData(array, 1588 reinterpret_cast<const int32_t*>(data), 1589 element_count, 1590 Primitive::kPrimInt, 1591 dex_pc); 1592 break; 1593 case 8: 1594 BuildFillWideArrayData(array, 1595 reinterpret_cast<const int64_t*>(data), 1596 element_count, 1597 dex_pc); 1598 break; 1599 default: 1600 LOG(FATAL) << "Unknown element width for " << payload->element_width; 1601 } 1602 graph_->SetHasBoundsChecks(true); 1603} 1604 1605void HInstructionBuilder::BuildFillWideArrayData(HInstruction* object, 1606 const int64_t* data, 1607 uint32_t element_count, 1608 uint32_t dex_pc) { 1609 for (uint32_t i = 0; i < element_count; ++i) { 1610 HInstruction* index = graph_->GetIntConstant(i, dex_pc); 1611 HInstruction* value = graph_->GetLongConstant(data[i], dex_pc); 1612 HArraySet* aset = new (arena_) HArraySet(object, index, value, Primitive::kPrimLong, dex_pc); 1613 ssa_builder_->MaybeAddAmbiguousArraySet(aset); 1614 AppendInstruction(aset); 1615 } 1616} 1617 1618static TypeCheckKind ComputeTypeCheckKind(Handle<mirror::Class> cls) 1619 REQUIRES_SHARED(Locks::mutator_lock_) { 1620 if (cls == nullptr) { 1621 return TypeCheckKind::kUnresolvedCheck; 1622 } else if (cls->IsInterface()) { 1623 return TypeCheckKind::kInterfaceCheck; 1624 } else if (cls->IsArrayClass()) { 1625 if (cls->GetComponentType()->IsObjectClass()) { 1626 return TypeCheckKind::kArrayObjectCheck; 1627 } else if (cls->CannotBeAssignedFromOtherTypes()) { 1628 return TypeCheckKind::kExactCheck; 1629 } else { 1630 return TypeCheckKind::kArrayCheck; 1631 } 1632 } else if (cls->IsFinal()) { 1633 return TypeCheckKind::kExactCheck; 1634 } else if (cls->IsAbstract()) { 1635 return TypeCheckKind::kAbstractClassCheck; 1636 } else { 1637 return TypeCheckKind::kClassHierarchyCheck; 1638 } 1639} 1640 1641HLoadClass* HInstructionBuilder::BuildLoadClass(dex::TypeIndex type_index, uint32_t dex_pc) { 1642 ScopedObjectAccess soa(Thread::Current()); 1643 const DexFile& dex_file = *dex_compilation_unit_->GetDexFile(); 1644 Handle<mirror::ClassLoader> class_loader = dex_compilation_unit_->GetClassLoader(); 1645 Handle<mirror::Class> klass = handles_->NewHandle(compiler_driver_->ResolveClass( 1646 soa, dex_compilation_unit_->GetDexCache(), class_loader, type_index, dex_compilation_unit_)); 1647 1648 bool needs_access_check = true; 1649 if (klass != nullptr) { 1650 if (klass->IsPublic()) { 1651 needs_access_check = false; 1652 } else { 1653 mirror::Class* compiling_class = GetCompilingClass(); 1654 if (compiling_class != nullptr && compiling_class->CanAccess(klass.Get())) { 1655 needs_access_check = false; 1656 } 1657 } 1658 } 1659 1660 return BuildLoadClass(type_index, dex_file, klass, dex_pc, needs_access_check); 1661} 1662 1663HLoadClass* HInstructionBuilder::BuildLoadClass(dex::TypeIndex type_index, 1664 const DexFile& dex_file, 1665 Handle<mirror::Class> klass, 1666 uint32_t dex_pc, 1667 bool needs_access_check) { 1668 // Try to find a reference in the compiling dex file. 1669 const DexFile* actual_dex_file = &dex_file; 1670 if (!IsSameDexFile(dex_file, *dex_compilation_unit_->GetDexFile())) { 1671 dex::TypeIndex local_type_index = 1672 klass->FindTypeIndexInOtherDexFile(*dex_compilation_unit_->GetDexFile()); 1673 if (local_type_index.IsValid()) { 1674 type_index = local_type_index; 1675 actual_dex_file = dex_compilation_unit_->GetDexFile(); 1676 } 1677 } 1678 1679 // Note: `klass` must be from `handles_`. 1680 HLoadClass* load_class = new (arena_) HLoadClass( 1681 graph_->GetCurrentMethod(), 1682 type_index, 1683 *actual_dex_file, 1684 klass, 1685 klass != nullptr && (klass.Get() == GetOutermostCompilingClass()), 1686 dex_pc, 1687 needs_access_check); 1688 1689 HLoadClass::LoadKind load_kind = HSharpening::ComputeLoadClassKind(load_class, 1690 code_generator_, 1691 compiler_driver_, 1692 *dex_compilation_unit_); 1693 1694 if (load_kind == HLoadClass::LoadKind::kInvalid) { 1695 // We actually cannot reference this class, we're forced to bail. 1696 return nullptr; 1697 } 1698 // Append the instruction first, as setting the load kind affects the inputs. 1699 AppendInstruction(load_class); 1700 load_class->SetLoadKind(load_kind); 1701 return load_class; 1702} 1703 1704void HInstructionBuilder::BuildTypeCheck(const Instruction& instruction, 1705 uint8_t destination, 1706 uint8_t reference, 1707 dex::TypeIndex type_index, 1708 uint32_t dex_pc) { 1709 HInstruction* object = LoadLocal(reference, Primitive::kPrimNot); 1710 HLoadClass* cls = BuildLoadClass(type_index, dex_pc); 1711 1712 ScopedObjectAccess soa(Thread::Current()); 1713 TypeCheckKind check_kind = ComputeTypeCheckKind(cls->GetClass()); 1714 if (instruction.Opcode() == Instruction::INSTANCE_OF) { 1715 AppendInstruction(new (arena_) HInstanceOf(object, cls, check_kind, dex_pc)); 1716 UpdateLocal(destination, current_block_->GetLastInstruction()); 1717 } else { 1718 DCHECK_EQ(instruction.Opcode(), Instruction::CHECK_CAST); 1719 // We emit a CheckCast followed by a BoundType. CheckCast is a statement 1720 // which may throw. If it succeeds BoundType sets the new type of `object` 1721 // for all subsequent uses. 1722 AppendInstruction(new (arena_) HCheckCast(object, cls, check_kind, dex_pc)); 1723 AppendInstruction(new (arena_) HBoundType(object, dex_pc)); 1724 UpdateLocal(reference, current_block_->GetLastInstruction()); 1725 } 1726} 1727 1728bool HInstructionBuilder::NeedsAccessCheck(dex::TypeIndex type_index, bool* finalizable) const { 1729 return !compiler_driver_->CanAccessInstantiableTypeWithoutChecks( 1730 LookupReferrerClass(), LookupResolvedType(type_index, *dex_compilation_unit_), finalizable); 1731} 1732 1733bool HInstructionBuilder::CanDecodeQuickenedInfo() const { 1734 return interpreter_metadata_ != nullptr; 1735} 1736 1737uint16_t HInstructionBuilder::LookupQuickenedInfo(uint32_t dex_pc) { 1738 DCHECK(interpreter_metadata_ != nullptr); 1739 1740 // First check if the info has already been decoded from `interpreter_metadata_`. 1741 auto it = skipped_interpreter_metadata_.find(dex_pc); 1742 if (it != skipped_interpreter_metadata_.end()) { 1743 // Remove the entry from the map and return the parsed info. 1744 uint16_t value_in_map = it->second; 1745 skipped_interpreter_metadata_.erase(it); 1746 return value_in_map; 1747 } 1748 1749 // Otherwise start parsing `interpreter_metadata_` until the slot for `dex_pc` 1750 // is found. Store skipped values in the `skipped_interpreter_metadata_` map. 1751 while (true) { 1752 uint32_t dex_pc_in_map = DecodeUnsignedLeb128(&interpreter_metadata_); 1753 uint16_t value_in_map = DecodeUnsignedLeb128(&interpreter_metadata_); 1754 DCHECK_LE(dex_pc_in_map, dex_pc); 1755 1756 if (dex_pc_in_map == dex_pc) { 1757 return value_in_map; 1758 } else { 1759 // Overwrite and not Put, as quickened CHECK-CAST has two entries with 1760 // the same dex_pc. This is OK, because the compiler does not care about those 1761 // entries. 1762 skipped_interpreter_metadata_.Overwrite(dex_pc_in_map, value_in_map); 1763 } 1764 } 1765} 1766 1767bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, uint32_t dex_pc) { 1768 switch (instruction.Opcode()) { 1769 case Instruction::CONST_4: { 1770 int32_t register_index = instruction.VRegA(); 1771 HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_11n(), dex_pc); 1772 UpdateLocal(register_index, constant); 1773 break; 1774 } 1775 1776 case Instruction::CONST_16: { 1777 int32_t register_index = instruction.VRegA(); 1778 HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_21s(), dex_pc); 1779 UpdateLocal(register_index, constant); 1780 break; 1781 } 1782 1783 case Instruction::CONST: { 1784 int32_t register_index = instruction.VRegA(); 1785 HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_31i(), dex_pc); 1786 UpdateLocal(register_index, constant); 1787 break; 1788 } 1789 1790 case Instruction::CONST_HIGH16: { 1791 int32_t register_index = instruction.VRegA(); 1792 HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_21h() << 16, dex_pc); 1793 UpdateLocal(register_index, constant); 1794 break; 1795 } 1796 1797 case Instruction::CONST_WIDE_16: { 1798 int32_t register_index = instruction.VRegA(); 1799 // Get 16 bits of constant value, sign extended to 64 bits. 1800 int64_t value = instruction.VRegB_21s(); 1801 value <<= 48; 1802 value >>= 48; 1803 HLongConstant* constant = graph_->GetLongConstant(value, dex_pc); 1804 UpdateLocal(register_index, constant); 1805 break; 1806 } 1807 1808 case Instruction::CONST_WIDE_32: { 1809 int32_t register_index = instruction.VRegA(); 1810 // Get 32 bits of constant value, sign extended to 64 bits. 1811 int64_t value = instruction.VRegB_31i(); 1812 value <<= 32; 1813 value >>= 32; 1814 HLongConstant* constant = graph_->GetLongConstant(value, dex_pc); 1815 UpdateLocal(register_index, constant); 1816 break; 1817 } 1818 1819 case Instruction::CONST_WIDE: { 1820 int32_t register_index = instruction.VRegA(); 1821 HLongConstant* constant = graph_->GetLongConstant(instruction.VRegB_51l(), dex_pc); 1822 UpdateLocal(register_index, constant); 1823 break; 1824 } 1825 1826 case Instruction::CONST_WIDE_HIGH16: { 1827 int32_t register_index = instruction.VRegA(); 1828 int64_t value = static_cast<int64_t>(instruction.VRegB_21h()) << 48; 1829 HLongConstant* constant = graph_->GetLongConstant(value, dex_pc); 1830 UpdateLocal(register_index, constant); 1831 break; 1832 } 1833 1834 // Note that the SSA building will refine the types. 1835 case Instruction::MOVE: 1836 case Instruction::MOVE_FROM16: 1837 case Instruction::MOVE_16: { 1838 HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); 1839 UpdateLocal(instruction.VRegA(), value); 1840 break; 1841 } 1842 1843 // Note that the SSA building will refine the types. 1844 case Instruction::MOVE_WIDE: 1845 case Instruction::MOVE_WIDE_FROM16: 1846 case Instruction::MOVE_WIDE_16: { 1847 HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimLong); 1848 UpdateLocal(instruction.VRegA(), value); 1849 break; 1850 } 1851 1852 case Instruction::MOVE_OBJECT: 1853 case Instruction::MOVE_OBJECT_16: 1854 case Instruction::MOVE_OBJECT_FROM16: { 1855 // The verifier has no notion of a null type, so a move-object of constant 0 1856 // will lead to the same constant 0 in the destination register. To mimic 1857 // this behavior, we just pretend we haven't seen a type change (int to reference) 1858 // for the 0 constant and phis. We rely on our type propagation to eventually get the 1859 // types correct. 1860 uint32_t reg_number = instruction.VRegB(); 1861 HInstruction* value = (*current_locals_)[reg_number]; 1862 if (value->IsIntConstant()) { 1863 DCHECK_EQ(value->AsIntConstant()->GetValue(), 0); 1864 } else if (value->IsPhi()) { 1865 DCHECK(value->GetType() == Primitive::kPrimInt || value->GetType() == Primitive::kPrimNot); 1866 } else { 1867 value = LoadLocal(reg_number, Primitive::kPrimNot); 1868 } 1869 UpdateLocal(instruction.VRegA(), value); 1870 break; 1871 } 1872 1873 case Instruction::RETURN_VOID_NO_BARRIER: 1874 case Instruction::RETURN_VOID: { 1875 BuildReturn(instruction, Primitive::kPrimVoid, dex_pc); 1876 break; 1877 } 1878 1879#define IF_XX(comparison, cond) \ 1880 case Instruction::IF_##cond: If_22t<comparison>(instruction, dex_pc); break; \ 1881 case Instruction::IF_##cond##Z: If_21t<comparison>(instruction, dex_pc); break 1882 1883 IF_XX(HEqual, EQ); 1884 IF_XX(HNotEqual, NE); 1885 IF_XX(HLessThan, LT); 1886 IF_XX(HLessThanOrEqual, LE); 1887 IF_XX(HGreaterThan, GT); 1888 IF_XX(HGreaterThanOrEqual, GE); 1889 1890 case Instruction::GOTO: 1891 case Instruction::GOTO_16: 1892 case Instruction::GOTO_32: { 1893 AppendInstruction(new (arena_) HGoto(dex_pc)); 1894 current_block_ = nullptr; 1895 break; 1896 } 1897 1898 case Instruction::RETURN: { 1899 BuildReturn(instruction, return_type_, dex_pc); 1900 break; 1901 } 1902 1903 case Instruction::RETURN_OBJECT: { 1904 BuildReturn(instruction, return_type_, dex_pc); 1905 break; 1906 } 1907 1908 case Instruction::RETURN_WIDE: { 1909 BuildReturn(instruction, return_type_, dex_pc); 1910 break; 1911 } 1912 1913 case Instruction::INVOKE_DIRECT: 1914 case Instruction::INVOKE_INTERFACE: 1915 case Instruction::INVOKE_STATIC: 1916 case Instruction::INVOKE_SUPER: 1917 case Instruction::INVOKE_VIRTUAL: 1918 case Instruction::INVOKE_VIRTUAL_QUICK: { 1919 uint16_t method_idx; 1920 if (instruction.Opcode() == Instruction::INVOKE_VIRTUAL_QUICK) { 1921 if (!CanDecodeQuickenedInfo()) { 1922 return false; 1923 } 1924 method_idx = LookupQuickenedInfo(dex_pc); 1925 } else { 1926 method_idx = instruction.VRegB_35c(); 1927 } 1928 uint32_t number_of_vreg_arguments = instruction.VRegA_35c(); 1929 uint32_t args[5]; 1930 instruction.GetVarArgs(args); 1931 if (!BuildInvoke(instruction, dex_pc, method_idx, 1932 number_of_vreg_arguments, false, args, -1)) { 1933 return false; 1934 } 1935 break; 1936 } 1937 1938 case Instruction::INVOKE_DIRECT_RANGE: 1939 case Instruction::INVOKE_INTERFACE_RANGE: 1940 case Instruction::INVOKE_STATIC_RANGE: 1941 case Instruction::INVOKE_SUPER_RANGE: 1942 case Instruction::INVOKE_VIRTUAL_RANGE: 1943 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: { 1944 uint16_t method_idx; 1945 if (instruction.Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK) { 1946 if (!CanDecodeQuickenedInfo()) { 1947 return false; 1948 } 1949 method_idx = LookupQuickenedInfo(dex_pc); 1950 } else { 1951 method_idx = instruction.VRegB_3rc(); 1952 } 1953 uint32_t number_of_vreg_arguments = instruction.VRegA_3rc(); 1954 uint32_t register_index = instruction.VRegC(); 1955 if (!BuildInvoke(instruction, dex_pc, method_idx, 1956 number_of_vreg_arguments, true, nullptr, register_index)) { 1957 return false; 1958 } 1959 break; 1960 } 1961 1962 case Instruction::INVOKE_POLYMORPHIC: { 1963 uint16_t method_idx = instruction.VRegB_45cc(); 1964 uint16_t proto_idx = instruction.VRegH_45cc(); 1965 uint32_t number_of_vreg_arguments = instruction.VRegA_45cc(); 1966 uint32_t args[5]; 1967 instruction.GetVarArgs(args); 1968 return BuildInvokePolymorphic(instruction, 1969 dex_pc, 1970 method_idx, 1971 proto_idx, 1972 number_of_vreg_arguments, 1973 false, 1974 args, 1975 -1); 1976 } 1977 1978 case Instruction::INVOKE_POLYMORPHIC_RANGE: { 1979 uint16_t method_idx = instruction.VRegB_4rcc(); 1980 uint16_t proto_idx = instruction.VRegH_4rcc(); 1981 uint32_t number_of_vreg_arguments = instruction.VRegA_4rcc(); 1982 uint32_t register_index = instruction.VRegC_4rcc(); 1983 return BuildInvokePolymorphic(instruction, 1984 dex_pc, 1985 method_idx, 1986 proto_idx, 1987 number_of_vreg_arguments, 1988 true, 1989 nullptr, 1990 register_index); 1991 } 1992 1993 case Instruction::NEG_INT: { 1994 Unop_12x<HNeg>(instruction, Primitive::kPrimInt, dex_pc); 1995 break; 1996 } 1997 1998 case Instruction::NEG_LONG: { 1999 Unop_12x<HNeg>(instruction, Primitive::kPrimLong, dex_pc); 2000 break; 2001 } 2002 2003 case Instruction::NEG_FLOAT: { 2004 Unop_12x<HNeg>(instruction, Primitive::kPrimFloat, dex_pc); 2005 break; 2006 } 2007 2008 case Instruction::NEG_DOUBLE: { 2009 Unop_12x<HNeg>(instruction, Primitive::kPrimDouble, dex_pc); 2010 break; 2011 } 2012 2013 case Instruction::NOT_INT: { 2014 Unop_12x<HNot>(instruction, Primitive::kPrimInt, dex_pc); 2015 break; 2016 } 2017 2018 case Instruction::NOT_LONG: { 2019 Unop_12x<HNot>(instruction, Primitive::kPrimLong, dex_pc); 2020 break; 2021 } 2022 2023 case Instruction::INT_TO_LONG: { 2024 Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimLong, dex_pc); 2025 break; 2026 } 2027 2028 case Instruction::INT_TO_FLOAT: { 2029 Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimFloat, dex_pc); 2030 break; 2031 } 2032 2033 case Instruction::INT_TO_DOUBLE: { 2034 Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimDouble, dex_pc); 2035 break; 2036 } 2037 2038 case Instruction::LONG_TO_INT: { 2039 Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimInt, dex_pc); 2040 break; 2041 } 2042 2043 case Instruction::LONG_TO_FLOAT: { 2044 Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimFloat, dex_pc); 2045 break; 2046 } 2047 2048 case Instruction::LONG_TO_DOUBLE: { 2049 Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimDouble, dex_pc); 2050 break; 2051 } 2052 2053 case Instruction::FLOAT_TO_INT: { 2054 Conversion_12x(instruction, Primitive::kPrimFloat, Primitive::kPrimInt, dex_pc); 2055 break; 2056 } 2057 2058 case Instruction::FLOAT_TO_LONG: { 2059 Conversion_12x(instruction, Primitive::kPrimFloat, Primitive::kPrimLong, dex_pc); 2060 break; 2061 } 2062 2063 case Instruction::FLOAT_TO_DOUBLE: { 2064 Conversion_12x(instruction, Primitive::kPrimFloat, Primitive::kPrimDouble, dex_pc); 2065 break; 2066 } 2067 2068 case Instruction::DOUBLE_TO_INT: { 2069 Conversion_12x(instruction, Primitive::kPrimDouble, Primitive::kPrimInt, dex_pc); 2070 break; 2071 } 2072 2073 case Instruction::DOUBLE_TO_LONG: { 2074 Conversion_12x(instruction, Primitive::kPrimDouble, Primitive::kPrimLong, dex_pc); 2075 break; 2076 } 2077 2078 case Instruction::DOUBLE_TO_FLOAT: { 2079 Conversion_12x(instruction, Primitive::kPrimDouble, Primitive::kPrimFloat, dex_pc); 2080 break; 2081 } 2082 2083 case Instruction::INT_TO_BYTE: { 2084 Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimByte, dex_pc); 2085 break; 2086 } 2087 2088 case Instruction::INT_TO_SHORT: { 2089 Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimShort, dex_pc); 2090 break; 2091 } 2092 2093 case Instruction::INT_TO_CHAR: { 2094 Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimChar, dex_pc); 2095 break; 2096 } 2097 2098 case Instruction::ADD_INT: { 2099 Binop_23x<HAdd>(instruction, Primitive::kPrimInt, dex_pc); 2100 break; 2101 } 2102 2103 case Instruction::ADD_LONG: { 2104 Binop_23x<HAdd>(instruction, Primitive::kPrimLong, dex_pc); 2105 break; 2106 } 2107 2108 case Instruction::ADD_DOUBLE: { 2109 Binop_23x<HAdd>(instruction, Primitive::kPrimDouble, dex_pc); 2110 break; 2111 } 2112 2113 case Instruction::ADD_FLOAT: { 2114 Binop_23x<HAdd>(instruction, Primitive::kPrimFloat, dex_pc); 2115 break; 2116 } 2117 2118 case Instruction::SUB_INT: { 2119 Binop_23x<HSub>(instruction, Primitive::kPrimInt, dex_pc); 2120 break; 2121 } 2122 2123 case Instruction::SUB_LONG: { 2124 Binop_23x<HSub>(instruction, Primitive::kPrimLong, dex_pc); 2125 break; 2126 } 2127 2128 case Instruction::SUB_FLOAT: { 2129 Binop_23x<HSub>(instruction, Primitive::kPrimFloat, dex_pc); 2130 break; 2131 } 2132 2133 case Instruction::SUB_DOUBLE: { 2134 Binop_23x<HSub>(instruction, Primitive::kPrimDouble, dex_pc); 2135 break; 2136 } 2137 2138 case Instruction::ADD_INT_2ADDR: { 2139 Binop_12x<HAdd>(instruction, Primitive::kPrimInt, dex_pc); 2140 break; 2141 } 2142 2143 case Instruction::MUL_INT: { 2144 Binop_23x<HMul>(instruction, Primitive::kPrimInt, dex_pc); 2145 break; 2146 } 2147 2148 case Instruction::MUL_LONG: { 2149 Binop_23x<HMul>(instruction, Primitive::kPrimLong, dex_pc); 2150 break; 2151 } 2152 2153 case Instruction::MUL_FLOAT: { 2154 Binop_23x<HMul>(instruction, Primitive::kPrimFloat, dex_pc); 2155 break; 2156 } 2157 2158 case Instruction::MUL_DOUBLE: { 2159 Binop_23x<HMul>(instruction, Primitive::kPrimDouble, dex_pc); 2160 break; 2161 } 2162 2163 case Instruction::DIV_INT: { 2164 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(), 2165 dex_pc, Primitive::kPrimInt, false, true); 2166 break; 2167 } 2168 2169 case Instruction::DIV_LONG: { 2170 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(), 2171 dex_pc, Primitive::kPrimLong, false, true); 2172 break; 2173 } 2174 2175 case Instruction::DIV_FLOAT: { 2176 Binop_23x<HDiv>(instruction, Primitive::kPrimFloat, dex_pc); 2177 break; 2178 } 2179 2180 case Instruction::DIV_DOUBLE: { 2181 Binop_23x<HDiv>(instruction, Primitive::kPrimDouble, dex_pc); 2182 break; 2183 } 2184 2185 case Instruction::REM_INT: { 2186 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(), 2187 dex_pc, Primitive::kPrimInt, false, false); 2188 break; 2189 } 2190 2191 case Instruction::REM_LONG: { 2192 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(), 2193 dex_pc, Primitive::kPrimLong, false, false); 2194 break; 2195 } 2196 2197 case Instruction::REM_FLOAT: { 2198 Binop_23x<HRem>(instruction, Primitive::kPrimFloat, dex_pc); 2199 break; 2200 } 2201 2202 case Instruction::REM_DOUBLE: { 2203 Binop_23x<HRem>(instruction, Primitive::kPrimDouble, dex_pc); 2204 break; 2205 } 2206 2207 case Instruction::AND_INT: { 2208 Binop_23x<HAnd>(instruction, Primitive::kPrimInt, dex_pc); 2209 break; 2210 } 2211 2212 case Instruction::AND_LONG: { 2213 Binop_23x<HAnd>(instruction, Primitive::kPrimLong, dex_pc); 2214 break; 2215 } 2216 2217 case Instruction::SHL_INT: { 2218 Binop_23x_shift<HShl>(instruction, Primitive::kPrimInt, dex_pc); 2219 break; 2220 } 2221 2222 case Instruction::SHL_LONG: { 2223 Binop_23x_shift<HShl>(instruction, Primitive::kPrimLong, dex_pc); 2224 break; 2225 } 2226 2227 case Instruction::SHR_INT: { 2228 Binop_23x_shift<HShr>(instruction, Primitive::kPrimInt, dex_pc); 2229 break; 2230 } 2231 2232 case Instruction::SHR_LONG: { 2233 Binop_23x_shift<HShr>(instruction, Primitive::kPrimLong, dex_pc); 2234 break; 2235 } 2236 2237 case Instruction::USHR_INT: { 2238 Binop_23x_shift<HUShr>(instruction, Primitive::kPrimInt, dex_pc); 2239 break; 2240 } 2241 2242 case Instruction::USHR_LONG: { 2243 Binop_23x_shift<HUShr>(instruction, Primitive::kPrimLong, dex_pc); 2244 break; 2245 } 2246 2247 case Instruction::OR_INT: { 2248 Binop_23x<HOr>(instruction, Primitive::kPrimInt, dex_pc); 2249 break; 2250 } 2251 2252 case Instruction::OR_LONG: { 2253 Binop_23x<HOr>(instruction, Primitive::kPrimLong, dex_pc); 2254 break; 2255 } 2256 2257 case Instruction::XOR_INT: { 2258 Binop_23x<HXor>(instruction, Primitive::kPrimInt, dex_pc); 2259 break; 2260 } 2261 2262 case Instruction::XOR_LONG: { 2263 Binop_23x<HXor>(instruction, Primitive::kPrimLong, dex_pc); 2264 break; 2265 } 2266 2267 case Instruction::ADD_LONG_2ADDR: { 2268 Binop_12x<HAdd>(instruction, Primitive::kPrimLong, dex_pc); 2269 break; 2270 } 2271 2272 case Instruction::ADD_DOUBLE_2ADDR: { 2273 Binop_12x<HAdd>(instruction, Primitive::kPrimDouble, dex_pc); 2274 break; 2275 } 2276 2277 case Instruction::ADD_FLOAT_2ADDR: { 2278 Binop_12x<HAdd>(instruction, Primitive::kPrimFloat, dex_pc); 2279 break; 2280 } 2281 2282 case Instruction::SUB_INT_2ADDR: { 2283 Binop_12x<HSub>(instruction, Primitive::kPrimInt, dex_pc); 2284 break; 2285 } 2286 2287 case Instruction::SUB_LONG_2ADDR: { 2288 Binop_12x<HSub>(instruction, Primitive::kPrimLong, dex_pc); 2289 break; 2290 } 2291 2292 case Instruction::SUB_FLOAT_2ADDR: { 2293 Binop_12x<HSub>(instruction, Primitive::kPrimFloat, dex_pc); 2294 break; 2295 } 2296 2297 case Instruction::SUB_DOUBLE_2ADDR: { 2298 Binop_12x<HSub>(instruction, Primitive::kPrimDouble, dex_pc); 2299 break; 2300 } 2301 2302 case Instruction::MUL_INT_2ADDR: { 2303 Binop_12x<HMul>(instruction, Primitive::kPrimInt, dex_pc); 2304 break; 2305 } 2306 2307 case Instruction::MUL_LONG_2ADDR: { 2308 Binop_12x<HMul>(instruction, Primitive::kPrimLong, dex_pc); 2309 break; 2310 } 2311 2312 case Instruction::MUL_FLOAT_2ADDR: { 2313 Binop_12x<HMul>(instruction, Primitive::kPrimFloat, dex_pc); 2314 break; 2315 } 2316 2317 case Instruction::MUL_DOUBLE_2ADDR: { 2318 Binop_12x<HMul>(instruction, Primitive::kPrimDouble, dex_pc); 2319 break; 2320 } 2321 2322 case Instruction::DIV_INT_2ADDR: { 2323 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(), 2324 dex_pc, Primitive::kPrimInt, false, true); 2325 break; 2326 } 2327 2328 case Instruction::DIV_LONG_2ADDR: { 2329 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(), 2330 dex_pc, Primitive::kPrimLong, false, true); 2331 break; 2332 } 2333 2334 case Instruction::REM_INT_2ADDR: { 2335 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(), 2336 dex_pc, Primitive::kPrimInt, false, false); 2337 break; 2338 } 2339 2340 case Instruction::REM_LONG_2ADDR: { 2341 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(), 2342 dex_pc, Primitive::kPrimLong, false, false); 2343 break; 2344 } 2345 2346 case Instruction::REM_FLOAT_2ADDR: { 2347 Binop_12x<HRem>(instruction, Primitive::kPrimFloat, dex_pc); 2348 break; 2349 } 2350 2351 case Instruction::REM_DOUBLE_2ADDR: { 2352 Binop_12x<HRem>(instruction, Primitive::kPrimDouble, dex_pc); 2353 break; 2354 } 2355 2356 case Instruction::SHL_INT_2ADDR: { 2357 Binop_12x_shift<HShl>(instruction, Primitive::kPrimInt, dex_pc); 2358 break; 2359 } 2360 2361 case Instruction::SHL_LONG_2ADDR: { 2362 Binop_12x_shift<HShl>(instruction, Primitive::kPrimLong, dex_pc); 2363 break; 2364 } 2365 2366 case Instruction::SHR_INT_2ADDR: { 2367 Binop_12x_shift<HShr>(instruction, Primitive::kPrimInt, dex_pc); 2368 break; 2369 } 2370 2371 case Instruction::SHR_LONG_2ADDR: { 2372 Binop_12x_shift<HShr>(instruction, Primitive::kPrimLong, dex_pc); 2373 break; 2374 } 2375 2376 case Instruction::USHR_INT_2ADDR: { 2377 Binop_12x_shift<HUShr>(instruction, Primitive::kPrimInt, dex_pc); 2378 break; 2379 } 2380 2381 case Instruction::USHR_LONG_2ADDR: { 2382 Binop_12x_shift<HUShr>(instruction, Primitive::kPrimLong, dex_pc); 2383 break; 2384 } 2385 2386 case Instruction::DIV_FLOAT_2ADDR: { 2387 Binop_12x<HDiv>(instruction, Primitive::kPrimFloat, dex_pc); 2388 break; 2389 } 2390 2391 case Instruction::DIV_DOUBLE_2ADDR: { 2392 Binop_12x<HDiv>(instruction, Primitive::kPrimDouble, dex_pc); 2393 break; 2394 } 2395 2396 case Instruction::AND_INT_2ADDR: { 2397 Binop_12x<HAnd>(instruction, Primitive::kPrimInt, dex_pc); 2398 break; 2399 } 2400 2401 case Instruction::AND_LONG_2ADDR: { 2402 Binop_12x<HAnd>(instruction, Primitive::kPrimLong, dex_pc); 2403 break; 2404 } 2405 2406 case Instruction::OR_INT_2ADDR: { 2407 Binop_12x<HOr>(instruction, Primitive::kPrimInt, dex_pc); 2408 break; 2409 } 2410 2411 case Instruction::OR_LONG_2ADDR: { 2412 Binop_12x<HOr>(instruction, Primitive::kPrimLong, dex_pc); 2413 break; 2414 } 2415 2416 case Instruction::XOR_INT_2ADDR: { 2417 Binop_12x<HXor>(instruction, Primitive::kPrimInt, dex_pc); 2418 break; 2419 } 2420 2421 case Instruction::XOR_LONG_2ADDR: { 2422 Binop_12x<HXor>(instruction, Primitive::kPrimLong, dex_pc); 2423 break; 2424 } 2425 2426 case Instruction::ADD_INT_LIT16: { 2427 Binop_22s<HAdd>(instruction, false, dex_pc); 2428 break; 2429 } 2430 2431 case Instruction::AND_INT_LIT16: { 2432 Binop_22s<HAnd>(instruction, false, dex_pc); 2433 break; 2434 } 2435 2436 case Instruction::OR_INT_LIT16: { 2437 Binop_22s<HOr>(instruction, false, dex_pc); 2438 break; 2439 } 2440 2441 case Instruction::XOR_INT_LIT16: { 2442 Binop_22s<HXor>(instruction, false, dex_pc); 2443 break; 2444 } 2445 2446 case Instruction::RSUB_INT: { 2447 Binop_22s<HSub>(instruction, true, dex_pc); 2448 break; 2449 } 2450 2451 case Instruction::MUL_INT_LIT16: { 2452 Binop_22s<HMul>(instruction, false, dex_pc); 2453 break; 2454 } 2455 2456 case Instruction::ADD_INT_LIT8: { 2457 Binop_22b<HAdd>(instruction, false, dex_pc); 2458 break; 2459 } 2460 2461 case Instruction::AND_INT_LIT8: { 2462 Binop_22b<HAnd>(instruction, false, dex_pc); 2463 break; 2464 } 2465 2466 case Instruction::OR_INT_LIT8: { 2467 Binop_22b<HOr>(instruction, false, dex_pc); 2468 break; 2469 } 2470 2471 case Instruction::XOR_INT_LIT8: { 2472 Binop_22b<HXor>(instruction, false, dex_pc); 2473 break; 2474 } 2475 2476 case Instruction::RSUB_INT_LIT8: { 2477 Binop_22b<HSub>(instruction, true, dex_pc); 2478 break; 2479 } 2480 2481 case Instruction::MUL_INT_LIT8: { 2482 Binop_22b<HMul>(instruction, false, dex_pc); 2483 break; 2484 } 2485 2486 case Instruction::DIV_INT_LIT16: 2487 case Instruction::DIV_INT_LIT8: { 2488 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(), 2489 dex_pc, Primitive::kPrimInt, true, true); 2490 break; 2491 } 2492 2493 case Instruction::REM_INT_LIT16: 2494 case Instruction::REM_INT_LIT8: { 2495 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(), 2496 dex_pc, Primitive::kPrimInt, true, false); 2497 break; 2498 } 2499 2500 case Instruction::SHL_INT_LIT8: { 2501 Binop_22b<HShl>(instruction, false, dex_pc); 2502 break; 2503 } 2504 2505 case Instruction::SHR_INT_LIT8: { 2506 Binop_22b<HShr>(instruction, false, dex_pc); 2507 break; 2508 } 2509 2510 case Instruction::USHR_INT_LIT8: { 2511 Binop_22b<HUShr>(instruction, false, dex_pc); 2512 break; 2513 } 2514 2515 case Instruction::NEW_INSTANCE: { 2516 if (!BuildNewInstance(dex::TypeIndex(instruction.VRegB_21c()), dex_pc)) { 2517 return false; 2518 } 2519 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 2520 break; 2521 } 2522 2523 case Instruction::NEW_ARRAY: { 2524 dex::TypeIndex type_index(instruction.VRegC_22c()); 2525 HInstruction* length = LoadLocal(instruction.VRegB_22c(), Primitive::kPrimInt); 2526 HLoadClass* cls = BuildLoadClass(type_index, dex_pc); 2527 AppendInstruction(new (arena_) HNewArray(cls, length, dex_pc)); 2528 UpdateLocal(instruction.VRegA_22c(), current_block_->GetLastInstruction()); 2529 break; 2530 } 2531 2532 case Instruction::FILLED_NEW_ARRAY: { 2533 uint32_t number_of_vreg_arguments = instruction.VRegA_35c(); 2534 dex::TypeIndex type_index(instruction.VRegB_35c()); 2535 uint32_t args[5]; 2536 instruction.GetVarArgs(args); 2537 BuildFilledNewArray(dex_pc, type_index, number_of_vreg_arguments, false, args, 0); 2538 break; 2539 } 2540 2541 case Instruction::FILLED_NEW_ARRAY_RANGE: { 2542 uint32_t number_of_vreg_arguments = instruction.VRegA_3rc(); 2543 dex::TypeIndex type_index(instruction.VRegB_3rc()); 2544 uint32_t register_index = instruction.VRegC_3rc(); 2545 BuildFilledNewArray( 2546 dex_pc, type_index, number_of_vreg_arguments, true, nullptr, register_index); 2547 break; 2548 } 2549 2550 case Instruction::FILL_ARRAY_DATA: { 2551 BuildFillArrayData(instruction, dex_pc); 2552 break; 2553 } 2554 2555 case Instruction::MOVE_RESULT: 2556 case Instruction::MOVE_RESULT_WIDE: 2557 case Instruction::MOVE_RESULT_OBJECT: { 2558 DCHECK(latest_result_ != nullptr); 2559 UpdateLocal(instruction.VRegA(), latest_result_); 2560 latest_result_ = nullptr; 2561 break; 2562 } 2563 2564 case Instruction::CMP_LONG: { 2565 Binop_23x_cmp(instruction, Primitive::kPrimLong, ComparisonBias::kNoBias, dex_pc); 2566 break; 2567 } 2568 2569 case Instruction::CMPG_FLOAT: { 2570 Binop_23x_cmp(instruction, Primitive::kPrimFloat, ComparisonBias::kGtBias, dex_pc); 2571 break; 2572 } 2573 2574 case Instruction::CMPG_DOUBLE: { 2575 Binop_23x_cmp(instruction, Primitive::kPrimDouble, ComparisonBias::kGtBias, dex_pc); 2576 break; 2577 } 2578 2579 case Instruction::CMPL_FLOAT: { 2580 Binop_23x_cmp(instruction, Primitive::kPrimFloat, ComparisonBias::kLtBias, dex_pc); 2581 break; 2582 } 2583 2584 case Instruction::CMPL_DOUBLE: { 2585 Binop_23x_cmp(instruction, Primitive::kPrimDouble, ComparisonBias::kLtBias, dex_pc); 2586 break; 2587 } 2588 2589 case Instruction::NOP: 2590 break; 2591 2592 case Instruction::IGET: 2593 case Instruction::IGET_QUICK: 2594 case Instruction::IGET_WIDE: 2595 case Instruction::IGET_WIDE_QUICK: 2596 case Instruction::IGET_OBJECT: 2597 case Instruction::IGET_OBJECT_QUICK: 2598 case Instruction::IGET_BOOLEAN: 2599 case Instruction::IGET_BOOLEAN_QUICK: 2600 case Instruction::IGET_BYTE: 2601 case Instruction::IGET_BYTE_QUICK: 2602 case Instruction::IGET_CHAR: 2603 case Instruction::IGET_CHAR_QUICK: 2604 case Instruction::IGET_SHORT: 2605 case Instruction::IGET_SHORT_QUICK: { 2606 if (!BuildInstanceFieldAccess(instruction, dex_pc, false)) { 2607 return false; 2608 } 2609 break; 2610 } 2611 2612 case Instruction::IPUT: 2613 case Instruction::IPUT_QUICK: 2614 case Instruction::IPUT_WIDE: 2615 case Instruction::IPUT_WIDE_QUICK: 2616 case Instruction::IPUT_OBJECT: 2617 case Instruction::IPUT_OBJECT_QUICK: 2618 case Instruction::IPUT_BOOLEAN: 2619 case Instruction::IPUT_BOOLEAN_QUICK: 2620 case Instruction::IPUT_BYTE: 2621 case Instruction::IPUT_BYTE_QUICK: 2622 case Instruction::IPUT_CHAR: 2623 case Instruction::IPUT_CHAR_QUICK: 2624 case Instruction::IPUT_SHORT: 2625 case Instruction::IPUT_SHORT_QUICK: { 2626 if (!BuildInstanceFieldAccess(instruction, dex_pc, true)) { 2627 return false; 2628 } 2629 break; 2630 } 2631 2632 case Instruction::SGET: 2633 case Instruction::SGET_WIDE: 2634 case Instruction::SGET_OBJECT: 2635 case Instruction::SGET_BOOLEAN: 2636 case Instruction::SGET_BYTE: 2637 case Instruction::SGET_CHAR: 2638 case Instruction::SGET_SHORT: { 2639 if (!BuildStaticFieldAccess(instruction, dex_pc, false)) { 2640 return false; 2641 } 2642 break; 2643 } 2644 2645 case Instruction::SPUT: 2646 case Instruction::SPUT_WIDE: 2647 case Instruction::SPUT_OBJECT: 2648 case Instruction::SPUT_BOOLEAN: 2649 case Instruction::SPUT_BYTE: 2650 case Instruction::SPUT_CHAR: 2651 case Instruction::SPUT_SHORT: { 2652 if (!BuildStaticFieldAccess(instruction, dex_pc, true)) { 2653 return false; 2654 } 2655 break; 2656 } 2657 2658#define ARRAY_XX(kind, anticipated_type) \ 2659 case Instruction::AGET##kind: { \ 2660 BuildArrayAccess(instruction, dex_pc, false, anticipated_type); \ 2661 break; \ 2662 } \ 2663 case Instruction::APUT##kind: { \ 2664 BuildArrayAccess(instruction, dex_pc, true, anticipated_type); \ 2665 break; \ 2666 } 2667 2668 ARRAY_XX(, Primitive::kPrimInt); 2669 ARRAY_XX(_WIDE, Primitive::kPrimLong); 2670 ARRAY_XX(_OBJECT, Primitive::kPrimNot); 2671 ARRAY_XX(_BOOLEAN, Primitive::kPrimBoolean); 2672 ARRAY_XX(_BYTE, Primitive::kPrimByte); 2673 ARRAY_XX(_CHAR, Primitive::kPrimChar); 2674 ARRAY_XX(_SHORT, Primitive::kPrimShort); 2675 2676 case Instruction::ARRAY_LENGTH: { 2677 HInstruction* object = LoadNullCheckedLocal(instruction.VRegB_12x(), dex_pc); 2678 AppendInstruction(new (arena_) HArrayLength(object, dex_pc)); 2679 UpdateLocal(instruction.VRegA_12x(), current_block_->GetLastInstruction()); 2680 break; 2681 } 2682 2683 case Instruction::CONST_STRING: { 2684 dex::StringIndex string_index(instruction.VRegB_21c()); 2685 AppendInstruction( 2686 new (arena_) HLoadString(graph_->GetCurrentMethod(), string_index, *dex_file_, dex_pc)); 2687 UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction()); 2688 break; 2689 } 2690 2691 case Instruction::CONST_STRING_JUMBO: { 2692 dex::StringIndex string_index(instruction.VRegB_31c()); 2693 AppendInstruction( 2694 new (arena_) HLoadString(graph_->GetCurrentMethod(), string_index, *dex_file_, dex_pc)); 2695 UpdateLocal(instruction.VRegA_31c(), current_block_->GetLastInstruction()); 2696 break; 2697 } 2698 2699 case Instruction::CONST_CLASS: { 2700 dex::TypeIndex type_index(instruction.VRegB_21c()); 2701 BuildLoadClass(type_index, dex_pc); 2702 UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction()); 2703 break; 2704 } 2705 2706 case Instruction::MOVE_EXCEPTION: { 2707 AppendInstruction(new (arena_) HLoadException(dex_pc)); 2708 UpdateLocal(instruction.VRegA_11x(), current_block_->GetLastInstruction()); 2709 AppendInstruction(new (arena_) HClearException(dex_pc)); 2710 break; 2711 } 2712 2713 case Instruction::THROW: { 2714 HInstruction* exception = LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot); 2715 AppendInstruction(new (arena_) HThrow(exception, dex_pc)); 2716 // We finished building this block. Set the current block to null to avoid 2717 // adding dead instructions to it. 2718 current_block_ = nullptr; 2719 break; 2720 } 2721 2722 case Instruction::INSTANCE_OF: { 2723 uint8_t destination = instruction.VRegA_22c(); 2724 uint8_t reference = instruction.VRegB_22c(); 2725 dex::TypeIndex type_index(instruction.VRegC_22c()); 2726 BuildTypeCheck(instruction, destination, reference, type_index, dex_pc); 2727 break; 2728 } 2729 2730 case Instruction::CHECK_CAST: { 2731 uint8_t reference = instruction.VRegA_21c(); 2732 dex::TypeIndex type_index(instruction.VRegB_21c()); 2733 BuildTypeCheck(instruction, -1, reference, type_index, dex_pc); 2734 break; 2735 } 2736 2737 case Instruction::MONITOR_ENTER: { 2738 AppendInstruction(new (arena_) HMonitorOperation( 2739 LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot), 2740 HMonitorOperation::OperationKind::kEnter, 2741 dex_pc)); 2742 break; 2743 } 2744 2745 case Instruction::MONITOR_EXIT: { 2746 AppendInstruction(new (arena_) HMonitorOperation( 2747 LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot), 2748 HMonitorOperation::OperationKind::kExit, 2749 dex_pc)); 2750 break; 2751 } 2752 2753 case Instruction::SPARSE_SWITCH: 2754 case Instruction::PACKED_SWITCH: { 2755 BuildSwitch(instruction, dex_pc); 2756 break; 2757 } 2758 2759 default: 2760 VLOG(compiler) << "Did not compile " 2761 << dex_file_->PrettyMethod(dex_compilation_unit_->GetDexMethodIndex()) 2762 << " because of unhandled instruction " 2763 << instruction.Name(); 2764 MaybeRecordStat(MethodCompilationStat::kNotCompiledUnhandledInstruction); 2765 return false; 2766 } 2767 return true; 2768} // NOLINT(readability/fn_size) 2769 2770ObjPtr<mirror::Class> HInstructionBuilder::LookupResolvedType( 2771 dex::TypeIndex type_index, 2772 const DexCompilationUnit& compilation_unit) const { 2773 return ClassLinker::LookupResolvedType( 2774 type_index, compilation_unit.GetDexCache().Get(), compilation_unit.GetClassLoader().Get()); 2775} 2776 2777ObjPtr<mirror::Class> HInstructionBuilder::LookupReferrerClass() const { 2778 // TODO: Cache the result in a Handle<mirror::Class>. 2779 const DexFile::MethodId& method_id = 2780 dex_compilation_unit_->GetDexFile()->GetMethodId(dex_compilation_unit_->GetDexMethodIndex()); 2781 return LookupResolvedType(method_id.class_idx_, *dex_compilation_unit_); 2782} 2783 2784} // namespace art 2785