diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-11-17 09:42:23 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-11-17 09:42:25 +0000 |
commit | c1d4ec95c9dc69a7373e2eca0e69965e54d9cf03 (patch) | |
tree | 7ded15095ee62d471fe1455ec915c1d68fb202f6 /compiler/optimizing/code_generator_arm.cc | |
parent | 44e6d985fddb3d921f054ff64c319c86005118e9 (diff) | |
parent | af07bc121121d7bd7e8329c55dfe24782207b561 (diff) | |
download | art-c1d4ec95c9dc69a7373e2eca0e69965e54d9cf03.tar.gz art-c1d4ec95c9dc69a7373e2eca0e69965e54d9cf03.tar.bz2 art-c1d4ec95c9dc69a7373e2eca0e69965e54d9cf03.zip |
Merge "Minor object store optimizations."
Diffstat (limited to 'compiler/optimizing/code_generator_arm.cc')
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 67 |
1 files changed, 45 insertions, 22 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 09e1b97570..bb2f899886 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -2034,11 +2034,12 @@ void InstructionCodeGeneratorARM::VisitPhi(HPhi* instruction) { void LocationsBuilderARM::VisitInstanceFieldSet(HInstanceFieldSet* instruction) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall); - bool is_object_type = instruction->GetFieldType() == Primitive::kPrimNot; + bool needs_write_barrier = + CodeGenerator::StoreNeedsWriteBarrier(instruction->GetFieldType(), instruction->GetValue()); locations->SetInAt(0, Location::RequiresRegister()); locations->SetInAt(1, Location::RequiresRegister()); // Temporary registers for the write barrier. - if (is_object_type) { + if (needs_write_barrier) { locations->AddTemp(Location::RequiresRegister()); locations->AddTemp(Location::RequiresRegister()); } @@ -2069,7 +2070,7 @@ void InstructionCodeGeneratorARM::VisitInstanceFieldSet(HInstanceFieldSet* instr case Primitive::kPrimNot: { Register value = locations->InAt(1).As<Register>(); __ StoreToOffset(kStoreWord, value, obj, offset); - if (field_type == Primitive::kPrimNot) { + if (CodeGenerator::StoreNeedsWriteBarrier(field_type, instruction->GetValue())) { Register temp = locations->GetTemp(0).As<Register>(); Register card = locations->GetTemp(1).As<Register>(); codegen_->MarkGCCard(temp, card, obj, value); @@ -2302,10 +2303,14 @@ void InstructionCodeGeneratorARM::VisitArrayGet(HArrayGet* instruction) { void LocationsBuilderARM::VisitArraySet(HArraySet* instruction) { Primitive::Type value_type = instruction->GetComponentType(); - bool is_object = value_type == Primitive::kPrimNot; + + bool needs_write_barrier = + CodeGenerator::StoreNeedsWriteBarrier(value_type, instruction->GetValue()); + bool needs_runtime_call = instruction->NeedsTypeCheck(); + LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary( - instruction, is_object ? LocationSummary::kCall : LocationSummary::kNoCall); - if (is_object) { + instruction, needs_runtime_call ? LocationSummary::kCall : LocationSummary::kNoCall); + if (needs_runtime_call) { InvokeRuntimeCallingConvention calling_convention; locations->SetInAt(0, Location::RegisterLocation(calling_convention.GetRegisterAt(0))); locations->SetInAt(1, Location::RegisterLocation(calling_convention.GetRegisterAt(1))); @@ -2314,6 +2319,12 @@ void LocationsBuilderARM::VisitArraySet(HArraySet* instruction) { locations->SetInAt(0, Location::RequiresRegister()); locations->SetInAt(1, Location::RegisterOrConstant(instruction->InputAt(1))); locations->SetInAt(2, Location::RequiresRegister()); + + if (needs_write_barrier) { + // Temporary registers for the write barrier. + locations->AddTemp(Location::RequiresRegister()); + locations->AddTemp(Location::RequiresRegister()); + } } } @@ -2322,6 +2333,9 @@ void InstructionCodeGeneratorARM::VisitArraySet(HArraySet* instruction) { Register obj = locations->InAt(0).As<Register>(); Location index = locations->InAt(1); Primitive::Type value_type = instruction->GetComponentType(); + bool needs_runtime_call = locations->WillCall(); + bool needs_write_barrier = + CodeGenerator::StoreNeedsWriteBarrier(value_type, instruction->GetValue()); switch (value_type) { case Primitive::kPrimBoolean: @@ -2352,24 +2366,32 @@ void InstructionCodeGeneratorARM::VisitArraySet(HArraySet* instruction) { break; } - case Primitive::kPrimInt: { - uint32_t data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Uint32Value(); - Register value = locations->InAt(2).As<Register>(); - if (index.IsConstant()) { - size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset; - __ StoreToOffset(kStoreWord, value, obj, offset); + case Primitive::kPrimInt: + case Primitive::kPrimNot: { + if (!needs_runtime_call) { + uint32_t data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Uint32Value(); + Register value = locations->InAt(2).As<Register>(); + if (index.IsConstant()) { + size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset; + __ StoreToOffset(kStoreWord, value, obj, offset); + } else { + DCHECK(index.IsRegister()) << index; + __ add(IP, obj, ShifterOperand(index.As<Register>(), LSL, TIMES_4)); + __ StoreToOffset(kStoreWord, value, IP, data_offset); + } + if (needs_write_barrier) { + DCHECK_EQ(value_type, Primitive::kPrimNot); + Register temp = locations->GetTemp(0).As<Register>(); + Register card = locations->GetTemp(1).As<Register>(); + codegen_->MarkGCCard(temp, card, obj, value); + } } else { - __ add(IP, obj, ShifterOperand(index.As<Register>(), LSL, TIMES_4)); - __ StoreToOffset(kStoreWord, value, IP, data_offset); + DCHECK_EQ(value_type, Primitive::kPrimNot); + codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pAputObject), instruction, instruction->GetDexPc()); } break; } - case Primitive::kPrimNot: { - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pAputObject), instruction, instruction->GetDexPc()); - break; - } - case Primitive::kPrimLong: { uint32_t data_offset = mirror::Array::DataOffset(sizeof(int64_t)).Uint32Value(); Location value = locations->InAt(2); @@ -2718,11 +2740,12 @@ void InstructionCodeGeneratorARM::VisitStaticFieldGet(HStaticFieldGet* instructi void LocationsBuilderARM::VisitStaticFieldSet(HStaticFieldSet* instruction) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall); - bool is_object_type = instruction->GetFieldType() == Primitive::kPrimNot; + bool needs_write_barrier = + CodeGenerator::StoreNeedsWriteBarrier(instruction->GetFieldType(), instruction->GetValue()); locations->SetInAt(0, Location::RequiresRegister()); locations->SetInAt(1, Location::RequiresRegister()); // Temporary registers for the write barrier. - if (is_object_type) { + if (needs_write_barrier) { locations->AddTemp(Location::RequiresRegister()); locations->AddTemp(Location::RequiresRegister()); } @@ -2753,7 +2776,7 @@ void InstructionCodeGeneratorARM::VisitStaticFieldSet(HStaticFieldSet* instructi case Primitive::kPrimNot: { Register value = locations->InAt(1).As<Register>(); __ StoreToOffset(kStoreWord, value, cls, offset); - if (field_type == Primitive::kPrimNot) { + if (CodeGenerator::StoreNeedsWriteBarrier(field_type, instruction->GetValue())) { Register temp = locations->GetTemp(0).As<Register>(); Register card = locations->GetTemp(1).As<Register>(); codegen_->MarkGCCard(temp, card, cls, value); |