Home | History | Annotate | Download | only in optimizing
      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 "code_generator.h"
     18 
     19 #ifdef ART_ENABLE_CODEGEN_arm
     20 #include "code_generator_arm.h"
     21 #endif
     22 
     23 #ifdef ART_ENABLE_CODEGEN_arm64
     24 #include "code_generator_arm64.h"
     25 #endif
     26 
     27 #ifdef ART_ENABLE_CODEGEN_x86
     28 #include "code_generator_x86.h"
     29 #endif
     30 
     31 #ifdef ART_ENABLE_CODEGEN_x86_64
     32 #include "code_generator_x86_64.h"
     33 #endif
     34 
     35 #ifdef ART_ENABLE_CODEGEN_mips
     36 #include "code_generator_mips.h"
     37 #endif
     38 
     39 #ifdef ART_ENABLE_CODEGEN_mips64
     40 #include "code_generator_mips64.h"
     41 #endif
     42 
     43 #include "bytecode_utils.h"
     44 #include "compiled_method.h"
     45 #include "dex/verified_method.h"
     46 #include "driver/compiler_driver.h"
     47 #include "graph_visualizer.h"
     48 #include "intrinsics.h"
     49 #include "leb128.h"
     50 #include "mirror/array-inl.h"
     51 #include "mirror/object_array-inl.h"
     52 #include "mirror/object_reference.h"
     53 #include "parallel_move_resolver.h"
     54 #include "ssa_liveness_analysis.h"
     55 #include "utils/assembler.h"
     56 
     57 namespace art {
     58 
     59 // Return whether a location is consistent with a type.
     60 static bool CheckType(Primitive::Type type, Location location) {
     61   if (location.IsFpuRegister()
     62       || (location.IsUnallocated() && (location.GetPolicy() == Location::kRequiresFpuRegister))) {
     63     return (type == Primitive::kPrimFloat) || (type == Primitive::kPrimDouble);
     64   } else if (location.IsRegister() ||
     65              (location.IsUnallocated() && (location.GetPolicy() == Location::kRequiresRegister))) {
     66     return Primitive::IsIntegralType(type) || (type == Primitive::kPrimNot);
     67   } else if (location.IsRegisterPair()) {
     68     return type == Primitive::kPrimLong;
     69   } else if (location.IsFpuRegisterPair()) {
     70     return type == Primitive::kPrimDouble;
     71   } else if (location.IsStackSlot()) {
     72     return (Primitive::IsIntegralType(type) && type != Primitive::kPrimLong)
     73            || (type == Primitive::kPrimFloat)
     74            || (type == Primitive::kPrimNot);
     75   } else if (location.IsDoubleStackSlot()) {
     76     return (type == Primitive::kPrimLong) || (type == Primitive::kPrimDouble);
     77   } else if (location.IsConstant()) {
     78     if (location.GetConstant()->IsIntConstant()) {
     79       return Primitive::IsIntegralType(type) && (type != Primitive::kPrimLong);
     80     } else if (location.GetConstant()->IsNullConstant()) {
     81       return type == Primitive::kPrimNot;
     82     } else if (location.GetConstant()->IsLongConstant()) {
     83       return type == Primitive::kPrimLong;
     84     } else if (location.GetConstant()->IsFloatConstant()) {
     85       return type == Primitive::kPrimFloat;
     86     } else {
     87       return location.GetConstant()->IsDoubleConstant()
     88           && (type == Primitive::kPrimDouble);
     89     }
     90   } else {
     91     return location.IsInvalid() || (location.GetPolicy() == Location::kAny);
     92   }
     93 }
     94 
     95 // Check that a location summary is consistent with an instruction.
     96 static bool CheckTypeConsistency(HInstruction* instruction) {
     97   LocationSummary* locations = instruction->GetLocations();
     98   if (locations == nullptr) {
     99     return true;
    100   }
    101 
    102   if (locations->Out().IsUnallocated()
    103       && (locations->Out().GetPolicy() == Location::kSameAsFirstInput)) {
    104     DCHECK(CheckType(instruction->GetType(), locations->InAt(0)))
    105         << instruction->GetType()
    106         << " " << locations->InAt(0);
    107   } else {
    108     DCHECK(CheckType(instruction->GetType(), locations->Out()))
    109         << instruction->GetType()
    110         << " " << locations->Out();
    111   }
    112 
    113   for (size_t i = 0, e = instruction->InputCount(); i < e; ++i) {
    114     DCHECK(CheckType(instruction->InputAt(i)->GetType(), locations->InAt(i)))
    115       << instruction->InputAt(i)->GetType()
    116       << " " << locations->InAt(i);
    117   }
    118 
    119   HEnvironment* environment = instruction->GetEnvironment();
    120   for (size_t i = 0; i < instruction->EnvironmentSize(); ++i) {
    121     if (environment->GetInstructionAt(i) != nullptr) {
    122       Primitive::Type type = environment->GetInstructionAt(i)->GetType();
    123       DCHECK(CheckType(type, environment->GetLocationAt(i)))
    124         << type << " " << environment->GetLocationAt(i);
    125     } else {
    126       DCHECK(environment->GetLocationAt(i).IsInvalid())
    127         << environment->GetLocationAt(i);
    128     }
    129   }
    130   return true;
    131 }
    132 
    133 size_t CodeGenerator::GetCacheOffset(uint32_t index) {
    134   return sizeof(GcRoot<mirror::Object>) * index;
    135 }
    136 
    137 size_t CodeGenerator::GetCachePointerOffset(uint32_t index) {
    138   auto pointer_size = InstructionSetPointerSize(GetInstructionSet());
    139   return pointer_size * index;
    140 }
    141 
    142 bool CodeGenerator::GoesToNextBlock(HBasicBlock* current, HBasicBlock* next) const {
    143   DCHECK_EQ((*block_order_)[current_block_index_], current);
    144   return GetNextBlockToEmit() == FirstNonEmptyBlock(next);
    145 }
    146 
    147 HBasicBlock* CodeGenerator::GetNextBlockToEmit() const {
    148   for (size_t i = current_block_index_ + 1; i < block_order_->size(); ++i) {
    149     HBasicBlock* block = (*block_order_)[i];
    150     if (!block->IsSingleJump()) {
    151       return block;
    152     }
    153   }
    154   return nullptr;
    155 }
    156 
    157 HBasicBlock* CodeGenerator::FirstNonEmptyBlock(HBasicBlock* block) const {
    158   while (block->IsSingleJump()) {
    159     block = block->GetSuccessors()[0];
    160   }
    161   return block;
    162 }
    163 
    164 class DisassemblyScope {
    165  public:
    166   DisassemblyScope(HInstruction* instruction, const CodeGenerator& codegen)
    167       : codegen_(codegen), instruction_(instruction), start_offset_(static_cast<size_t>(-1)) {
    168     if (codegen_.GetDisassemblyInformation() != nullptr) {
    169       start_offset_ = codegen_.GetAssembler().CodeSize();
    170     }
    171   }
    172 
    173   ~DisassemblyScope() {
    174     // We avoid building this data when we know it will not be used.
    175     if (codegen_.GetDisassemblyInformation() != nullptr) {
    176       codegen_.GetDisassemblyInformation()->AddInstructionInterval(
    177           instruction_, start_offset_, codegen_.GetAssembler().CodeSize());
    178     }
    179   }
    180 
    181  private:
    182   const CodeGenerator& codegen_;
    183   HInstruction* instruction_;
    184   size_t start_offset_;
    185 };
    186 
    187 
    188 void CodeGenerator::GenerateSlowPaths() {
    189   size_t code_start = 0;
    190   for (const std::unique_ptr<SlowPathCode>& slow_path_unique_ptr : slow_paths_) {
    191     SlowPathCode* slow_path = slow_path_unique_ptr.get();
    192     current_slow_path_ = slow_path;
    193     if (disasm_info_ != nullptr) {
    194       code_start = GetAssembler()->CodeSize();
    195     }
    196     // Record the dex pc at start of slow path (required for java line number mapping).
    197     MaybeRecordNativeDebugInfo(slow_path->GetInstruction(), slow_path->GetDexPc(), slow_path);
    198     slow_path->EmitNativeCode(this);
    199     if (disasm_info_ != nullptr) {
    200       disasm_info_->AddSlowPathInterval(slow_path, code_start, GetAssembler()->CodeSize());
    201     }
    202   }
    203   current_slow_path_ = nullptr;
    204 }
    205 
    206 void CodeGenerator::Compile(CodeAllocator* allocator) {
    207   // The register allocator already called `InitializeCodeGeneration`,
    208   // where the frame size has been computed.
    209   DCHECK(block_order_ != nullptr);
    210   Initialize();
    211 
    212   HGraphVisitor* instruction_visitor = GetInstructionVisitor();
    213   DCHECK_EQ(current_block_index_, 0u);
    214 
    215   size_t frame_start = GetAssembler()->CodeSize();
    216   GenerateFrameEntry();
    217   DCHECK_EQ(GetAssembler()->cfi().GetCurrentCFAOffset(), static_cast<int>(frame_size_));
    218   if (disasm_info_ != nullptr) {
    219     disasm_info_->SetFrameEntryInterval(frame_start, GetAssembler()->CodeSize());
    220   }
    221 
    222   for (size_t e = block_order_->size(); current_block_index_ < e; ++current_block_index_) {
    223     HBasicBlock* block = (*block_order_)[current_block_index_];
    224     // Don't generate code for an empty block. Its predecessors will branch to its successor
    225     // directly. Also, the label of that block will not be emitted, so this helps catch
    226     // errors where we reference that label.
    227     if (block->IsSingleJump()) continue;
    228     Bind(block);
    229     // This ensures that we have correct native line mapping for all native instructions.
    230     // It is necessary to make stepping over a statement work. Otherwise, any initial
    231     // instructions (e.g. moves) would be assumed to be the start of next statement.
    232     MaybeRecordNativeDebugInfo(nullptr /* instruction */, block->GetDexPc());
    233     for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) {
    234       HInstruction* current = it.Current();
    235       if (current->HasEnvironment()) {
    236         // Create stackmap for HNativeDebugInfo or any instruction which calls native code.
    237         // Note that we need correct mapping for the native PC of the call instruction,
    238         // so the runtime's stackmap is not sufficient since it is at PC after the call.
    239         MaybeRecordNativeDebugInfo(current, block->GetDexPc());
    240       }
    241       DisassemblyScope disassembly_scope(current, *this);
    242       DCHECK(CheckTypeConsistency(current));
    243       current->Accept(instruction_visitor);
    244     }
    245   }
    246 
    247   GenerateSlowPaths();
    248 
    249   // Emit catch stack maps at the end of the stack map stream as expected by the
    250   // runtime exception handler.
    251   if (graph_->HasTryCatch()) {
    252     RecordCatchBlockInfo();
    253   }
    254 
    255   // Finalize instructions in assember;
    256   Finalize(allocator);
    257 }
    258 
    259 void CodeGenerator::Finalize(CodeAllocator* allocator) {
    260   size_t code_size = GetAssembler()->CodeSize();
    261   uint8_t* buffer = allocator->Allocate(code_size);
    262 
    263   MemoryRegion code(buffer, code_size);
    264   GetAssembler()->FinalizeInstructions(code);
    265 }
    266 
    267 void CodeGenerator::EmitLinkerPatches(ArenaVector<LinkerPatch>* linker_patches ATTRIBUTE_UNUSED) {
    268   // No linker patches by default.
    269 }
    270 
    271 void CodeGenerator::InitializeCodeGeneration(size_t number_of_spill_slots,
    272                                              size_t maximum_number_of_live_core_registers,
    273                                              size_t maximum_number_of_live_fpu_registers,
    274                                              size_t number_of_out_slots,
    275                                              const ArenaVector<HBasicBlock*>& block_order) {
    276   block_order_ = &block_order;
    277   DCHECK(!block_order.empty());
    278   DCHECK(block_order[0] == GetGraph()->GetEntryBlock());
    279   ComputeSpillMask();
    280   first_register_slot_in_slow_path_ = (number_of_out_slots + number_of_spill_slots) * kVRegSize;
    281 
    282   if (number_of_spill_slots == 0
    283       && !HasAllocatedCalleeSaveRegisters()
    284       && IsLeafMethod()
    285       && !RequiresCurrentMethod()) {
    286     DCHECK_EQ(maximum_number_of_live_core_registers, 0u);
    287     DCHECK_EQ(maximum_number_of_live_fpu_registers, 0u);
    288     SetFrameSize(CallPushesPC() ? GetWordSize() : 0);
    289   } else {
    290     SetFrameSize(RoundUp(
    291         number_of_spill_slots * kVRegSize
    292         + number_of_out_slots * kVRegSize
    293         + maximum_number_of_live_core_registers * GetWordSize()
    294         + maximum_number_of_live_fpu_registers * GetFloatingPointSpillSlotSize()
    295         + FrameEntrySpillSize(),
    296         kStackAlignment));
    297   }
    298 }
    299 
    300 void CodeGenerator::CreateCommonInvokeLocationSummary(
    301     HInvoke* invoke, InvokeDexCallingConventionVisitor* visitor) {
    302   ArenaAllocator* allocator = invoke->GetBlock()->GetGraph()->GetArena();
    303   LocationSummary* locations = new (allocator) LocationSummary(invoke, LocationSummary::kCall);
    304 
    305   for (size_t i = 0; i < invoke->GetNumberOfArguments(); i++) {
    306     HInstruction* input = invoke->InputAt(i);
    307     locations->SetInAt(i, visitor->GetNextLocation(input->GetType()));
    308   }
    309 
    310   locations->SetOut(visitor->GetReturnLocation(invoke->GetType()));
    311 
    312   if (invoke->IsInvokeStaticOrDirect()) {
    313     HInvokeStaticOrDirect* call = invoke->AsInvokeStaticOrDirect();
    314     switch (call->GetMethodLoadKind()) {
    315       case HInvokeStaticOrDirect::MethodLoadKind::kRecursive:
    316         locations->SetInAt(call->GetSpecialInputIndex(), visitor->GetMethodLocation());
    317         break;
    318       case HInvokeStaticOrDirect::MethodLoadKind::kDexCacheViaMethod:
    319         locations->AddTemp(visitor->GetMethodLocation());
    320         locations->SetInAt(call->GetSpecialInputIndex(), Location::RequiresRegister());
    321         break;
    322       default:
    323         locations->AddTemp(visitor->GetMethodLocation());
    324         break;
    325     }
    326   } else {
    327     locations->AddTemp(visitor->GetMethodLocation());
    328   }
    329 }
    330 
    331 void CodeGenerator::GenerateInvokeUnresolvedRuntimeCall(HInvokeUnresolved* invoke) {
    332   MoveConstant(invoke->GetLocations()->GetTemp(0), invoke->GetDexMethodIndex());
    333 
    334   // Initialize to anything to silent compiler warnings.
    335   QuickEntrypointEnum entrypoint = kQuickInvokeStaticTrampolineWithAccessCheck;
    336   switch (invoke->GetOriginalInvokeType()) {
    337     case kStatic:
    338       entrypoint = kQuickInvokeStaticTrampolineWithAccessCheck;
    339       break;
    340     case kDirect:
    341       entrypoint = kQuickInvokeDirectTrampolineWithAccessCheck;
    342       break;
    343     case kVirtual:
    344       entrypoint = kQuickInvokeVirtualTrampolineWithAccessCheck;
    345       break;
    346     case kSuper:
    347       entrypoint = kQuickInvokeSuperTrampolineWithAccessCheck;
    348       break;
    349     case kInterface:
    350       entrypoint = kQuickInvokeInterfaceTrampolineWithAccessCheck;
    351       break;
    352   }
    353   InvokeRuntime(entrypoint, invoke, invoke->GetDexPc(), nullptr);
    354 }
    355 
    356 void CodeGenerator::CreateUnresolvedFieldLocationSummary(
    357     HInstruction* field_access,
    358     Primitive::Type field_type,
    359     const FieldAccessCallingConvention& calling_convention) {
    360   bool is_instance = field_access->IsUnresolvedInstanceFieldGet()
    361       || field_access->IsUnresolvedInstanceFieldSet();
    362   bool is_get = field_access->IsUnresolvedInstanceFieldGet()
    363       || field_access->IsUnresolvedStaticFieldGet();
    364 
    365   ArenaAllocator* allocator = field_access->GetBlock()->GetGraph()->GetArena();
    366   LocationSummary* locations =
    367       new (allocator) LocationSummary(field_access, LocationSummary::kCall);
    368 
    369   locations->AddTemp(calling_convention.GetFieldIndexLocation());
    370 
    371   if (is_instance) {
    372     // Add the `this` object for instance field accesses.
    373     locations->SetInAt(0, calling_convention.GetObjectLocation());
    374   }
    375 
    376   // Note that pSetXXStatic/pGetXXStatic always takes/returns an int or int64
    377   // regardless of the the type. Because of that we forced to special case
    378   // the access to floating point values.
    379   if (is_get) {
    380     if (Primitive::IsFloatingPointType(field_type)) {
    381       // The return value will be stored in regular registers while register
    382       // allocator expects it in a floating point register.
    383       // Note We don't need to request additional temps because the return
    384       // register(s) are already blocked due the call and they may overlap with
    385       // the input or field index.
    386       // The transfer between the two will be done at codegen level.
    387       locations->SetOut(calling_convention.GetFpuLocation(field_type));
    388     } else {
    389       locations->SetOut(calling_convention.GetReturnLocation(field_type));
    390     }
    391   } else {
    392      size_t set_index = is_instance ? 1 : 0;
    393      if (Primitive::IsFloatingPointType(field_type)) {
    394       // The set value comes from a float location while the calling convention
    395       // expects it in a regular register location. Allocate a temp for it and
    396       // make the transfer at codegen.
    397       AddLocationAsTemp(calling_convention.GetSetValueLocation(field_type, is_instance), locations);
    398       locations->SetInAt(set_index, calling_convention.GetFpuLocation(field_type));
    399     } else {
    400       locations->SetInAt(set_index,
    401           calling_convention.GetSetValueLocation(field_type, is_instance));
    402     }
    403   }
    404 }
    405 
    406 void CodeGenerator::GenerateUnresolvedFieldAccess(
    407     HInstruction* field_access,
    408     Primitive::Type field_type,
    409     uint32_t field_index,
    410     uint32_t dex_pc,
    411     const FieldAccessCallingConvention& calling_convention) {
    412   LocationSummary* locations = field_access->GetLocations();
    413 
    414   MoveConstant(locations->GetTemp(0), field_index);
    415 
    416   bool is_instance = field_access->IsUnresolvedInstanceFieldGet()
    417       || field_access->IsUnresolvedInstanceFieldSet();
    418   bool is_get = field_access->IsUnresolvedInstanceFieldGet()
    419       || field_access->IsUnresolvedStaticFieldGet();
    420 
    421   if (!is_get && Primitive::IsFloatingPointType(field_type)) {
    422     // Copy the float value to be set into the calling convention register.
    423     // Note that using directly the temp location is problematic as we don't
    424     // support temp register pairs. To avoid boilerplate conversion code, use
    425     // the location from the calling convention.
    426     MoveLocation(calling_convention.GetSetValueLocation(field_type, is_instance),
    427                  locations->InAt(is_instance ? 1 : 0),
    428                  (Primitive::Is64BitType(field_type) ? Primitive::kPrimLong : Primitive::kPrimInt));
    429   }
    430 
    431   QuickEntrypointEnum entrypoint = kQuickSet8Static;  // Initialize to anything to avoid warnings.
    432   switch (field_type) {
    433     case Primitive::kPrimBoolean:
    434       entrypoint = is_instance
    435           ? (is_get ? kQuickGetBooleanInstance : kQuickSet8Instance)
    436           : (is_get ? kQuickGetBooleanStatic : kQuickSet8Static);
    437       break;
    438     case Primitive::kPrimByte:
    439       entrypoint = is_instance
    440           ? (is_get ? kQuickGetByteInstance : kQuickSet8Instance)
    441           : (is_get ? kQuickGetByteStatic : kQuickSet8Static);
    442       break;
    443     case Primitive::kPrimShort:
    444       entrypoint = is_instance
    445           ? (is_get ? kQuickGetShortInstance : kQuickSet16Instance)
    446           : (is_get ? kQuickGetShortStatic : kQuickSet16Static);
    447       break;
    448     case Primitive::kPrimChar:
    449       entrypoint = is_instance
    450           ? (is_get ? kQuickGetCharInstance : kQuickSet16Instance)
    451           : (is_get ? kQuickGetCharStatic : kQuickSet16Static);
    452       break;
    453     case Primitive::kPrimInt:
    454     case Primitive::kPrimFloat:
    455       entrypoint = is_instance
    456           ? (is_get ? kQuickGet32Instance : kQuickSet32Instance)
    457           : (is_get ? kQuickGet32Static : kQuickSet32Static);
    458       break;
    459     case Primitive::kPrimNot:
    460       entrypoint = is_instance
    461           ? (is_get ? kQuickGetObjInstance : kQuickSetObjInstance)
    462           : (is_get ? kQuickGetObjStatic : kQuickSetObjStatic);
    463       break;
    464     case Primitive::kPrimLong:
    465     case Primitive::kPrimDouble:
    466       entrypoint = is_instance
    467           ? (is_get ? kQuickGet64Instance : kQuickSet64Instance)
    468           : (is_get ? kQuickGet64Static : kQuickSet64Static);
    469       break;
    470     default:
    471       LOG(FATAL) << "Invalid type " << field_type;
    472   }
    473   InvokeRuntime(entrypoint, field_access, dex_pc, nullptr);
    474 
    475   if (is_get && Primitive::IsFloatingPointType(field_type)) {
    476     MoveLocation(locations->Out(), calling_convention.GetReturnLocation(field_type), field_type);
    477   }
    478 }
    479 
    480 // TODO: Remove argument `code_generator_supports_read_barrier` when
    481 // all code generators have read barrier support.
    482 void CodeGenerator::CreateLoadClassLocationSummary(HLoadClass* cls,
    483                                                    Location runtime_type_index_location,
    484                                                    Location runtime_return_location,
    485                                                    bool code_generator_supports_read_barrier) {
    486   ArenaAllocator* allocator = cls->GetBlock()->GetGraph()->GetArena();
    487   LocationSummary::CallKind call_kind = cls->NeedsAccessCheck()
    488       ? LocationSummary::kCall
    489       : (((code_generator_supports_read_barrier && kEmitCompilerReadBarrier) ||
    490           cls->CanCallRuntime())
    491             ? LocationSummary::kCallOnSlowPath
    492             : LocationSummary::kNoCall);
    493   LocationSummary* locations = new (allocator) LocationSummary(cls, call_kind);
    494   if (cls->NeedsAccessCheck()) {
    495     locations->SetInAt(0, Location::NoLocation());
    496     locations->AddTemp(runtime_type_index_location);
    497     locations->SetOut(runtime_return_location);
    498   } else {
    499     locations->SetInAt(0, Location::RequiresRegister());
    500     locations->SetOut(Location::RequiresRegister());
    501   }
    502 }
    503 
    504 
    505 void CodeGenerator::BlockIfInRegister(Location location, bool is_out) const {
    506   // The DCHECKS below check that a register is not specified twice in
    507   // the summary. The out location can overlap with an input, so we need
    508   // to special case it.
    509   if (location.IsRegister()) {
    510     DCHECK(is_out || !blocked_core_registers_[location.reg()]);
    511     blocked_core_registers_[location.reg()] = true;
    512   } else if (location.IsFpuRegister()) {
    513     DCHECK(is_out || !blocked_fpu_registers_[location.reg()]);
    514     blocked_fpu_registers_[location.reg()] = true;
    515   } else if (location.IsFpuRegisterPair()) {
    516     DCHECK(is_out || !blocked_fpu_registers_[location.AsFpuRegisterPairLow<int>()]);
    517     blocked_fpu_registers_[location.AsFpuRegisterPairLow<int>()] = true;
    518     DCHECK(is_out || !blocked_fpu_registers_[location.AsFpuRegisterPairHigh<int>()]);
    519     blocked_fpu_registers_[location.AsFpuRegisterPairHigh<int>()] = true;
    520   } else if (location.IsRegisterPair()) {
    521     DCHECK(is_out || !blocked_core_registers_[location.AsRegisterPairLow<int>()]);
    522     blocked_core_registers_[location.AsRegisterPairLow<int>()] = true;
    523     DCHECK(is_out || !blocked_core_registers_[location.AsRegisterPairHigh<int>()]);
    524     blocked_core_registers_[location.AsRegisterPairHigh<int>()] = true;
    525   }
    526 }
    527 
    528 void CodeGenerator::AllocateLocations(HInstruction* instruction) {
    529   instruction->Accept(GetLocationBuilder());
    530   DCHECK(CheckTypeConsistency(instruction));
    531   LocationSummary* locations = instruction->GetLocations();
    532   if (!instruction->IsSuspendCheckEntry()) {
    533     if (locations != nullptr) {
    534       if (locations->CanCall()) {
    535         MarkNotLeaf();
    536       } else if (locations->Intrinsified() &&
    537                  instruction->IsInvokeStaticOrDirect() &&
    538                  !instruction->AsInvokeStaticOrDirect()->HasCurrentMethodInput()) {
    539         // A static method call that has been fully intrinsified, and cannot call on the slow
    540         // path or refer to the current method directly, no longer needs current method.
    541         return;
    542       }
    543     }
    544     if (instruction->NeedsCurrentMethod()) {
    545       SetRequiresCurrentMethod();
    546     }
    547   }
    548 }
    549 
    550 void CodeGenerator::MaybeRecordStat(MethodCompilationStat compilation_stat, size_t count) const {
    551   if (stats_ != nullptr) {
    552     stats_->RecordStat(compilation_stat, count);
    553   }
    554 }
    555 
    556 std::unique_ptr<CodeGenerator> CodeGenerator::Create(HGraph* graph,
    557                                                      InstructionSet instruction_set,
    558                                                      const InstructionSetFeatures& isa_features,
    559                                                      const CompilerOptions& compiler_options,
    560                                                      OptimizingCompilerStats* stats) {
    561   ArenaAllocator* arena = graph->GetArena();
    562   switch (instruction_set) {
    563 #ifdef ART_ENABLE_CODEGEN_arm
    564     case kArm:
    565     case kThumb2: {
    566       return std::unique_ptr<CodeGenerator>(
    567           new (arena) arm::CodeGeneratorARM(graph,
    568                                             *isa_features.AsArmInstructionSetFeatures(),
    569                                             compiler_options,
    570                                             stats));
    571     }
    572 #endif
    573 #ifdef ART_ENABLE_CODEGEN_arm64
    574     case kArm64: {
    575       return std::unique_ptr<CodeGenerator>(
    576           new (arena) arm64::CodeGeneratorARM64(graph,
    577                                                 *isa_features.AsArm64InstructionSetFeatures(),
    578                                                 compiler_options,
    579                                                 stats));
    580     }
    581 #endif
    582 #ifdef ART_ENABLE_CODEGEN_mips
    583     case kMips: {
    584       return std::unique_ptr<CodeGenerator>(
    585           new (arena) mips::CodeGeneratorMIPS(graph,
    586                                               *isa_features.AsMipsInstructionSetFeatures(),
    587                                               compiler_options,
    588                                               stats));
    589     }
    590 #endif
    591 #ifdef ART_ENABLE_CODEGEN_mips64
    592     case kMips64: {
    593       return std::unique_ptr<CodeGenerator>(
    594           new (arena) mips64::CodeGeneratorMIPS64(graph,
    595                                                   *isa_features.AsMips64InstructionSetFeatures(),
    596                                                   compiler_options,
    597                                                   stats));
    598     }
    599 #endif
    600 #ifdef ART_ENABLE_CODEGEN_x86
    601     case kX86: {
    602       return std::unique_ptr<CodeGenerator>(
    603           new (arena) x86::CodeGeneratorX86(graph,
    604                                             *isa_features.AsX86InstructionSetFeatures(),
    605                                             compiler_options,
    606                                             stats));
    607     }
    608 #endif
    609 #ifdef ART_ENABLE_CODEGEN_x86_64
    610     case kX86_64: {
    611       return std::unique_ptr<CodeGenerator>(
    612           new (arena) x86_64::CodeGeneratorX86_64(graph,
    613                                                   *isa_features.AsX86_64InstructionSetFeatures(),
    614                                                   compiler_options,
    615                                                   stats));
    616     }
    617 #endif
    618     default:
    619       return nullptr;
    620   }
    621 }
    622 
    623 size_t CodeGenerator::ComputeStackMapsSize() {
    624   return stack_map_stream_.PrepareForFillIn();
    625 }
    626 
    627 static void CheckCovers(uint32_t dex_pc,
    628                         const HGraph& graph,
    629                         const CodeInfo& code_info,
    630                         const ArenaVector<HSuspendCheck*>& loop_headers,
    631                         ArenaVector<size_t>* covered) {
    632   CodeInfoEncoding encoding = code_info.ExtractEncoding();
    633   for (size_t i = 0; i < loop_headers.size(); ++i) {
    634     if (loop_headers[i]->GetDexPc() == dex_pc) {
    635       if (graph.IsCompilingOsr()) {
    636         DCHECK(code_info.GetOsrStackMapForDexPc(dex_pc, encoding).IsValid());
    637       }
    638       ++(*covered)[i];
    639     }
    640   }
    641 }
    642 
    643 // Debug helper to ensure loop entries in compiled code are matched by
    644 // dex branch instructions.
    645 static void CheckLoopEntriesCanBeUsedForOsr(const HGraph& graph,
    646                                             const CodeInfo& code_info,
    647                                             const DexFile::CodeItem& code_item) {
    648   if (graph.HasTryCatch()) {
    649     // One can write loops through try/catch, which we do not support for OSR anyway.
    650     return;
    651   }
    652   ArenaVector<HSuspendCheck*> loop_headers(graph.GetArena()->Adapter(kArenaAllocMisc));
    653   for (HReversePostOrderIterator it(graph); !it.Done(); it.Advance()) {
    654     if (it.Current()->IsLoopHeader()) {
    655       HSuspendCheck* suspend_check = it.Current()->GetLoopInformation()->GetSuspendCheck();
    656       if (!suspend_check->GetEnvironment()->IsFromInlinedInvoke()) {
    657         loop_headers.push_back(suspend_check);
    658       }
    659     }
    660   }
    661   ArenaVector<size_t> covered(loop_headers.size(), 0, graph.GetArena()->Adapter(kArenaAllocMisc));
    662   const uint16_t* code_ptr = code_item.insns_;
    663   const uint16_t* code_end = code_item.insns_ + code_item.insns_size_in_code_units_;
    664 
    665   size_t dex_pc = 0;
    666   while (code_ptr < code_end) {
    667     const Instruction& instruction = *Instruction::At(code_ptr);
    668     if (instruction.IsBranch()) {
    669       uint32_t target = dex_pc + instruction.GetTargetOffset();
    670       CheckCovers(target, graph, code_info, loop_headers, &covered);
    671     } else if (instruction.IsSwitch()) {
    672       DexSwitchTable table(instruction, dex_pc);
    673       uint16_t num_entries = table.GetNumEntries();
    674       size_t offset = table.GetFirstValueIndex();
    675 
    676       // Use a larger loop counter type to avoid overflow issues.
    677       for (size_t i = 0; i < num_entries; ++i) {
    678         // The target of the case.
    679         uint32_t target = dex_pc + table.GetEntryAt(i + offset);
    680         CheckCovers(target, graph, code_info, loop_headers, &covered);
    681       }
    682     }
    683     dex_pc += instruction.SizeInCodeUnits();
    684     code_ptr += instruction.SizeInCodeUnits();
    685   }
    686 
    687   for (size_t i = 0; i < covered.size(); ++i) {
    688     DCHECK_NE(covered[i], 0u) << "Loop in compiled code has no dex branch equivalent";
    689   }
    690 }
    691 
    692 void CodeGenerator::BuildStackMaps(MemoryRegion region, const DexFile::CodeItem& code_item) {
    693   stack_map_stream_.FillIn(region);
    694   if (kIsDebugBuild) {
    695     CheckLoopEntriesCanBeUsedForOsr(*graph_, CodeInfo(region), code_item);
    696   }
    697 }
    698 
    699 void CodeGenerator::RecordPcInfo(HInstruction* instruction,
    700                                  uint32_t dex_pc,
    701                                  SlowPathCode* slow_path) {
    702   if (instruction != nullptr) {
    703     // The code generated for some type conversions
    704     // may call the runtime, thus normally requiring a subsequent
    705     // call to this method. However, the method verifier does not
    706     // produce PC information for certain instructions, which are
    707     // considered "atomic" (they cannot join a GC).
    708     // Therefore we do not currently record PC information for such
    709     // instructions.  As this may change later, we added this special
    710     // case so that code generators may nevertheless call
    711     // CodeGenerator::RecordPcInfo without triggering an error in
    712     // CodeGenerator::BuildNativeGCMap ("Missing ref for dex pc 0x")
    713     // thereafter.
    714     if (instruction->IsTypeConversion()) {
    715       return;
    716     }
    717     if (instruction->IsRem()) {
    718       Primitive::Type type = instruction->AsRem()->GetResultType();
    719       if ((type == Primitive::kPrimFloat) || (type == Primitive::kPrimDouble)) {
    720         return;
    721       }
    722     }
    723   }
    724 
    725   uint32_t outer_dex_pc = dex_pc;
    726   uint32_t outer_environment_size = 0;
    727   uint32_t inlining_depth = 0;
    728   if (instruction != nullptr) {
    729     for (HEnvironment* environment = instruction->GetEnvironment();
    730          environment != nullptr;
    731          environment = environment->GetParent()) {
    732       outer_dex_pc = environment->GetDexPc();
    733       outer_environment_size = environment->Size();
    734       if (environment != instruction->GetEnvironment()) {
    735         inlining_depth++;
    736       }
    737     }
    738   }
    739 
    740   // Collect PC infos for the mapping table.
    741   uint32_t native_pc = GetAssembler()->CodeSize();
    742 
    743   if (instruction == nullptr) {
    744     // For stack overflow checks and native-debug-info entries without dex register
    745     // mapping (i.e. start of basic block or start of slow path).
    746     stack_map_stream_.BeginStackMapEntry(outer_dex_pc, native_pc, 0, 0, 0, 0);
    747     stack_map_stream_.EndStackMapEntry();
    748     return;
    749   }
    750   LocationSummary* locations = instruction->GetLocations();
    751 
    752   uint32_t register_mask = locations->GetRegisterMask();
    753   if (locations->OnlyCallsOnSlowPath()) {
    754     // In case of slow path, we currently set the location of caller-save registers
    755     // to register (instead of their stack location when pushed before the slow-path
    756     // call). Therefore register_mask contains both callee-save and caller-save
    757     // registers that hold objects. We must remove the caller-save from the mask, since
    758     // they will be overwritten by the callee.
    759     register_mask &= core_callee_save_mask_;
    760   }
    761   // The register mask must be a subset of callee-save registers.
    762   DCHECK_EQ(register_mask & core_callee_save_mask_, register_mask);
    763   stack_map_stream_.BeginStackMapEntry(outer_dex_pc,
    764                                        native_pc,
    765                                        register_mask,
    766                                        locations->GetStackMask(),
    767                                        outer_environment_size,
    768                                        inlining_depth);
    769 
    770   EmitEnvironment(instruction->GetEnvironment(), slow_path);
    771   stack_map_stream_.EndStackMapEntry();
    772 
    773   HLoopInformation* info = instruction->GetBlock()->GetLoopInformation();
    774   if (instruction->IsSuspendCheck() &&
    775       (info != nullptr) &&
    776       graph_->IsCompilingOsr() &&
    777       (inlining_depth == 0)) {
    778     DCHECK_EQ(info->GetSuspendCheck(), instruction);
    779     // We duplicate the stack map as a marker that this stack map can be an OSR entry.
    780     // Duplicating it avoids having the runtime recognize and skip an OSR stack map.
    781     DCHECK(info->IsIrreducible());
    782     stack_map_stream_.BeginStackMapEntry(
    783         dex_pc, native_pc, register_mask, locations->GetStackMask(), outer_environment_size, 0);
    784     EmitEnvironment(instruction->GetEnvironment(), slow_path);
    785     stack_map_stream_.EndStackMapEntry();
    786     if (kIsDebugBuild) {
    787       HEnvironment* environment = instruction->GetEnvironment();
    788       for (size_t i = 0, environment_size = environment->Size(); i < environment_size; ++i) {
    789         HInstruction* in_environment = environment->GetInstructionAt(i);
    790         if (in_environment != nullptr) {
    791           DCHECK(in_environment->IsPhi() || in_environment->IsConstant());
    792           Location location = environment->GetLocationAt(i);
    793           DCHECK(location.IsStackSlot() ||
    794                  location.IsDoubleStackSlot() ||
    795                  location.IsConstant() ||
    796                  location.IsInvalid());
    797           if (location.IsStackSlot() || location.IsDoubleStackSlot()) {
    798             DCHECK_LT(location.GetStackIndex(), static_cast<int32_t>(GetFrameSize()));
    799           }
    800         }
    801       }
    802     }
    803   } else if (kIsDebugBuild) {
    804     // Ensure stack maps are unique, by checking that the native pc in the stack map
    805     // last emitted is different than the native pc of the stack map just emitted.
    806     size_t number_of_stack_maps = stack_map_stream_.GetNumberOfStackMaps();
    807     if (number_of_stack_maps > 1) {
    808       DCHECK_NE(stack_map_stream_.GetStackMap(number_of_stack_maps - 1).native_pc_offset,
    809                 stack_map_stream_.GetStackMap(number_of_stack_maps - 2).native_pc_offset);
    810     }
    811   }
    812 }
    813 
    814 bool CodeGenerator::HasStackMapAtCurrentPc() {
    815   uint32_t pc = GetAssembler()->CodeSize();
    816   size_t count = stack_map_stream_.GetNumberOfStackMaps();
    817   return count > 0 && stack_map_stream_.GetStackMap(count - 1).native_pc_offset == pc;
    818 }
    819 
    820 void CodeGenerator::MaybeRecordNativeDebugInfo(HInstruction* instruction,
    821                                                uint32_t dex_pc,
    822                                                SlowPathCode* slow_path) {
    823   if (GetCompilerOptions().GetNativeDebuggable() && dex_pc != kNoDexPc) {
    824     if (HasStackMapAtCurrentPc()) {
    825       // Ensure that we do not collide with the stack map of the previous instruction.
    826       GenerateNop();
    827     }
    828     RecordPcInfo(instruction, dex_pc, slow_path);
    829   }
    830 }
    831 
    832 void CodeGenerator::RecordCatchBlockInfo() {
    833   ArenaAllocator* arena = graph_->GetArena();
    834 
    835   for (HBasicBlock* block : *block_order_) {
    836     if (!block->IsCatchBlock()) {
    837       continue;
    838     }
    839 
    840     uint32_t dex_pc = block->GetDexPc();
    841     uint32_t num_vregs = graph_->GetNumberOfVRegs();
    842     uint32_t inlining_depth = 0;  // Inlining of catch blocks is not supported at the moment.
    843     uint32_t native_pc = GetAddressOf(block);
    844     uint32_t register_mask = 0;   // Not used.
    845 
    846     // The stack mask is not used, so we leave it empty.
    847     ArenaBitVector* stack_mask =
    848         ArenaBitVector::Create(arena, 0, /* expandable */ true, kArenaAllocCodeGenerator);
    849 
    850     stack_map_stream_.BeginStackMapEntry(dex_pc,
    851                                          native_pc,
    852                                          register_mask,
    853                                          stack_mask,
    854                                          num_vregs,
    855                                          inlining_depth);
    856 
    857     HInstruction* current_phi = block->GetFirstPhi();
    858     for (size_t vreg = 0; vreg < num_vregs; ++vreg) {
    859     while (current_phi != nullptr && current_phi->AsPhi()->GetRegNumber() < vreg) {
    860       HInstruction* next_phi = current_phi->GetNext();
    861       DCHECK(next_phi == nullptr ||
    862              current_phi->AsPhi()->GetRegNumber() <= next_phi->AsPhi()->GetRegNumber())
    863           << "Phis need to be sorted by vreg number to keep this a linear-time loop.";
    864       current_phi = next_phi;
    865     }
    866 
    867       if (current_phi == nullptr || current_phi->AsPhi()->GetRegNumber() != vreg) {
    868         stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kNone, 0);
    869       } else {
    870         Location location = current_phi->GetLiveInterval()->ToLocation();
    871         switch (location.GetKind()) {
    872           case Location::kStackSlot: {
    873             stack_map_stream_.AddDexRegisterEntry(
    874                 DexRegisterLocation::Kind::kInStack, location.GetStackIndex());
    875             break;
    876           }
    877           case Location::kDoubleStackSlot: {
    878             stack_map_stream_.AddDexRegisterEntry(
    879                 DexRegisterLocation::Kind::kInStack, location.GetStackIndex());
    880             stack_map_stream_.AddDexRegisterEntry(
    881                 DexRegisterLocation::Kind::kInStack, location.GetHighStackIndex(kVRegSize));
    882             ++vreg;
    883             DCHECK_LT(vreg, num_vregs);
    884             break;
    885           }
    886           default: {
    887             // All catch phis must be allocated to a stack slot.
    888             LOG(FATAL) << "Unexpected kind " << location.GetKind();
    889             UNREACHABLE();
    890           }
    891         }
    892       }
    893     }
    894 
    895     stack_map_stream_.EndStackMapEntry();
    896   }
    897 }
    898 
    899 void CodeGenerator::EmitEnvironment(HEnvironment* environment, SlowPathCode* slow_path) {
    900   if (environment == nullptr) return;
    901 
    902   if (environment->GetParent() != nullptr) {
    903     // We emit the parent environment first.
    904     EmitEnvironment(environment->GetParent(), slow_path);
    905     stack_map_stream_.BeginInlineInfoEntry(environment->GetMethodIdx(),
    906                                            environment->GetDexPc(),
    907                                            environment->GetInvokeType(),
    908                                            environment->Size());
    909   }
    910 
    911   // Walk over the environment, and record the location of dex registers.
    912   for (size_t i = 0, environment_size = environment->Size(); i < environment_size; ++i) {
    913     HInstruction* current = environment->GetInstructionAt(i);
    914     if (current == nullptr) {
    915       stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kNone, 0);
    916       continue;
    917     }
    918 
    919     Location location = environment->GetLocationAt(i);
    920     switch (location.GetKind()) {
    921       case Location::kConstant: {
    922         DCHECK_EQ(current, location.GetConstant());
    923         if (current->IsLongConstant()) {
    924           int64_t value = current->AsLongConstant()->GetValue();
    925           stack_map_stream_.AddDexRegisterEntry(
    926               DexRegisterLocation::Kind::kConstant, Low32Bits(value));
    927           stack_map_stream_.AddDexRegisterEntry(
    928               DexRegisterLocation::Kind::kConstant, High32Bits(value));
    929           ++i;
    930           DCHECK_LT(i, environment_size);
    931         } else if (current->IsDoubleConstant()) {
    932           int64_t value = bit_cast<int64_t, double>(current->AsDoubleConstant()->GetValue());
    933           stack_map_stream_.AddDexRegisterEntry(
    934               DexRegisterLocation::Kind::kConstant, Low32Bits(value));
    935           stack_map_stream_.AddDexRegisterEntry(
    936               DexRegisterLocation::Kind::kConstant, High32Bits(value));
    937           ++i;
    938           DCHECK_LT(i, environment_size);
    939         } else if (current->IsIntConstant()) {
    940           int32_t value = current->AsIntConstant()->GetValue();
    941           stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kConstant, value);
    942         } else if (current->IsNullConstant()) {
    943           stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kConstant, 0);
    944         } else {
    945           DCHECK(current->IsFloatConstant()) << current->DebugName();
    946           int32_t value = bit_cast<int32_t, float>(current->AsFloatConstant()->GetValue());
    947           stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kConstant, value);
    948         }
    949         break;
    950       }
    951 
    952       case Location::kStackSlot: {
    953         stack_map_stream_.AddDexRegisterEntry(
    954             DexRegisterLocation::Kind::kInStack, location.GetStackIndex());
    955         break;
    956       }
    957 
    958       case Location::kDoubleStackSlot: {
    959         stack_map_stream_.AddDexRegisterEntry(
    960             DexRegisterLocation::Kind::kInStack, location.GetStackIndex());
    961         stack_map_stream_.AddDexRegisterEntry(
    962             DexRegisterLocation::Kind::kInStack, location.GetHighStackIndex(kVRegSize));
    963         ++i;
    964         DCHECK_LT(i, environment_size);
    965         break;
    966       }
    967 
    968       case Location::kRegister : {
    969         int id = location.reg();
    970         if (slow_path != nullptr && slow_path->IsCoreRegisterSaved(id)) {
    971           uint32_t offset = slow_path->GetStackOffsetOfCoreRegister(id);
    972           stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInStack, offset);
    973           if (current->GetType() == Primitive::kPrimLong) {
    974             stack_map_stream_.AddDexRegisterEntry(
    975                 DexRegisterLocation::Kind::kInStack, offset + kVRegSize);
    976             ++i;
    977             DCHECK_LT(i, environment_size);
    978           }
    979         } else {
    980           stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInRegister, id);
    981           if (current->GetType() == Primitive::kPrimLong) {
    982             stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInRegisterHigh, id);
    983             ++i;
    984             DCHECK_LT(i, environment_size);
    985           }
    986         }
    987         break;
    988       }
    989 
    990       case Location::kFpuRegister : {
    991         int id = location.reg();
    992         if (slow_path != nullptr && slow_path->IsFpuRegisterSaved(id)) {
    993           uint32_t offset = slow_path->GetStackOffsetOfFpuRegister(id);
    994           stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInStack, offset);
    995           if (current->GetType() == Primitive::kPrimDouble) {
    996             stack_map_stream_.AddDexRegisterEntry(
    997                 DexRegisterLocation::Kind::kInStack, offset + kVRegSize);
    998             ++i;
    999             DCHECK_LT(i, environment_size);
   1000           }
   1001         } else {
   1002           stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInFpuRegister, id);
   1003           if (current->GetType() == Primitive::kPrimDouble) {
   1004             stack_map_stream_.AddDexRegisterEntry(
   1005                 DexRegisterLocation::Kind::kInFpuRegisterHigh, id);
   1006             ++i;
   1007             DCHECK_LT(i, environment_size);
   1008           }
   1009         }
   1010         break;
   1011       }
   1012 
   1013       case Location::kFpuRegisterPair : {
   1014         int low = location.low();
   1015         int high = location.high();
   1016         if (slow_path != nullptr && slow_path->IsFpuRegisterSaved(low)) {
   1017           uint32_t offset = slow_path->GetStackOffsetOfFpuRegister(low);
   1018           stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInStack, offset);
   1019         } else {
   1020           stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInFpuRegister, low);
   1021         }
   1022         if (slow_path != nullptr && slow_path->IsFpuRegisterSaved(high)) {
   1023           uint32_t offset = slow_path->GetStackOffsetOfFpuRegister(high);
   1024           stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInStack, offset);
   1025           ++i;
   1026         } else {
   1027           stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInFpuRegister, high);
   1028           ++i;
   1029         }
   1030         DCHECK_LT(i, environment_size);
   1031         break;
   1032       }
   1033 
   1034       case Location::kRegisterPair : {
   1035         int low = location.low();
   1036         int high = location.high();
   1037         if (slow_path != nullptr && slow_path->IsCoreRegisterSaved(low)) {
   1038           uint32_t offset = slow_path->GetStackOffsetOfCoreRegister(low);
   1039           stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInStack, offset);
   1040         } else {
   1041           stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInRegister, low);
   1042         }
   1043         if (slow_path != nullptr && slow_path->IsCoreRegisterSaved(high)) {
   1044           uint32_t offset = slow_path->GetStackOffsetOfCoreRegister(high);
   1045           stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInStack, offset);
   1046         } else {
   1047           stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kInRegister, high);
   1048         }
   1049         ++i;
   1050         DCHECK_LT(i, environment_size);
   1051         break;
   1052       }
   1053 
   1054       case Location::kInvalid: {
   1055         stack_map_stream_.AddDexRegisterEntry(DexRegisterLocation::Kind::kNone, 0);
   1056         break;
   1057       }
   1058 
   1059       default:
   1060         LOG(FATAL) << "Unexpected kind " << location.GetKind();
   1061     }
   1062   }
   1063 
   1064   if (environment->GetParent() != nullptr) {
   1065     stack_map_stream_.EndInlineInfoEntry();
   1066   }
   1067 }
   1068 
   1069 bool CodeGenerator::IsImplicitNullCheckAllowed(HNullCheck* null_check) const {
   1070   return compiler_options_.GetImplicitNullChecks() &&
   1071          // Null checks which might throw into a catch block need to save live
   1072          // registers and therefore cannot be done implicitly.
   1073          !null_check->CanThrowIntoCatchBlock();
   1074 }
   1075 
   1076 bool CodeGenerator::CanMoveNullCheckToUser(HNullCheck* null_check) {
   1077   HInstruction* first_next_not_move = null_check->GetNextDisregardingMoves();
   1078 
   1079   return (first_next_not_move != nullptr)
   1080       && first_next_not_move->CanDoImplicitNullCheckOn(null_check->InputAt(0));
   1081 }
   1082 
   1083 void CodeGenerator::MaybeRecordImplicitNullCheck(HInstruction* instr) {
   1084   // If we are from a static path don't record the pc as we can't throw NPE.
   1085   // NB: having the checks here makes the code much less verbose in the arch
   1086   // specific code generators.
   1087   if (instr->IsStaticFieldSet() || instr->IsStaticFieldGet()) {
   1088     return;
   1089   }
   1090 
   1091   if (!instr->CanDoImplicitNullCheckOn(instr->InputAt(0))) {
   1092     return;
   1093   }
   1094 
   1095   // Find the first previous instruction which is not a move.
   1096   HInstruction* first_prev_not_move = instr->GetPreviousDisregardingMoves();
   1097 
   1098   // If the instruction is a null check it means that `instr` is the first user
   1099   // and needs to record the pc.
   1100   if (first_prev_not_move != nullptr && first_prev_not_move->IsNullCheck()) {
   1101     HNullCheck* null_check = first_prev_not_move->AsNullCheck();
   1102     if (IsImplicitNullCheckAllowed(null_check)) {
   1103       // TODO: The parallel moves modify the environment. Their changes need to be
   1104       // reverted otherwise the stack maps at the throw point will not be correct.
   1105       RecordPcInfo(null_check, null_check->GetDexPc());
   1106     }
   1107   }
   1108 }
   1109 
   1110 void CodeGenerator::GenerateNullCheck(HNullCheck* instruction) {
   1111   if (IsImplicitNullCheckAllowed(instruction)) {
   1112     MaybeRecordStat(kImplicitNullCheckGenerated);
   1113     GenerateImplicitNullCheck(instruction);
   1114   } else {
   1115     MaybeRecordStat(kExplicitNullCheckGenerated);
   1116     GenerateExplicitNullCheck(instruction);
   1117   }
   1118 }
   1119 
   1120 void CodeGenerator::ClearSpillSlotsFromLoopPhisInStackMap(HSuspendCheck* suspend_check) const {
   1121   LocationSummary* locations = suspend_check->GetLocations();
   1122   HBasicBlock* block = suspend_check->GetBlock();
   1123   DCHECK(block->GetLoopInformation()->GetSuspendCheck() == suspend_check);
   1124   DCHECK(block->IsLoopHeader());
   1125 
   1126   for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
   1127     HInstruction* current = it.Current();
   1128     LiveInterval* interval = current->GetLiveInterval();
   1129     // We only need to clear bits of loop phis containing objects and allocated in register.
   1130     // Loop phis allocated on stack already have the object in the stack.
   1131     if (current->GetType() == Primitive::kPrimNot
   1132         && interval->HasRegister()
   1133         && interval->HasSpillSlot()) {
   1134       locations->ClearStackBit(interval->GetSpillSlot() / kVRegSize);
   1135     }
   1136   }
   1137 }
   1138 
   1139 void CodeGenerator::EmitParallelMoves(Location from1,
   1140                                       Location to1,
   1141                                       Primitive::Type type1,
   1142                                       Location from2,
   1143                                       Location to2,
   1144                                       Primitive::Type type2) {
   1145   HParallelMove parallel_move(GetGraph()->GetArena());
   1146   parallel_move.AddMove(from1, to1, type1, nullptr);
   1147   parallel_move.AddMove(from2, to2, type2, nullptr);
   1148   GetMoveResolver()->EmitNativeCode(&parallel_move);
   1149 }
   1150 
   1151 void CodeGenerator::ValidateInvokeRuntime(HInstruction* instruction, SlowPathCode* slow_path) {
   1152   // Ensure that the call kind indication given to the register allocator is
   1153   // coherent with the runtime call generated, and that the GC side effect is
   1154   // set when required.
   1155   if (slow_path == nullptr) {
   1156     DCHECK(instruction->GetLocations()->WillCall())
   1157         << "instruction->DebugName()=" << instruction->DebugName();
   1158     DCHECK(instruction->GetSideEffects().Includes(SideEffects::CanTriggerGC()))
   1159         << "instruction->DebugName()=" << instruction->DebugName()
   1160         << " instruction->GetSideEffects().ToString()=" << instruction->GetSideEffects().ToString();
   1161   } else {
   1162     DCHECK(instruction->GetLocations()->OnlyCallsOnSlowPath() || slow_path->IsFatal())
   1163         << "instruction->DebugName()=" << instruction->DebugName()
   1164         << " slow_path->GetDescription()=" << slow_path->GetDescription();
   1165     DCHECK(instruction->GetSideEffects().Includes(SideEffects::CanTriggerGC()) ||
   1166            // When read barriers are enabled, some instructions use a
   1167            // slow path to emit a read barrier, which does not trigger
   1168            // GC, is not fatal, nor is emitted by HDeoptimize
   1169            // instructions.
   1170            (kEmitCompilerReadBarrier &&
   1171             (instruction->IsInstanceFieldGet() ||
   1172              instruction->IsStaticFieldGet() ||
   1173              instruction->IsArraySet() ||
   1174              instruction->IsArrayGet() ||
   1175              instruction->IsLoadClass() ||
   1176              instruction->IsLoadString() ||
   1177              instruction->IsInstanceOf() ||
   1178              instruction->IsCheckCast())))
   1179         << "instruction->DebugName()=" << instruction->DebugName()
   1180         << " instruction->GetSideEffects().ToString()=" << instruction->GetSideEffects().ToString()
   1181         << " slow_path->GetDescription()=" << slow_path->GetDescription();
   1182   }
   1183 
   1184   // Check the coherency of leaf information.
   1185   DCHECK(instruction->IsSuspendCheck()
   1186          || ((slow_path != nullptr) && slow_path->IsFatal())
   1187          || instruction->GetLocations()->CanCall()
   1188          || !IsLeafMethod())
   1189       << instruction->DebugName() << ((slow_path != nullptr) ? slow_path->GetDescription() : "");
   1190 }
   1191 
   1192 void SlowPathCode::SaveLiveRegisters(CodeGenerator* codegen, LocationSummary* locations) {
   1193   RegisterSet* live_registers = locations->GetLiveRegisters();
   1194   size_t stack_offset = codegen->GetFirstRegisterSlotInSlowPath();
   1195 
   1196   for (size_t i = 0, e = codegen->GetNumberOfCoreRegisters(); i < e; ++i) {
   1197     if (!codegen->IsCoreCalleeSaveRegister(i)) {
   1198       if (live_registers->ContainsCoreRegister(i)) {
   1199         // If the register holds an object, update the stack mask.
   1200         if (locations->RegisterContainsObject(i)) {
   1201           locations->SetStackBit(stack_offset / kVRegSize);
   1202         }
   1203         DCHECK_LT(stack_offset, codegen->GetFrameSize() - codegen->FrameEntrySpillSize());
   1204         DCHECK_LT(i, kMaximumNumberOfExpectedRegisters);
   1205         saved_core_stack_offsets_[i] = stack_offset;
   1206         stack_offset += codegen->SaveCoreRegister(stack_offset, i);
   1207       }
   1208     }
   1209   }
   1210 
   1211   for (size_t i = 0, e = codegen->GetNumberOfFloatingPointRegisters(); i < e; ++i) {
   1212     if (!codegen->IsFloatingPointCalleeSaveRegister(i)) {
   1213       if (live_registers->ContainsFloatingPointRegister(i)) {
   1214         DCHECK_LT(stack_offset, codegen->GetFrameSize() - codegen->FrameEntrySpillSize());
   1215         DCHECK_LT(i, kMaximumNumberOfExpectedRegisters);
   1216         saved_fpu_stack_offsets_[i] = stack_offset;
   1217         stack_offset += codegen->SaveFloatingPointRegister(stack_offset, i);
   1218       }
   1219     }
   1220   }
   1221 }
   1222 
   1223 void SlowPathCode::RestoreLiveRegisters(CodeGenerator* codegen, LocationSummary* locations) {
   1224   RegisterSet* live_registers = locations->GetLiveRegisters();
   1225   size_t stack_offset = codegen->GetFirstRegisterSlotInSlowPath();
   1226 
   1227   for (size_t i = 0, e = codegen->GetNumberOfCoreRegisters(); i < e; ++i) {
   1228     if (!codegen->IsCoreCalleeSaveRegister(i)) {
   1229       if (live_registers->ContainsCoreRegister(i)) {
   1230         DCHECK_LT(stack_offset, codegen->GetFrameSize() - codegen->FrameEntrySpillSize());
   1231         DCHECK_LT(i, kMaximumNumberOfExpectedRegisters);
   1232         stack_offset += codegen->RestoreCoreRegister(stack_offset, i);
   1233       }
   1234     }
   1235   }
   1236 
   1237   for (size_t i = 0, e = codegen->GetNumberOfFloatingPointRegisters(); i < e; ++i) {
   1238     if (!codegen->IsFloatingPointCalleeSaveRegister(i)) {
   1239       if (live_registers->ContainsFloatingPointRegister(i)) {
   1240         DCHECK_LT(stack_offset, codegen->GetFrameSize() - codegen->FrameEntrySpillSize());
   1241         DCHECK_LT(i, kMaximumNumberOfExpectedRegisters);
   1242         stack_offset += codegen->RestoreFloatingPointRegister(stack_offset, i);
   1243       }
   1244     }
   1245   }
   1246 }
   1247 
   1248 void CodeGenerator::CreateSystemArrayCopyLocationSummary(HInvoke* invoke) {
   1249   // Check to see if we have known failures that will cause us to have to bail out
   1250   // to the runtime, and just generate the runtime call directly.
   1251   HIntConstant* src_pos = invoke->InputAt(1)->AsIntConstant();
   1252   HIntConstant* dest_pos = invoke->InputAt(3)->AsIntConstant();
   1253 
   1254   // The positions must be non-negative.
   1255   if ((src_pos != nullptr && src_pos->GetValue() < 0) ||
   1256       (dest_pos != nullptr && dest_pos->GetValue() < 0)) {
   1257     // We will have to fail anyways.
   1258     return;
   1259   }
   1260 
   1261   // The length must be >= 0.
   1262   HIntConstant* length = invoke->InputAt(4)->AsIntConstant();
   1263   if (length != nullptr) {
   1264     int32_t len = length->GetValue();
   1265     if (len < 0) {
   1266       // Just call as normal.
   1267       return;
   1268     }
   1269   }
   1270 
   1271   SystemArrayCopyOptimizations optimizations(invoke);
   1272 
   1273   if (optimizations.GetDestinationIsSource()) {
   1274     if (src_pos != nullptr && dest_pos != nullptr && src_pos->GetValue() < dest_pos->GetValue()) {
   1275       // We only support backward copying if source and destination are the same.
   1276       return;
   1277     }
   1278   }
   1279 
   1280   if (optimizations.GetDestinationIsPrimitiveArray() || optimizations.GetSourceIsPrimitiveArray()) {
   1281     // We currently don't intrinsify primitive copying.
   1282     return;
   1283   }
   1284 
   1285   ArenaAllocator* allocator = invoke->GetBlock()->GetGraph()->GetArena();
   1286   LocationSummary* locations = new (allocator) LocationSummary(invoke,
   1287                                                                LocationSummary::kCallOnSlowPath,
   1288                                                                kIntrinsified);
   1289   // arraycopy(Object src, int src_pos, Object dest, int dest_pos, int length).
   1290   locations->SetInAt(0, Location::RequiresRegister());
   1291   locations->SetInAt(1, Location::RegisterOrConstant(invoke->InputAt(1)));
   1292   locations->SetInAt(2, Location::RequiresRegister());
   1293   locations->SetInAt(3, Location::RegisterOrConstant(invoke->InputAt(3)));
   1294   locations->SetInAt(4, Location::RegisterOrConstant(invoke->InputAt(4)));
   1295 
   1296   locations->AddTemp(Location::RequiresRegister());
   1297   locations->AddTemp(Location::RequiresRegister());
   1298   locations->AddTemp(Location::RequiresRegister());
   1299 }
   1300 
   1301 }  // namespace art
   1302