builder.cc revision 1cf95287364948689f6a1a320567acd7728e94a3
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 "base/logging.h" 20#include "class_linker.h" 21#include "dex_file.h" 22#include "dex_file-inl.h" 23#include "dex_instruction.h" 24#include "dex_instruction-inl.h" 25#include "driver/compiler_driver-inl.h" 26#include "mirror/art_field.h" 27#include "mirror/art_field-inl.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); 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 PotentiallyAddSuspendCheck(target_offset, dex_pc); 194 HInstruction* first = LoadLocal(instruction.VRegA(), Primitive::kPrimInt); 195 HInstruction* second = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); 196 T* comparison = new (arena_) T(first, second); 197 current_block_->AddInstruction(comparison); 198 HInstruction* ifinst = new (arena_) HIf(comparison); 199 current_block_->AddInstruction(ifinst); 200 HBasicBlock* target = FindBlockStartingAt(dex_pc + target_offset); 201 DCHECK(target != nullptr); 202 current_block_->AddSuccessor(target); 203 target = FindBlockStartingAt(dex_pc + instruction.SizeInCodeUnits()); 204 DCHECK(target != nullptr); 205 current_block_->AddSuccessor(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 PotentiallyAddSuspendCheck(target_offset, dex_pc); 213 HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt); 214 T* comparison = new (arena_) T(value, GetIntConstant(0)); 215 current_block_->AddInstruction(comparison); 216 HInstruction* ifinst = new (arena_) HIf(comparison); 217 current_block_->AddInstruction(ifinst); 218 HBasicBlock* target = FindBlockStartingAt(dex_pc + target_offset); 219 DCHECK(target != nullptr); 220 current_block_->AddSuccessor(target); 221 target = FindBlockStartingAt(dex_pc + instruction.SizeInCodeUnits()); 222 DCHECK(target != nullptr); 223 current_block_->AddSuccessor(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(size_t number_of_dex_instructions, 234 size_t number_of_blocks ATTRIBUTE_UNUSED, 235 size_t number_of_branches) { 236 const CompilerOptions& compiler_options = compiler_driver_->GetCompilerOptions(); 237 CompilerOptions::CompilerFilter compiler_filter = compiler_options.GetCompilerFilter(); 238 if (compiler_filter == CompilerOptions::kEverything) { 239 return false; 240 } 241 242 if (compiler_options.IsHugeMethod(number_of_dex_instructions)) { 243 VLOG(compiler) << "Skip compilation of huge method " 244 << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_) 245 << ": " << number_of_dex_instructions << " dex instructions"; 246 MaybeRecordStat(MethodCompilationStat::kNotCompiledHugeMethod); 247 return true; 248 } 249 250 // If it's large and contains no branches, it's likely to be machine generated initialization. 251 if (compiler_options.IsLargeMethod(number_of_dex_instructions) && (number_of_branches == 0)) { 252 VLOG(compiler) << "Skip compilation of large method with no branch " 253 << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_) 254 << ": " << number_of_dex_instructions << " dex instructions"; 255 MaybeRecordStat(MethodCompilationStat::kNotCompiledLargeMethodNoBranches); 256 return true; 257 } 258 259 return false; 260} 261 262HGraph* HGraphBuilder::BuildGraph(const DexFile::CodeItem& code_item, int start_instruction_id) { 263 const uint16_t* code_ptr = code_item.insns_; 264 const uint16_t* code_end = code_item.insns_ + code_item.insns_size_in_code_units_; 265 code_start_ = code_ptr; 266 267 // Setup the graph with the entry block and exit block. 268 graph_ = new (arena_) HGraph(arena_, start_instruction_id); 269 entry_block_ = new (arena_) HBasicBlock(graph_, 0); 270 graph_->AddBlock(entry_block_); 271 exit_block_ = new (arena_) HBasicBlock(graph_, kNoDexPc); 272 graph_->SetEntryBlock(entry_block_); 273 graph_->SetExitBlock(exit_block_); 274 275 InitializeLocals(code_item.registers_size_); 276 graph_->SetMaximumNumberOfOutVRegs(code_item.outs_size_); 277 278 // Compute the number of dex instructions, blocks, and branches. We will 279 // check these values against limits given to the compiler. 280 size_t number_of_dex_instructions = 0; 281 size_t number_of_blocks = 0; 282 size_t number_of_branches = 0; 283 284 // To avoid splitting blocks, we compute ahead of time the instructions that 285 // start a new block, and create these blocks. 286 ComputeBranchTargets( 287 code_ptr, code_end, &number_of_dex_instructions, &number_of_blocks, &number_of_branches); 288 289 // Note that the compiler driver is null when unit testing. 290 if ((compiler_driver_ != nullptr) 291 && SkipCompilation(number_of_dex_instructions, number_of_blocks, number_of_branches)) { 292 return nullptr; 293 } 294 295 // Also create blocks for catch handlers. 296 if (code_item.tries_size_ != 0) { 297 const uint8_t* handlers_ptr = DexFile::GetCatchHandlerData(code_item, 0); 298 uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr); 299 for (uint32_t idx = 0; idx < handlers_size; ++idx) { 300 CatchHandlerIterator iterator(handlers_ptr); 301 for (; iterator.HasNext(); iterator.Next()) { 302 uint32_t address = iterator.GetHandlerAddress(); 303 HBasicBlock* block = FindBlockStartingAt(address); 304 if (block == nullptr) { 305 block = new (arena_) HBasicBlock(graph_, address); 306 branch_targets_.Put(address, block); 307 } 308 block->SetIsCatchBlock(); 309 } 310 handlers_ptr = iterator.EndDataPointer(); 311 } 312 } 313 314 InitializeParameters(code_item.ins_size_); 315 316 size_t dex_pc = 0; 317 while (code_ptr < code_end) { 318 // Update the current block if dex_pc starts a new block. 319 MaybeUpdateCurrentBlock(dex_pc); 320 const Instruction& instruction = *Instruction::At(code_ptr); 321 if (!AnalyzeDexInstruction(instruction, dex_pc)) { 322 return nullptr; 323 } 324 dex_pc += instruction.SizeInCodeUnits(); 325 code_ptr += instruction.SizeInCodeUnits(); 326 } 327 328 // Add the exit block at the end to give it the highest id. 329 graph_->AddBlock(exit_block_); 330 exit_block_->AddInstruction(new (arena_) HExit()); 331 // Add the suspend check to the entry block. 332 entry_block_->AddInstruction(new (arena_) HSuspendCheck(0)); 333 entry_block_->AddInstruction(new (arena_) HGoto()); 334 return graph_; 335} 336 337void HGraphBuilder::MaybeUpdateCurrentBlock(size_t index) { 338 HBasicBlock* block = FindBlockStartingAt(index); 339 if (block == nullptr) { 340 return; 341 } 342 343 if (current_block_ != nullptr) { 344 // Branching instructions clear current_block, so we know 345 // the last instruction of the current block is not a branching 346 // instruction. We add an unconditional goto to the found block. 347 current_block_->AddInstruction(new (arena_) HGoto()); 348 current_block_->AddSuccessor(block); 349 } 350 graph_->AddBlock(block); 351 current_block_ = block; 352} 353 354void HGraphBuilder::ComputeBranchTargets(const uint16_t* code_ptr, 355 const uint16_t* code_end, 356 size_t* number_of_dex_instructions, 357 size_t* number_of_blocks, 358 size_t* number_of_branches) { 359 branch_targets_.SetSize(code_end - code_ptr); 360 361 // Create the first block for the dex instructions, single successor of the entry block. 362 HBasicBlock* block = new (arena_) HBasicBlock(graph_, 0); 363 branch_targets_.Put(0, block); 364 entry_block_->AddSuccessor(block); 365 366 // Iterate over all instructions and find branching instructions. Create blocks for 367 // the locations these instructions branch to. 368 uint32_t dex_pc = 0; 369 while (code_ptr < code_end) { 370 (*number_of_dex_instructions)++; 371 const Instruction& instruction = *Instruction::At(code_ptr); 372 if (instruction.IsBranch()) { 373 (*number_of_branches)++; 374 int32_t target = instruction.GetTargetOffset() + dex_pc; 375 // Create a block for the target instruction. 376 if (FindBlockStartingAt(target) == nullptr) { 377 block = new (arena_) HBasicBlock(graph_, target); 378 branch_targets_.Put(target, block); 379 (*number_of_blocks)++; 380 } 381 dex_pc += instruction.SizeInCodeUnits(); 382 code_ptr += instruction.SizeInCodeUnits(); 383 if ((code_ptr < code_end) && (FindBlockStartingAt(dex_pc) == nullptr)) { 384 block = new (arena_) HBasicBlock(graph_, dex_pc); 385 branch_targets_.Put(dex_pc, block); 386 (*number_of_blocks)++; 387 } 388 } else if (instruction.IsSwitch()) { 389 SwitchTable table(instruction, dex_pc, instruction.Opcode() == Instruction::SPARSE_SWITCH); 390 391 uint16_t num_entries = table.GetNumEntries(); 392 393 // In a packed-switch, the entry at index 0 is the starting key. In a sparse-switch, the 394 // entry at index 0 is the first key, and values are after *all* keys. 395 size_t offset = table.GetFirstValueIndex(); 396 397 // Use a larger loop counter type to avoid overflow issues. 398 for (size_t i = 0; i < num_entries; ++i) { 399 // The target of the case. 400 uint32_t target = dex_pc + table.GetEntryAt(i + offset); 401 if (FindBlockStartingAt(target) == nullptr) { 402 block = new (arena_) HBasicBlock(graph_, target); 403 branch_targets_.Put(target, block); 404 (*number_of_blocks)++; 405 } 406 407 // The next case gets its own block. 408 if (i < num_entries) { 409 block = new (arena_) HBasicBlock(graph_, target); 410 branch_targets_.Put(table.GetDexPcForIndex(i), block); 411 (*number_of_blocks)++; 412 } 413 } 414 415 // Fall-through. Add a block if there is more code afterwards. 416 dex_pc += instruction.SizeInCodeUnits(); 417 code_ptr += instruction.SizeInCodeUnits(); 418 if ((code_ptr < code_end) && (FindBlockStartingAt(dex_pc) == nullptr)) { 419 block = new (arena_) HBasicBlock(graph_, dex_pc); 420 branch_targets_.Put(dex_pc, block); 421 (*number_of_blocks)++; 422 } 423 } else { 424 code_ptr += instruction.SizeInCodeUnits(); 425 dex_pc += instruction.SizeInCodeUnits(); 426 } 427 } 428} 429 430HBasicBlock* HGraphBuilder::FindBlockStartingAt(int32_t index) const { 431 DCHECK_GE(index, 0); 432 return branch_targets_.Get(index); 433} 434 435template<typename T> 436void HGraphBuilder::Unop_12x(const Instruction& instruction, Primitive::Type type) { 437 HInstruction* first = LoadLocal(instruction.VRegB(), type); 438 current_block_->AddInstruction(new (arena_) T(type, first)); 439 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 440} 441 442void HGraphBuilder::Conversion_12x(const Instruction& instruction, 443 Primitive::Type input_type, 444 Primitive::Type result_type, 445 uint32_t dex_pc) { 446 HInstruction* first = LoadLocal(instruction.VRegB(), input_type); 447 current_block_->AddInstruction(new (arena_) HTypeConversion(result_type, first, dex_pc)); 448 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 449} 450 451template<typename T> 452void HGraphBuilder::Binop_23x(const Instruction& instruction, Primitive::Type type) { 453 HInstruction* first = LoadLocal(instruction.VRegB(), type); 454 HInstruction* second = LoadLocal(instruction.VRegC(), type); 455 current_block_->AddInstruction(new (arena_) T(type, first, second)); 456 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 457} 458 459template<typename T> 460void HGraphBuilder::Binop_23x(const Instruction& instruction, 461 Primitive::Type type, 462 uint32_t dex_pc) { 463 HInstruction* first = LoadLocal(instruction.VRegB(), type); 464 HInstruction* second = LoadLocal(instruction.VRegC(), type); 465 current_block_->AddInstruction(new (arena_) T(type, first, second, dex_pc)); 466 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 467} 468 469template<typename T> 470void HGraphBuilder::Binop_23x_shift(const Instruction& instruction, 471 Primitive::Type type) { 472 HInstruction* first = LoadLocal(instruction.VRegB(), type); 473 HInstruction* second = LoadLocal(instruction.VRegC(), Primitive::kPrimInt); 474 current_block_->AddInstruction(new (arena_) T(type, first, second)); 475 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 476} 477 478void HGraphBuilder::Binop_23x_cmp(const Instruction& instruction, 479 Primitive::Type type, 480 HCompare::Bias bias) { 481 HInstruction* first = LoadLocal(instruction.VRegB(), type); 482 HInstruction* second = LoadLocal(instruction.VRegC(), type); 483 current_block_->AddInstruction(new (arena_) HCompare(type, first, second, bias)); 484 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 485} 486 487template<typename T> 488void HGraphBuilder::Binop_12x(const Instruction& instruction, Primitive::Type type) { 489 HInstruction* first = LoadLocal(instruction.VRegA(), type); 490 HInstruction* second = LoadLocal(instruction.VRegB(), type); 491 current_block_->AddInstruction(new (arena_) T(type, first, second)); 492 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 493} 494 495template<typename T> 496void HGraphBuilder::Binop_12x_shift(const Instruction& instruction, Primitive::Type type) { 497 HInstruction* first = LoadLocal(instruction.VRegA(), type); 498 HInstruction* second = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); 499 current_block_->AddInstruction(new (arena_) T(type, first, second)); 500 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 501} 502 503template<typename T> 504void HGraphBuilder::Binop_12x(const Instruction& instruction, 505 Primitive::Type type, 506 uint32_t dex_pc) { 507 HInstruction* first = LoadLocal(instruction.VRegA(), type); 508 HInstruction* second = LoadLocal(instruction.VRegB(), type); 509 current_block_->AddInstruction(new (arena_) T(type, first, second, dex_pc)); 510 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 511} 512 513template<typename T> 514void HGraphBuilder::Binop_22s(const Instruction& instruction, bool reverse) { 515 HInstruction* first = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); 516 HInstruction* second = GetIntConstant(instruction.VRegC_22s()); 517 if (reverse) { 518 std::swap(first, second); 519 } 520 current_block_->AddInstruction(new (arena_) T(Primitive::kPrimInt, first, second)); 521 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 522} 523 524template<typename T> 525void HGraphBuilder::Binop_22b(const Instruction& instruction, bool reverse) { 526 HInstruction* first = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); 527 HInstruction* second = GetIntConstant(instruction.VRegC_22b()); 528 if (reverse) { 529 std::swap(first, second); 530 } 531 current_block_->AddInstruction(new (arena_) T(Primitive::kPrimInt, first, second)); 532 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 533} 534 535void HGraphBuilder::BuildReturn(const Instruction& instruction, Primitive::Type type) { 536 if (type == Primitive::kPrimVoid) { 537 current_block_->AddInstruction(new (arena_) HReturnVoid()); 538 } else { 539 HInstruction* value = LoadLocal(instruction.VRegA(), type); 540 current_block_->AddInstruction(new (arena_) HReturn(value)); 541 } 542 current_block_->AddSuccessor(exit_block_); 543 current_block_ = nullptr; 544} 545 546bool HGraphBuilder::BuildInvoke(const Instruction& instruction, 547 uint32_t dex_pc, 548 uint32_t method_idx, 549 uint32_t number_of_vreg_arguments, 550 bool is_range, 551 uint32_t* args, 552 uint32_t register_index) { 553 Instruction::Code opcode = instruction.Opcode(); 554 InvokeType invoke_type; 555 switch (opcode) { 556 case Instruction::INVOKE_STATIC: 557 case Instruction::INVOKE_STATIC_RANGE: 558 invoke_type = kStatic; 559 break; 560 case Instruction::INVOKE_DIRECT: 561 case Instruction::INVOKE_DIRECT_RANGE: 562 invoke_type = kDirect; 563 break; 564 case Instruction::INVOKE_VIRTUAL: 565 case Instruction::INVOKE_VIRTUAL_RANGE: 566 invoke_type = kVirtual; 567 break; 568 case Instruction::INVOKE_INTERFACE: 569 case Instruction::INVOKE_INTERFACE_RANGE: 570 invoke_type = kInterface; 571 break; 572 case Instruction::INVOKE_SUPER_RANGE: 573 case Instruction::INVOKE_SUPER: 574 invoke_type = kSuper; 575 break; 576 default: 577 LOG(FATAL) << "Unexpected invoke op: " << opcode; 578 return false; 579 } 580 581 const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx); 582 const DexFile::ProtoId& proto_id = dex_file_->GetProtoId(method_id.proto_idx_); 583 const char* descriptor = dex_file_->StringDataByIdx(proto_id.shorty_idx_); 584 Primitive::Type return_type = Primitive::GetType(descriptor[0]); 585 bool is_instance_call = invoke_type != kStatic; 586 const size_t number_of_arguments = strlen(descriptor) - (is_instance_call ? 0 : 1); 587 588 MethodReference target_method(dex_file_, method_idx); 589 uintptr_t direct_code; 590 uintptr_t direct_method; 591 int table_index; 592 InvokeType optimized_invoke_type = invoke_type; 593 594 if (!compiler_driver_->ComputeInvokeInfo(dex_compilation_unit_, dex_pc, true, true, 595 &optimized_invoke_type, &target_method, &table_index, 596 &direct_code, &direct_method)) { 597 VLOG(compiler) << "Did not compile " << PrettyMethod(method_idx, *dex_file_) 598 << " because a method call could not be resolved"; 599 MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedMethod); 600 return false; 601 } 602 DCHECK(optimized_invoke_type != kSuper); 603 604 HInvoke* invoke = nullptr; 605 if (optimized_invoke_type == kVirtual) { 606 invoke = new (arena_) HInvokeVirtual( 607 arena_, number_of_arguments, return_type, dex_pc, method_idx, table_index); 608 } else if (optimized_invoke_type == kInterface) { 609 invoke = new (arena_) HInvokeInterface( 610 arena_, number_of_arguments, return_type, dex_pc, method_idx, table_index); 611 } else { 612 DCHECK(optimized_invoke_type == kDirect || optimized_invoke_type == kStatic); 613 // Sharpening to kDirect only works if we compile PIC. 614 DCHECK((optimized_invoke_type == invoke_type) || (optimized_invoke_type != kDirect) 615 || compiler_driver_->GetCompilerOptions().GetCompilePic()); 616 bool is_recursive = 617 (target_method.dex_method_index == outer_compilation_unit_->GetDexMethodIndex()); 618 DCHECK(!is_recursive || (target_method.dex_file == outer_compilation_unit_->GetDexFile())); 619 invoke = new (arena_) HInvokeStaticOrDirect( 620 arena_, number_of_arguments, return_type, dex_pc, target_method.dex_method_index, 621 is_recursive, optimized_invoke_type); 622 } 623 624 size_t start_index = 0; 625 Temporaries temps(graph_); 626 if (is_instance_call) { 627 HInstruction* arg = LoadLocal(is_range ? register_index : args[0], Primitive::kPrimNot); 628 HNullCheck* null_check = new (arena_) HNullCheck(arg, dex_pc); 629 current_block_->AddInstruction(null_check); 630 temps.Add(null_check); 631 invoke->SetArgumentAt(0, null_check); 632 start_index = 1; 633 } 634 635 uint32_t descriptor_index = 1; 636 uint32_t argument_index = start_index; 637 for (size_t i = start_index; i < number_of_vreg_arguments; i++, argument_index++) { 638 Primitive::Type type = Primitive::GetType(descriptor[descriptor_index++]); 639 bool is_wide = (type == Primitive::kPrimLong) || (type == Primitive::kPrimDouble); 640 if (!is_range && is_wide && args[i] + 1 != args[i + 1]) { 641 LOG(WARNING) << "Non sequential register pair in " << dex_compilation_unit_->GetSymbol() 642 << " at " << dex_pc; 643 // We do not implement non sequential register pair. 644 MaybeRecordStat(MethodCompilationStat::kNotCompiledNonSequentialRegPair); 645 return false; 646 } 647 HInstruction* arg = LoadLocal(is_range ? register_index + i : args[i], type); 648 invoke->SetArgumentAt(argument_index, arg); 649 if (is_wide) { 650 i++; 651 } 652 } 653 654 DCHECK_EQ(argument_index, number_of_arguments); 655 current_block_->AddInstruction(invoke); 656 latest_result_ = invoke; 657 return true; 658} 659 660bool HGraphBuilder::BuildInstanceFieldAccess(const Instruction& instruction, 661 uint32_t dex_pc, 662 bool is_put) { 663 uint32_t source_or_dest_reg = instruction.VRegA_22c(); 664 uint32_t obj_reg = instruction.VRegB_22c(); 665 uint16_t field_index = instruction.VRegC_22c(); 666 667 ScopedObjectAccess soa(Thread::Current()); 668 StackHandleScope<1> hs(soa.Self()); 669 Handle<mirror::ArtField> resolved_field(hs.NewHandle( 670 compiler_driver_->ComputeInstanceFieldInfo(field_index, dex_compilation_unit_, is_put, soa))); 671 672 if (resolved_field.Get() == nullptr) { 673 MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedField); 674 return false; 675 } 676 677 Primitive::Type field_type = resolved_field->GetTypeAsPrimitiveType(); 678 679 HInstruction* object = LoadLocal(obj_reg, Primitive::kPrimNot); 680 current_block_->AddInstruction(new (arena_) HNullCheck(object, dex_pc)); 681 if (is_put) { 682 Temporaries temps(graph_); 683 HInstruction* null_check = current_block_->GetLastInstruction(); 684 // We need one temporary for the null check. 685 temps.Add(null_check); 686 HInstruction* value = LoadLocal(source_or_dest_reg, field_type); 687 current_block_->AddInstruction(new (arena_) HInstanceFieldSet( 688 null_check, 689 value, 690 field_type, 691 resolved_field->GetOffset(), 692 resolved_field->IsVolatile())); 693 } else { 694 current_block_->AddInstruction(new (arena_) HInstanceFieldGet( 695 current_block_->GetLastInstruction(), 696 field_type, 697 resolved_field->GetOffset(), 698 resolved_field->IsVolatile())); 699 700 UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction()); 701 } 702 return true; 703} 704 705bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction, 706 uint32_t dex_pc, 707 bool is_put) { 708 uint32_t source_or_dest_reg = instruction.VRegA_21c(); 709 uint16_t field_index = instruction.VRegB_21c(); 710 711 ScopedObjectAccess soa(Thread::Current()); 712 StackHandleScope<4> hs(soa.Self()); 713 Handle<mirror::DexCache> dex_cache(hs.NewHandle( 714 dex_compilation_unit_->GetClassLinker()->FindDexCache(*dex_compilation_unit_->GetDexFile()))); 715 Handle<mirror::ClassLoader> class_loader(hs.NewHandle( 716 soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader()))); 717 Handle<mirror::ArtField> resolved_field(hs.NewHandle(compiler_driver_->ResolveField( 718 soa, dex_cache, class_loader, dex_compilation_unit_, field_index, true))); 719 720 if (resolved_field.Get() == nullptr) { 721 MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedField); 722 return false; 723 } 724 725 Handle<mirror::Class> referrer_class(hs.NewHandle(compiler_driver_->ResolveCompilingMethodsClass( 726 soa, dex_cache, class_loader, outer_compilation_unit_))); 727 728 // The index at which the field's class is stored in the DexCache's type array. 729 uint32_t storage_index; 730 std::pair<bool, bool> pair = compiler_driver_->IsFastStaticField( 731 dex_cache.Get(), referrer_class.Get(), resolved_field.Get(), field_index, &storage_index); 732 bool can_easily_access = is_put ? pair.second : pair.first; 733 if (!can_easily_access) { 734 return false; 735 } 736 737 // TODO: find out why this check is needed. 738 bool is_in_dex_cache = compiler_driver_->CanAssumeTypeIsPresentInDexCache( 739 *outer_compilation_unit_->GetDexFile(), storage_index); 740 bool is_initialized = resolved_field->GetDeclaringClass()->IsInitialized() && is_in_dex_cache; 741 bool is_referrer_class = (referrer_class.Get() == resolved_field->GetDeclaringClass()); 742 743 HLoadClass* constant = new (arena_) HLoadClass(storage_index, is_referrer_class, dex_pc); 744 current_block_->AddInstruction(constant); 745 746 HInstruction* cls = constant; 747 if (!is_initialized && !is_referrer_class) { 748 cls = new (arena_) HClinitCheck(constant, dex_pc); 749 current_block_->AddInstruction(cls); 750 } 751 752 Primitive::Type field_type = resolved_field->GetTypeAsPrimitiveType(); 753 if (is_put) { 754 // We need to keep the class alive before loading the value. 755 Temporaries temps(graph_); 756 temps.Add(cls); 757 HInstruction* value = LoadLocal(source_or_dest_reg, field_type); 758 DCHECK_EQ(value->GetType(), field_type); 759 current_block_->AddInstruction( 760 new (arena_) HStaticFieldSet(cls, value, field_type, resolved_field->GetOffset(), 761 resolved_field->IsVolatile())); 762 } else { 763 current_block_->AddInstruction( 764 new (arena_) HStaticFieldGet(cls, field_type, resolved_field->GetOffset(), 765 resolved_field->IsVolatile())); 766 UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction()); 767 } 768 return true; 769} 770 771void HGraphBuilder::BuildCheckedDivRem(uint16_t out_vreg, 772 uint16_t first_vreg, 773 int64_t second_vreg_or_constant, 774 uint32_t dex_pc, 775 Primitive::Type type, 776 bool second_is_constant, 777 bool isDiv) { 778 DCHECK(type == Primitive::kPrimInt || type == Primitive::kPrimLong); 779 780 HInstruction* first = LoadLocal(first_vreg, type); 781 HInstruction* second = nullptr; 782 if (second_is_constant) { 783 if (type == Primitive::kPrimInt) { 784 second = GetIntConstant(second_vreg_or_constant); 785 } else { 786 second = GetLongConstant(second_vreg_or_constant); 787 } 788 } else { 789 second = LoadLocal(second_vreg_or_constant, type); 790 } 791 792 if (!second_is_constant 793 || (type == Primitive::kPrimInt && second->AsIntConstant()->GetValue() == 0) 794 || (type == Primitive::kPrimLong && second->AsLongConstant()->GetValue() == 0)) { 795 second = new (arena_) HDivZeroCheck(second, dex_pc); 796 Temporaries temps(graph_); 797 current_block_->AddInstruction(second); 798 temps.Add(current_block_->GetLastInstruction()); 799 } 800 801 if (isDiv) { 802 current_block_->AddInstruction(new (arena_) HDiv(type, first, second, dex_pc)); 803 } else { 804 current_block_->AddInstruction(new (arena_) HRem(type, first, second, dex_pc)); 805 } 806 UpdateLocal(out_vreg, current_block_->GetLastInstruction()); 807} 808 809void HGraphBuilder::BuildArrayAccess(const Instruction& instruction, 810 uint32_t dex_pc, 811 bool is_put, 812 Primitive::Type anticipated_type) { 813 uint8_t source_or_dest_reg = instruction.VRegA_23x(); 814 uint8_t array_reg = instruction.VRegB_23x(); 815 uint8_t index_reg = instruction.VRegC_23x(); 816 817 // We need one temporary for the null check, one for the index, and one for the length. 818 Temporaries temps(graph_); 819 820 HInstruction* object = LoadLocal(array_reg, Primitive::kPrimNot); 821 object = new (arena_) HNullCheck(object, dex_pc); 822 current_block_->AddInstruction(object); 823 temps.Add(object); 824 825 HInstruction* length = new (arena_) HArrayLength(object); 826 current_block_->AddInstruction(length); 827 temps.Add(length); 828 HInstruction* index = LoadLocal(index_reg, Primitive::kPrimInt); 829 index = new (arena_) HBoundsCheck(index, length, dex_pc); 830 current_block_->AddInstruction(index); 831 temps.Add(index); 832 if (is_put) { 833 HInstruction* value = LoadLocal(source_or_dest_reg, anticipated_type); 834 // TODO: Insert a type check node if the type is Object. 835 current_block_->AddInstruction(new (arena_) HArraySet( 836 object, index, value, anticipated_type, dex_pc)); 837 } else { 838 current_block_->AddInstruction(new (arena_) HArrayGet(object, index, anticipated_type)); 839 UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction()); 840 } 841} 842 843void HGraphBuilder::BuildFilledNewArray(uint32_t dex_pc, 844 uint32_t type_index, 845 uint32_t number_of_vreg_arguments, 846 bool is_range, 847 uint32_t* args, 848 uint32_t register_index) { 849 HInstruction* length = GetIntConstant(number_of_vreg_arguments); 850 HInstruction* object = new (arena_) HNewArray(length, dex_pc, type_index); 851 current_block_->AddInstruction(object); 852 853 const char* descriptor = dex_file_->StringByTypeIdx(type_index); 854 DCHECK_EQ(descriptor[0], '[') << descriptor; 855 char primitive = descriptor[1]; 856 DCHECK(primitive == 'I' 857 || primitive == 'L' 858 || primitive == '[') << descriptor; 859 bool is_reference_array = (primitive == 'L') || (primitive == '['); 860 Primitive::Type type = is_reference_array ? Primitive::kPrimNot : Primitive::kPrimInt; 861 862 Temporaries temps(graph_); 863 temps.Add(object); 864 for (size_t i = 0; i < number_of_vreg_arguments; ++i) { 865 HInstruction* value = LoadLocal(is_range ? register_index + i : args[i], type); 866 HInstruction* index = GetIntConstant(i); 867 current_block_->AddInstruction( 868 new (arena_) HArraySet(object, index, value, type, dex_pc)); 869 } 870 latest_result_ = object; 871} 872 873template <typename T> 874void HGraphBuilder::BuildFillArrayData(HInstruction* object, 875 const T* data, 876 uint32_t element_count, 877 Primitive::Type anticipated_type, 878 uint32_t dex_pc) { 879 for (uint32_t i = 0; i < element_count; ++i) { 880 HInstruction* index = GetIntConstant(i); 881 HInstruction* value = GetIntConstant(data[i]); 882 current_block_->AddInstruction(new (arena_) HArraySet( 883 object, index, value, anticipated_type, dex_pc)); 884 } 885} 886 887void HGraphBuilder::BuildFillArrayData(const Instruction& instruction, uint32_t dex_pc) { 888 Temporaries temps(graph_); 889 HInstruction* array = LoadLocal(instruction.VRegA_31t(), Primitive::kPrimNot); 890 HNullCheck* null_check = new (arena_) HNullCheck(array, dex_pc); 891 current_block_->AddInstruction(null_check); 892 temps.Add(null_check); 893 894 HInstruction* length = new (arena_) HArrayLength(null_check); 895 current_block_->AddInstruction(length); 896 897 int32_t payload_offset = instruction.VRegB_31t() + dex_pc; 898 const Instruction::ArrayDataPayload* payload = 899 reinterpret_cast<const Instruction::ArrayDataPayload*>(code_start_ + payload_offset); 900 const uint8_t* data = payload->data; 901 uint32_t element_count = payload->element_count; 902 903 // Implementation of this DEX instruction seems to be that the bounds check is 904 // done before doing any stores. 905 HInstruction* last_index = GetIntConstant(payload->element_count - 1); 906 current_block_->AddInstruction(new (arena_) HBoundsCheck(last_index, length, dex_pc)); 907 908 switch (payload->element_width) { 909 case 1: 910 BuildFillArrayData(null_check, 911 reinterpret_cast<const int8_t*>(data), 912 element_count, 913 Primitive::kPrimByte, 914 dex_pc); 915 break; 916 case 2: 917 BuildFillArrayData(null_check, 918 reinterpret_cast<const int16_t*>(data), 919 element_count, 920 Primitive::kPrimShort, 921 dex_pc); 922 break; 923 case 4: 924 BuildFillArrayData(null_check, 925 reinterpret_cast<const int32_t*>(data), 926 element_count, 927 Primitive::kPrimInt, 928 dex_pc); 929 break; 930 case 8: 931 BuildFillWideArrayData(null_check, 932 reinterpret_cast<const int64_t*>(data), 933 element_count, 934 dex_pc); 935 break; 936 default: 937 LOG(FATAL) << "Unknown element width for " << payload->element_width; 938 } 939} 940 941void HGraphBuilder::BuildFillWideArrayData(HInstruction* object, 942 const int64_t* data, 943 uint32_t element_count, 944 uint32_t dex_pc) { 945 for (uint32_t i = 0; i < element_count; ++i) { 946 HInstruction* index = GetIntConstant(i); 947 HInstruction* value = GetLongConstant(data[i]); 948 current_block_->AddInstruction(new (arena_) HArraySet( 949 object, index, value, Primitive::kPrimLong, dex_pc)); 950 } 951} 952 953bool HGraphBuilder::BuildTypeCheck(const Instruction& instruction, 954 uint8_t destination, 955 uint8_t reference, 956 uint16_t type_index, 957 uint32_t dex_pc) { 958 bool type_known_final; 959 bool type_known_abstract; 960 // `CanAccessTypeWithoutChecks` will tell whether the method being 961 // built is trying to access its own class, so that the generated 962 // code can optimize for this case. However, the optimization does not 963 // work for inlining, so we use `IsCompilingClass` instead. 964 bool dont_use_is_referrers_class; 965 bool can_access = compiler_driver_->CanAccessTypeWithoutChecks( 966 dex_compilation_unit_->GetDexMethodIndex(), *dex_file_, type_index, 967 &type_known_final, &type_known_abstract, &dont_use_is_referrers_class); 968 if (!can_access) { 969 MaybeRecordStat(MethodCompilationStat::kNotCompiledCantAccesType); 970 return false; 971 } 972 HInstruction* object = LoadLocal(reference, Primitive::kPrimNot); 973 HLoadClass* cls = new (arena_) HLoadClass(type_index, IsCompilingClass(type_index), dex_pc); 974 current_block_->AddInstruction(cls); 975 // The class needs a temporary before being used by the type check. 976 Temporaries temps(graph_); 977 temps.Add(cls); 978 if (instruction.Opcode() == Instruction::INSTANCE_OF) { 979 current_block_->AddInstruction( 980 new (arena_) HInstanceOf(object, cls, type_known_final, dex_pc)); 981 UpdateLocal(destination, current_block_->GetLastInstruction()); 982 } else { 983 DCHECK_EQ(instruction.Opcode(), Instruction::CHECK_CAST); 984 current_block_->AddInstruction( 985 new (arena_) HCheckCast(object, cls, type_known_final, dex_pc)); 986 } 987 return true; 988} 989 990void HGraphBuilder::BuildPackedSwitch(const Instruction& instruction, uint32_t dex_pc) { 991 SwitchTable table(instruction, dex_pc, false); 992 993 // Value to test against. 994 HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt); 995 996 uint16_t num_entries = table.GetNumEntries(); 997 // There should be at least one entry here. 998 DCHECK_GT(num_entries, 0U); 999 1000 // Chained cmp-and-branch, starting from starting_key. 1001 int32_t starting_key = table.GetEntryAt(0); 1002 1003 for (size_t i = 1; i <= num_entries; i++) { 1004 BuildSwitchCaseHelper(instruction, i, i == num_entries, table, value, starting_key + i - 1, 1005 table.GetEntryAt(i), dex_pc); 1006 } 1007} 1008 1009void HGraphBuilder::BuildSparseSwitch(const Instruction& instruction, uint32_t dex_pc) { 1010 SwitchTable table(instruction, dex_pc, true); 1011 1012 // Value to test against. 1013 HInstruction* value = LoadLocal(instruction.VRegA(), Primitive::kPrimInt); 1014 1015 uint16_t num_entries = table.GetNumEntries(); 1016 // There should be at least one entry here. 1017 DCHECK_GT(num_entries, 0U); 1018 1019 for (size_t i = 0; i < num_entries; i++) { 1020 BuildSwitchCaseHelper(instruction, i, i == static_cast<size_t>(num_entries) - 1, table, value, 1021 table.GetEntryAt(i), table.GetEntryAt(i + num_entries), dex_pc); 1022 } 1023} 1024 1025void HGraphBuilder::BuildSwitchCaseHelper(const Instruction& instruction, size_t index, 1026 bool is_last_case, const SwitchTable& table, 1027 HInstruction* value, int32_t case_value_int, 1028 int32_t target_offset, uint32_t dex_pc) { 1029 PotentiallyAddSuspendCheck(target_offset, dex_pc); 1030 1031 // The current case's value. 1032 HInstruction* this_case_value = GetIntConstant(case_value_int); 1033 1034 // Compare value and this_case_value. 1035 HEqual* comparison = new (arena_) HEqual(value, this_case_value); 1036 current_block_->AddInstruction(comparison); 1037 HInstruction* ifinst = new (arena_) HIf(comparison); 1038 current_block_->AddInstruction(ifinst); 1039 1040 // Case hit: use the target offset to determine where to go. 1041 HBasicBlock* case_target = FindBlockStartingAt(dex_pc + target_offset); 1042 DCHECK(case_target != nullptr); 1043 current_block_->AddSuccessor(case_target); 1044 1045 // Case miss: go to the next case (or default fall-through). 1046 // When there is a next case, we use the block stored with the table offset representing this 1047 // case (that is where we registered them in ComputeBranchTargets). 1048 // When there is no next case, we use the following instruction. 1049 // TODO: Find a good way to peel the last iteration to avoid conditional, but still have re-use. 1050 if (!is_last_case) { 1051 HBasicBlock* next_case_target = FindBlockStartingAt(table.GetDexPcForIndex(index)); 1052 DCHECK(next_case_target != nullptr); 1053 current_block_->AddSuccessor(next_case_target); 1054 1055 // Need to manually add the block, as there is no dex-pc transition for the cases. 1056 graph_->AddBlock(next_case_target); 1057 1058 current_block_ = next_case_target; 1059 } else { 1060 HBasicBlock* default_target = FindBlockStartingAt(dex_pc + instruction.SizeInCodeUnits()); 1061 DCHECK(default_target != nullptr); 1062 current_block_->AddSuccessor(default_target); 1063 current_block_ = nullptr; 1064 } 1065} 1066 1067void HGraphBuilder::PotentiallyAddSuspendCheck(int32_t target_offset, uint32_t dex_pc) { 1068 if (target_offset <= 0) { 1069 // Unconditionnally add a suspend check to backward branches. We can remove 1070 // them after we recognize loops in the graph. 1071 current_block_->AddInstruction(new (arena_) HSuspendCheck(dex_pc)); 1072 } 1073} 1074 1075bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32_t dex_pc) { 1076 if (current_block_ == nullptr) { 1077 return true; // Dead code 1078 } 1079 1080 switch (instruction.Opcode()) { 1081 case Instruction::CONST_4: { 1082 int32_t register_index = instruction.VRegA(); 1083 HIntConstant* constant = GetIntConstant(instruction.VRegB_11n()); 1084 UpdateLocal(register_index, constant); 1085 break; 1086 } 1087 1088 case Instruction::CONST_16: { 1089 int32_t register_index = instruction.VRegA(); 1090 HIntConstant* constant = GetIntConstant(instruction.VRegB_21s()); 1091 UpdateLocal(register_index, constant); 1092 break; 1093 } 1094 1095 case Instruction::CONST: { 1096 int32_t register_index = instruction.VRegA(); 1097 HIntConstant* constant = GetIntConstant(instruction.VRegB_31i()); 1098 UpdateLocal(register_index, constant); 1099 break; 1100 } 1101 1102 case Instruction::CONST_HIGH16: { 1103 int32_t register_index = instruction.VRegA(); 1104 HIntConstant* constant = GetIntConstant(instruction.VRegB_21h() << 16); 1105 UpdateLocal(register_index, constant); 1106 break; 1107 } 1108 1109 case Instruction::CONST_WIDE_16: { 1110 int32_t register_index = instruction.VRegA(); 1111 // Get 16 bits of constant value, sign extended to 64 bits. 1112 int64_t value = instruction.VRegB_21s(); 1113 value <<= 48; 1114 value >>= 48; 1115 HLongConstant* constant = GetLongConstant(value); 1116 UpdateLocal(register_index, constant); 1117 break; 1118 } 1119 1120 case Instruction::CONST_WIDE_32: { 1121 int32_t register_index = instruction.VRegA(); 1122 // Get 32 bits of constant value, sign extended to 64 bits. 1123 int64_t value = instruction.VRegB_31i(); 1124 value <<= 32; 1125 value >>= 32; 1126 HLongConstant* constant = GetLongConstant(value); 1127 UpdateLocal(register_index, constant); 1128 break; 1129 } 1130 1131 case Instruction::CONST_WIDE: { 1132 int32_t register_index = instruction.VRegA(); 1133 HLongConstant* constant = GetLongConstant(instruction.VRegB_51l()); 1134 UpdateLocal(register_index, constant); 1135 break; 1136 } 1137 1138 case Instruction::CONST_WIDE_HIGH16: { 1139 int32_t register_index = instruction.VRegA(); 1140 int64_t value = static_cast<int64_t>(instruction.VRegB_21h()) << 48; 1141 HLongConstant* constant = GetLongConstant(value); 1142 UpdateLocal(register_index, constant); 1143 break; 1144 } 1145 1146 // Note that the SSA building will refine the types. 1147 case Instruction::MOVE: 1148 case Instruction::MOVE_FROM16: 1149 case Instruction::MOVE_16: { 1150 HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimInt); 1151 UpdateLocal(instruction.VRegA(), value); 1152 break; 1153 } 1154 1155 // Note that the SSA building will refine the types. 1156 case Instruction::MOVE_WIDE: 1157 case Instruction::MOVE_WIDE_FROM16: 1158 case Instruction::MOVE_WIDE_16: { 1159 HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimLong); 1160 UpdateLocal(instruction.VRegA(), value); 1161 break; 1162 } 1163 1164 case Instruction::MOVE_OBJECT: 1165 case Instruction::MOVE_OBJECT_16: 1166 case Instruction::MOVE_OBJECT_FROM16: { 1167 HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimNot); 1168 UpdateLocal(instruction.VRegA(), value); 1169 break; 1170 } 1171 1172 case Instruction::RETURN_VOID: { 1173 BuildReturn(instruction, Primitive::kPrimVoid); 1174 break; 1175 } 1176 1177#define IF_XX(comparison, cond) \ 1178 case Instruction::IF_##cond: If_22t<comparison>(instruction, dex_pc); break; \ 1179 case Instruction::IF_##cond##Z: If_21t<comparison>(instruction, dex_pc); break 1180 1181 IF_XX(HEqual, EQ); 1182 IF_XX(HNotEqual, NE); 1183 IF_XX(HLessThan, LT); 1184 IF_XX(HLessThanOrEqual, LE); 1185 IF_XX(HGreaterThan, GT); 1186 IF_XX(HGreaterThanOrEqual, GE); 1187 1188 case Instruction::GOTO: 1189 case Instruction::GOTO_16: 1190 case Instruction::GOTO_32: { 1191 int32_t offset = instruction.GetTargetOffset(); 1192 PotentiallyAddSuspendCheck(offset, dex_pc); 1193 HBasicBlock* target = FindBlockStartingAt(offset + dex_pc); 1194 DCHECK(target != nullptr); 1195 current_block_->AddInstruction(new (arena_) HGoto()); 1196 current_block_->AddSuccessor(target); 1197 current_block_ = nullptr; 1198 break; 1199 } 1200 1201 case Instruction::RETURN: { 1202 DCHECK_NE(return_type_, Primitive::kPrimNot); 1203 DCHECK_NE(return_type_, Primitive::kPrimLong); 1204 DCHECK_NE(return_type_, Primitive::kPrimDouble); 1205 BuildReturn(instruction, return_type_); 1206 break; 1207 } 1208 1209 case Instruction::RETURN_OBJECT: { 1210 DCHECK(return_type_ == Primitive::kPrimNot); 1211 BuildReturn(instruction, return_type_); 1212 break; 1213 } 1214 1215 case Instruction::RETURN_WIDE: { 1216 DCHECK(return_type_ == Primitive::kPrimDouble || return_type_ == Primitive::kPrimLong); 1217 BuildReturn(instruction, return_type_); 1218 break; 1219 } 1220 1221 case Instruction::INVOKE_DIRECT: 1222 case Instruction::INVOKE_INTERFACE: 1223 case Instruction::INVOKE_STATIC: 1224 case Instruction::INVOKE_SUPER: 1225 case Instruction::INVOKE_VIRTUAL: { 1226 uint32_t method_idx = instruction.VRegB_35c(); 1227 uint32_t number_of_vreg_arguments = instruction.VRegA_35c(); 1228 uint32_t args[5]; 1229 instruction.GetVarArgs(args); 1230 if (!BuildInvoke(instruction, dex_pc, method_idx, 1231 number_of_vreg_arguments, false, args, -1)) { 1232 return false; 1233 } 1234 break; 1235 } 1236 1237 case Instruction::INVOKE_DIRECT_RANGE: 1238 case Instruction::INVOKE_INTERFACE_RANGE: 1239 case Instruction::INVOKE_STATIC_RANGE: 1240 case Instruction::INVOKE_SUPER_RANGE: 1241 case Instruction::INVOKE_VIRTUAL_RANGE: { 1242 uint32_t method_idx = instruction.VRegB_3rc(); 1243 uint32_t number_of_vreg_arguments = instruction.VRegA_3rc(); 1244 uint32_t register_index = instruction.VRegC(); 1245 if (!BuildInvoke(instruction, dex_pc, method_idx, 1246 number_of_vreg_arguments, true, nullptr, register_index)) { 1247 return false; 1248 } 1249 break; 1250 } 1251 1252 case Instruction::NEG_INT: { 1253 Unop_12x<HNeg>(instruction, Primitive::kPrimInt); 1254 break; 1255 } 1256 1257 case Instruction::NEG_LONG: { 1258 Unop_12x<HNeg>(instruction, Primitive::kPrimLong); 1259 break; 1260 } 1261 1262 case Instruction::NEG_FLOAT: { 1263 Unop_12x<HNeg>(instruction, Primitive::kPrimFloat); 1264 break; 1265 } 1266 1267 case Instruction::NEG_DOUBLE: { 1268 Unop_12x<HNeg>(instruction, Primitive::kPrimDouble); 1269 break; 1270 } 1271 1272 case Instruction::NOT_INT: { 1273 Unop_12x<HNot>(instruction, Primitive::kPrimInt); 1274 break; 1275 } 1276 1277 case Instruction::NOT_LONG: { 1278 Unop_12x<HNot>(instruction, Primitive::kPrimLong); 1279 break; 1280 } 1281 1282 case Instruction::INT_TO_LONG: { 1283 Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimLong, dex_pc); 1284 break; 1285 } 1286 1287 case Instruction::INT_TO_FLOAT: { 1288 Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimFloat, dex_pc); 1289 break; 1290 } 1291 1292 case Instruction::INT_TO_DOUBLE: { 1293 Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimDouble, dex_pc); 1294 break; 1295 } 1296 1297 case Instruction::LONG_TO_INT: { 1298 Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimInt, dex_pc); 1299 break; 1300 } 1301 1302 case Instruction::LONG_TO_FLOAT: { 1303 Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimFloat, dex_pc); 1304 break; 1305 } 1306 1307 case Instruction::LONG_TO_DOUBLE: { 1308 Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimDouble, dex_pc); 1309 break; 1310 } 1311 1312 case Instruction::FLOAT_TO_INT: { 1313 Conversion_12x(instruction, Primitive::kPrimFloat, Primitive::kPrimInt, dex_pc); 1314 break; 1315 } 1316 1317 case Instruction::FLOAT_TO_LONG: { 1318 Conversion_12x(instruction, Primitive::kPrimFloat, Primitive::kPrimLong, dex_pc); 1319 break; 1320 } 1321 1322 case Instruction::FLOAT_TO_DOUBLE: { 1323 Conversion_12x(instruction, Primitive::kPrimFloat, Primitive::kPrimDouble, dex_pc); 1324 break; 1325 } 1326 1327 case Instruction::DOUBLE_TO_INT: { 1328 Conversion_12x(instruction, Primitive::kPrimDouble, Primitive::kPrimInt, dex_pc); 1329 break; 1330 } 1331 1332 case Instruction::DOUBLE_TO_LONG: { 1333 Conversion_12x(instruction, Primitive::kPrimDouble, Primitive::kPrimLong, dex_pc); 1334 break; 1335 } 1336 1337 case Instruction::DOUBLE_TO_FLOAT: { 1338 Conversion_12x(instruction, Primitive::kPrimDouble, Primitive::kPrimFloat, dex_pc); 1339 break; 1340 } 1341 1342 case Instruction::INT_TO_BYTE: { 1343 Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimByte, dex_pc); 1344 break; 1345 } 1346 1347 case Instruction::INT_TO_SHORT: { 1348 Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimShort, dex_pc); 1349 break; 1350 } 1351 1352 case Instruction::INT_TO_CHAR: { 1353 Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimChar, dex_pc); 1354 break; 1355 } 1356 1357 case Instruction::ADD_INT: { 1358 Binop_23x<HAdd>(instruction, Primitive::kPrimInt); 1359 break; 1360 } 1361 1362 case Instruction::ADD_LONG: { 1363 Binop_23x<HAdd>(instruction, Primitive::kPrimLong); 1364 break; 1365 } 1366 1367 case Instruction::ADD_DOUBLE: { 1368 Binop_23x<HAdd>(instruction, Primitive::kPrimDouble); 1369 break; 1370 } 1371 1372 case Instruction::ADD_FLOAT: { 1373 Binop_23x<HAdd>(instruction, Primitive::kPrimFloat); 1374 break; 1375 } 1376 1377 case Instruction::SUB_INT: { 1378 Binop_23x<HSub>(instruction, Primitive::kPrimInt); 1379 break; 1380 } 1381 1382 case Instruction::SUB_LONG: { 1383 Binop_23x<HSub>(instruction, Primitive::kPrimLong); 1384 break; 1385 } 1386 1387 case Instruction::SUB_FLOAT: { 1388 Binop_23x<HSub>(instruction, Primitive::kPrimFloat); 1389 break; 1390 } 1391 1392 case Instruction::SUB_DOUBLE: { 1393 Binop_23x<HSub>(instruction, Primitive::kPrimDouble); 1394 break; 1395 } 1396 1397 case Instruction::ADD_INT_2ADDR: { 1398 Binop_12x<HAdd>(instruction, Primitive::kPrimInt); 1399 break; 1400 } 1401 1402 case Instruction::MUL_INT: { 1403 Binop_23x<HMul>(instruction, Primitive::kPrimInt); 1404 break; 1405 } 1406 1407 case Instruction::MUL_LONG: { 1408 Binop_23x<HMul>(instruction, Primitive::kPrimLong); 1409 break; 1410 } 1411 1412 case Instruction::MUL_FLOAT: { 1413 Binop_23x<HMul>(instruction, Primitive::kPrimFloat); 1414 break; 1415 } 1416 1417 case Instruction::MUL_DOUBLE: { 1418 Binop_23x<HMul>(instruction, Primitive::kPrimDouble); 1419 break; 1420 } 1421 1422 case Instruction::DIV_INT: { 1423 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(), 1424 dex_pc, Primitive::kPrimInt, false, true); 1425 break; 1426 } 1427 1428 case Instruction::DIV_LONG: { 1429 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(), 1430 dex_pc, Primitive::kPrimLong, false, true); 1431 break; 1432 } 1433 1434 case Instruction::DIV_FLOAT: { 1435 Binop_23x<HDiv>(instruction, Primitive::kPrimFloat, dex_pc); 1436 break; 1437 } 1438 1439 case Instruction::DIV_DOUBLE: { 1440 Binop_23x<HDiv>(instruction, Primitive::kPrimDouble, dex_pc); 1441 break; 1442 } 1443 1444 case Instruction::REM_INT: { 1445 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(), 1446 dex_pc, Primitive::kPrimInt, false, false); 1447 break; 1448 } 1449 1450 case Instruction::REM_LONG: { 1451 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(), 1452 dex_pc, Primitive::kPrimLong, false, false); 1453 break; 1454 } 1455 1456 case Instruction::REM_FLOAT: { 1457 Binop_23x<HRem>(instruction, Primitive::kPrimFloat, dex_pc); 1458 break; 1459 } 1460 1461 case Instruction::REM_DOUBLE: { 1462 Binop_23x<HRem>(instruction, Primitive::kPrimDouble, dex_pc); 1463 break; 1464 } 1465 1466 case Instruction::AND_INT: { 1467 Binop_23x<HAnd>(instruction, Primitive::kPrimInt); 1468 break; 1469 } 1470 1471 case Instruction::AND_LONG: { 1472 Binop_23x<HAnd>(instruction, Primitive::kPrimLong); 1473 break; 1474 } 1475 1476 case Instruction::SHL_INT: { 1477 Binop_23x_shift<HShl>(instruction, Primitive::kPrimInt); 1478 break; 1479 } 1480 1481 case Instruction::SHL_LONG: { 1482 Binop_23x_shift<HShl>(instruction, Primitive::kPrimLong); 1483 break; 1484 } 1485 1486 case Instruction::SHR_INT: { 1487 Binop_23x_shift<HShr>(instruction, Primitive::kPrimInt); 1488 break; 1489 } 1490 1491 case Instruction::SHR_LONG: { 1492 Binop_23x_shift<HShr>(instruction, Primitive::kPrimLong); 1493 break; 1494 } 1495 1496 case Instruction::USHR_INT: { 1497 Binop_23x_shift<HUShr>(instruction, Primitive::kPrimInt); 1498 break; 1499 } 1500 1501 case Instruction::USHR_LONG: { 1502 Binop_23x_shift<HUShr>(instruction, Primitive::kPrimLong); 1503 break; 1504 } 1505 1506 case Instruction::OR_INT: { 1507 Binop_23x<HOr>(instruction, Primitive::kPrimInt); 1508 break; 1509 } 1510 1511 case Instruction::OR_LONG: { 1512 Binop_23x<HOr>(instruction, Primitive::kPrimLong); 1513 break; 1514 } 1515 1516 case Instruction::XOR_INT: { 1517 Binop_23x<HXor>(instruction, Primitive::kPrimInt); 1518 break; 1519 } 1520 1521 case Instruction::XOR_LONG: { 1522 Binop_23x<HXor>(instruction, Primitive::kPrimLong); 1523 break; 1524 } 1525 1526 case Instruction::ADD_LONG_2ADDR: { 1527 Binop_12x<HAdd>(instruction, Primitive::kPrimLong); 1528 break; 1529 } 1530 1531 case Instruction::ADD_DOUBLE_2ADDR: { 1532 Binop_12x<HAdd>(instruction, Primitive::kPrimDouble); 1533 break; 1534 } 1535 1536 case Instruction::ADD_FLOAT_2ADDR: { 1537 Binop_12x<HAdd>(instruction, Primitive::kPrimFloat); 1538 break; 1539 } 1540 1541 case Instruction::SUB_INT_2ADDR: { 1542 Binop_12x<HSub>(instruction, Primitive::kPrimInt); 1543 break; 1544 } 1545 1546 case Instruction::SUB_LONG_2ADDR: { 1547 Binop_12x<HSub>(instruction, Primitive::kPrimLong); 1548 break; 1549 } 1550 1551 case Instruction::SUB_FLOAT_2ADDR: { 1552 Binop_12x<HSub>(instruction, Primitive::kPrimFloat); 1553 break; 1554 } 1555 1556 case Instruction::SUB_DOUBLE_2ADDR: { 1557 Binop_12x<HSub>(instruction, Primitive::kPrimDouble); 1558 break; 1559 } 1560 1561 case Instruction::MUL_INT_2ADDR: { 1562 Binop_12x<HMul>(instruction, Primitive::kPrimInt); 1563 break; 1564 } 1565 1566 case Instruction::MUL_LONG_2ADDR: { 1567 Binop_12x<HMul>(instruction, Primitive::kPrimLong); 1568 break; 1569 } 1570 1571 case Instruction::MUL_FLOAT_2ADDR: { 1572 Binop_12x<HMul>(instruction, Primitive::kPrimFloat); 1573 break; 1574 } 1575 1576 case Instruction::MUL_DOUBLE_2ADDR: { 1577 Binop_12x<HMul>(instruction, Primitive::kPrimDouble); 1578 break; 1579 } 1580 1581 case Instruction::DIV_INT_2ADDR: { 1582 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(), 1583 dex_pc, Primitive::kPrimInt, false, true); 1584 break; 1585 } 1586 1587 case Instruction::DIV_LONG_2ADDR: { 1588 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(), 1589 dex_pc, Primitive::kPrimLong, false, true); 1590 break; 1591 } 1592 1593 case Instruction::REM_INT_2ADDR: { 1594 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(), 1595 dex_pc, Primitive::kPrimInt, false, false); 1596 break; 1597 } 1598 1599 case Instruction::REM_LONG_2ADDR: { 1600 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegA(), instruction.VRegB(), 1601 dex_pc, Primitive::kPrimLong, false, false); 1602 break; 1603 } 1604 1605 case Instruction::REM_FLOAT_2ADDR: { 1606 Binop_12x<HRem>(instruction, Primitive::kPrimFloat, dex_pc); 1607 break; 1608 } 1609 1610 case Instruction::REM_DOUBLE_2ADDR: { 1611 Binop_12x<HRem>(instruction, Primitive::kPrimDouble, dex_pc); 1612 break; 1613 } 1614 1615 case Instruction::SHL_INT_2ADDR: { 1616 Binop_12x_shift<HShl>(instruction, Primitive::kPrimInt); 1617 break; 1618 } 1619 1620 case Instruction::SHL_LONG_2ADDR: { 1621 Binop_12x_shift<HShl>(instruction, Primitive::kPrimLong); 1622 break; 1623 } 1624 1625 case Instruction::SHR_INT_2ADDR: { 1626 Binop_12x_shift<HShr>(instruction, Primitive::kPrimInt); 1627 break; 1628 } 1629 1630 case Instruction::SHR_LONG_2ADDR: { 1631 Binop_12x_shift<HShr>(instruction, Primitive::kPrimLong); 1632 break; 1633 } 1634 1635 case Instruction::USHR_INT_2ADDR: { 1636 Binop_12x_shift<HUShr>(instruction, Primitive::kPrimInt); 1637 break; 1638 } 1639 1640 case Instruction::USHR_LONG_2ADDR: { 1641 Binop_12x_shift<HUShr>(instruction, Primitive::kPrimLong); 1642 break; 1643 } 1644 1645 case Instruction::DIV_FLOAT_2ADDR: { 1646 Binop_12x<HDiv>(instruction, Primitive::kPrimFloat, dex_pc); 1647 break; 1648 } 1649 1650 case Instruction::DIV_DOUBLE_2ADDR: { 1651 Binop_12x<HDiv>(instruction, Primitive::kPrimDouble, dex_pc); 1652 break; 1653 } 1654 1655 case Instruction::AND_INT_2ADDR: { 1656 Binop_12x<HAnd>(instruction, Primitive::kPrimInt); 1657 break; 1658 } 1659 1660 case Instruction::AND_LONG_2ADDR: { 1661 Binop_12x<HAnd>(instruction, Primitive::kPrimLong); 1662 break; 1663 } 1664 1665 case Instruction::OR_INT_2ADDR: { 1666 Binop_12x<HOr>(instruction, Primitive::kPrimInt); 1667 break; 1668 } 1669 1670 case Instruction::OR_LONG_2ADDR: { 1671 Binop_12x<HOr>(instruction, Primitive::kPrimLong); 1672 break; 1673 } 1674 1675 case Instruction::XOR_INT_2ADDR: { 1676 Binop_12x<HXor>(instruction, Primitive::kPrimInt); 1677 break; 1678 } 1679 1680 case Instruction::XOR_LONG_2ADDR: { 1681 Binop_12x<HXor>(instruction, Primitive::kPrimLong); 1682 break; 1683 } 1684 1685 case Instruction::ADD_INT_LIT16: { 1686 Binop_22s<HAdd>(instruction, false); 1687 break; 1688 } 1689 1690 case Instruction::AND_INT_LIT16: { 1691 Binop_22s<HAnd>(instruction, false); 1692 break; 1693 } 1694 1695 case Instruction::OR_INT_LIT16: { 1696 Binop_22s<HOr>(instruction, false); 1697 break; 1698 } 1699 1700 case Instruction::XOR_INT_LIT16: { 1701 Binop_22s<HXor>(instruction, false); 1702 break; 1703 } 1704 1705 case Instruction::RSUB_INT: { 1706 Binop_22s<HSub>(instruction, true); 1707 break; 1708 } 1709 1710 case Instruction::MUL_INT_LIT16: { 1711 Binop_22s<HMul>(instruction, false); 1712 break; 1713 } 1714 1715 case Instruction::ADD_INT_LIT8: { 1716 Binop_22b<HAdd>(instruction, false); 1717 break; 1718 } 1719 1720 case Instruction::AND_INT_LIT8: { 1721 Binop_22b<HAnd>(instruction, false); 1722 break; 1723 } 1724 1725 case Instruction::OR_INT_LIT8: { 1726 Binop_22b<HOr>(instruction, false); 1727 break; 1728 } 1729 1730 case Instruction::XOR_INT_LIT8: { 1731 Binop_22b<HXor>(instruction, false); 1732 break; 1733 } 1734 1735 case Instruction::RSUB_INT_LIT8: { 1736 Binop_22b<HSub>(instruction, true); 1737 break; 1738 } 1739 1740 case Instruction::MUL_INT_LIT8: { 1741 Binop_22b<HMul>(instruction, false); 1742 break; 1743 } 1744 1745 case Instruction::DIV_INT_LIT16: 1746 case Instruction::DIV_INT_LIT8: { 1747 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(), 1748 dex_pc, Primitive::kPrimInt, true, true); 1749 break; 1750 } 1751 1752 case Instruction::REM_INT_LIT16: 1753 case Instruction::REM_INT_LIT8: { 1754 BuildCheckedDivRem(instruction.VRegA(), instruction.VRegB(), instruction.VRegC(), 1755 dex_pc, Primitive::kPrimInt, true, false); 1756 break; 1757 } 1758 1759 case Instruction::SHL_INT_LIT8: { 1760 Binop_22b<HShl>(instruction, false); 1761 break; 1762 } 1763 1764 case Instruction::SHR_INT_LIT8: { 1765 Binop_22b<HShr>(instruction, false); 1766 break; 1767 } 1768 1769 case Instruction::USHR_INT_LIT8: { 1770 Binop_22b<HUShr>(instruction, false); 1771 break; 1772 } 1773 1774 case Instruction::NEW_INSTANCE: { 1775 current_block_->AddInstruction( 1776 new (arena_) HNewInstance(dex_pc, instruction.VRegB_21c())); 1777 UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); 1778 break; 1779 } 1780 1781 case Instruction::NEW_ARRAY: { 1782 HInstruction* length = LoadLocal(instruction.VRegB_22c(), Primitive::kPrimInt); 1783 current_block_->AddInstruction( 1784 new (arena_) HNewArray(length, dex_pc, instruction.VRegC_22c())); 1785 UpdateLocal(instruction.VRegA_22c(), current_block_->GetLastInstruction()); 1786 break; 1787 } 1788 1789 case Instruction::FILLED_NEW_ARRAY: { 1790 uint32_t number_of_vreg_arguments = instruction.VRegA_35c(); 1791 uint32_t type_index = instruction.VRegB_35c(); 1792 uint32_t args[5]; 1793 instruction.GetVarArgs(args); 1794 BuildFilledNewArray(dex_pc, type_index, number_of_vreg_arguments, false, args, 0); 1795 break; 1796 } 1797 1798 case Instruction::FILLED_NEW_ARRAY_RANGE: { 1799 uint32_t number_of_vreg_arguments = instruction.VRegA_3rc(); 1800 uint32_t type_index = instruction.VRegB_3rc(); 1801 uint32_t register_index = instruction.VRegC_3rc(); 1802 BuildFilledNewArray( 1803 dex_pc, type_index, number_of_vreg_arguments, true, nullptr, register_index); 1804 break; 1805 } 1806 1807 case Instruction::FILL_ARRAY_DATA: { 1808 BuildFillArrayData(instruction, dex_pc); 1809 break; 1810 } 1811 1812 case Instruction::MOVE_RESULT: 1813 case Instruction::MOVE_RESULT_WIDE: 1814 case Instruction::MOVE_RESULT_OBJECT: 1815 UpdateLocal(instruction.VRegA(), latest_result_); 1816 latest_result_ = nullptr; 1817 break; 1818 1819 case Instruction::CMP_LONG: { 1820 Binop_23x_cmp(instruction, Primitive::kPrimLong, HCompare::kNoBias); 1821 break; 1822 } 1823 1824 case Instruction::CMPG_FLOAT: { 1825 Binop_23x_cmp(instruction, Primitive::kPrimFloat, HCompare::kGtBias); 1826 break; 1827 } 1828 1829 case Instruction::CMPG_DOUBLE: { 1830 Binop_23x_cmp(instruction, Primitive::kPrimDouble, HCompare::kGtBias); 1831 break; 1832 } 1833 1834 case Instruction::CMPL_FLOAT: { 1835 Binop_23x_cmp(instruction, Primitive::kPrimFloat, HCompare::kLtBias); 1836 break; 1837 } 1838 1839 case Instruction::CMPL_DOUBLE: { 1840 Binop_23x_cmp(instruction, Primitive::kPrimDouble, HCompare::kLtBias); 1841 break; 1842 } 1843 1844 case Instruction::NOP: 1845 break; 1846 1847 case Instruction::IGET: 1848 case Instruction::IGET_WIDE: 1849 case Instruction::IGET_OBJECT: 1850 case Instruction::IGET_BOOLEAN: 1851 case Instruction::IGET_BYTE: 1852 case Instruction::IGET_CHAR: 1853 case Instruction::IGET_SHORT: { 1854 if (!BuildInstanceFieldAccess(instruction, dex_pc, false)) { 1855 return false; 1856 } 1857 break; 1858 } 1859 1860 case Instruction::IPUT: 1861 case Instruction::IPUT_WIDE: 1862 case Instruction::IPUT_OBJECT: 1863 case Instruction::IPUT_BOOLEAN: 1864 case Instruction::IPUT_BYTE: 1865 case Instruction::IPUT_CHAR: 1866 case Instruction::IPUT_SHORT: { 1867 if (!BuildInstanceFieldAccess(instruction, dex_pc, true)) { 1868 return false; 1869 } 1870 break; 1871 } 1872 1873 case Instruction::SGET: 1874 case Instruction::SGET_WIDE: 1875 case Instruction::SGET_OBJECT: 1876 case Instruction::SGET_BOOLEAN: 1877 case Instruction::SGET_BYTE: 1878 case Instruction::SGET_CHAR: 1879 case Instruction::SGET_SHORT: { 1880 if (!BuildStaticFieldAccess(instruction, dex_pc, false)) { 1881 return false; 1882 } 1883 break; 1884 } 1885 1886 case Instruction::SPUT: 1887 case Instruction::SPUT_WIDE: 1888 case Instruction::SPUT_OBJECT: 1889 case Instruction::SPUT_BOOLEAN: 1890 case Instruction::SPUT_BYTE: 1891 case Instruction::SPUT_CHAR: 1892 case Instruction::SPUT_SHORT: { 1893 if (!BuildStaticFieldAccess(instruction, dex_pc, true)) { 1894 return false; 1895 } 1896 break; 1897 } 1898 1899#define ARRAY_XX(kind, anticipated_type) \ 1900 case Instruction::AGET##kind: { \ 1901 BuildArrayAccess(instruction, dex_pc, false, anticipated_type); \ 1902 break; \ 1903 } \ 1904 case Instruction::APUT##kind: { \ 1905 BuildArrayAccess(instruction, dex_pc, true, anticipated_type); \ 1906 break; \ 1907 } 1908 1909 ARRAY_XX(, Primitive::kPrimInt); 1910 ARRAY_XX(_WIDE, Primitive::kPrimLong); 1911 ARRAY_XX(_OBJECT, Primitive::kPrimNot); 1912 ARRAY_XX(_BOOLEAN, Primitive::kPrimBoolean); 1913 ARRAY_XX(_BYTE, Primitive::kPrimByte); 1914 ARRAY_XX(_CHAR, Primitive::kPrimChar); 1915 ARRAY_XX(_SHORT, Primitive::kPrimShort); 1916 1917 case Instruction::ARRAY_LENGTH: { 1918 HInstruction* object = LoadLocal(instruction.VRegB_12x(), Primitive::kPrimNot); 1919 // No need for a temporary for the null check, it is the only input of the following 1920 // instruction. 1921 object = new (arena_) HNullCheck(object, dex_pc); 1922 current_block_->AddInstruction(object); 1923 current_block_->AddInstruction(new (arena_) HArrayLength(object)); 1924 UpdateLocal(instruction.VRegA_12x(), current_block_->GetLastInstruction()); 1925 break; 1926 } 1927 1928 case Instruction::CONST_STRING: { 1929 current_block_->AddInstruction(new (arena_) HLoadString(instruction.VRegB_21c(), dex_pc)); 1930 UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction()); 1931 break; 1932 } 1933 1934 case Instruction::CONST_STRING_JUMBO: { 1935 current_block_->AddInstruction(new (arena_) HLoadString(instruction.VRegB_31c(), dex_pc)); 1936 UpdateLocal(instruction.VRegA_31c(), current_block_->GetLastInstruction()); 1937 break; 1938 } 1939 1940 case Instruction::CONST_CLASS: { 1941 uint16_t type_index = instruction.VRegB_21c(); 1942 bool type_known_final; 1943 bool type_known_abstract; 1944 bool dont_use_is_referrers_class; 1945 // `CanAccessTypeWithoutChecks` will tell whether the method being 1946 // built is trying to access its own class, so that the generated 1947 // code can optimize for this case. However, the optimization does not 1948 // work for inlining, so we use `IsCompilingClass` instead. 1949 bool can_access = compiler_driver_->CanAccessTypeWithoutChecks( 1950 dex_compilation_unit_->GetDexMethodIndex(), *dex_file_, type_index, 1951 &type_known_final, &type_known_abstract, &dont_use_is_referrers_class); 1952 if (!can_access) { 1953 MaybeRecordStat(MethodCompilationStat::kNotCompiledCantAccesType); 1954 return false; 1955 } 1956 current_block_->AddInstruction( 1957 new (arena_) HLoadClass(type_index, IsCompilingClass(type_index), dex_pc)); 1958 UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction()); 1959 break; 1960 } 1961 1962 case Instruction::MOVE_EXCEPTION: { 1963 current_block_->AddInstruction(new (arena_) HLoadException()); 1964 UpdateLocal(instruction.VRegA_11x(), current_block_->GetLastInstruction()); 1965 break; 1966 } 1967 1968 case Instruction::THROW: { 1969 HInstruction* exception = LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot); 1970 current_block_->AddInstruction(new (arena_) HThrow(exception, dex_pc)); 1971 // A throw instruction must branch to the exit block. 1972 current_block_->AddSuccessor(exit_block_); 1973 // We finished building this block. Set the current block to null to avoid 1974 // adding dead instructions to it. 1975 current_block_ = nullptr; 1976 break; 1977 } 1978 1979 case Instruction::INSTANCE_OF: { 1980 uint8_t destination = instruction.VRegA_22c(); 1981 uint8_t reference = instruction.VRegB_22c(); 1982 uint16_t type_index = instruction.VRegC_22c(); 1983 if (!BuildTypeCheck(instruction, destination, reference, type_index, dex_pc)) { 1984 return false; 1985 } 1986 break; 1987 } 1988 1989 case Instruction::CHECK_CAST: { 1990 uint8_t reference = instruction.VRegA_21c(); 1991 uint16_t type_index = instruction.VRegB_21c(); 1992 if (!BuildTypeCheck(instruction, -1, reference, type_index, dex_pc)) { 1993 return false; 1994 } 1995 break; 1996 } 1997 1998 case Instruction::MONITOR_ENTER: { 1999 current_block_->AddInstruction(new (arena_) HMonitorOperation( 2000 LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot), 2001 HMonitorOperation::kEnter, 2002 dex_pc)); 2003 break; 2004 } 2005 2006 case Instruction::MONITOR_EXIT: { 2007 current_block_->AddInstruction(new (arena_) HMonitorOperation( 2008 LoadLocal(instruction.VRegA_11x(), Primitive::kPrimNot), 2009 HMonitorOperation::kExit, 2010 dex_pc)); 2011 break; 2012 } 2013 2014 case Instruction::PACKED_SWITCH: { 2015 BuildPackedSwitch(instruction, dex_pc); 2016 break; 2017 } 2018 2019 case Instruction::SPARSE_SWITCH: { 2020 BuildSparseSwitch(instruction, dex_pc); 2021 break; 2022 } 2023 2024 default: 2025 VLOG(compiler) << "Did not compile " 2026 << PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_) 2027 << " because of unhandled instruction " 2028 << instruction.Name(); 2029 MaybeRecordStat(MethodCompilationStat::kNotCompiledUnhandledInstruction); 2030 return false; 2031 } 2032 return true; 2033} // NOLINT(readability/fn_size) 2034 2035HIntConstant* HGraphBuilder::GetIntConstant0() { 2036 if (constant0_ != nullptr) { 2037 return constant0_; 2038 } 2039 constant0_ = new(arena_) HIntConstant(0); 2040 entry_block_->AddInstruction(constant0_); 2041 return constant0_; 2042} 2043 2044HIntConstant* HGraphBuilder::GetIntConstant1() { 2045 if (constant1_ != nullptr) { 2046 return constant1_; 2047 } 2048 constant1_ = new(arena_) HIntConstant(1); 2049 entry_block_->AddInstruction(constant1_); 2050 return constant1_; 2051} 2052 2053HIntConstant* HGraphBuilder::GetIntConstant(int32_t constant) { 2054 switch (constant) { 2055 case 0: return GetIntConstant0(); 2056 case 1: return GetIntConstant1(); 2057 default: { 2058 HIntConstant* instruction = new (arena_) HIntConstant(constant); 2059 entry_block_->AddInstruction(instruction); 2060 return instruction; 2061 } 2062 } 2063} 2064 2065HLongConstant* HGraphBuilder::GetLongConstant(int64_t constant) { 2066 HLongConstant* instruction = new (arena_) HLongConstant(constant); 2067 entry_block_->AddInstruction(instruction); 2068 return instruction; 2069} 2070 2071HLocal* HGraphBuilder::GetLocalAt(int register_index) const { 2072 return locals_.Get(register_index); 2073} 2074 2075void HGraphBuilder::UpdateLocal(int register_index, HInstruction* instruction) const { 2076 HLocal* local = GetLocalAt(register_index); 2077 current_block_->AddInstruction(new (arena_) HStoreLocal(local, instruction)); 2078} 2079 2080HInstruction* HGraphBuilder::LoadLocal(int register_index, Primitive::Type type) const { 2081 HLocal* local = GetLocalAt(register_index); 2082 current_block_->AddInstruction(new (arena_) HLoadLocal(local, type)); 2083 return current_block_->GetLastInstruction(); 2084} 2085 2086} // namespace art 2087