diff options
-rw-r--r-- | compiler/optimizing/code_generator.cc | 3 | ||||
-rw-r--r-- | compiler/optimizing/instruction_builder.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/nodes.cc | 6 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 109 | ||||
-rw-r--r-- | compiler/optimizing/nodes_test.cc | 16 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_unit_test.h | 4 | ||||
-rw-r--r-- | compiler/optimizing/prepare_for_register_allocation.cc | 10 | ||||
-rw-r--r-- | compiler/optimizing/scheduler_test.cc | 10 | ||||
-rw-r--r-- | compiler/optimizing/superblock_cloner.cc | 2 | ||||
-rw-r--r-- | libartbase/base/arena_allocator.cc | 1 | ||||
-rw-r--r-- | libartbase/base/arena_allocator.h | 1 |
11 files changed, 101 insertions, 63 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index 51714ef548..757fdc2cee 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -913,8 +913,9 @@ void CodeGenerator::BlockIfInRegister(Location location, bool is_out) const { } void CodeGenerator::AllocateLocations(HInstruction* instruction) { + ArenaAllocator* allocator = GetGraph()->GetAllocator(); for (HEnvironment* env = instruction->GetEnvironment(); env != nullptr; env = env->GetParent()) { - env->AllocateLocations(); + env->AllocateLocations(allocator); } instruction->Accept(GetLocationBuilder()); DCHECK(CheckTypeConsistency(instruction)); diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 09d7c23fed..5b762d69fa 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -297,7 +297,7 @@ void HInstructionBuilder::InsertInstructionAtTop(HInstruction* instruction) { void HInstructionBuilder::InitializeInstruction(HInstruction* instruction) { if (instruction->NeedsEnvironment()) { - HEnvironment* environment = new (allocator_) HEnvironment( + HEnvironment* environment = HEnvironment::Create( allocator_, current_locals_->size(), graph_->GetArtMethod(), diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 32ae89eeea..f7ec0871d4 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -1142,7 +1142,7 @@ void HEnvironment::CopyFrom(ArrayRef<HInstruction* const> locals) { } } -void HEnvironment::CopyFrom(HEnvironment* env) { +void HEnvironment::CopyFrom(const HEnvironment* env) { for (size_t i = 0; i < env->Size(); i++) { HInstruction* instruction = env->GetInstructionAt(i); SetRawEnvAt(i, instruction); @@ -1174,7 +1174,7 @@ void HEnvironment::CopyFromWithLoopPhiAdjustment(HEnvironment* env, } void HEnvironment::RemoveAsUserOfInput(size_t index) const { - const HUserRecord<HEnvironment*>& env_use = vregs_[index]; + const HUserRecord<HEnvironment*>& env_use = GetVRegs()[index]; HInstruction* user = env_use.GetInstruction(); auto before_env_use_node = env_use.GetBeforeUseNode(); user->env_uses_.erase_after(before_env_use_node); @@ -1182,7 +1182,7 @@ void HEnvironment::RemoveAsUserOfInput(size_t index) const { } void HEnvironment::ReplaceInput(HInstruction* replacement, size_t index) { - const HUserRecord<HEnvironment*>& env_use_record = vregs_[index]; + const HUserRecord<HEnvironment*>& env_use_record = GetVRegs()[index]; HInstruction* orig_instr = env_use_record.GetInstruction(); DCHECK(orig_instr != replacement); diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index fd00a5e2fe..4a7eb1cd22 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -2074,38 +2074,37 @@ class SideEffects : public ValueObject { // A HEnvironment object contains the values of virtual registers at a given location. class HEnvironment : public ArenaObject<kArenaAllocEnvironment> { public: - ALWAYS_INLINE HEnvironment(ArenaAllocator* allocator, - size_t number_of_vregs, - ArtMethod* method, - uint32_t dex_pc, - HInstruction* holder) - : vregs_(number_of_vregs, allocator->Adapter(kArenaAllocEnvironmentVRegs)), - locations_(allocator->Adapter(kArenaAllocEnvironmentLocations)), - parent_(nullptr), - method_(method), - dex_pc_(dex_pc), - holder_(holder) { - } - - ALWAYS_INLINE HEnvironment(ArenaAllocator* allocator, - const HEnvironment& to_copy, - HInstruction* holder) - : HEnvironment(allocator, - to_copy.Size(), - to_copy.GetMethod(), - to_copy.GetDexPc(), - holder) {} - - void AllocateLocations() { - DCHECK(locations_.empty()); - locations_.resize(vregs_.size()); + static HEnvironment* Create(ArenaAllocator* allocator, + size_t number_of_vregs, + ArtMethod* method, + uint32_t dex_pc, + HInstruction* holder) { + // The storage for vreg records is allocated right after the `HEnvironment` itself. + static_assert(IsAligned<alignof(HUserRecord<HEnvironment*>)>(sizeof(HEnvironment))); + static_assert(IsAligned<alignof(HUserRecord<HEnvironment*>)>(ArenaAllocator::kAlignment)); + size_t alloc_size = sizeof(HEnvironment) + number_of_vregs * sizeof(HUserRecord<HEnvironment*>); + void* storage = allocator->Alloc(alloc_size, kArenaAllocEnvironment); + return new (storage) HEnvironment(number_of_vregs, method, dex_pc, holder); + } + + static HEnvironment* Create(ArenaAllocator* allocator, + const HEnvironment& to_copy, + HInstruction* holder) { + return Create(allocator, to_copy.Size(), to_copy.GetMethod(), to_copy.GetDexPc(), holder); + } + + void AllocateLocations(ArenaAllocator* allocator) { + DCHECK(locations_ == nullptr); + if (Size() != 0u) { + locations_ = allocator->AllocArray<Location>(Size(), kArenaAllocEnvironmentLocations); + } } void SetAndCopyParentChain(ArenaAllocator* allocator, HEnvironment* parent) { if (parent_ != nullptr) { parent_->SetAndCopyParentChain(allocator, parent); } else { - parent_ = new (allocator) HEnvironment(allocator, *parent, holder_); + parent_ = Create(allocator, *parent, holder_); parent_->CopyFrom(parent); if (parent->GetParent() != nullptr) { parent_->SetAndCopyParentChain(allocator, parent->GetParent()); @@ -2114,7 +2113,7 @@ class HEnvironment : public ArenaObject<kArenaAllocEnvironment> { } void CopyFrom(ArrayRef<HInstruction* const> locals); - void CopyFrom(HEnvironment* environment); + void CopyFrom(const HEnvironment* environment); // Copy from `env`. If it's a loop phi for `loop_header`, copy the first // input to the loop phi instead. This is for inserting instructions that @@ -2122,11 +2121,11 @@ class HEnvironment : public ArenaObject<kArenaAllocEnvironment> { void CopyFromWithLoopPhiAdjustment(HEnvironment* env, HBasicBlock* loop_header); void SetRawEnvAt(size_t index, HInstruction* instruction) { - vregs_[index] = HUserRecord<HEnvironment*>(instruction); + GetVRegs()[index] = HUserRecord<HEnvironment*>(instruction); } HInstruction* GetInstructionAt(size_t index) const { - return vregs_[index].GetInstruction(); + return GetVRegs()[index].GetInstruction(); } void RemoveAsUserOfInput(size_t index) const; @@ -2136,15 +2135,19 @@ class HEnvironment : public ArenaObject<kArenaAllocEnvironment> { // HInstruction::ReplaceInput. void ReplaceInput(HInstruction* replacement, size_t index); - size_t Size() const { return vregs_.size(); } + size_t Size() const { return number_of_vregs_; } HEnvironment* GetParent() const { return parent_; } void SetLocationAt(size_t index, Location location) { + DCHECK_LT(index, number_of_vregs_); + DCHECK(locations_ != nullptr); locations_[index] = location; } Location GetLocationAt(size_t index) const { + DCHECK_LT(index, number_of_vregs_); + DCHECK(locations_ != nullptr); return locations_[index]; } @@ -2183,15 +2186,43 @@ class HEnvironment : public ArenaObject<kArenaAllocEnvironment> { } private: - ArenaVector<HUserRecord<HEnvironment*>> vregs_; - ArenaVector<Location> locations_; - HEnvironment* parent_; - ArtMethod* method_; + ALWAYS_INLINE HEnvironment(size_t number_of_vregs, + ArtMethod* method, + uint32_t dex_pc, + HInstruction* holder) + : number_of_vregs_(dchecked_integral_cast<uint32_t>(number_of_vregs)), + dex_pc_(dex_pc), + holder_(holder), + parent_(nullptr), + method_(method), + locations_(nullptr) { + } + + ArrayRef<HUserRecord<HEnvironment*>> GetVRegs() { + auto* vregs = reinterpret_cast<HUserRecord<HEnvironment*>*>(this + 1); + return ArrayRef<HUserRecord<HEnvironment*>>(vregs, number_of_vregs_); + } + + ArrayRef<const HUserRecord<HEnvironment*>> GetVRegs() const { + auto* vregs = reinterpret_cast<const HUserRecord<HEnvironment*>*>(this + 1); + return ArrayRef<const HUserRecord<HEnvironment*>>(vregs, number_of_vregs_); + } + + const uint32_t number_of_vregs_; const uint32_t dex_pc_; // The instruction that holds this environment. HInstruction* const holder_; + // The parent environment for inlined code. + HEnvironment* parent_; + + // The environment's method, if resolved. + ArtMethod* method_; + + // Locations assigned by the register allocator. + Location* locations_; + friend class HInstruction; DISALLOW_COPY_AND_ASSIGN(HEnvironment); @@ -2523,7 +2554,7 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> { void CopyEnvironmentFrom(HEnvironment* environment) { DCHECK(environment_ == nullptr); ArenaAllocator* allocator = GetBlock()->GetGraph()->GetAllocator(); - environment_ = new (allocator) HEnvironment(allocator, *environment, this); + environment_ = HEnvironment::Create(allocator, *environment, this); environment_->CopyFrom(environment); if (environment->GetParent() != nullptr) { environment_->SetAndCopyParentChain(allocator, environment->GetParent()); @@ -2534,7 +2565,7 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> { HBasicBlock* block) { DCHECK(environment_ == nullptr); ArenaAllocator* allocator = GetBlock()->GetGraph()->GetAllocator(); - environment_ = new (allocator) HEnvironment(allocator, *environment, this); + environment_ = HEnvironment::Create(allocator, *environment, this); environment_->CopyFromWithLoopPhiAdjustment(environment, block); if (environment->GetParent() != nullptr) { environment_->SetAndCopyParentChain(allocator, environment->GetParent()); @@ -2786,7 +2817,7 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> { for (auto env_use_node = env_uses_.begin(); env_use_node != env_fixup_end; ++env_use_node) { HEnvironment* user = env_use_node->GetUser(); size_t input_index = env_use_node->GetIndex(); - user->vregs_[input_index] = HUserRecord<HEnvironment*>(this, before_env_use_node); + user->GetVRegs()[input_index] = HUserRecord<HEnvironment*>(this, before_env_use_node); before_env_use_node = env_use_node; } } @@ -2796,8 +2827,8 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> { if (next != env_uses_.end()) { HEnvironment* next_user = next->GetUser(); size_t next_index = next->GetIndex(); - DCHECK(next_user->vregs_[next_index].GetInstruction() == this); - next_user->vregs_[next_index] = HUserRecord<HEnvironment*>(this, before_env_use_node); + DCHECK(next_user->GetVRegs()[next_index].GetInstruction() == this); + next_user->GetVRegs()[next_index] = HUserRecord<HEnvironment*>(this, before_env_use_node); } } diff --git a/compiler/optimizing/nodes_test.cc b/compiler/optimizing/nodes_test.cc index 1a1d9ac7da..0302298b9c 100644 --- a/compiler/optimizing/nodes_test.cc +++ b/compiler/optimizing/nodes_test.cc @@ -212,14 +212,22 @@ TEST_F(NodeTest, ParentEnvironment) { ASSERT_TRUE(parameter1->HasEnvironmentUses()); ASSERT_TRUE(parameter1->GetEnvUses().HasExactlyOneElement()); - HEnvironment* parent1 = new (GetAllocator()) HEnvironment( - GetAllocator(), 1, graph->GetArtMethod(), 0, nullptr); + HEnvironment* parent1 = HEnvironment::Create( + GetAllocator(), + /*number_of_vregs=*/ 1, + graph->GetArtMethod(), + /*dex_pc=*/ 0, + /*holder=*/ nullptr); parent1->CopyFrom(ArrayRef<HInstruction* const>(¶meter1, 1u)); ASSERT_EQ(parameter1->GetEnvUses().SizeSlow(), 2u); - HEnvironment* parent2 = new (GetAllocator()) HEnvironment( - GetAllocator(), 1, graph->GetArtMethod(), 0, nullptr); + HEnvironment* parent2 = HEnvironment::Create( + GetAllocator(), + /*number_of_vregs=*/ 1, + graph->GetArtMethod(), + /*dex_pc=*/ 0, + /*holder=*/ nullptr); parent2->CopyFrom(ArrayRef<HInstruction* const>(¶meter1, 1u)); parent1->SetAndCopyParentChain(GetAllocator(), parent2); diff --git a/compiler/optimizing/optimizing_unit_test.h b/compiler/optimizing/optimizing_unit_test.h index 2fe11299fc..6d451663e5 100644 --- a/compiler/optimizing/optimizing_unit_test.h +++ b/compiler/optimizing/optimizing_unit_test.h @@ -404,8 +404,8 @@ class OptimizingUnitTestHelper { HEnvironment* ManuallyBuildEnvFor(HInstruction* instruction, ArenaVector<HInstruction*>* current_locals) { - HEnvironment* environment = new (GetAllocator()) HEnvironment( - (GetAllocator()), + HEnvironment* environment = HEnvironment::Create( + GetAllocator(), current_locals->size(), graph_->GetArtMethod(), instruction->GetDexPc(), diff --git a/compiler/optimizing/prepare_for_register_allocation.cc b/compiler/optimizing/prepare_for_register_allocation.cc index 1e99732d03..7453e58d3b 100644 --- a/compiler/optimizing/prepare_for_register_allocation.cc +++ b/compiler/optimizing/prepare_for_register_allocation.cc @@ -86,11 +86,11 @@ void PrepareForRegisterAllocation::VisitBoundsCheck(HBoundsCheck* check) { ArtMethod* char_at_method = WellKnownClasses::java_lang_String_charAt; if (GetGraph()->GetArtMethod() != char_at_method) { ArenaAllocator* allocator = GetGraph()->GetAllocator(); - HEnvironment* environment = new (allocator) HEnvironment(allocator, - /* number_of_vregs= */ 0u, - char_at_method, - /* dex_pc= */ dex::kDexNoIndex, - check); + HEnvironment* environment = HEnvironment::Create(allocator, + /* number_of_vregs= */ 0u, + char_at_method, + /* dex_pc= */ dex::kDexNoIndex, + check); check->InsertRawEnvironment(environment); } } diff --git a/compiler/optimizing/scheduler_test.cc b/compiler/optimizing/scheduler_test.cc index f613e0a9e2..182465aa54 100644 --- a/compiler/optimizing/scheduler_test.cc +++ b/compiler/optimizing/scheduler_test.cc @@ -111,11 +111,11 @@ class SchedulerTest : public CommonCompilerTest, public OptimizingUnitTestHelper DCHECK(div_check->CanThrow()); - HEnvironment* environment = new (GetAllocator()) HEnvironment(GetAllocator(), - 2, - graph_->GetArtMethod(), - 0, - div_check); + HEnvironment* environment = HEnvironment::Create(GetAllocator(), + /*number_of_vregs=*/ 2, + graph_->GetArtMethod(), + /*dex_pc=*/ 0, + div_check); div_check->SetRawEnvironment(environment); environment->SetRawEnvAt(0, add2); add2->AddEnvUseAt(div_check->GetEnvironment(), 0); diff --git a/compiler/optimizing/superblock_cloner.cc b/compiler/optimizing/superblock_cloner.cc index e14f7347fb..1e74dcba78 100644 --- a/compiler/optimizing/superblock_cloner.cc +++ b/compiler/optimizing/superblock_cloner.cc @@ -134,7 +134,7 @@ void SuperblockCloner::DeepCloneEnvironmentWithRemapping(HInstruction* copy_inst if (orig_env->GetParent() != nullptr) { DeepCloneEnvironmentWithRemapping(copy_instr, orig_env->GetParent()); } - HEnvironment* copy_env = new (arena_) HEnvironment(arena_, *orig_env, copy_instr); + HEnvironment* copy_env = HEnvironment::Create(arena_, *orig_env, copy_instr); for (size_t i = 0; i < orig_env->Size(); i++) { HInstruction* env_input = orig_env->GetInstructionAt(i); diff --git a/libartbase/base/arena_allocator.cc b/libartbase/base/arena_allocator.cc index 0bbc816272..a44d1ba0b2 100644 --- a/libartbase/base/arena_allocator.cc +++ b/libartbase/base/arena_allocator.cc @@ -57,7 +57,6 @@ const char* const ArenaAllocatorStatsImpl<kCount>::kAllocNames[] = { "TryCatchInf ", "UseListNode ", "Environment ", - "EnvVRegs ", "EnvLocations ", "LocSummary ", "SsaBuilder ", diff --git a/libartbase/base/arena_allocator.h b/libartbase/base/arena_allocator.h index 10f7f3183d..f7cda26f43 100644 --- a/libartbase/base/arena_allocator.h +++ b/libartbase/base/arena_allocator.h @@ -68,7 +68,6 @@ enum ArenaAllocKind { kArenaAllocTryCatchInfo, kArenaAllocUseListNode, kArenaAllocEnvironment, - kArenaAllocEnvironmentVRegs, kArenaAllocEnvironmentLocations, kArenaAllocLocationSummary, kArenaAllocSsaBuilder, |