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