From 1e296936eb20f7ce1c23269d1c28665c51bb53e7 Mon Sep 17 00:00:00 2001 From: "mstarzinger@chromium.org" Date: Fri, 2 Aug 2013 11:24:55 +0000 Subject: [PATCH] Store transition on HStoreNamedField as HConstant. This allows optimization passes that run in the parallel compiler thread to use the map that a store transitions to for further analysis even though the map handle cannot be dereferenced. R=jkummerow@chromium.org Review URL: https://codereview.chromium.org/21560002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16028 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/lithium-arm.cc | 2 +- src/arm/lithium-arm.h | 2 +- src/hydrogen-instructions.cc | 10 +++++----- src/hydrogen-instructions.h | 42 ++++++++++++++++++++++++------------------ src/hydrogen.cc | 3 ++- src/ia32/lithium-ia32.cc | 2 +- src/ia32/lithium-ia32.h | 2 +- src/mips/lithium-mips.cc | 2 +- src/mips/lithium-mips.h | 2 +- src/x64/lithium-x64.cc | 2 +- src/x64/lithium-x64.h | 2 +- 11 files changed, 39 insertions(+), 32 deletions(-) diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index 5ffe51d..d8be79c 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -2311,7 +2311,7 @@ LInstruction* LChunkBuilder::DoTrapAllocationMemento( LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { bool is_in_object = instr->access().IsInobject(); bool needs_write_barrier = instr->NeedsWriteBarrier(); - bool needs_write_barrier_for_map = !instr->transition().is_null() && + bool needs_write_barrier_for_map = instr->has_transition() && instr->NeedsWriteBarrierForMap(); LOperand* obj; diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h index 63d34f5..e7f27c2 100644 --- a/src/arm/lithium-arm.h +++ b/src/arm/lithium-arm.h @@ -2150,7 +2150,7 @@ class LStoreNamedField: public LTemplateInstruction<0, 2, 1> { virtual void PrintDataTo(StringStream* stream); - Handle transition() const { return hydrogen()->transition(); } + Handle transition() const { return hydrogen()->transition_map(); } Representation representation() const { return hydrogen()->field_representation(); } diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index 34f6a8d..8c70a34 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -1389,10 +1389,10 @@ void HCheckMaps::HandleSideEffectDominator(GVNFlag side_effect, // for which the map is known. if (HasNoUses() && dominator->IsStoreNamedField()) { HStoreNamedField* store = HStoreNamedField::cast(dominator); - UniqueValueId map_unique_id = store->transition_unique_id(); - if (!map_unique_id.IsInitialized() || store->object() != value()) return; + if (!store->has_transition() || store->object() != value()) return; + HConstant* transition = HConstant::cast(store->transition()); for (int i = 0; i < map_set()->length(); i++) { - if (map_unique_id == map_unique_ids_.at(i)) { + if (transition->UniqueValueIdsMatch(map_unique_ids_.at(i))) { DeleteAndReplaceWith(NULL); return; } @@ -3160,8 +3160,8 @@ void HStoreNamedField::PrintDataTo(StringStream* stream) { if (NeedsWriteBarrier()) { stream->Add(" (write-barrier)"); } - if (!transition().is_null()) { - stream->Add(" (transition map %p)", *transition()); + if (has_transition()) { + stream->Add(" (transition map %p)", *transition_map()); } } diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index d73c62f..b785724 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -5971,7 +5971,7 @@ class HLoadKeyedGeneric: public HTemplateInstruction<3> { }; -class HStoreNamedField: public HTemplateInstruction<2> { +class HStoreNamedField: public HTemplateInstruction<3> { public: DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*, HObjectAccess, HValue*); @@ -6003,24 +6003,37 @@ class HStoreNamedField: public HTemplateInstruction<2> { return write_barrier_mode_ == SKIP_WRITE_BARRIER; } - HValue* object() { return OperandAt(0); } - HValue* value() { return OperandAt(1); } + HValue* object() const { return OperandAt(0); } + HValue* value() const { return OperandAt(1); } + HValue* transition() const { return OperandAt(2); } HObjectAccess access() const { return access_; } - Handle transition() const { return transition_; } - UniqueValueId transition_unique_id() const { return transition_unique_id_; } - void SetTransition(Handle map, CompilationInfo* info) { - ASSERT(transition_.is_null()); // Only set once. + HValue* new_space_dominator() const { return new_space_dominator_; } + + bool has_transition() const { + return transition() != object(); + } + + Handle transition_map() const { + if (has_transition()) { + return Handle::cast(HConstant::cast(transition())->handle()); + } else { + return Handle(); + } + } + + void SetTransition(HConstant* map_constant, CompilationInfo* info) { + ASSERT(!has_transition()); // Only set once. + Handle map = Handle::cast(map_constant->handle()); if (map->CanBeDeprecated()) { map->AddDependentCompilationInfo(DependentCode::kTransitionGroup, info); } - transition_ = map; + SetOperandAt(2, map_constant); } - HValue* new_space_dominator() const { return new_space_dominator_; } bool NeedsWriteBarrier() { ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || - transition_.is_null()); + !has_transition()); if (IsSkipWriteBarrier()) return false; if (field_representation().IsDouble()) return false; if (field_representation().IsSmi()) return false; @@ -6035,10 +6048,6 @@ class HStoreNamedField: public HTemplateInstruction<2> { return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); } - virtual void FinalizeUniqueValueId() { - transition_unique_id_ = UniqueValueId(transition_); - } - Representation field_representation() const { return access_.representation(); } @@ -6048,18 +6057,15 @@ class HStoreNamedField: public HTemplateInstruction<2> { HObjectAccess access, HValue* val) : access_(access), - transition_(), - transition_unique_id_(), new_space_dominator_(NULL), write_barrier_mode_(UPDATE_WRITE_BARRIER) { SetOperandAt(0, obj); SetOperandAt(1, val); + SetOperandAt(2, obj); access.SetGVNFlags(this, true); } HObjectAccess access_; - Handle transition_; - UniqueValueId transition_unique_id_; HValue* new_space_dominator_; WriteBarrierMode write_barrier_mode_; }; diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 46f0390..496b6ad 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -4506,7 +4506,8 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( if (transition_to_field) { Handle transition(lookup->GetTransitionMapFromMap(*map)); - instr->SetTransition(transition, top_info()); + HConstant* transition_constant = Add(transition); + instr->SetTransition(transition_constant, top_info()); // TODO(fschneider): Record the new map type of the object in the IR to // enable elimination of redundant checks after the transition store. instr->SetGVNFlag(kChangesMaps); diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index 94fab29..194cf85 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -2407,7 +2407,7 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { bool is_external_location = instr->access().IsExternalMemory() && instr->access().offset() == 0; bool needs_write_barrier = instr->NeedsWriteBarrier(); - bool needs_write_barrier_for_map = !instr->transition().is_null() && + bool needs_write_barrier_for_map = instr->has_transition() && instr->NeedsWriteBarrierForMap(); LOperand* obj; diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h index fc558cd..eae492e 100644 --- a/src/ia32/lithium-ia32.h +++ b/src/ia32/lithium-ia32.h @@ -2236,7 +2236,7 @@ class LStoreNamedField: public LTemplateInstruction<0, 2, 2> { virtual void PrintDataTo(StringStream* stream); - Handle transition() const { return hydrogen()->transition(); } + Handle transition() const { return hydrogen()->transition_map(); } Representation representation() const { return hydrogen()->field_representation(); } diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc index b10409d..7fdd079 100644 --- a/src/mips/lithium-mips.cc +++ b/src/mips/lithium-mips.cc @@ -2234,7 +2234,7 @@ LInstruction* LChunkBuilder::DoTrapAllocationMemento( LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { bool is_in_object = instr->access().IsInobject(); bool needs_write_barrier = instr->NeedsWriteBarrier(); - bool needs_write_barrier_for_map = !instr->transition().is_null() && + bool needs_write_barrier_for_map = instr->has_transition() && instr->NeedsWriteBarrierForMap(); LOperand* obj; diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h index 4c329d9..19af84f 100644 --- a/src/mips/lithium-mips.h +++ b/src/mips/lithium-mips.h @@ -2128,7 +2128,7 @@ class LStoreNamedField: public LTemplateInstruction<0, 2, 1> { virtual void PrintDataTo(StringStream* stream); - Handle transition() const { return hydrogen()->transition(); } + Handle transition() const { return hydrogen()->transition_map(); } Representation representation() const { return hydrogen()->field_representation(); } diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index ee3a6df..60b0a2c 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -2222,7 +2222,7 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { bool is_external_location = instr->access().IsExternalMemory() && instr->access().offset() == 0; bool needs_write_barrier = instr->NeedsWriteBarrier(); - bool needs_write_barrier_for_map = !instr->transition().is_null() && + bool needs_write_barrier_for_map = instr->has_transition() && instr->NeedsWriteBarrierForMap(); LOperand* obj; diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h index 6d8cf5a..63f5227 100644 --- a/src/x64/lithium-x64.h +++ b/src/x64/lithium-x64.h @@ -2066,7 +2066,7 @@ class LStoreNamedField: public LTemplateInstruction<0, 2, 1> { virtual void PrintDataTo(StringStream* stream); - Handle transition() const { return hydrogen()->transition(); } + Handle transition() const { return hydrogen()->transition_map(); } Representation representation() const { return hydrogen()->field_representation(); } -- 2.7.4