builder.cc revision cb1c0557033065f2436ee79e7fa6c19d87064801
1/* 2 * Copyright (C) 2014 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 "builder.h" 18 19#include "art_field-inl.h" 20#include "base/logging.h" 21#include "class_linker.h" 22#include "dex/verified_method.h" 23#include "dex_file-inl.h" 24#include "dex_instruction-inl.h" 25#include "dex/verified_method.h" 26#include "driver/compiler_driver-inl.h" 27#include "driver/compiler_options.h" 28#include "mirror/class_loader.h" 29#include "mirror/dex_cache.h" 30#include "nodes.h" 31#include "primitive.h" 32#include "scoped_thread_state_change.h" 33#include "thread.h" 34 35namespace art { 36 37/** 38 * Helper class to add HTemporary instructions. This class is used when 39 * converting a DEX instruction to multiple HInstruction, and where those 40 * instructions do not die at the following instruction, but instead spans 41 * multiple instructions. 42 */ 43class Temporaries : public ValueObject { 44 public: 45 explicit Temporaries(HGraph* graph) : graph_(graph), index_(0) {} 46 47 void Add(HInstruction* instruction) { 48 HInstruction* temp = new (graph_->GetArena()) HTemporary(index_); 49 instruction->GetBlock()->AddInstruction(temp); 50 51 DCHECK(temp->GetPrevious() == instruction); 52 53 size_t offset; 54 if (instruction->GetType() == Primitive::kPrimLong 55 || instruction->GetType() == Primitive::kPrimDouble) { 56 offset = 2; 57 } else { 58 offset = 1; 59 } 60 index_ += offset; 61 62 graph_->UpdateTemporariesVRegSlots(index_); 63 } 64 65 private: 66 HGraph* const graph_; 67 68 // Current index in the temporary stack, updated by `Add`. 69 size_t index_; 70}; 71 72class SwitchTable : public ValueObject { 73 public: 74 SwitchTable(const Instruction& instruction, uint32_t dex_pc, bool sparse) 75 : instruction_(instruction), dex_pc_(dex_pc), sparse_(sparse) { 76 int32_t table_offset = instruction.VRegB_31t(); 77 const uint16_t* table = reinterpret_cast<const uint16_t*>(&instruction) + table_offset; 78 if (sparse) { 79 CHECK_EQ(table[0], static_cast<uint16_t>(Instruction::kSparseSwitchSignature)); 80 } else { 81 CHECK_EQ(table[0], static_cast<uint16_t>(Instruction::kPackedSwitchSignature)); 82 } 83 num_entries_ = table[1]; 84 values_ = reinterpret_cast<const int32_t*>(&table[2]); 85 } 86 87 uint16_t GetNumEntries() const { 88 return num_entries_; 89 } 90 91 void CheckIndex(size_t index) const { 92 if (sparse_) { 93 // In a sparse table, we have num_entries_ keys and num_entries_ values, in that order. 94 DCHECK_LT(index, 2 * static_cast<size_t>(num_entries_)); 95 } else { 96 // In a packed table, we have the starting key and num_entries_ values. 97 DCHECK_LT(index, 1 + static_cast<size_t>(num_entries_)); 98 } 99 } 100 101 int32_t GetEntryAt(size_t index) const { 102 CheckIndex(index); 103 return values_[index]; 104 } 105 106 uint32_t GetDexPcForIndex(size_t index) const { 107 CheckIndex(index); 108 return dex_pc_ + 109 (reinterpret_cast<const int16_t*>(values_ + index) - 110 reinterpret_cast<const int16_t*>(&instruction_)); 111 } 112 113 // Index of the first value in the table. 114 size_t GetFirstValueIndex() const { 115 if (sparse_) { 116 // In a sparse table, we have num_entries_ keys and num_entries_ values, in that order. 117 return num_entries_; 118 } else { 119 // In a packed table, we have the starting key and num_entries_ values. 120 return 1; 121 } 122 } 123 124 private: 125 const Instruction& instruction_; 126 const uint32_t dex_pc_; 127 128 // Whether this is a sparse-switch table (or a packed-switch one). 129 const bool sparse_; 130 131 // This can't be const as it needs to be computed off of the given instruction, and complicated 132 // expressions in the initializer list seemed very ugly. 133 uint16_t num_entries_; 134 135 const int32_t* values_; 136 137 DISALLOW_COPY_AND_ASSIGN(SwitchTable); 138}; 139 140void HGraphBuilder::InitializeLocals(uint16_t count) { 141 graph_->SetNumberOfVRegs(count); 142 locals_.SetSize(count); 143 for (int i = 0; i < count; i++) { 144 HLocal* local = new (arena_) HLocal(i); 145 entry_block_->AddInstruction(local); 146 locals_.Put(i, local); 147 } 148} 149 150void HGraphBuilder::InitializeParameters(uint16_t number_of_parameters) { 151 // dex_compilation_unit_ is null only when unit testing. 152 if (dex_compilation_unit_ == nullptr) { 153 return; 154 } 155 156 graph_->SetNumberOfInVRegs(number_of_parameters); 157 const char* shorty = dex_compilation_unit_->GetShorty(); 158 int locals_index = locals_.Size() - number_of_parameters; 159 int parameter_index = 0; 160 161 if (!dex_compilation_unit_->IsStatic()) { 162 // Add the implicit 'this' argument, not expressed in the signature. 163 HParameterValue* parameter = 164 new (arena_) HParameterValue(parameter_index++, Primitive::kPrimNot, true); 165 entry_block_->AddInstruction(parameter); 166 HLocal* local = GetLocalAt(locals_index++); 167 entry_block_->AddInstruction(new (arena_) HStoreLocal(local, parameter)); 168 number_of_parameters--; 169 } 170 171 uint32_t pos = 1; 172 for (int i = 0; i < number_of_parameters; i++) { 173 HParameterValue* parameter = 174 new (arena_) HParameterValue(parameter_index++, Primitive::GetType(shorty[pos++])); 175 entry_block_->AddInstruction(parameter); 176 HLocal* local = GetLocalAt(locals_index++); 177 // Store the parameter value in the local that the dex code will use 178 // to reference that parameter. 179 entry_block_->AddInstruction(new (arena_) HStoreLocal(local, parameter)); 180 bool is_wide = (parameter->GetType() == Primitive::kPrimLong) 181 || (parameter->GetType() == Primitive::kPrimDouble); 182 if (is_wide) { 183 i++; 184 locals_index++; 185 parameter_index++; 186 } 187 } 188} 189 190template<typename T> 191void HGraphBuilder::If_22t(const Instruction& instruction, uint32_t dex_pc) { 192 int32_t target_offset = instruction.GetTargetOffset(); 193 HBasicBlock* branch_target = FindBlockStartingAt(dex_pc + target_offset); 194 HBasicBlock* fallthrough_target = FindBlockStartingAt(dex_pc + instruction.SizeInCodeUnits()); 195 DCHECK(branch_target != nullptr); 196 DCHECK(fallthrough_target != nullptr); 197 PotentiallyAddSuspendCheck(branch_target, dex_pc); 198 HInstruction* first = LoadLocal(instruction.VRegA(), Primitive::kPrimInt); 199 HInstruction* second = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); 200 T* comparison = new (arena_) T(first, second); 201 current_block_->AddInstruction(comparison); 202 HInstruction* ifinst = new (arena_) HIf(comparison); 203 current_block_->AddInstruction(ifinst); 204 current_block_->AddSuccessor(branch_target); 205 current_block_->AddSuccessor(fallthrough_target); 206 current_block_ = nullptr; 207} 208 209template<typename T> 210void HGraphBuilder::If_21t(const Instruction& instruction, uint32_t dex_pc) { 211 int32_t target_offset = instruction.GetTargetOffset(); 212 HBasicBlock* branch_target = FindBlockStartingAt(dex_pc + target_offset); 213 HBasicBlock* fallthrough_target = FindBlockStartingAt(dex_pc + instruction.SizeInCodeUnits()); 214 DCHECK(branch_target != nullptr); 215 DCHECK(fallthrough_target != nullptr); 216 PotentiallyAddSuspendCheck(branch_target, dex_pc); 217 HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt); 218 T* comparison = new (arena_) T(value, graph_->GetIntConstant(0)); 219 current_block_->AddInstruction(comparison); 220 HInstruction* ifinst = new (arena_) HIf(comparison); 221 current_block_->AddInstruction(ifinst); 222 current_block_->AddSuccessor(branch_target); 223 current_block_->AddSuccessor(fallthrough_target); 224 current_block_ = nullptr; 225} 226 227void HGraphBuilder::MaybeRecordStat(MethodCompilationStat compilation_stat) { 228 if (compilation_stats_ != nullptr) { 229 compilation_stats_->RecordStat(compilation_stat); 230 } 231} 232 233bool HGraphBuilder::SkipCompilation(const DexFile::CodeItem& code_item, 234 size_t number_of_branches) { 235 const CompilerOptions& compiler_options = compiler_driver_->GetCompilerOptions(); 236 CompilerOptions::CompilerFilter compiler_filter = compiler_options.GetCompilerFilter(); 237 if (compiler_filter == CompilerOptions::kEverything) { 238 return false; 239 } 240 241 if (compiler_options.IsHugeMethod(code_item.insns_size_in_code_units_)) { 242 VLOG(compiler) << "Skip compilation of huge method " 243 << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_) 244 << ": " << code_item.insns_size_in_code_units_ << " code units"; 245 MaybeRecordStat(MethodCompilationStat::kNotCompiledHugeMethod); 246 return true; 247 } 248 249 // If it's large and contains no branches, it's likely to be machine generated initialization. 250 if (compiler_options.IsLargeMethod(code_item.insns_size_in_code_units_) 251 && (number_of_branches == 0)) { 252 VLOG(compiler) << "Skip compilation of large method with no branch " 253 << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_) 254 << ": " << code_item.insns_size_in_code_units_ << " code units"; 255 MaybeRecordStat(MethodCompilationStat::kNotCompiledLargeMethodNoBranches); 256 return true; 257 } 258 259 return false; 260} 261 262static const DexFile::TryItem* GetTryItem(HBasicBlock* block, 263 const DexFile::CodeItem& code_item, 264 const ArenaBitVector& can_block_throw) { 265 DCHECK(!block->IsSingleTryBoundary()); 266 267 // Block does not contain throwing instructions. Even if it is covered by 268 // a TryItem, we will consider it not in a try block. 269 if (!can_block_throw.IsBitSet(block->GetBlockId())) { 270 return nullptr; 271 } 272 273 // Instructions in the block may throw. Find a TryItem covering this block. 274 int32_t try_item_idx = DexFile::FindTryItem(code_item, block->GetDexPc()); 275 return (try_item_idx == -1) ? nullptr : DexFile::GetTryItems(code_item, try_item_idx); 276} 277 278void HGraphBuilder::CreateBlocksForTryCatch(const DexFile::CodeItem& code_item) { 279 if (code_item.tries_size_ == 0) { 280 return; 281 } 282 283 // Create branch targets at the start/end of the TryItem range. These are 284 // places where the program might fall through into/out of the a block and 285 // where TryBoundary instructions will be inserted later. Other edges which 286 // enter/exit the try blocks are a result of branches/switches. 287 for (size_t idx = 0; idx < code_item.tries_size_; ++idx) { 288 const DexFile::TryItem* try_item = DexFile::GetTryItems(code_item, idx); 289 uint32_t dex_pc_start = try_item->start_addr_; 290 uint32_t dex_pc_end = dex_pc_start + try_item->insn_count_; 291 FindOrCreateBlockStartingAt(dex_pc_start); 292 if (dex_pc_end < code_item.insns_size_in_code_units_) { 293 // TODO: Do not create block if the last instruction cannot fall through. 294 FindOrCreateBlockStartingAt(dex_pc_end); 295 } else { 296 // The TryItem spans until the very end of the CodeItem (or beyond if 297 // invalid) and therefore cannot have any code afterwards. 298 } 299 } 300 301 // Create branch targets for exception handlers. 302 const uint8_t* handlers_ptr = DexFile::GetCatchHandlerData(code_item, 0); 303 uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr); 304 for (uint32_t idx = 0; idx < handlers_size; ++idx) { 305 CatchHandlerIterator iterator(handlers_ptr); 306 for (; iterator.HasNext(); iterator.Next()) { 307 uint32_t address = iterator.GetHandlerAddress(); 308 HBasicBlock* block = FindOrCreateBlockStartingAt(address); 309 block->SetIsCatchBlock(); 310 } 311 handlers_ptr = iterator.EndDataPointer(); 312 } 313} 314 315void HGraphBuilder::SplitTryBoundaryEdge(HBasicBlock* predecessor, 316 HBasicBlock* successor, 317 HTryBoundary::BoundaryKind kind, 318 const DexFile::CodeItem& code_item, 319 const DexFile::TryItem& try_item) { 320 // Split the edge with a single TryBoundary instruction. 321 HTryBoundary* try_boundary = new (arena_) HTryBoundary(kind); 322 HBasicBlock* try_entry_block = graph_->SplitEdge(predecessor, successor); 323 try_entry_block->AddInstruction(try_boundary); 324 325 // Link the TryBoundary to the handlers of `try_item`. 326 for (CatchHandlerIterator it(code_item, try_item); it.HasNext(); it.Next()) { 327 try_boundary->AddExceptionHandler(FindBlockStartingAt(it.GetHandlerAddress())); 328 } 329} 330 331void HGraphBuilder::InsertTryBoundaryBlocks(const DexFile::CodeItem& code_item) { 332 if (code_item.tries_size_ == 0) { 333 return; 334 } 335 336 // Bit vector stores information on which blocks contain throwing instructions. 337 // Must be expandable because catch blocks may be split into two. 338 ArenaBitVector can_block_throw(arena_, graph_->GetBlocks().Size(), /* expandable */ true); 339 340 // Scan blocks and mark those which contain throwing instructions. 341 for (size_t block_id = 0, e = graph_->GetBlocks().Size(); block_id < e; ++block_id) { 342 HBasicBlock* block = graph_->GetBlocks().Get(block_id); 343 bool can_throw = false; 344 for (HInstructionIterator insn(block->GetInstructions()); !insn.Done(); insn.Advance()) { 345 if (insn.Current()->CanThrow()) { 346 can_throw = true; 347 break; 348 } 349 } 350 351 if (can_throw) { 352 if (block->IsCatchBlock()) { 353 // Catch blocks are always considered an entry point into the TryItem in 354 // order to avoid splitting exceptional edges. We split the block after 355 // the move-exception (if present) and mark the first part non-throwing. 356 // Later on, a TryBoundary will be inserted between the two blocks. 357 HInstruction* first_insn = block->GetFirstInstruction(); 358 if (first_insn->IsLoadException()) { 359 // Catch block starts with a LoadException. Split the block after the 360 // StoreLocal and ClearException which must come after the load. 361 DCHECK(first_insn->GetNext()->IsStoreLocal()); 362 DCHECK(first_insn->GetNext()->GetNext()->IsClearException()); 363 block = block->SplitBefore(first_insn->GetNext()->GetNext()->GetNext()); 364 } else { 365 // Catch block does not load the exception. Split at the beginning to 366 // create an empty catch block. 367 block = block->SplitBefore(first_insn); 368 } 369 } 370 can_block_throw.SetBit(block->GetBlockId()); 371 } 372 } 373 374 // Iterate over all blocks, find those covered by some TryItem and: 375 // (a) split edges which enter/exit the try range, 376 // (b) create TryBoundary instructions in the new blocks, 377 // (c) link the new blocks to corresponding exception handlers. 378 // We cannot iterate only over blocks in `branch_targets_` because switch-case 379 // blocks share the same dex_pc. 380 for (size_t block_id = 0, e = graph_->GetBlocks().Size(); block_id < e; ++block_id) { 381 HBasicBlock* try_block = graph_->GetBlocks().Get(block_id); 382 383 // TryBoundary blocks are added at the end of the list and not iterated over. 384 DCHECK(!try_block->IsSingleTryBoundary()); 385 386 // Find the TryItem for this block. 387 const DexFile::TryItem* try_item = GetTryItem(try_block, code_item, can_block_throw); 388 if (try_item == nullptr) { 389 continue; 390 } 391 392 // Catch blocks were split earlier and cannot throw. 393 DCHECK(!try_block->IsCatchBlock()); 394 395 // Find predecessors which are not covered by the same TryItem range. Such 396 // edges enter the try block and will have a TryBoundary inserted. 397 for (size_t i = 0; i < try_block->GetPredecessors().Size(); ++i) { 398 HBasicBlock* predecessor = try_block->GetPredecessors().Get(i); 399 if (predecessor->IsSingleTryBoundary()) { 400 // The edge was already split because of an exit from a neighbouring 401 // TryItem. We split it again and insert an entry point. 402 if (kIsDebugBuild) { 403 HTryBoundary* last_insn = predecessor->GetLastInstruction()->AsTryBoundary(); 404 const DexFile::TryItem* predecessor_try_item = 405 GetTryItem(predecessor->GetSinglePredecessor(), code_item, can_block_throw); 406 DCHECK(!last_insn->IsEntry()); 407 DCHECK_EQ(last_insn->GetNormalFlowSuccessor(), try_block); 408 DCHECK(try_block->IsFirstIndexOfPredecessor(predecessor, i)); 409 DCHECK_NE(try_item, predecessor_try_item); 410 } 411 } else if (GetTryItem(predecessor, code_item, can_block_throw) != try_item) { 412 // This is an entry point into the TryItem and the edge has not been 413 // split yet. That means that `predecessor` is not in a TryItem, or 414 // it is in a different TryItem and we happened to iterate over this 415 // block first. We split the edge and insert an entry point. 416 } else { 417 // Not an edge on the boundary of the try block. 418 continue; 419 } 420 SplitTryBoundaryEdge(predecessor, try_block, HTryBoundary::kEntry, code_item, *try_item); 421 } 422 423 // Find successors which are not covered by the same TryItem range. Such 424 // edges exit the try block and will have a TryBoundary inserted. 425 for (size_t i = 0; i < try_block->GetSuccessors().Size(); ++i) { 426 HBasicBlock* successor = try_block->GetSuccessors().Get(i); 427 if (successor->IsCatchBlock()) { 428 // A catch block is always considered an entry point into its TryItem. 429 // We therefore assume this is an exit point, regardless of whether 430 // the catch block is in a different TryItem or not. 431 } else if (successor->IsSingleTryBoundary()) { 432 // The edge was already split because of an entry into a neighbouring 433 // TryItem. We split it again and insert an exit. 434 if (kIsDebugBuild) { 435 HTryBoundary* last_insn = successor->GetLastInstruction()->AsTryBoundary(); 436 const DexFile::TryItem* successor_try_item = 437 GetTryItem(last_insn->GetNormalFlowSuccessor(), code_item, can_block_throw); 438 DCHECK_EQ(try_block, successor->GetSinglePredecessor()); 439 DCHECK(last_insn->IsEntry()); 440 DCHECK_NE(try_item, successor_try_item); 441 } 442 } else if (GetTryItem(successor, code_item, can_block_throw) != try_item) { 443 // This is an exit out of the TryItem and the edge has not been split 444 // yet. That means that either `successor` is not in a TryItem, or it 445 // is in a different TryItem and we happened to iterate over this 446 // block first. We split the edge and insert an exit. 447 HInstruction* last_instruction = try_block->GetLastInstruction(); 448 if (last_instruction->IsReturn() || last_instruction->IsReturnVoid()) { 449 DCHECK_EQ(successor, exit_block_); 450 // Control flow exits the try block with a Return(Void). Because 451 // splitting the edge would invalidate the invariant that Return 452 // always jumps to Exit, we move the Return outside the try block. 453 successor = try_block->SplitBefore(last_instruction); 454 } 455 } else { 456 // Not an edge on the boundary of the try block. 457 continue; 458 } 459 SplitTryBoundaryEdge(try_block, successor, HTryBoundary::kExit, code_item, *try_item); 460 } 461 } 462} 463 464bool HGraphBuilder::BuildGraph(const DexFile::CodeItem& code_item) { 465 DCHECK(graph_->GetBlocks().IsEmpty()); 466 467 const uint16_t* code_ptr = code_item.insns_; 468 const uint16_t* code_end = code_item.insns_ + code_item.insns_size_in_code_units_; 469 code_start_ = code_ptr; 470 471 // Setup the graph with the entry block and exit block. 472 entry_block_ = new (arena_) HBasicBlock(graph_, 0); 473 graph_->AddBlock(entry_block_); 474 exit_block_ = new (arena_) HBasicBlock(graph_, kNoDexPc); 475 graph_->SetEntryBlock(entry_block_); 476 graph_->SetExitBlock(exit_block_); 477 478 InitializeLocals(code_item.registers_size_); 479 graph_->SetMaximumNumberOfOutVRegs(code_item.outs_size_); 480 481 // Compute the number of dex instructions, blocks, and branches. We will 482 // check these values against limits given to the compiler. 483 size_t number_of_branches = 0; 484 485 // To avoid splitting blocks, we compute ahead of time the instructions that 486 // start a new block, and create these blocks. 487 if (!ComputeBranchTargets(code_ptr, code_end, &number_of_branches)) { 488 MaybeRecordStat(MethodCompilationStat::kNotCompiledBranchOutsideMethodCode); 489 return false; 490 } 491 492 // Note that the compiler driver is null when unit testing. 493 if ((compiler_driver_ != nullptr) && SkipCompilation(code_item, number_of_branches)) { 494 return false; 495 } 496 497 CreateBlocksForTryCatch(code_item); 498 499 InitializeParameters(code_item.ins_size_); 500 501 size_t dex_pc = 0; 502 while (code_ptr < code_end) { 503 // Update the current block if dex_pc starts a new block. 504 MaybeUpdateCurrentBlock(dex_pc); 505 const Instruction& instruction = *Instruction::At(code_ptr); 506 if (!AnalyzeDexInstruction(instruction, dex_pc)) { 507 return false; 508 } 509 dex_pc += instruction.SizeInCodeUnits(); 510 code_ptr += instruction.SizeInCodeUnits(); 511 } 512 513 // Add Exit to the exit block. 514 exit_block_->AddInstruction(new (arena_) HExit()); 515 // Add the suspend check to the entry block. 516 entry_block_->AddInstruction(new (arena_) HSuspendCheck(0)); 517 entry_block_->AddInstruction(new (arena_) HGoto()); 518 // Add the exit block at the end. 519 graph_->AddBlock(exit_block_); 520 521 // Iterate over blocks covered by TryItems and insert TryBoundaries at entry 522 // and exit points. This requires all control-flow instructions and 523 // non-exceptional edges to have been created. 524 InsertTryBoundaryBlocks(code_item); 525 526 return true; 527} 528 529void HGraphBuilder::MaybeUpdateCurrentBlock(size_t dex_pc) { 530 HBasicBlock* block = FindBlockStartingAt(dex_pc); 531 if (block == nullptr) { 532 return; 533 } 534 535 if (current_block_ != nullptr) { 536 // Branching instructions clear current_block, so we know 537 // the last instruction of the current block is not a branching 538 // instruction. We add an unconditional goto to the found block. 539 current_block_->AddInstruction(new (arena_) HGoto()); 540 current_block_->AddSuccessor(block); 541 } 542 graph_->AddBlock(block); 543 current_block_ = block; 544} 545 546bool HGraphBuilder::ComputeBranchTargets(const uint16_t* code_ptr, 547 const uint16_t* code_end, 548 size_t* number_of_branches) { 549 branch_targets_.SetSize(code_end - code_ptr); 550 551 // Create the first block for the dex instructions, single successor of the entry block. 552 HBasicBlock* block = new (arena_) HBasicBlock(graph_, 0); 553 branch_targets_.Put(0, block); 554 entry_block_->AddSuccessor(block); 555 556 // Iterate over all instructions and find branching instructions. Create blocks for 557 // the locations these instructions branch to. 558 uint32_t dex_pc = 0; 559 while (code_ptr < code_end) { 560 const Instruction& instruction = *Instruction::At(code_ptr); 561 if (instruction.IsBranch()) { 562 (*number_of_branches)++; 563 int32_t target = instruction.GetTargetOffset() + dex_pc; 564 // Create a block for the target instruction. 565 FindOrCreateBlockStartingAt(target); 566 567 dex_pc += instruction.SizeInCodeUnits(); 568 code_ptr += instruction.SizeInCodeUnits(); 569 570 if (instruction.CanFlowThrough()) { 571 if (code_ptr >= code_end) { 572 // In the normal case we should never hit this but someone can artificially forge a dex 573 // file to fall-through out the method code. In this case we bail out compilation. 574 return false; 575 } else { 576 FindOrCreateBlockStartingAt(dex_pc); 577 } 578 } 579 } else if (instruction.IsSwitch()) { 580 SwitchTable table(instruction, dex_pc, instruction.Opcode() == Instruction::SPARSE_SWITCH); 581 582 uint16_t num_entries = table.GetNumEntries(); 583 584 // In a packed-switch, the entry at index 0 is the starting key. In a sparse-switch, the 585 // entry at index 0 is the first key, and values are after *all* keys. 586 size_t offset = table.GetFirstValueIndex(); 587 588 // Use a larger loop counter type to avoid overflow issues. 589 for (size_t i = 0; i < num_entries; ++i) { 590 // The target of the case. 591 uint32_t target = dex_pc + table.GetEntryAt(i + offset); 592 FindOrCreateBlockStartingAt(target); 593 594 // Create a block for the switch-case logic. The block gets the dex_pc 595 // of the SWITCH instruction because it is part of its semantics. 596 block = new (arena_) HBasicBlock(graph_, dex_pc); 597 branch_targets_.Put(table.GetDexPcForIndex(i), block); 598 } 599 600 // Fall-through. Add a block if there is more code afterwards. 601 dex_pc += instruction.SizeInCodeUnits(); 602 code_ptr += instruction.SizeInCodeUnits(); 603 if (code_ptr >= code_end) { 604 // In the normal case we should never hit this but someone can artificially forge a dex 605 // file to fall-through out the method code. In this case we bail out compilation. 606 // (A switch can fall-through so we don't need to check CanFlowThrough().) 607 return false; 608 } else { 609 FindOrCreateBlockStartingAt(dex_pc); 610 } 611 } else { 612 code_ptr += instruction.SizeInCodeUnits(); 613 dex_pc += instruction.SizeInCodeUnits(); 614 } 615 } 616 return true; 617} 618 619HBasicBlock* HGraphBuilder::FindBlockStartingAt(int32_t dex_pc) const { 620 DCHECK_GE(dex_pc, 0); 621 DCHECK_LT(static_cast<size_t>(dex_pc), branch_targets_.Size()); 622 return branch_targets_.Get(dex_pc); 623} 624 625HBasicBlock* HGraphBuilder::FindOrCreateBlockStartingAt(int32_t dex_pc) { 626 HBasicBlock* block = FindBlockStartingAt(dex_pc); 627 if (block == nullptr) { 628 block = new (arena_) HBasicBlock(graph_, dex_pc); 629 branch_targets_.Put(dex_pc, block); 630 } 631 return block; 632} 633 634template<typename T> 635void HGraphBuilder::Unop_12x(const Instruction& instruction, Primitive::Type type) { 636 HInstruction* first = LoadLocal(instruction.VRegB(), type); 637 current_block_->AddInstruction(new (arena_) T(type, first)); 638 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 639} 640 641void HGraphBuilder::Conversion_12x(const Instruction& instruction, 642 Primitive::Type input_type, 643 Primitive::Type result_type, 644 uint32_t dex_pc) { 645 HInstruction* first = LoadLocal(instruction.VRegB(), input_type); 646 current_block_->AddInstruction(new (arena_) HTypeConversion(result_type, first, dex_pc)); 647 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 648} 649 650template<typename T> 651void HGraphBuilder::Binop_23x(const Instruction& instruction, Primitive::Type type) { 652 HInstruction* first = LoadLocal(instruction.VRegB(), type); 653 HInstruction* second = LoadLocal(instruction.VRegC(), type); 654 current_block_->AddInstruction(new (arena_) T(type, first, second)); 655 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 656} 657 658template<typename T> 659void HGraphBuilder::Binop_23x(const Instruction& instruction, 660 Primitive::Type type, 661 uint32_t dex_pc) { 662 HInstruction* first = LoadLocal(instruction.VRegB(), type); 663 HInstruction* second = LoadLocal(instruction.VRegC(), type); 664 current_block_->AddInstruction(new (arena_) T(type, first, second, dex_pc)); 665 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 666} 667 668template<typename T> 669void HGraphBuilder::Binop_23x_shift(const Instruction& instruction, 670 Primitive::Type type) { 671 HInstruction* first = LoadLocal(instruction.VRegB(), type); 672 HInstruction* second = LoadLocal(instruction.VRegC(), Primitive::kPrimInt); 673 current_block_->AddInstruction(new (arena_) T(type, first, second)); 674 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 675} 676 677void HGraphBuilder::Binop_23x_cmp(const Instruction& instruction, 678 Primitive::Type type, 679 ComparisonBias bias, 680 uint32_t dex_pc) { 681 HInstruction* first = LoadLocal(instruction.VRegB(), type); 682 HInstruction* second = LoadLocal(instruction.VRegC(), type); 683 current_block_->AddInstruction(new (arena_) HCompare(type, first, second, bias, dex_pc)); 684 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 685} 686 687template<typename T> 688void HGraphBuilder::Binop_12x(const Instruction& instruction, Primitive::Type type) { 689 HInstruction* first = LoadLocal(instruction.VRegA(), type); 690 HInstruction* second = LoadLocal(instruction.VRegB(), type); 691 current_block_->AddInstruction(new (arena_) T(type, first, second)); 692 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 693} 694 695template<typename T> 696void HGraphBuilder::Binop_12x_shift(const Instruction& instruction, Primitive::Type type) { 697 HInstruction* first = LoadLocal(instruction.VRegA(), type); 698 HInstruction* second = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); 699 current_block_->AddInstruction(new (arena_) T(type, first, second)); 700 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 701} 702 703template<typename T> 704void HGraphBuilder::Binop_12x(const Instruction& instruction, 705 Primitive::Type type, 706 uint32_t dex_pc) { 707 HInstruction* first = LoadLocal(instruction.VRegA(), type); 708 HInstruction* second = LoadLocal(instruction.VRegB(), type); 709 current_block_->AddInstruction(new (arena_) T(type, first, second, dex_pc)); 710 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 711} 712 713template<typename T> 714void HGraphBuilder::Binop_22s(const Instruction& instruction, bool reverse) { 715 HInstruction* first = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); 716 HInstruction* second = graph_->GetIntConstant(instruction.VRegC_22s()); 717 if (reverse) { 718 std::swap(first, second); 719 } 720 current_block_->AddInstruction(new (arena_) T(Primitive::kPrimInt, first, second)); 721 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 722} 723 724template<typename T> 725void HGraphBuilder::Binop_22b(const Instruction& instruction, bool reverse) { 726 HInstruction* first = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); 727 HInstruction* second = graph_->GetIntConstant(instruction.VRegC_22b()); 728 if (reverse) { 729 std::swap(first, second); 730 } 731 current_block_->AddInstruction(new (arena_) T(Primitive::kPrimInt, first, second)); 732 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 733} 734 735static bool RequiresConstructorBarrier(const DexCompilationUnit* cu, const CompilerDriver& driver) { 736 Thread* self = Thread::Current(); 737 return cu->IsConstructor() 738 && driver.RequiresConstructorBarrier(self, cu->GetDexFile(), cu->GetClassDefIndex()); 739} 740 741void HGraphBuilder::BuildReturn(const Instruction& instruction, Primitive::Type type) { 742 if (type == Primitive::kPrimVoid) { 743 if (graph_->ShouldGenerateConstructorBarrier()) { 744 // The compilation unit is null during testing. 745 if (dex_compilation_unit_ != nullptr) { 746 DCHECK(RequiresConstructorBarrier(dex_compilation_unit_, *compiler_driver_)) 747 << "Inconsistent use of ShouldGenerateConstructorBarrier. Should not generate a barrier."; 748 } 749 current_block_->AddInstruction(new (arena_) HMemoryBarrier(kStoreStore)); 750 } 751 current_block_->AddInstruction(new (arena_) HReturnVoid()); 752 } else { 753 HInstruction* value = LoadLocal(instruction.VRegA(), type); 754 current_block_->AddInstruction(new (arena_) HReturn(value)); 755 } 756 current_block_->AddSuccessor(exit_block_); 757 current_block_ = nullptr; 758} 759 760void HGraphBuilder::PotentiallySimplifyFakeString(uint16_t original_dex_register, 761 uint32_t dex_pc, 762 HInvoke* actual_string) { 763 if (!graph_->IsDebuggable()) { 764 // Notify that we cannot compile with baseline. The dex registers aliasing 765 // with `original_dex_register` will be handled when we optimize 766 // (see HInstructionSimplifer::VisitFakeString). 767 can_use_baseline_for_string_init_ = false; 768 return; 769 } 770 const VerifiedMethod* verified_method = 771 compiler_driver_->GetVerifiedMethod(dex_file_, dex_compilation_unit_->GetDexMethodIndex()); 772 if (verified_method != nullptr) { 773 UpdateLocal(original_dex_register, actual_string); 774 const SafeMap<uint32_t, std::set<uint32_t>>& string_init_map = 775 verified_method->GetStringInitPcRegMap(); 776 auto map_it = string_init_map.find(dex_pc); 777 if (map_it != string_init_map.end()) { 778 std::set<uint32_t> reg_set = map_it->second; 779 for (auto set_it = reg_set.begin(); set_it != reg_set.end(); ++set_it) { 780 HInstruction* load_local = LoadLocal(original_dex_register, Primitive::kPrimNot); 781 UpdateLocal(*set_it, load_local); 782 } 783 } 784 } else { 785 can_use_baseline_for_string_init_ = false; 786 } 787} 788 789bool HGraphBuilder::BuildInvoke(const Instruction& instruction, 790 uint32_t dex_pc, 791 uint32_t method_idx, 792 uint32_t number_of_vreg_arguments, 793 bool is_range, 794 uint32_t* args, 795 uint32_t register_index) { 796 Instruction::Code opcode = instruction.Opcode(); 797 InvokeType invoke_type; 798 switch (opcode) { 799 case Instruction::INVOKE_STATIC: 800 case Instruction::INVOKE_STATIC_RANGE: 801 invoke_type = kStatic; 802 break; 803 case Instruction::INVOKE_DIRECT: 804 case Instruction::INVOKE_DIRECT_RANGE: 805 invoke_type = kDirect; 806 break; 807 case Instruction::INVOKE_VIRTUAL: 808 case Instruction::INVOKE_VIRTUAL_QUICK: 809 case Instruction::INVOKE_VIRTUAL_RANGE: 810 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: 811 invoke_type = kVirtual; 812 break; 813 case Instruction::INVOKE_INTERFACE: 814 case Instruction::INVOKE_INTERFACE_RANGE: 815 invoke_type = kInterface; 816 break; 817 case Instruction::INVOKE_SUPER_RANGE: 818 case Instruction::INVOKE_SUPER: 819 invoke_type = kSuper; 820 break; 821 default: 822 LOG(FATAL) << "Unexpected invoke op: " << opcode; 823 return false; 824 } 825 826 const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx); 827 const DexFile::ProtoId& proto_id = dex_file_->GetProtoId(method_id.proto_idx_); 828 const char* descriptor = dex_file_->StringDataByIdx(proto_id.shorty_idx_); 829 Primitive::Type return_type = Primitive::GetType(descriptor[0]); 830 bool is_instance_call = invoke_type != kStatic; 831 // Remove the return type from the 'proto'. 832 size_t number_of_arguments = strlen(descriptor) - 1; 833 if (is_instance_call) { 834 // One extra argument for 'this'. 835 ++number_of_arguments; 836 } 837 838 MethodReference target_method(dex_file_, method_idx); 839 uintptr_t direct_code; 840 uintptr_t direct_method; 841 int table_index; 842 InvokeType optimized_invoke_type = invoke_type; 843 844 if (!compiler_driver_->ComputeInvokeInfo(dex_compilation_unit_, dex_pc, true, true, 845 &optimized_invoke_type, &target_method, &table_index, 846 &direct_code, &direct_method)) { 847 VLOG(compiler) << "Did not compile " 848 << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_) 849 << " because a method call could not be resolved"; 850 MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedMethod); 851 return false; 852 } 853 DCHECK(optimized_invoke_type != kSuper); 854 855 // By default, consider that the called method implicitly requires 856 // an initialization check of its declaring method. 857 HInvokeStaticOrDirect::ClinitCheckRequirement clinit_check_requirement = 858 HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit; 859 // Potential class initialization check, in the case of a static method call. 860 HClinitCheck* clinit_check = nullptr; 861 // Replace calls to String.<init> with StringFactory. 862 int32_t string_init_offset = 0; 863 bool is_string_init = compiler_driver_->IsStringInit(method_idx, dex_file_, &string_init_offset); 864 if (is_string_init) { 865 return_type = Primitive::kPrimNot; 866 is_instance_call = false; 867 number_of_arguments--; 868 invoke_type = kStatic; 869 optimized_invoke_type = kStatic; 870 } 871 872 HInvoke* invoke = nullptr; 873 874 if (optimized_invoke_type == kVirtual) { 875 invoke = new (arena_) HInvokeVirtual( 876 arena_, number_of_arguments, return_type, dex_pc, method_idx, table_index); 877 } else if (optimized_invoke_type == kInterface) { 878 invoke = new (arena_) HInvokeInterface( 879 arena_, number_of_arguments, return_type, dex_pc, method_idx, table_index); 880 } else { 881 DCHECK(optimized_invoke_type == kDirect || optimized_invoke_type == kStatic); 882 // Sharpening to kDirect only works if we compile PIC. 883 DCHECK((optimized_invoke_type == invoke_type) || (optimized_invoke_type != kDirect) 884 || compiler_driver_->GetCompilerOptions().GetCompilePic()); 885 bool is_recursive = 886 (target_method.dex_method_index == outer_compilation_unit_->GetDexMethodIndex()) 887 && (target_method.dex_file == outer_compilation_unit_->GetDexFile()); 888 889 if (optimized_invoke_type == kStatic && !is_string_init) { 890 ScopedObjectAccess soa(Thread::Current()); 891 StackHandleScope<4> hs(soa.Self()); 892 Handle<mirror::DexCache> dex_cache(hs.NewHandle( 893 dex_compilation_unit_->GetClassLinker()->FindDexCache( 894 *dex_compilation_unit_->GetDexFile()))); 895 Handle<mirror::ClassLoader> class_loader(hs.NewHandle( 896 soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader()))); 897 ArtMethod* resolved_method = compiler_driver_->ResolveMethod( 898 soa, dex_cache, class_loader, dex_compilation_unit_, method_idx, optimized_invoke_type); 899 900 if (resolved_method == nullptr) { 901 MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedMethod); 902 return false; 903 } 904 905 const DexFile& outer_dex_file = *outer_compilation_unit_->GetDexFile(); 906 Handle<mirror::DexCache> outer_dex_cache(hs.NewHandle( 907 outer_compilation_unit_->GetClassLinker()->FindDexCache(outer_dex_file))); 908 Handle<mirror::Class> outer_class(hs.NewHandle(GetOutermostCompilingClass())); 909 910 // The index at which the method's class is stored in the DexCache's type array. 911 uint32_t storage_index = DexFile::kDexNoIndex; 912 bool is_outer_class = (resolved_method->GetDeclaringClass() == outer_class.Get()); 913 if (is_outer_class) { 914 storage_index = outer_class->GetDexTypeIndex(); 915 } else if (outer_dex_cache.Get() == dex_cache.Get()) { 916 // Get `storage_index` from IsClassOfStaticMethodAvailableToReferrer. 917 compiler_driver_->IsClassOfStaticMethodAvailableToReferrer(outer_dex_cache.Get(), 918 GetCompilingClass(), 919 resolved_method, 920 method_idx, 921 &storage_index); 922 } 923 924 if (!outer_class->IsInterface() 925 && outer_class->IsSubClass(resolved_method->GetDeclaringClass())) { 926 // If the outer class is the declaring class or a subclass 927 // of the declaring class, no class initialization is needed 928 // before the static method call. 929 // Note that in case of inlining, we do not need to add clinit checks 930 // to calls that satisfy this subclass check with any inlined methods. This 931 // will be detected by the optimization passes. 932 clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kNone; 933 } else if (storage_index != DexFile::kDexNoIndex) { 934 // If the method's class type index is available, check 935 // whether we should add an explicit class initialization 936 // check for its declaring class before the static method call. 937 938 // TODO: find out why this check is needed. 939 bool is_in_dex_cache = compiler_driver_->CanAssumeTypeIsPresentInDexCache( 940 *outer_compilation_unit_->GetDexFile(), storage_index); 941 bool is_initialized = 942 resolved_method->GetDeclaringClass()->IsInitialized() && is_in_dex_cache; 943 944 if (is_initialized) { 945 clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kNone; 946 } else { 947 clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kExplicit; 948 HLoadClass* load_class = new (arena_) HLoadClass( 949 graph_->GetCurrentMethod(), 950 storage_index, 951 *dex_compilation_unit_->GetDexFile(), 952 is_outer_class, 953 dex_pc); 954 current_block_->AddInstruction(load_class); 955 clinit_check = new (arena_) HClinitCheck(load_class, dex_pc); 956 current_block_->AddInstruction(clinit_check); 957 } 958 } 959 } 960 961 invoke = new (arena_) HInvokeStaticOrDirect(arena_, 962 number_of_arguments, 963 return_type, 964 dex_pc, 965 target_method.dex_method_index, 966 is_recursive, 967 string_init_offset, 968 invoke_type, 969 optimized_invoke_type, 970 clinit_check_requirement); 971 } 972 973 size_t start_index = 0; 974 Temporaries temps(graph_); 975 if (is_instance_call) { 976 HInstruction* arg = LoadLocal(is_range ? register_index : args[0], Primitive::kPrimNot); 977 HNullCheck* null_check = new (arena_) HNullCheck(arg, dex_pc); 978 current_block_->AddInstruction(null_check); 979 temps.Add(null_check); 980 invoke->SetArgumentAt(0, null_check); 981 start_index = 1; 982 } 983 984 uint32_t descriptor_index = 1; // Skip the return type. 985 uint32_t argument_index = start_index; 986 if (is_string_init) { 987 start_index = 1; 988 } 989 for (size_t i = start_index; 990 // Make sure we don't go over the expected arguments or over the number of 991 // dex registers given. If the instruction was seen as dead by the verifier, 992 // it hasn't been properly checked. 993 (i < number_of_vreg_arguments) && (argument_index < number_of_arguments); 994 i++, argument_index++) { 995 Primitive::Type type = Primitive::GetType(descriptor[descriptor_index++]); 996 bool is_wide = (type == Primitive::kPrimLong) || (type == Primitive::kPrimDouble); 997 if (!is_range 998 && is_wide 999 && ((i + 1 == number_of_vreg_arguments) || (args[i] + 1 != args[i + 1]))) { 1000 // Longs and doubles should be in pairs, that is, sequential registers. The verifier should 1001 // reject any class where this is violated. However, the verifier only does these checks 1002 // on non trivially dead instructions, so we just bailout the compilation. 1003 VLOG(compiler) << "Did not compile " 1004 << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_) 1005 << " because of non-sequential dex register pair in wide argument"; 1006 MaybeRecordStat(MethodCompilationStat::kNotCompiledMalformedOpcode); 1007 return false; 1008 } 1009 HInstruction* arg = LoadLocal(is_range ? register_index + i : args[i], type); 1010 invoke->SetArgumentAt(argument_index, arg); 1011 if (is_wide) { 1012 i++; 1013 } 1014 } 1015 1016 if (argument_index != number_of_arguments) { 1017 VLOG(compiler) << "Did not compile " 1018 << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_) 1019 << " because of wrong number of arguments in invoke instruction"; 1020 MaybeRecordStat(MethodCompilationStat::kNotCompiledMalformedOpcode); 1021 return false; 1022 } 1023 1024 if (invoke->IsInvokeStaticOrDirect()) { 1025 invoke->SetArgumentAt(argument_index, graph_->GetCurrentMethod()); 1026 argument_index++; 1027 } 1028 1029 if (clinit_check_requirement == HInvokeStaticOrDirect::ClinitCheckRequirement::kExplicit) { 1030 // Add the class initialization check as last input of `invoke`. 1031 DCHECK(clinit_check != nullptr); 1032 DCHECK(!is_string_init); 1033 invoke->SetArgumentAt(argument_index, clinit_check); 1034 argument_index++; 1035 } 1036 1037 // Add move-result for StringFactory method. 1038 if (is_string_init) { 1039 uint32_t orig_this_reg = is_range ? register_index : args[0]; 1040 HInstruction* fake_string = LoadLocal(orig_this_reg, Primitive::kPrimNot); 1041 invoke->SetArgumentAt(argument_index, fake_string); 1042 current_block_->AddInstruction(invoke); 1043 PotentiallySimplifyFakeString(orig_this_reg, dex_pc, invoke); 1044 } else { 1045 current_block_->AddInstruction(invoke); 1046 } 1047 latest_result_ = invoke; 1048 1049 return true; 1050} 1051 1052bool HGraphBuilder::BuildInstanceFieldAccess(const Instruction& instruction, 1053 uint32_t dex_pc, 1054 bool is_put) { 1055 uint32_t source_or_dest_reg = instruction.VRegA_22c(); 1056 uint32_t obj_reg = instruction.VRegB_22c(); 1057 uint16_t field_index; 1058 if (instruction.IsQuickened()) { 1059 if (!CanDecodeQuickenedInfo()) { 1060 return false; 1061 } 1062 field_index = LookupQuickenedInfo(dex_pc); 1063 } else { 1064 field_index = instruction.VRegC_22c(); 1065 } 1066 1067 ScopedObjectAccess soa(Thread::Current()); 1068 ArtField* resolved_field = 1069 compiler_driver_->ComputeInstanceFieldInfo(field_index, dex_compilation_unit_, is_put, soa); 1070 1071 if (resolved_field == nullptr) { 1072 MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedField); 1073 return false; 1074 } 1075 1076 Primitive::Type field_type = resolved_field->GetTypeAsPrimitiveType(); 1077 1078 HInstruction* object = LoadLocal(obj_reg, Primitive::kPrimNot); 1079 current_block_->AddInstruction(new (arena_) HNullCheck(object, dex_pc)); 1080 if (is_put) { 1081 Temporaries temps(graph_); 1082 HInstruction* null_check = current_block_->GetLastInstruction(); 1083 // We need one temporary for the null check. 1084 temps.Add(null_check); 1085 HInstruction* value = LoadLocal(source_or_dest_reg, field_type); 1086 current_block_->AddInstruction(new (arena_) HInstanceFieldSet( 1087 null_check, 1088 value, 1089 field_type, 1090 resolved_field->GetOffset(), 1091 resolved_field->IsVolatile(), 1092 field_index, 1093 *dex_file_)); 1094 } else { 1095 current_block_->AddInstruction(new (arena_) HInstanceFieldGet( 1096 current_block_->GetLastInstruction(), 1097 field_type, 1098 resolved_field->GetOffset(), 1099 resolved_field->IsVolatile(), 1100 field_index, 1101 *dex_file_)); 1102 1103 UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction()); 1104 } 1105 return true; 1106} 1107 1108static mirror::Class* GetClassFrom(CompilerDriver* driver, 1109 const DexCompilationUnit& compilation_unit) { 1110 ScopedObjectAccess soa(Thread::Current()); 1111 StackHandleScope<2> hs(soa.Self()); 1112 const DexFile& dex_file = *compilation_unit.GetDexFile(); 1113 Handle<mirror::ClassLoader> class_loader(hs.NewHandle( 1114 soa.Decode<mirror::ClassLoader*>(compilation_unit.GetClassLoader()))); 1115 Handle<mirror::DexCache> dex_cache(hs.NewHandle( 1116 compilation_unit.GetClassLinker()->FindDexCache(dex_file))); 1117 1118 return driver->ResolveCompilingMethodsClass(soa, dex_cache, class_loader, &compilation_unit); 1119} 1120 1121mirror::Class* HGraphBuilder::GetOutermostCompilingClass() const { 1122 return GetClassFrom(compiler_driver_, *outer_compilation_unit_); 1123} 1124 1125mirror::Class* HGraphBuilder::GetCompilingClass() const { 1126 return GetClassFrom(compiler_driver_, *dex_compilation_unit_); 1127} 1128 1129bool HGraphBuilder::IsOutermostCompilingClass(uint16_t type_index) const { 1130 ScopedObjectAccess soa(Thread::Current()); 1131 StackHandleScope<4> hs(soa.Self()); 1132 Handle<mirror::DexCache> dex_cache(hs.NewHandle( 1133 dex_compilation_unit_->GetClassLinker()->FindDexCache(*dex_compilation_unit_->GetDexFile()))); 1134 Handle<mirror::ClassLoader> class_loader(hs.NewHandle( 1135 soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader()))); 1136 Handle<mirror::Class> cls(hs.NewHandle(compiler_driver_->ResolveClass( 1137 soa, dex_cache, class_loader, type_index, dex_compilation_unit_))); 1138 Handle<mirror::Class> outer_class(hs.NewHandle(GetOutermostCompilingClass())); 1139 1140 return outer_class.Get() == cls.Get(); 1141} 1142 1143bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction, 1144 uint32_t dex_pc, 1145 bool is_put) { 1146 uint32_t source_or_dest_reg = instruction.VRegA_21c(); 1147 uint16_t field_index = instruction.VRegB_21c(); 1148 1149 ScopedObjectAccess soa(Thread::Current()); 1150 StackHandleScope<4> hs(soa.Self()); 1151 Handle<mirror::DexCache> dex_cache(hs.NewHandle( 1152 dex_compilation_unit_->GetClassLinker()->FindDexCache(*dex_compilation_unit_->GetDexFile()))); 1153 Handle<mirror::ClassLoader> class_loader(hs.NewHandle( 1154 soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader()))); 1155 ArtField* resolved_field = compiler_driver_->ResolveField( 1156 soa, dex_cache, class_loader, dex_compilation_unit_, field_index, true); 1157 1158 if (resolved_field == nullptr) { 1159 MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedField); 1160 return false; 1161 } 1162 1163 const DexFile& outer_dex_file = *outer_compilation_unit_->GetDexFile(); 1164 Handle<mirror::DexCache> outer_dex_cache(hs.NewHandle( 1165 outer_compilation_unit_->GetClassLinker()->FindDexCache(outer_dex_file))); 1166 Handle<mirror::Class> outer_class(hs.NewHandle(GetOutermostCompilingClass())); 1167 1168 // The index at which the field's class is stored in the DexCache's type array. 1169 uint32_t storage_index; 1170 bool is_outer_class = (outer_class.Get() == resolved_field->GetDeclaringClass()); 1171 if (is_outer_class) { 1172 storage_index = outer_class->GetDexTypeIndex(); 1173 } else if (outer_dex_cache.Get() != dex_cache.Get()) { 1174 // The compiler driver cannot currently understand multiple dex caches involved. Just bailout. 1175 return false; 1176 } else { 1177 std::pair<bool, bool> pair = compiler_driver_->IsFastStaticField( 1178 outer_dex_cache.Get(), 1179 GetCompilingClass(), 1180 resolved_field, 1181 field_index, 1182 &storage_index); 1183 bool can_easily_access = is_put ? pair.second : pair.first; 1184 if (!can_easily_access) { 1185 return false; 1186 } 1187 } 1188 1189 // TODO: find out why this check is needed. 1190 bool is_in_dex_cache = compiler_driver_->CanAssumeTypeIsPresentInDexCache( 1191 *outer_compilation_unit_->GetDexFile(), storage_index); 1192 bool is_initialized = resolved_field->GetDeclaringClass()->IsInitialized() && is_in_dex_cache; 1193 1194 HLoadClass* constant = new (arena_) HLoadClass(graph_->GetCurrentMethod(), 1195 storage_index, 1196 *dex_compilation_unit_->GetDexFile(), 1197 is_outer_class, 1198 dex_pc); 1199 current_block_->AddInstruction(constant); 1200 1201 HInstruction* cls = constant; 1202 if (!is_initialized && !is_outer_class) { 1203 cls = new (arena_) HClinitCheck(constant, dex_pc); 1204 current_block_->AddInstruction(cls); 1205 } 1206 1207 Primitive::Type field_type = resolved_field->GetTypeAsPrimitiveType(); 1208 if (is_put) { 1209 // We need to keep the class alive before loading the value. 1210 Temporaries temps(graph_); 1211 temps.Add(cls); 1212 HInstruction* value = LoadLocal(source_or_dest_reg, field_type); 1213 DCHECK_EQ(value->GetType(), field_type); 1214 current_block_->AddInstruction(new (arena_) HStaticFieldSet(cls, 1215 value, 1216 field_type, 1217 resolved_field->GetOffset(), 1218 resolved_field->IsVolatile(), 1219 field_index, 1220 *dex_file_)); 1221 } else { 1222 current_block_->AddInstruction(new (arena_) HStaticFieldGet(cls, 1223 field_type, 1224 resolved_field->GetOffset(), 1225 resolved_field->IsVolatile(), 1226 field_index, 1227 *dex_file_)); 1228 UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction()); 1229 } 1230 return true; 1231} 1232 1233void HGraphBuilder::BuildCheckedDivRem(uint16_t out_vreg, 1234 uint16_t first_vreg, 1235 int64_t second_vreg_or_constant, 1236 uint32_t dex_pc, 1237 Primitive::Type type, 1238 bool second_is_constant, 1239 bool isDiv) { 1240 DCHECK(type == Primitive::kPrimInt || type == Primitive::kPrimLong); 1241 1242 HInstruction* first = LoadLocal(first_vreg, type); 1243 HInstruction* second = nullptr; 1244 if (second_is_constant) { 1245 if (type == Primitive::kPrimInt) { 1246 second = graph_->GetIntConstant(second_vreg_or_constant); 1247 } else { 1248 second = graph_->GetLongConstant(second_vreg_or_constant); 1249 } 1250 } else { 1251 second = LoadLocal(second_vreg_or_constant, type); 1252 } 1253 1254 if (!second_is_constant 1255 || (type == Primitive::kPrimInt && second->AsIntConstant()->GetValue() == 0) 1256 || (type == Primitive::kPrimLong && second->AsLongConstant()->GetValue() == 0)) { 1257 second = new (arena_) HDivZeroCheck(second, dex_pc); 1258 Temporaries temps(graph_); 1259 current_block_->AddInstruction(second); 1260 temps.Add(current_block_->GetLastInstruction()); 1261 } 1262 1263 if (isDiv) { 1264 current_block_->AddInstruction(new (arena_) HDiv(type, first, second, dex_pc)); 1265 } else { 1266 current_block_->AddInstruction(new (arena_) HRem(type, first, second, dex_pc)); 1267 } 1268 UpdateLocal(out_vreg, current_block_->GetLastInstruction()); 1269} 1270 1271void HGraphBuilder::BuildArrayAccess(const Instruction& instruction, 1272 uint32_t dex_pc, 1273 bool is_put, 1274 Primitive::Type anticipated_type) { 1275 uint8_t source_or_dest_reg = instruction.VRegA_23x(); 1276 uint8_t array_reg = instruction.VRegB_23x(); 1277 uint8_t index_reg = instruction.VRegC_23x(); 1278 1279 // We need one temporary for the null check, one for the index, and one for the length. 1280 Temporaries temps(graph_); 1281 1282 HInstruction* object = LoadLocal(array_reg, Primitive::kPrimNot); 1283 object = new (arena_) HNullCheck(object, dex_pc); 1284 current_block_->AddInstruction(object); 1285 temps.Add(object); 1286 1287 HInstruction* length = new (arena_) HArrayLength(object); 1288 current_block_->AddInstruction(length); 1289 temps.Add(length); 1290 HInstruction* index = LoadLocal(index_reg, Primitive::kPrimInt); 1291 index = new (arena_) HBoundsCheck(index, length, dex_pc); 1292 current_block_->AddInstruction(index); 1293 temps.Add(index); 1294 if (is_put) { 1295 HInstruction* value = LoadLocal(source_or_dest_reg, anticipated_type); 1296 // TODO: Insert a type check node if the type is Object. 1297 current_block_->AddInstruction(new (arena_) HArraySet( 1298 object, index, value, anticipated_type, dex_pc)); 1299 } else { 1300 current_block_->AddInstruction(new (arena_) HArrayGet(object, index, anticipated_type)); 1301 UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction()); 1302 } 1303 graph_->SetHasBoundsChecks(true); 1304} 1305 1306void HGraphBuilder::BuildFilledNewArray(uint32_t dex_pc, 1307 uint32_t type_index, 1308 uint32_t number_of_vreg_arguments, 1309 bool is_range, 1310 uint32_t* args, 1311 uint32_t register_index) { 1312 HInstruction* length = graph_->GetIntConstant(number_of_vreg_arguments); 1313 QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index) 1314 ? kQuickAllocArrayWithAccessCheck 1315 : kQuickAllocArray; 1316 HInstruction* object = new (arena_) HNewArray(length, 1317 graph_->GetCurrentMethod(), 1318 dex_pc, 1319 type_index, 1320 *dex_compilation_unit_->GetDexFile(), 1321 entrypoint); 1322 current_block_->AddInstruction(object); 1323 1324 const char* descriptor = dex_file_->StringByTypeIdx(type_index); 1325 DCHECK_EQ(descriptor[0], '[') << descriptor; 1326 char primitive = descriptor[1]; 1327 DCHECK(primitive == 'I' 1328 || primitive == 'L' 1329 || primitive == '[') << descriptor; 1330 bool is_reference_array = (primitive == 'L') || (primitive == '['); 1331 Primitive::Type type = is_reference_array ? Primitive::kPrimNot : Primitive::kPrimInt; 1332 1333 Temporaries temps(graph_); 1334 temps.Add(object); 1335 for (size_t i = 0; i < number_of_vreg_arguments; ++i) { 1336 HInstruction* value = LoadLocal(is_range ? register_index + i : args[i], type); 1337 HInstruction* index = graph_->GetIntConstant(i); 1338 current_block_->AddInstruction( 1339 new (arena_) HArraySet(object, index, value, type, dex_pc)); 1340 } 1341 latest_result_ = object; 1342} 1343 1344template <typename T> 1345void HGraphBuilder::BuildFillArrayData(HInstruction* object, 1346 const T* data, 1347 uint32_t element_count, 1348 Primitive::Type anticipated_type, 1349 uint32_t dex_pc) { 1350 for (uint32_t i = 0; i < element_count; ++i) { 1351 HInstruction* index = graph_->GetIntConstant(i); 1352 HInstruction* value = graph_->GetIntConstant(data[i]); 1353 current_block_->AddInstruction(new (arena_) HArraySet( 1354 object, index, value, anticipated_type, dex_pc)); 1355 } 1356} 1357 1358void HGraphBuilder::BuildFillArrayData(const Instruction& instruction, uint32_t dex_pc) { 1359 Temporaries temps(graph_); 1360 HInstruction* array = LoadLocal(instruction.VRegA_31t(), Primitive::kPrimNot); 1361 HNullCheck* null_check = new (arena_) HNullCheck(array, dex_pc); 1362 current_block_->AddInstruction(null_check); 1363 temps.Add(null_check); 1364 1365 HInstruction* length = new (arena_) HArrayLength(null_check); 1366 current_block_->AddInstruction(length); 1367 1368 int32_t payload_offset = instruction.VRegB_31t() + dex_pc; 1369 const Instruction::ArrayDataPayload* payload = 1370 reinterpret_cast<const Instruction::ArrayDataPayload*>(code_start_ + payload_offset); 1371 const uint8_t* data = payload->data; 1372 uint32_t element_count = payload->element_count; 1373 1374 // Implementation of this DEX instruction seems to be that the bounds check is 1375 // done before doing any stores. 1376 HInstruction* last_index = graph_->GetIntConstant(payload->element_count - 1); 1377 current_block_->AddInstruction(new (arena_) HBoundsCheck(last_index, length, dex_pc)); 1378 1379 switch (payload->element_width) { 1380 case 1: 1381 BuildFillArrayData(null_check, 1382 reinterpret_cast<const int8_t*>(data), 1383 element_count, 1384 Primitive::kPrimByte, 1385 dex_pc); 1386 break; 1387 case 2: 1388 BuildFillArrayData(null_check, 1389 reinterpret_cast<const int16_t*>(data), 1390 element_count, 1391 Primitive::kPrimShort, 1392 dex_pc); 1393 break; 1394 case 4: 1395 BuildFillArrayData(null_check, 1396 reinterpret_cast<const int32_t*>(data), 1397 element_count, 1398 Primitive::kPrimInt, 1399 dex_pc); 1400 break; 1401 case 8: 1402 BuildFillWideArrayData(null_check, 1403 reinterpret_cast<const int64_t*>(data), 1404 element_count, 1405 dex_pc); 1406 break; 1407 default: 1408 LOG(FATAL) << "Unknown element width for " << payload->element_width; 1409 } 1410 graph_->SetHasBoundsChecks(true); 1411} 1412 1413void HGraphBuilder::BuildFillWideArrayData(HInstruction* object, 1414 const int64_t* data, 1415 uint32_t element_count, 1416 uint32_t dex_pc) { 1417 for (uint32_t i = 0; i < element_count; ++i) { 1418 HInstruction* index = graph_->GetIntConstant(i); 1419 HInstruction* value = graph_->GetLongConstant(data[i]); 1420 current_block_->AddInstruction(new (arena_) HArraySet( 1421 object, index, value, Primitive::kPrimLong, dex_pc)); 1422 } 1423} 1424 1425bool HGraphBuilder::BuildTypeCheck(const Instruction& instruction, 1426 uint8_t destination, 1427 uint8_t reference, 1428 uint16_t type_index, 1429 uint32_t dex_pc) { 1430 bool type_known_final; 1431 bool type_known_abstract; 1432 // `CanAccessTypeWithoutChecks` will tell whether the method being 1433 // built is trying to access its own class, so that the generated 1434 // code can optimize for this case. However, the optimization does not 1435 // work for inlining, so we use `IsOutermostCompilingClass` instead. 1436 bool dont_use_is_referrers_class; 1437 bool can_access = compiler_driver_->CanAccessTypeWithoutChecks( 1438 dex_compilation_unit_->GetDexMethodIndex(), *dex_file_, type_index, 1439 &type_known_final, &type_known_abstract, &dont_use_is_referrers_class); 1440 if (!can_access) { 1441 MaybeRecordStat(MethodCompilationStat::kNotCompiledCantAccesType); 1442 return false; 1443 } 1444 HInstruction* object = LoadLocal(reference, Primitive::kPrimNot); 1445 HLoadClass* cls = new (arena_) HLoadClass( 1446 graph_->GetCurrentMethod(), 1447 type_index, 1448 *dex_compilation_unit_->GetDexFile(), 1449 IsOutermostCompilingClass(type_index), 1450 dex_pc); 1451 current_block_->AddInstruction(cls); 1452 // The class needs a temporary before being used by the type check. 1453 Temporaries temps(graph_); 1454 temps.Add(cls); 1455 if (instruction.Opcode() == Instruction::INSTANCE_OF) { 1456 current_block_->AddInstruction( 1457 new (arena_) HInstanceOf(object, cls, type_known_final, dex_pc)); 1458 UpdateLocal(destination, current_block_->GetLastInstruction()); 1459 } else { 1460 DCHECK_EQ(instruction.Opcode(), Instruction::CHECK_CAST); 1461 current_block_->AddInstruction( 1462 new (arena_) HCheckCast(object, cls, type_known_final, dex_pc)); 1463 } 1464 return true; 1465} 1466 1467bool HGraphBuilder::NeedsAccessCheck(uint32_t type_index) const { 1468 return !compiler_driver_->CanAccessInstantiableTypeWithoutChecks( 1469 dex_compilation_unit_->GetDexMethodIndex(), *dex_file_, type_index); 1470} 1471 1472void HGraphBuilder::BuildPackedSwitch(const Instruction& instruction, uint32_t dex_pc) { 1473 // Verifier guarantees that the payload for PackedSwitch contains: 1474 // (a) number of entries (may be zero) 1475 // (b) first and lowest switch case value (entry 0, always present) 1476 // (c) list of target pcs (entries 1 <= i <= N) 1477 SwitchTable table(instruction, dex_pc, false); 1478 1479 // Value to test against. 1480 HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt); 1481 1482 // Retrieve number of entries. 1483 uint16_t num_entries = table.GetNumEntries(); 1484 if (num_entries == 0) { 1485 return; 1486 } 1487 1488 // Chained cmp-and-branch, starting from starting_key. 1489 int32_t starting_key = table.GetEntryAt(0); 1490 1491 for (size_t i = 1; i <= num_entries; i++) { 1492 BuildSwitchCaseHelper(instruction, i, i == num_entries, table, value, starting_key + i - 1, 1493 table.GetEntryAt(i), dex_pc); 1494 } 1495} 1496 1497void HGraphBuilder::BuildSparseSwitch(const Instruction& instruction, uint32_t dex_pc) { 1498 // Verifier guarantees that the payload for SparseSwitch contains: 1499 // (a) number of entries (may be zero) 1500 // (b) sorted key values (entries 0 <= i < N) 1501 // (c) target pcs corresponding to the switch values (entries N <= i < 2*N) 1502 SwitchTable table(instruction, dex_pc, true); 1503 1504 // Value to test against. 1505 HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt); 1506 1507 uint16_t num_entries = table.GetNumEntries(); 1508 1509 for (size_t i = 0; i < num_entries; i++) { 1510 BuildSwitchCaseHelper(instruction, i, i == static_cast<size_t>(num_entries) - 1, table, value, 1511 table.GetEntryAt(i), table.GetEntryAt(i + num_entries), dex_pc); 1512 } 1513} 1514 1515void HGraphBuilder::BuildSwitchCaseHelper(const Instruction& instruction, size_t index, 1516 bool is_last_case, const SwitchTable& table, 1517 HInstruction* value, int32_t case_value_int, 1518 int32_t target_offset, uint32_t dex_pc) { 1519 HBasicBlock* case_target = FindBlockStartingAt(dex_pc + target_offset); 1520 DCHECK(case_target != nullptr); 1521 PotentiallyAddSuspendCheck(case_target, dex_pc); 1522 1523 // The current case's value. 1524 HInstruction* this_case_value = graph_->GetIntConstant(case_value_int); 1525 1526 // Compare value and this_case_value. 1527 HEqual* comparison = new (arena_) HEqual(value, this_case_value); 1528 current_block_->AddInstruction(comparison); 1529 HInstruction* ifinst = new (arena_) HIf(comparison); 1530 current_block_->AddInstruction(ifinst); 1531 1532 // Case hit: use the target offset to determine where to go. 1533 current_block_->AddSuccessor(case_target); 1534 1535 // Case miss: go to the next case (or default fall-through). 1536 // When there is a next case, we use the block stored with the table offset representing this 1537 // case (that is where we registered them in ComputeBranchTargets). 1538 // When there is no next case, we use the following instruction. 1539 // TODO: Find a good way to peel the last iteration to avoid conditional, but still have re-use. 1540 if (!is_last_case) { 1541 HBasicBlock* next_case_target = FindBlockStartingAt(table.GetDexPcForIndex(index)); 1542 DCHECK(next_case_target != nullptr); 1543 current_block_->AddSuccessor(next_case_target); 1544 1545 // Need to manually add the block, as there is no dex-pc transition for the cases. 1546 graph_->AddBlock(next_case_target); 1547 1548 current_block_ = next_case_target; 1549 } else { 1550 HBasicBlock* default_target = FindBlockStartingAt(dex_pc + instruction.SizeInCodeUnits()); 1551 DCHECK(default_target != nullptr); 1552 current_block_->AddSuccessor(default_target); 1553 current_block_ = nullptr; 1554 } 1555} 1556 1557void HGraphBuilder::PotentiallyAddSuspendCheck(HBasicBlock* target, uint32_t dex_pc) { 1558 int32_t target_offset = target->GetDexPc() - dex_pc; 1559 if (target_offset <= 0) { 1560 // DX generates back edges to the first encountered return. We can save 1561 // time of later passes by not adding redundant suspend checks. 1562 HInstruction* last_in_target = target->GetLastInstruction(); 1563 if (last_in_target != nullptr && 1564 (last_in_target->IsReturn() || last_in_target->IsReturnVoid())) { 1565 return; 1566 } 1567 1568 // Add a suspend check to backward branches which may potentially loop. We 1569 // can remove them after we recognize loops in the graph. 1570 current_block_->AddInstruction(new (arena_) HSuspendCheck(dex_pc)); 1571 } 1572} 1573 1574bool HGraphBuilder::CanDecodeQuickenedInfo() const { 1575 return interpreter_metadata_ != nullptr; 1576} 1577 1578uint16_t HGraphBuilder::LookupQuickenedInfo(uint32_t dex_pc) { 1579 DCHECK(interpreter_metadata_ != nullptr); 1580 uint32_t dex_pc_in_map = DecodeUnsignedLeb128(&interpreter_metadata_); 1581 DCHECK_EQ(dex_pc, dex_pc_in_map); 1582 return DecodeUnsignedLeb128(&interpreter_metadata_); 1583} 1584 1585bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32_t dex_pc) { 1586 if (current_block_ == nullptr) { 1587 return true; // Dead code 1588 } 1589 1590 switch (instruction.Opcode()) { 1591 case Instruction::CONST_4: { 1592 int32_t register_index = instruction.VRegA(); 1593 HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_11n()); 1594 UpdateLocal(register_index, constant); 1595 break; 1596 } 1597 1598 case Instruction::CONST_16: { 1599 int32_t register_index = instruction.VRegA(); 1600 HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_21s()); 1601 UpdateLocal(register_index, constant); 1602 break; 1603 } 1604 1605 case Instruction::CONST: { 1606 int32_t register_index = instruction.VRegA(); 1607 HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_31i()); 1608 UpdateLocal(register_index, constant); 1609 break; 1610 } 1611 1612 case Instruction::CONST_HIGH16: { 1613 int32_t register_index = instruction.VRegA(); 1614 HIntConstant* constant = graph_->GetIntConstant(instruction.VRegB_21h() << 16); 1615 UpdateLocal(register_index, constant); 1616 break; 1617 } 1618 1619 case Instruction::CONST_WIDE_16: { 1620 int32_t register_index = instruction.VRegA(); 1621 // Get 16 bits of constant value, sign extended to 64 bits. 1622 int64_t value = instruction.VRegB_21s(); 1623 value <<= 48; 1624 value >>= 48; 1625 HLongConstant* constant = graph_->GetLongConstant(value); 1626 UpdateLocal(register_index, constant); 1627 break; 1628 } 1629 1630 case Instruction::CONST_WIDE_32: { 1631 int32_t register_index = instruction.VRegA(); 1632 // Get 32 bits of constant value, sign extended to 64 bits. 1633 int64_t value = instruction.VRegB_31i(); 1634 value <<= 32; 1635 value >>= 32; 1636 HLongConstant* constant = graph_->GetLongConstant(value); 1637 UpdateLocal(register_index, constant); 1638 break; 1639 } 1640 1641 case Instruction::CONST_WIDE: { 1642 int32_t register_index = instruction.VRegA(); 1643 HLongConstant* constant = graph_->GetLongConstant(instruction.VRegB_51l()); 1644 UpdateLocal(register_index, constant); 1645 break; 1646 } 1647 1648 case Instruction::CONST_WIDE_HIGH16: { 1649 int32_t register_index = instruction.VRegA(); 1650 int64_t value = static_cast<int64_t>(instruction.VRegB_21h()) << 48; 1651 HLongConstant* constant = graph_->GetLongConstant(value); 1652 UpdateLocal(register_index, constant); 1653 break; 1654 } 1655 1656 // Note that the SSA building will refine the types. 1657 case Instruction::MOVE: 1658 case Instruction::MOVE_FROM16: 1659 case Instruction::MOVE_16: { 1660 HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); 1661 UpdateLocal(instruction.VRegA(), value); 1662 break; 1663 } 1664 1665 // Note that the SSA building will refine the types. 1666 case Instruction::MOVE_WIDE: 1667 case Instruction::MOVE_WIDE_FROM16: 1668 case Instruction::MOVE_WIDE_16: { 1669 HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimLong); 1670 UpdateLocal(instruction.VRegA(), value); 1671 break; 1672 } 1673 1674 case Instruction::MOVE_OBJECT: 1675 case Instruction::MOVE_OBJECT_16: 1676 case Instruction::MOVE_OBJECT_FROM16: { 1677 HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimNot); 1678 UpdateLocal(instruction.VRegA(), value); 1679 break; 1680 } 1681 1682 case Instruction::RETURN_VOID_NO_BARRIER: 1683 case Instruction::RETURN_VOID: { 1684 BuildReturn(instruction, Primitive::kPrimVoid); 1685 break; 1686 } 1687 1688#define IF_XX(comparison, cond) \ 1689 case Instruction::IF_##cond: If_22t<comparison>(instruction, dex_pc); break; \ 1690 case Instruction::IF_##cond##Z: If_21t<comparison>(instruction, dex_pc); break 1691 1692 IF_XX(HEqual, EQ); 1693 IF_XX(HNotEqual, NE); 1694 IF_XX(HLessThan, LT); 1695 IF_XX(HLessThanOrEqual, LE); 1696 IF_XX(HGreaterThan, GT); 1697 IF_XX(HGreaterThanOrEqual, GE); 1698 1699 case Instruction::GOTO: 1700 case Instruction::GOTO_16: 1701 case Instruction::GOTO_32: { 1702 int32_t offset = instruction.GetTargetOffset(); 1703 HBasicBlock* target = FindBlockStartingAt(offset + dex_pc); 1704 DCHECK(target != nullptr); 1705 PotentiallyAddSuspendCheck(target, dex_pc); 1706 current_block_->AddInstruction(new (arena_) HGoto()); 1707 current_block_->AddSuccessor(target); 1708 current_block_ = nullptr; 1709 break; 1710 } 1711 1712 case Instruction::RETURN: { 1713 BuildReturn(instruction, return_type_); 1714 break; 1715 } 1716 1717 case Instruction::RETURN_OBJECT: { 1718 BuildReturn(instruction, return_type_); 1719 break; 1720 } 1721 1722 case Instruction::RETURN_WIDE: { 1723 BuildReturn(instruction, return_type_); 1724 break; 1725 } 1726 1727 case Instruction::INVOKE_DIRECT: 1728 case Instruction::INVOKE_INTERFACE: 1729 case Instruction::INVOKE_STATIC: 1730 case Instruction::INVOKE_SUPER: 1731 case Instruction::INVOKE_VIRTUAL: 1732 case Instruction::INVOKE_VIRTUAL_QUICK: { 1733 uint16_t method_idx; 1734 if (instruction.Opcode() == Instruction::INVOKE_VIRTUAL_QUICK) { 1735 if (!CanDecodeQuickenedInfo()) { 1736 return false; 1737 } 1738 method_idx = LookupQuickenedInfo(dex_pc); 1739 } else { 1740 method_idx = instruction.VRegB_35c(); 1741 } 1742 uint32_t number_of_vreg_arguments = instruction.VRegA_35c(); 1743 uint32_t args[5]; 1744 instruction.GetVarArgs(args); 1745 if (!BuildInvoke(instruction, dex_pc, method_idx, 1746 number_of_vreg_arguments, false, args, -1)) { 1747 return false; 1748 } 1749 break; 1750 } 1751 1752 case Instruction::INVOKE_DIRECT_RANGE: 1753 case Instruction::INVOKE_INTERFACE_RANGE: 1754 case Instruction::INVOKE_STATIC_RANGE: 1755 case Instruction::INVOKE_SUPER_RANGE: 1756 case Instruction::INVOKE_VIRTUAL_RANGE: 1757 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: { 1758 uint16_t method_idx; 1759 if (instruction.Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK) { 1760 if (!CanDecodeQuickenedInfo()) { 1761 return false; 1762 } 1763 method_idx = LookupQuickenedInfo(dex_pc); 1764 } else { 1765 method_idx = instruction.VRegB_3rc(); 1766 } 1767 uint32_t number_of_vreg_arguments = instruction.VRegA_3rc(); 1768 uint32_t register_index = instruction.VRegC(); 1769 if (!BuildInvoke(instruction, dex_pc, method_idx, 1770 number_of_vreg_arguments, true, nullptr, register_index)) { 1771 return false; 1772 } 1773 break; 1774 } 1775 1776 case Instruction::NEG_INT: { 1777 Unop_12x<HNeg>(instruction, Primitive::kPrimInt); 1778 break; 1779 } 1780 1781 case Instruction::NEG_LONG: { 1782 Unop_12x<HNeg>(instruction, Primitive::kPrimLong); 1783 break; 1784 } 1785 1786 case Instruction::NEG_FLOAT: { 1787 Unop_12x<HNeg>(instruction, Primitive::kPrimFloat); 1788 break; 1789 } 1790 1791 case Instruction::NEG_DOUBLE: { 1792 Unop_12x<HNeg>(instruction, Primitive::kPrimDouble); 1793 break; 1794 } 1795 1796 case Instruction::NOT_INT: { 1797 Unop_12x<HNot>(instruction, Primitive::kPrimInt); 1798 break; 1799 } 1800 1801 case Instruction::NOT_LONG: { 1802 Unop_12x<HNot>(instruction, Primitive::kPrimLong); 1803 break; 1804 } 1805 1806 case Instruction::INT_TO_LONG: { 1807 Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimLong, dex_pc); 1808 break; 1809 } 1810 1811 case Instruction::INT_TO_FLOAT: { 1812 Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimFloat, dex_pc); 1813 break; 1814 } 1815 1816 case Instruction::INT_TO_DOUBLE: { 1817 Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimDouble, dex_pc); 1818 break; 1819 } 1820 1821 case Instruction::LONG_TO_INT: { 1822 Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimInt, dex_pc); 1823 break; 1824 } 1825 1826 case Instruction::LONG_TO_FLOAT: { 1827 Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimFloat, dex_pc); 1828 break; 1829 } 1830 1831 case Instruction::LONG_TO_DOUBLE: { 1832 Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimDouble, dex_pc); 1833 break; 1834 } 1835 1836 case Instruction::FLOAT_TO_INT: { 1837 Conversion_12x(instruction, Primitive::kPrimFloat, Primitive::kPrimInt, dex_pc); 1838 break; 1839 } 1840 1841 case Instruction::FLOAT_TO_LONG: { 1842 Conversion_12x(instruction, Primitive::kPrimFloat, Primitive::kPrimLong, dex_pc); 1843 break; 1844 } 1845 1846 case Instruction::FLOAT_TO_DOUBLE: { 1847 Conversion_12x(instruction, Primitive::kPrimFloat, Primitive::kPrimDouble, dex_pc); 1848 break; 1849 } 1850 1851 case Instruction::DOUBLE_TO_INT: { 1852 Conversion_12x(instruction, Primitive::kPrimDouble, Primitive::kPrimInt, dex_pc); 1853 break; 1854 } 1855 1856 case Instruction::DOUBLE_TO_LONG: { 1857 Conversion_12x(instruction, Primitive::kPrimDouble, Primitive::kPrimLong, dex_pc); 1858 break; 1859 } 1860 1861 case Instruction::DOUBLE_TO_FLOAT: { 1862 Conversion_12x(instruction, Primitive::kPrimDouble, Primitive::kPrimFloat, dex_pc); 1863 break; 1864 } 1865 1866 case Instruction::INT_TO_BYTE: { 1867 Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimByte, dex_pc); 1868 break; 1869 } 1870 1871 case Instruction::INT_TO_SHORT: { 1872 Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimShort, dex_pc); 1873 break; 1874 } 1875 1876 case Instruction::INT_TO_CHAR: { 1877 Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimChar, dex_pc); 1878 break; 1879 } 1880 1881 case Instruction::ADD_INT: { 1882 Binop_23x<HAdd>(instruction, Primitive::kPrimInt); 1883 break; 1884 } 1885 1886 case Instruction::ADD_LONG: { 1887 Binop_23x<HAdd>(instruction, Primitive::kPrimLong); 1888 break; 1889 } 1890 1891 case Instruction::ADD_DOUBLE: { 1892 Binop_23x<HAdd>(instruction, Primitive::kPrimDouble); 1893 break; 1894 } 1895 1896 case Instruction::ADD_FLOAT: { 1897 Binop_23x<HAdd>(instruction, Primitive::kPrimFloat); 1898 break; 1899 } 1900 1901 case Instruction::SUB_INT: { 1902 Binop_23x<HSub>(instruction, Primitive::kPrimInt); 1903 break; 1904 } 1905 1906 case Instruction::SUB_LONG: { 1907 Binop_23x<HSub>(instruction, Primitive::kPrimLong); 1908 break; 1909 } 1910 1911 case Instruction::SUB_FLOAT: { 1912 Binop_23x<HSub>(instruction, Primitive::kPrimFloat); 1913 break; 1914 } 1915 1916 case Instruction::SUB_DOUBLE: { 1917 Binop_23x<HSub>(instruction, Primitive::kPrimDouble); 1918 break; 1919 } 1920 1921 case Instruction::ADD_INT_2ADDR: { 1922 Binop_12x<HAdd>(instruction, Primitive::kPrimInt); 1923 break; 1924 } 1925 1926 case Instruction::MUL_INT: { 1927 Binop_23x<HMul>(instruction, Primitive::kPrimInt); 1928 break; 1929 } 1930 1931 case Instruction::MUL_LONG: { 1932 Binop_23x<HMul>(instruction, Primitive::kPrimLong); 1933 break; 1934 } 1935 1936 case Instruction::MUL_FLOAT: { 1937 Binop_23x<HMul>(instruction, Primitive::kPrimFloat); 1938 break; 1939 } 1940 1941 case Instruction::MUL_DOUBLE: { 1942 Binop_23x<HMul>(instruction, Primitive::kPrimDouble); 1943 break; 1944 } 1945 1946 case Instruction::DIV_INT: { 1947 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(), 1948 dex_pc, Primitive::kPrimInt, false, true); 1949 break; 1950 } 1951 1952 case Instruction::DIV_LONG: { 1953 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(), 1954 dex_pc, Primitive::kPrimLong, false, true); 1955 break; 1956 } 1957 1958 case Instruction::DIV_FLOAT: { 1959 Binop_23x<HDiv>(instruction, Primitive::kPrimFloat, dex_pc); 1960 break; 1961 } 1962 1963 case Instruction::DIV_DOUBLE: { 1964 Binop_23x<HDiv>(instruction, Primitive::kPrimDouble, dex_pc); 1965 break; 1966 } 1967 1968 case Instruction::REM_INT: { 1969 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(), 1970 dex_pc, Primitive::kPrimInt, false, false); 1971 break; 1972 } 1973 1974 case Instruction::REM_LONG: { 1975 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(), 1976 dex_pc, Primitive::kPrimLong, false, false); 1977 break; 1978 } 1979 1980 case Instruction::REM_FLOAT: { 1981 Binop_23x<HRem>(instruction, Primitive::kPrimFloat, dex_pc); 1982 break; 1983 } 1984 1985 case Instruction::REM_DOUBLE: { 1986 Binop_23x<HRem>(instruction, Primitive::kPrimDouble, dex_pc); 1987 break; 1988 } 1989 1990 case Instruction::AND_INT: { 1991 Binop_23x<HAnd>(instruction, Primitive::kPrimInt); 1992 break; 1993 } 1994 1995 case Instruction::AND_LONG: { 1996 Binop_23x<HAnd>(instruction, Primitive::kPrimLong); 1997 break; 1998 } 1999 2000 case Instruction::SHL_INT: { 2001 Binop_23x_shift<HShl>(instruction, Primitive::kPrimInt); 2002 break; 2003 } 2004 2005 case Instruction::SHL_LONG: { 2006 Binop_23x_shift<HShl>(instruction, Primitive::kPrimLong); 2007 break; 2008 } 2009 2010 case Instruction::SHR_INT: { 2011 Binop_23x_shift<HShr>(instruction, Primitive::kPrimInt); 2012 break; 2013 } 2014 2015 case Instruction::SHR_LONG: { 2016 Binop_23x_shift<HShr>(instruction, Primitive::kPrimLong); 2017 break; 2018 } 2019 2020 case Instruction::USHR_INT: { 2021 Binop_23x_shift<HUShr>(instruction, Primitive::kPrimInt); 2022 break; 2023 } 2024 2025 case Instruction::USHR_LONG: { 2026 Binop_23x_shift<HUShr>(instruction, Primitive::kPrimLong); 2027 break; 2028 } 2029 2030 case Instruction::OR_INT: { 2031 Binop_23x<HOr>(instruction, Primitive::kPrimInt); 2032 break; 2033 } 2034 2035 case Instruction::OR_LONG: { 2036 Binop_23x<HOr>(instruction, Primitive::kPrimLong); 2037 break; 2038 } 2039 2040 case Instruction::XOR_INT: { 2041 Binop_23x<HXor>(instruction, Primitive::kPrimInt); 2042 break; 2043 } 2044 2045 case Instruction::XOR_LONG: { 2046 Binop_23x<HXor>(instruction, Primitive::kPrimLong); 2047 break; 2048 } 2049 2050 case Instruction::ADD_LONG_2ADDR: { 2051 Binop_12x<HAdd>(instruction, Primitive::kPrimLong); 2052 break; 2053 } 2054 2055 case Instruction::ADD_DOUBLE_2ADDR: { 2056 Binop_12x<HAdd>(instruction, Primitive::kPrimDouble); 2057 break; 2058 } 2059 2060 case Instruction::ADD_FLOAT_2ADDR: { 2061 Binop_12x<HAdd>(instruction, Primitive::kPrimFloat); 2062 break; 2063 } 2064 2065 case Instruction::SUB_INT_2ADDR: { 2066 Binop_12x<HSub>(instruction, Primitive::kPrimInt); 2067 break; 2068 } 2069 2070 case Instruction::SUB_LONG_2ADDR: { 2071 Binop_12x<HSub>(instruction, Primitive::kPrimLong); 2072 break; 2073 } 2074 2075 case Instruction::SUB_FLOAT_2ADDR: { 2076 Binop_12x<HSub>(instruction, Primitive::kPrimFloat); 2077 break; 2078 } 2079 2080 case Instruction::SUB_DOUBLE_2ADDR: { 2081 Binop_12x<HSub>(instruction, Primitive::kPrimDouble); 2082 break; 2083 } 2084 2085 case Instruction::MUL_INT_2ADDR: { 2086 Binop_12x<HMul>(instruction, Primitive::kPrimInt); 2087 break; 2088 } 2089 2090 case Instruction::MUL_LONG_2ADDR: { 2091 Binop_12x<HMul>(instruction, Primitive::kPrimLong); 2092 break; 2093 } 2094 2095 case Instruction::MUL_FLOAT_2ADDR: { 2096 Binop_12x<HMul>(instruction, Primitive::kPrimFloat); 2097 break; 2098 } 2099 2100 case Instruction::MUL_DOUBLE_2ADDR: { 2101 Binop_12x<HMul>(instruction, Primitive::kPrimDouble); 2102 break; 2103 } 2104 2105 case Instruction::DIV_INT_2ADDR: { 2106 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(), 2107 dex_pc, Primitive::kPrimInt, false, true); 2108 break; 2109 } 2110 2111 case Instruction::DIV_LONG_2ADDR: { 2112 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(), 2113 dex_pc, Primitive::kPrimLong, false, true); 2114 break; 2115 } 2116 2117 case Instruction::REM_INT_2ADDR: { 2118 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(), 2119 dex_pc, Primitive::kPrimInt, false, false); 2120 break; 2121 } 2122 2123 case Instruction::REM_LONG_2ADDR: { 2124 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(), 2125 dex_pc, Primitive::kPrimLong, false, false); 2126 break; 2127 } 2128 2129 case Instruction::REM_FLOAT_2ADDR: { 2130 Binop_12x<HRem>(instruction, Primitive::kPrimFloat, dex_pc); 2131 break; 2132 } 2133 2134 case Instruction::REM_DOUBLE_2ADDR: { 2135 Binop_12x<HRem>(instruction, Primitive::kPrimDouble, dex_pc); 2136 break; 2137 } 2138 2139 case Instruction::SHL_INT_2ADDR: { 2140 Binop_12x_shift<HShl>(instruction, Primitive::kPrimInt); 2141 break; 2142 } 2143 2144 case Instruction::SHL_LONG_2ADDR: { 2145 Binop_12x_shift<HShl>(instruction, Primitive::kPrimLong); 2146 break; 2147 } 2148 2149 case Instruction::SHR_INT_2ADDR: { 2150 Binop_12x_shift<HShr>(instruction, Primitive::kPrimInt); 2151 break; 2152 } 2153 2154 case Instruction::SHR_LONG_2ADDR: { 2155 Binop_12x_shift<HShr>(instruction, Primitive::kPrimLong); 2156 break; 2157 } 2158 2159 case Instruction::USHR_INT_2ADDR: { 2160 Binop_12x_shift<HUShr>(instruction, Primitive::kPrimInt); 2161 break; 2162 } 2163 2164 case Instruction::USHR_LONG_2ADDR: { 2165 Binop_12x_shift<HUShr>(instruction, Primitive::kPrimLong); 2166 break; 2167 } 2168 2169 case Instruction::DIV_FLOAT_2ADDR: { 2170 Binop_12x<HDiv>(instruction, Primitive::kPrimFloat, dex_pc); 2171 break; 2172 } 2173 2174 case Instruction::DIV_DOUBLE_2ADDR: { 2175 Binop_12x<HDiv>(instruction, Primitive::kPrimDouble, dex_pc); 2176 break; 2177 } 2178 2179 case Instruction::AND_INT_2ADDR: { 2180 Binop_12x<HAnd>(instruction, Primitive::kPrimInt); 2181 break; 2182 } 2183 2184 case Instruction::AND_LONG_2ADDR: { 2185 Binop_12x<HAnd>(instruction, Primitive::kPrimLong); 2186 break; 2187 } 2188 2189 case Instruction::OR_INT_2ADDR: { 2190 Binop_12x<HOr>(instruction, Primitive::kPrimInt); 2191 break; 2192 } 2193 2194 case Instruction::OR_LONG_2ADDR: { 2195 Binop_12x<HOr>(instruction, Primitive::kPrimLong); 2196 break; 2197 } 2198 2199 case Instruction::XOR_INT_2ADDR: { 2200 Binop_12x<HXor>(instruction, Primitive::kPrimInt); 2201 break; 2202 } 2203 2204 case Instruction::XOR_LONG_2ADDR: { 2205 Binop_12x<HXor>(instruction, Primitive::kPrimLong); 2206 break; 2207 } 2208 2209 case Instruction::ADD_INT_LIT16: { 2210 Binop_22s<HAdd>(instruction, false); 2211 break; 2212 } 2213 2214 case Instruction::AND_INT_LIT16: { 2215 Binop_22s<HAnd>(instruction, false); 2216 break; 2217 } 2218 2219 case Instruction::OR_INT_LIT16: { 2220 Binop_22s<HOr>(instruction, false); 2221 break; 2222 } 2223 2224 case Instruction::XOR_INT_LIT16: { 2225 Binop_22s<HXor>(instruction, false); 2226 break; 2227 } 2228 2229 case Instruction::RSUB_INT: { 2230 Binop_22s<HSub>(instruction, true); 2231 break; 2232 } 2233 2234 case Instruction::MUL_INT_LIT16: { 2235 Binop_22s<HMul>(instruction, false); 2236 break; 2237 } 2238 2239 case Instruction::ADD_INT_LIT8: { 2240 Binop_22b<HAdd>(instruction, false); 2241 break; 2242 } 2243 2244 case Instruction::AND_INT_LIT8: { 2245 Binop_22b<HAnd>(instruction, false); 2246 break; 2247 } 2248 2249 case Instruction::OR_INT_LIT8: { 2250 Binop_22b<HOr>(instruction, false); 2251 break; 2252 } 2253 2254 case Instruction::XOR_INT_LIT8: { 2255 Binop_22b<HXor>(instruction, false); 2256 break; 2257 } 2258 2259 case Instruction::RSUB_INT_LIT8: { 2260 Binop_22b<HSub>(instruction, true); 2261 break; 2262 } 2263 2264 case Instruction::MUL_INT_LIT8: { 2265 Binop_22b<HMul>(instruction, false); 2266 break; 2267 } 2268 2269 case Instruction::DIV_INT_LIT16: 2270 case Instruction::DIV_INT_LIT8: { 2271 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(), 2272 dex_pc, Primitive::kPrimInt, true, true); 2273 break; 2274 } 2275 2276 case Instruction::REM_INT_LIT16: 2277 case Instruction::REM_INT_LIT8: { 2278 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(), 2279 dex_pc, Primitive::kPrimInt, true, false); 2280 break; 2281 } 2282 2283 case Instruction::SHL_INT_LIT8: { 2284 Binop_22b<HShl>(instruction, false); 2285 break; 2286 } 2287 2288 case Instruction::SHR_INT_LIT8: { 2289 Binop_22b<HShr>(instruction, false); 2290 break; 2291 } 2292 2293 case Instruction::USHR_INT_LIT8: { 2294 Binop_22b<HUShr>(instruction, false); 2295 break; 2296 } 2297 2298 case Instruction::NEW_INSTANCE: { 2299 uint16_t type_index = instruction.VRegB_21c(); 2300 if (compiler_driver_->IsStringTypeIndex(type_index, dex_file_)) { 2301 int32_t register_index = instruction.VRegA(); 2302 HFakeString* fake_string = new (arena_) HFakeString(); 2303 current_block_->AddInstruction(fake_string); 2304 UpdateLocal(register_index, fake_string); 2305 } else { 2306 QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index) 2307 ? kQuickAllocObjectWithAccessCheck 2308 : kQuickAllocObject; 2309 2310 current_block_->AddInstruction(new (arena_) HNewInstance( 2311 graph_->GetCurrentMethod(), 2312 dex_pc, 2313 type_index, 2314 *dex_compilation_unit_->GetDexFile(), 2315 entrypoint)); 2316 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 2317 } 2318 break; 2319 } 2320 2321 case Instruction::NEW_ARRAY: { 2322 uint16_t type_index = instruction.VRegC_22c(); 2323 HInstruction* length = LoadLocal(instruction.VRegB_22c(), Primitive::kPrimInt); 2324 QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index) 2325 ? kQuickAllocArrayWithAccessCheck 2326 : kQuickAllocArray; 2327 current_block_->AddInstruction(new (arena_) HNewArray(length, 2328 graph_->GetCurrentMethod(), 2329 dex_pc, 2330 type_index, 2331 *dex_compilation_unit_->GetDexFile(), 2332 entrypoint)); 2333 UpdateLocal(instruction.VRegA_22c(), current_block_->GetLastInstruction()); 2334 break; 2335 } 2336 2337 case Instruction::FILLED_NEW_ARRAY: { 2338 uint32_t number_of_vreg_arguments = instruction.VRegA_35c(); 2339 uint32_t type_index = instruction.VRegB_35c(); 2340 uint32_t args[5]; 2341 instruction.GetVarArgs(args); 2342 BuildFilledNewArray(dex_pc, type_index, number_of_vreg_arguments, false, args, 0); 2343 break; 2344 } 2345 2346 case Instruction::FILLED_NEW_ARRAY_RANGE: { 2347 uint32_t number_of_vreg_arguments = instruction.VRegA_3rc(); 2348 uint32_t type_index = instruction.VRegB_3rc(); 2349 uint32_t register_index = instruction.VRegC_3rc(); 2350 BuildFilledNewArray( 2351 dex_pc, type_index, number_of_vreg_arguments, true, nullptr, register_index); 2352 break; 2353 } 2354 2355 case Instruction::FILL_ARRAY_DATA: { 2356 BuildFillArrayData(instruction, dex_pc); 2357 break; 2358 } 2359 2360 case Instruction::MOVE_RESULT: 2361 case Instruction::MOVE_RESULT_WIDE: 2362 case Instruction::MOVE_RESULT_OBJECT: { 2363 if (latest_result_ == nullptr) { 2364 // Only dead code can lead to this situation, where the verifier 2365 // does not reject the method. 2366 } else { 2367 // An Invoke/FilledNewArray and its MoveResult could have landed in 2368 // different blocks if there was a try/catch block boundary between 2369 // them. For Invoke, we insert a StoreLocal after the instruction. For 2370 // FilledNewArray, the local needs to be updated after the array was 2371 // filled, otherwise we might overwrite an input vreg. 2372 HStoreLocal* update_local = 2373 new (arena_) HStoreLocal(GetLocalAt(instruction.VRegA()), latest_result_); 2374 HBasicBlock* block = latest_result_->GetBlock(); 2375 if (block == current_block_) { 2376 // MoveResult and the previous instruction are in the same block. 2377 current_block_->AddInstruction(update_local); 2378 } else { 2379 // The two instructions are in different blocks. Insert the MoveResult 2380 // before the final control-flow instruction of the previous block. 2381 DCHECK(block->EndsWithControlFlowInstruction()); 2382 DCHECK(current_block_->GetInstructions().IsEmpty()); 2383 block->InsertInstructionBefore(update_local, block->GetLastInstruction()); 2384 } 2385 latest_result_ = nullptr; 2386 } 2387 break; 2388 } 2389 2390 case Instruction::CMP_LONG: { 2391 Binop_23x_cmp(instruction, Primitive::kPrimLong, ComparisonBias::kNoBias, dex_pc); 2392 break; 2393 } 2394 2395 case Instruction::CMPG_FLOAT: { 2396 Binop_23x_cmp(instruction, Primitive::kPrimFloat, ComparisonBias::kGtBias, dex_pc); 2397 break; 2398 } 2399 2400 case Instruction::CMPG_DOUBLE: { 2401 Binop_23x_cmp(instruction, Primitive::kPrimDouble, ComparisonBias::kGtBias, dex_pc); 2402 break; 2403 } 2404 2405 case Instruction::CMPL_FLOAT: { 2406 Binop_23x_cmp(instruction, Primitive::kPrimFloat, ComparisonBias::kLtBias, dex_pc); 2407 break; 2408 } 2409 2410 case Instruction::CMPL_DOUBLE: { 2411 Binop_23x_cmp(instruction, Primitive::kPrimDouble, ComparisonBias::kLtBias, dex_pc); 2412 break; 2413 } 2414 2415 case Instruction::NOP: 2416 break; 2417 2418 case Instruction::IGET: 2419 case Instruction::IGET_QUICK: 2420 case Instruction::IGET_WIDE: 2421 case Instruction::IGET_WIDE_QUICK: 2422 case Instruction::IGET_OBJECT: 2423 case Instruction::IGET_OBJECT_QUICK: 2424 case Instruction::IGET_BOOLEAN: 2425 case Instruction::IGET_BOOLEAN_QUICK: 2426 case Instruction::IGET_BYTE: 2427 case Instruction::IGET_BYTE_QUICK: 2428 case Instruction::IGET_CHAR: 2429 case Instruction::IGET_CHAR_QUICK: 2430 case Instruction::IGET_SHORT: 2431 case Instruction::IGET_SHORT_QUICK: { 2432 if (!BuildInstanceFieldAccess(instruction, dex_pc, false)) { 2433 return false; 2434 } 2435 break; 2436 } 2437 2438 case Instruction::IPUT: 2439 case Instruction::IPUT_QUICK: 2440 case Instruction::IPUT_WIDE: 2441 case Instruction::IPUT_WIDE_QUICK: 2442 case Instruction::IPUT_OBJECT: 2443 case Instruction::IPUT_OBJECT_QUICK: 2444 case Instruction::IPUT_BOOLEAN: 2445 case Instruction::IPUT_BOOLEAN_QUICK: 2446 case Instruction::IPUT_BYTE: 2447 case Instruction::IPUT_BYTE_QUICK: 2448 case Instruction::IPUT_CHAR: 2449 case Instruction::IPUT_CHAR_QUICK: 2450 case Instruction::IPUT_SHORT: 2451 case Instruction::IPUT_SHORT_QUICK: { 2452 if (!BuildInstanceFieldAccess(instruction, dex_pc, true)) { 2453 return false; 2454 } 2455 break; 2456 } 2457 2458 case Instruction::SGET: 2459 case Instruction::SGET_WIDE: 2460 case Instruction::SGET_OBJECT: 2461 case Instruction::SGET_BOOLEAN: 2462 case Instruction::SGET_BYTE: 2463 case Instruction::SGET_CHAR: 2464 case Instruction::SGET_SHORT: { 2465 if (!BuildStaticFieldAccess(instruction, dex_pc, false)) { 2466 return false; 2467 } 2468 break; 2469 } 2470 2471 case Instruction::SPUT: 2472 case Instruction::SPUT_WIDE: 2473 case Instruction::SPUT_OBJECT: 2474 case Instruction::SPUT_BOOLEAN: 2475 case Instruction::SPUT_BYTE: 2476 case Instruction::SPUT_CHAR: 2477 case Instruction::SPUT_SHORT: { 2478 if (!BuildStaticFieldAccess(instruction, dex_pc, true)) { 2479 return false; 2480 } 2481 break; 2482 } 2483 2484#define ARRAY_XX(kind, anticipated_type) \ 2485 case Instruction::AGET##kind: { \ 2486 BuildArrayAccess(instruction, dex_pc, false, anticipated_type); \ 2487 break; \ 2488 } \ 2489 case Instruction::APUT##kind: { \ 2490 BuildArrayAccess(instruction, dex_pc, true, anticipated_type); \ 2491 break; \ 2492 } 2493 2494 ARRAY_XX(, Primitive::kPrimInt); 2495 ARRAY_XX(_WIDE, Primitive::kPrimLong); 2496 ARRAY_XX(_OBJECT, Primitive::kPrimNot); 2497 ARRAY_XX(_BOOLEAN, Primitive::kPrimBoolean); 2498 ARRAY_XX(_BYTE, Primitive::kPrimByte); 2499 ARRAY_XX(_CHAR, Primitive::kPrimChar); 2500 ARRAY_XX(_SHORT, Primitive::kPrimShort); 2501 2502 case Instruction::ARRAY_LENGTH: { 2503 HInstruction* object = LoadLocal(instruction.VRegB_12x(), Primitive::kPrimNot); 2504 // No need for a temporary for the null check, it is the only input of the following 2505 // instruction. 2506 object = new (arena_) HNullCheck(object, dex_pc); 2507 current_block_->AddInstruction(object); 2508 current_block_->AddInstruction(new (arena_) HArrayLength(object)); 2509 UpdateLocal(instruction.VRegA_12x(), current_block_->GetLastInstruction()); 2510 break; 2511 } 2512 2513 case Instruction::CONST_STRING: { 2514 current_block_->AddInstruction( 2515 new (arena_) HLoadString(graph_->GetCurrentMethod(), instruction.VRegB_21c(), dex_pc)); 2516 UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction()); 2517 break; 2518 } 2519 2520 case Instruction::CONST_STRING_JUMBO: { 2521 current_block_->AddInstruction( 2522 new (arena_) HLoadString(graph_->GetCurrentMethod(), instruction.VRegB_31c(), dex_pc)); 2523 UpdateLocal(instruction.VRegA_31c(), current_block_->GetLastInstruction()); 2524 break; 2525 } 2526 2527 case Instruction::CONST_CLASS: { 2528 uint16_t type_index = instruction.VRegB_21c(); 2529 bool type_known_final; 2530 bool type_known_abstract; 2531 bool dont_use_is_referrers_class; 2532 // `CanAccessTypeWithoutChecks` will tell whether the method being 2533 // built is trying to access its own class, so that the generated 2534 // code can optimize for this case. However, the optimization does not 2535 // work for inlining, so we use `IsOutermostCompilingClass` instead. 2536 bool can_access = compiler_driver_->CanAccessTypeWithoutChecks( 2537 dex_compilation_unit_->GetDexMethodIndex(), *dex_file_, type_index, 2538 &type_known_final, &type_known_abstract, &dont_use_is_referrers_class); 2539 if (!can_access) { 2540 MaybeRecordStat(MethodCompilationStat::kNotCompiledCantAccesType); 2541 return false; 2542 } 2543 current_block_->AddInstruction(new (arena_) HLoadClass( 2544 graph_->GetCurrentMethod(), 2545 type_index, 2546 *dex_compilation_unit_->GetDexFile(), 2547 IsOutermostCompilingClass(type_index), 2548 dex_pc)); 2549 UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction()); 2550 break; 2551 } 2552 2553 case Instruction::MOVE_EXCEPTION: { 2554 current_block_->AddInstruction(new (arena_) HLoadException()); 2555 UpdateLocal(instruction.VRegA_11x(), current_block_->GetLastInstruction()); 2556 current_block_->AddInstruction(new (arena_) HClearException()); 2557 break; 2558 } 2559 2560 case Instruction::THROW: { 2561 HInstruction* exception = LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot); 2562 current_block_->AddInstruction(new (arena_) HThrow(exception, dex_pc)); 2563 // A throw instruction must branch to the exit block. 2564 current_block_->AddSuccessor(exit_block_); 2565 // We finished building this block. Set the current block to null to avoid 2566 // adding dead instructions to it. 2567 current_block_ = nullptr; 2568 break; 2569 } 2570 2571 case Instruction::INSTANCE_OF: { 2572 uint8_t destination = instruction.VRegA_22c(); 2573 uint8_t reference = instruction.VRegB_22c(); 2574 uint16_t type_index = instruction.VRegC_22c(); 2575 if (!BuildTypeCheck(instruction, destination, reference, type_index, dex_pc)) { 2576 return false; 2577 } 2578 break; 2579 } 2580 2581 case Instruction::CHECK_CAST: { 2582 uint8_t reference = instruction.VRegA_21c(); 2583 uint16_t type_index = instruction.VRegB_21c(); 2584 if (!BuildTypeCheck(instruction, -1, reference, type_index, dex_pc)) { 2585 return false; 2586 } 2587 break; 2588 } 2589 2590 case Instruction::MONITOR_ENTER: { 2591 current_block_->AddInstruction(new (arena_) HMonitorOperation( 2592 LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot), 2593 HMonitorOperation::kEnter, 2594 dex_pc)); 2595 break; 2596 } 2597 2598 case Instruction::MONITOR_EXIT: { 2599 current_block_->AddInstruction(new (arena_) HMonitorOperation( 2600 LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot), 2601 HMonitorOperation::kExit, 2602 dex_pc)); 2603 break; 2604 } 2605 2606 case Instruction::PACKED_SWITCH: { 2607 BuildPackedSwitch(instruction, dex_pc); 2608 break; 2609 } 2610 2611 case Instruction::SPARSE_SWITCH: { 2612 BuildSparseSwitch(instruction, dex_pc); 2613 break; 2614 } 2615 2616 default: 2617 VLOG(compiler) << "Did not compile " 2618 << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_) 2619 << " because of unhandled instruction " 2620 << instruction.Name(); 2621 MaybeRecordStat(MethodCompilationStat::kNotCompiledUnhandledInstruction); 2622 return false; 2623 } 2624 return true; 2625} // NOLINT(readability/fn_size) 2626 2627HLocal* HGraphBuilder::GetLocalAt(int register_index) const { 2628 return locals_.Get(register_index); 2629} 2630 2631void HGraphBuilder::UpdateLocal(int register_index, HInstruction* instruction) const { 2632 HLocal* local = GetLocalAt(register_index); 2633 current_block_->AddInstruction(new (arena_) HStoreLocal(local, instruction)); 2634} 2635 2636HInstruction* HGraphBuilder::LoadLocal(int register_index, Primitive::Type type) const { 2637 HLocal* local = GetLocalAt(register_index); 2638 current_block_->AddInstruction(new (arena_) HLoadLocal(local, type)); 2639 return current_block_->GetLastInstruction(); 2640} 2641 2642} // namespace art 2643