diff options
Diffstat (limited to 'compiler/optimizing/code_generator_arm.cc')
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 68 |
1 files changed, 46 insertions, 22 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 07c84bcc01..980de040fa 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -1226,6 +1226,7 @@ void InstructionCodeGeneratorARM::VisitInvokeVirtual(HInvokeVirtual* invoke) { } else { __ LoadFromOffset(kLoadWord, temp, receiver.AsRegister<Register>(), class_offset); } + codegen_->MaybeRecordImplicitNullCheck(invoke); // temp = temp->GetMethodAt(method_offset); uint32_t entry_point = mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset( kArmWordSize).Int32Value(); @@ -1264,6 +1265,7 @@ void InstructionCodeGeneratorARM::VisitInvokeInterface(HInvokeInterface* invoke) } else { __ LoadFromOffset(kLoadWord, temp, receiver.AsRegister<Register>(), class_offset); } + codegen_->MaybeRecordImplicitNullCheck(invoke); // temp = temp->GetImtEntryAt(method_offset); uint32_t entry_point = mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset( kArmWordSize).Int32Value(); @@ -2579,7 +2581,8 @@ void InstructionCodeGeneratorARM::GenerateWideAtomicStore(Register addr, Register value_lo, Register value_hi, Register temp1, - Register temp2) { + Register temp2, + HInstruction* instruction) { Label fail; if (offset != 0) { __ LoadImmediate(temp1, offset); @@ -2590,6 +2593,7 @@ void InstructionCodeGeneratorARM::GenerateWideAtomicStore(Register addr, // We need a load followed by store. (The address used in a STREX instruction must // be the same as the address in the most recently executed LDREX instruction.) __ ldrexd(temp1, temp2, addr); + codegen_->MaybeRecordImplicitNullCheck(instruction); __ strexd(temp1, value_lo, value_hi, addr); __ cmp(temp1, ShifterOperand(0)); __ b(&fail, NE); @@ -2664,13 +2668,7 @@ void InstructionCodeGeneratorARM::HandleFieldSet(HInstruction* instruction, case Primitive::kPrimInt: case Primitive::kPrimNot: { - Register value_reg = value.AsRegister<Register>(); - __ StoreToOffset(kStoreWord, value_reg, base, offset); - if (CodeGenerator::StoreNeedsWriteBarrier(field_type, instruction->InputAt(1))) { - Register temp = locations->GetTemp(0).AsRegister<Register>(); - Register card = locations->GetTemp(1).AsRegister<Register>(); - codegen_->MarkGCCard(temp, card, base, value_reg); - } + __ StoreToOffset(kStoreWord, value.AsRegister<Register>(), base, offset); break; } @@ -2680,9 +2678,11 @@ void InstructionCodeGeneratorARM::HandleFieldSet(HInstruction* instruction, value.AsRegisterPairLow<Register>(), value.AsRegisterPairHigh<Register>(), locations->GetTemp(0).AsRegister<Register>(), - locations->GetTemp(1).AsRegister<Register>()); + locations->GetTemp(1).AsRegister<Register>(), + instruction); } else { __ StoreToOffset(kStoreWordPair, value.AsRegisterPairLow<Register>(), base, offset); + codegen_->MaybeRecordImplicitNullCheck(instruction); } break; } @@ -2704,9 +2704,11 @@ void InstructionCodeGeneratorARM::HandleFieldSet(HInstruction* instruction, value_reg_lo, value_reg_hi, locations->GetTemp(2).AsRegister<Register>(), - locations->GetTemp(3).AsRegister<Register>()); + locations->GetTemp(3).AsRegister<Register>(), + instruction); } else { __ StoreDToOffset(value_reg, base, offset); + codegen_->MaybeRecordImplicitNullCheck(instruction); } break; } @@ -2716,6 +2718,17 @@ void InstructionCodeGeneratorARM::HandleFieldSet(HInstruction* instruction, UNREACHABLE(); } + // Longs and doubles are handled in the switch. + if (field_type != Primitive::kPrimLong && field_type != Primitive::kPrimDouble) { + codegen_->MaybeRecordImplicitNullCheck(instruction); + } + + if (CodeGenerator::StoreNeedsWriteBarrier(field_type, instruction->InputAt(1))) { + Register temp = locations->GetTemp(0).AsRegister<Register>(); + Register card = locations->GetTemp(1).AsRegister<Register>(); + codegen_->MarkGCCard(temp, card, base, value.AsRegister<Register>()); + } + if (is_volatile) { GenerateMemoryBarrier(MemBarrierKind::kAnyAny); } @@ -2804,9 +2817,11 @@ void InstructionCodeGeneratorARM::HandleFieldGet(HInstruction* instruction, Register lo = locations->GetTemp(0).AsRegister<Register>(); Register hi = locations->GetTemp(1).AsRegister<Register>(); GenerateWideAtomicLoad(base, offset, lo, hi); + codegen_->MaybeRecordImplicitNullCheck(instruction); __ vmovdrr(out_reg, lo, hi); } else { __ LoadDFromOffset(out_reg, base, offset); + codegen_->MaybeRecordImplicitNullCheck(instruction); } break; } @@ -2816,6 +2831,11 @@ void InstructionCodeGeneratorARM::HandleFieldGet(HInstruction* instruction, UNREACHABLE(); } + // Doubles are handled in the switch. + if (field_type != Primitive::kPrimDouble) { + codegen_->MaybeRecordImplicitNullCheck(instruction); + } + if (is_volatile) { GenerateMemoryBarrier(MemBarrierKind::kLoadAny); } @@ -2856,17 +2876,18 @@ void InstructionCodeGeneratorARM::VisitStaticFieldSet(HStaticFieldSet* instructi void LocationsBuilderARM::VisitNullCheck(HNullCheck* instruction) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall); - Location loc = codegen_->GetCompilerOptions().GetImplicitNullChecks() - ? Location::RequiresRegister() - : Location::RegisterOrConstant(instruction->InputAt(0)); - locations->SetInAt(0, loc); + locations->SetInAt(0, Location::RequiresRegister()); if (instruction->HasUses()) { locations->SetOut(Location::SameAsFirstInput()); } } void InstructionCodeGeneratorARM::GenerateImplicitNullCheck(HNullCheck* instruction) { + if (codegen_->CanMoveNullCheckToUser(instruction)) { + return; + } Location obj = instruction->GetLocations()->InAt(0); + __ LoadFromOffset(kLoadWord, IP, obj.AsRegister<Register>(), 0); codegen_->RecordPcInfo(instruction, instruction->GetDexPc()); } @@ -2878,14 +2899,8 @@ void InstructionCodeGeneratorARM::GenerateExplicitNullCheck(HNullCheck* instruct LocationSummary* locations = instruction->GetLocations(); Location obj = locations->InAt(0); - if (obj.IsRegister()) { - __ cmp(obj.AsRegister<Register>(), ShifterOperand(0)); - __ b(slow_path->GetEntryLabel(), EQ); - } else { - DCHECK(obj.IsConstant()) << obj; - DCHECK_EQ(obj.GetConstant()->AsIntConstant()->GetValue(), 0); - __ b(slow_path->GetEntryLabel()); - } + __ cmp(obj.AsRegister<Register>(), ShifterOperand(0)); + __ b(slow_path->GetEntryLabel(), EQ); } void InstructionCodeGeneratorARM::VisitNullCheck(HNullCheck* instruction) { @@ -3028,6 +3043,7 @@ void InstructionCodeGeneratorARM::VisitArrayGet(HArrayGet* instruction) { LOG(FATAL) << "Unreachable type " << instruction->GetType(); UNREACHABLE(); } + codegen_->MaybeRecordImplicitNullCheck(instruction); } void LocationsBuilderARM::VisitArraySet(HArraySet* instruction) { @@ -3111,6 +3127,7 @@ void InstructionCodeGeneratorARM::VisitArraySet(HArraySet* instruction) { __ add(IP, obj, ShifterOperand(index.AsRegister<Register>(), LSL, TIMES_4)); __ StoreToOffset(kStoreWord, value, IP, data_offset); } + codegen_->MaybeRecordImplicitNullCheck(instruction); if (needs_write_barrier) { DCHECK_EQ(value_type, Primitive::kPrimNot); Register temp = locations->GetTemp(0).AsRegister<Register>(); @@ -3165,6 +3182,7 @@ void InstructionCodeGeneratorARM::VisitArraySet(HArraySet* instruction) { __ add(IP, obj, ShifterOperand(index.AsRegister<Register>(), LSL, TIMES_8)); __ StoreDToOffset(FromLowSToD(value.AsFpuRegisterPairLow<SRegister>()), IP, data_offset); } + break; } @@ -3172,6 +3190,11 @@ void InstructionCodeGeneratorARM::VisitArraySet(HArraySet* instruction) { LOG(FATAL) << "Unreachable type " << value_type; UNREACHABLE(); } + + // Ints and objects are handled in the switch. + if (value_type != Primitive::kPrimInt && value_type != Primitive::kPrimNot) { + codegen_->MaybeRecordImplicitNullCheck(instruction); + } } void LocationsBuilderARM::VisitArrayLength(HArrayLength* instruction) { @@ -3187,6 +3210,7 @@ void InstructionCodeGeneratorARM::VisitArrayLength(HArrayLength* instruction) { Register obj = locations->InAt(0).AsRegister<Register>(); Register out = locations->Out().AsRegister<Register>(); __ LoadFromOffset(kLoadWord, out, obj, offset); + codegen_->MaybeRecordImplicitNullCheck(instruction); } void LocationsBuilderARM::VisitBoundsCheck(HBoundsCheck* instruction) { |