diff options
author | Calin Juravle <calin@google.com> | 2015-01-20 12:28:09 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-01-20 12:28:11 +0000 |
commit | e7fd3e3a8e7f10048b7ea558cc525331c97bbefa (patch) | |
tree | a5d1a942460fe34c82f3dce7846d004b90ebd08d /compiler/optimizing/code_generator_arm.cc | |
parent | 606a81aab3b9289d37d828375793020b93718c6a (diff) | |
parent | cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3f (diff) | |
download | art-e7fd3e3a8e7f10048b7ea558cc525331c97bbefa.tar.gz art-e7fd3e3a8e7f10048b7ea558cc525331c97bbefa.tar.bz2 art-e7fd3e3a8e7f10048b7ea558cc525331c97bbefa.zip |
Merge "Add implicit null checks for the optimizing compiler"
Diffstat (limited to 'compiler/optimizing/code_generator_arm.cc')
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index d40c2d170d..1ca1cee275 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -384,8 +384,10 @@ size_t CodeGeneratorARM::RestoreFloatingPointRegister(size_t stack_index, uint32 } CodeGeneratorARM::CodeGeneratorARM(HGraph* graph, - const ArmInstructionSetFeatures* isa_features) - : CodeGenerator(graph, kNumberOfCoreRegisters, kNumberOfSRegisters, kNumberOfRegisterPairs), + const ArmInstructionSetFeatures& isa_features, + const CompilerOptions& compiler_options) + : CodeGenerator(graph, kNumberOfCoreRegisters, kNumberOfSRegisters, + kNumberOfRegisterPairs, compiler_options), block_labels_(graph->GetArena(), 0), location_builder_(graph, this), instruction_visitor_(graph, this), @@ -2608,7 +2610,7 @@ void LocationsBuilderARM::HandleFieldSet(HInstruction* instruction, const FieldI bool is_wide = field_type == Primitive::kPrimLong || field_type == Primitive::kPrimDouble; bool generate_volatile = field_info.IsVolatile() && is_wide - && !codegen_->GetInstructionSetFeatures()->HasAtomicLdrdAndStrd(); + && !codegen_->GetInstructionSetFeatures().HasAtomicLdrdAndStrd(); // Temporary registers for the write barrier. // TODO: consider renaming StoreNeedsWriteBarrier to StoreNeedsGCMark. if (CodeGenerator::StoreNeedsWriteBarrier(field_type, instruction->InputAt(1))) { @@ -2641,7 +2643,7 @@ void InstructionCodeGeneratorARM::HandleFieldSet(HInstruction* instruction, Location value = locations->InAt(1); bool is_volatile = field_info.IsVolatile(); - bool atomic_ldrd_strd = codegen_->GetInstructionSetFeatures()->HasAtomicLdrdAndStrd(); + bool atomic_ldrd_strd = codegen_->GetInstructionSetFeatures().HasAtomicLdrdAndStrd(); Primitive::Type field_type = field_info.GetFieldType(); uint32_t offset = field_info.GetFieldOffset().Uint32Value(); @@ -2730,7 +2732,7 @@ void LocationsBuilderARM::HandleFieldGet(HInstruction* instruction, const FieldI bool generate_volatile = field_info.IsVolatile() && (field_info.GetFieldType() == Primitive::kPrimDouble) - && !codegen_->GetInstructionSetFeatures()->HasAtomicLdrdAndStrd(); + && !codegen_->GetInstructionSetFeatures().HasAtomicLdrdAndStrd(); if (generate_volatile) { // Arm encoding have some additional constraints for ldrexd/strexd: // - registers need to be consecutive @@ -2751,7 +2753,7 @@ void InstructionCodeGeneratorARM::HandleFieldGet(HInstruction* instruction, Register base = locations->InAt(0).AsRegister<Register>(); Location out = locations->Out(); bool is_volatile = field_info.IsVolatile(); - bool atomic_ldrd_strd = codegen_->GetInstructionSetFeatures()->HasAtomicLdrdAndStrd(); + bool atomic_ldrd_strd = codegen_->GetInstructionSetFeatures().HasAtomicLdrdAndStrd(); Primitive::Type field_type = field_info.GetFieldType(); uint32_t offset = field_info.GetFieldOffset().Uint32Value(); @@ -2856,13 +2858,22 @@ void InstructionCodeGeneratorARM::VisitStaticFieldSet(HStaticFieldSet* instructi void LocationsBuilderARM::VisitNullCheck(HNullCheck* instruction) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall); - locations->SetInAt(0, Location::RequiresRegister()); + Location loc = codegen_->GetCompilerOptions().GetImplicitNullChecks() + ? Location::RequiresRegister() + : Location::RegisterOrConstant(instruction->InputAt(0)); + locations->SetInAt(0, loc); if (instruction->HasUses()) { locations->SetOut(Location::SameAsFirstInput()); } } -void InstructionCodeGeneratorARM::VisitNullCheck(HNullCheck* instruction) { +void InstructionCodeGeneratorARM::GenerateImplicitNullCheck(HNullCheck* instruction) { + Location obj = instruction->GetLocations()->InAt(0); + __ LoadFromOffset(kLoadWord, IP, obj.AsRegister<Register>(), 0); + codegen_->RecordPcInfo(instruction, instruction->GetDexPc()); +} + +void InstructionCodeGeneratorARM::GenerateExplicitNullCheck(HNullCheck* instruction) { SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) NullCheckSlowPathARM(instruction); codegen_->AddSlowPath(slow_path); @@ -2879,6 +2890,14 @@ void InstructionCodeGeneratorARM::VisitNullCheck(HNullCheck* instruction) { } } +void InstructionCodeGeneratorARM::VisitNullCheck(HNullCheck* instruction) { + if (codegen_->GetCompilerOptions().GetImplicitNullChecks()) { + GenerateImplicitNullCheck(instruction); + } else { + GenerateExplicitNullCheck(instruction); + } +} + void LocationsBuilderARM::VisitArrayGet(HArrayGet* instruction) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall); |