summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/optimizing/code_generator.cc3
-rw-r--r--compiler/optimizing/instruction_builder.cc2
-rw-r--r--compiler/optimizing/nodes.cc6
-rw-r--r--compiler/optimizing/nodes.h109
-rw-r--r--compiler/optimizing/nodes_test.cc16
-rw-r--r--compiler/optimizing/optimizing_unit_test.h4
-rw-r--r--compiler/optimizing/prepare_for_register_allocation.cc10
-rw-r--r--compiler/optimizing/scheduler_test.cc10
-rw-r--r--compiler/optimizing/superblock_cloner.cc2
-rw-r--r--libartbase/base/arena_allocator.cc1
-rw-r--r--libartbase/base/arena_allocator.h1
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>(&parameter1, 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>(&parameter1, 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,