Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(479)

Unified Diff: src/hydrogen.cc

Issue 11659022: Generate the TransitionElementsStub using Crankshaft (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address review feedback Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index f62a2835fcca26a4e8a75f1ee2ef31d5e19486a0..00207c142f44d528805a7172698ae09cf21388a2 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -221,8 +221,9 @@ void HBasicBlock::SetJoinId(BailoutId ast_id) {
HSimulate* simulate = HSimulate::cast(predecessor->end()->previous());
// We only need to verify the ID once.
ASSERT(i != 0 ||
- predecessor->last_environment()->closure()->shared()
- ->VerifyBailoutId(ast_id));
+ (predecessor->last_environment()->closure().is_null() ||
+ predecessor->last_environment()->closure()->shared()
+ ->VerifyBailoutId(ast_id)));
simulate->set_ast_id(ast_id);
}
}
@@ -602,6 +603,11 @@ HConstant* HGraph::GetConstantInt32(SetOncePointer<HConstant>* pointer,
}
+HConstant* HGraph::GetConstant0() {
+ return GetConstantInt32(&constant_0_, 0);
+}
+
+
HConstant* HGraph::GetConstant1() {
return GetConstantInt32(&constant_1_, 1);
}
@@ -627,6 +633,128 @@ HConstant* HGraph::GetConstantHole() {
}
+HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, BailoutId id)
+ : builder_(builder),
+ finished_(false),
+ id_(id) {
+ HEnvironment* env = builder->environment();
+ HEnvironment* true_env = env->Copy();
+ HEnvironment* false_env = env->Copy();
+ HEnvironment* merge_env = env->Copy();
+ true_block_ = builder->CreateBasicBlock(true_env);
+ false_block_ = builder->CreateBasicBlock(false_env);
+ merge_block_ = builder->CreateBasicBlock(merge_env);
+}
+
+
+void HGraphBuilder::IfBuilder::BeginTrue(HValue* left,
+ HValue* right,
+ Token::Value token) {
+ HCompareIDAndBranch* compare =
+ new(zone()) HCompareIDAndBranch(left, right, token);
+ compare->ChangeRepresentation(Representation::Integer32());
+ compare->SetSuccessorAt(0, true_block_);
+ compare->SetSuccessorAt(1, false_block_);
+ builder_->current_block()->Finish(compare);
+ builder_->set_current_block(true_block_);
+}
+
+
+void HGraphBuilder::IfBuilder::BeginFalse() {
+ builder_->current_block()->Goto(merge_block_);
+ builder_->set_current_block(false_block_);
+}
+
+
+void HGraphBuilder::IfBuilder::End() {
+ ASSERT(!finished_);
+ builder_->current_block()->Goto(merge_block_);
+ builder_->set_current_block(merge_block_);
+ merge_block_->SetJoinId(id_);
+ finished_ = true;
+}
+
+
+HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder,
+ HValue* context,
+ LoopBuilder::Direction direction,
+ BailoutId id)
+ : builder_(builder),
+ context_(context),
+ direction_(direction),
+ id_(id),
+ finished_(false) {
+ HEnvironment* env = builder_->environment();
+ HEnvironment* body_env = env->Copy();
+ HEnvironment* exit_env = env->Copy();
+ header_block_ = builder->CreateLoopHeaderBlock();
+ body_block_ = builder->CreateBasicBlock(body_env);
+ exit_block_ = builder->CreateBasicBlock(exit_env);
+}
+
+
+HValue* HGraphBuilder::LoopBuilder::BeginBody(HValue* initial,
+ HValue* terminating,
+ Token::Value token) {
+ phi_ = new(zone()) HPhi(0, zone());
+ header_block_->AddPhi(phi_);
+ phi_->AddInput(initial);
+ phi_->ChangeRepresentation(Representation::Integer32());
+ HEnvironment* env = builder_->environment();
+ env->Push(initial);
+ builder_->current_block()->Goto(header_block_);
+ builder_->set_current_block(header_block_);
+
+ builder_->set_current_block(header_block_);
+ HCompareIDAndBranch* compare =
+ new(zone()) HCompareIDAndBranch(phi_, terminating, token);
+ compare->ChangeRepresentation(Representation::Integer32());
+ compare->SetSuccessorAt(0, body_block_);
+ compare->SetSuccessorAt(1, exit_block_);
+ builder_->current_block()->Finish(compare);
+
+ builder_->set_current_block(body_block_);
+ if (direction_ == kPreIncrement || direction_ == kPreDecrement) {
+ HValue* one = builder_->graph()->GetConstant1();
+ if (direction_ == kPreIncrement) {
+ increment_ = new(zone()) HAdd(context_, phi_, one);
+ } else {
+ increment_ = new(zone()) HSub(context_, phi_, one);
+ }
+ increment_->ClearFlag(HValue::kCanOverflow);
+ increment_->ChangeRepresentation(Representation::Integer32());
+ builder_->AddInstruction(increment_);
+ return increment_;
+ } else {
+ return phi_;
+ }
+}
+
+
+void HGraphBuilder::LoopBuilder::EndBody() {
+ ASSERT(!finished_);
+
+ if (direction_ == kPostIncrement || direction_ == kPostDecrement) {
+ HValue* one = builder_->graph()->GetConstant1();
+ if (direction_ == kPostIncrement) {
+ increment_ = new(zone()) HAdd(context_, phi_, one);
+ } else {
+ increment_ = new(zone()) HSub(context_, phi_, one);
+ }
+ increment_->ClearFlag(HValue::kCanOverflow);
+ increment_->ChangeRepresentation(Representation::Integer32());
+ builder_->AddInstruction(increment_);
+ }
+
+ builder_->environment()->Push(increment_);
+ builder_->current_block()->Goto(header_block_);
+ header_block_->loop_information()->RegisterBackEdge(body_block_);
+ header_block_->SetJoinId(BailoutId::StubEntry());
+ builder_->set_current_block(exit_block_);
+ finished_ = true;
+}
+
+
HGraph* HGraphBuilder::CreateGraph() {
graph_ = new(zone()) HGraph(info_);
if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info_);
@@ -651,6 +779,22 @@ void HGraphBuilder::AddSimulate(BailoutId id,
}
+HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
+ HBasicBlock* b = graph()->CreateBasicBlock();
+ b->SetInitialEnvironment(env);
+ return b;
+}
+
+
+HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() {
+ HBasicBlock* header = graph()->CreateBasicBlock();
+ HEnvironment* entry_env = environment()->CopyAsLoopHeader(header);
+ header->SetInitialEnvironment(entry_env);
+ header->AttachLoopInformation();
+ return header;
+}
+
+
HInstruction* HGraphBuilder::BuildExternalArrayElementAccess(
HValue* external_elements,
HValue* checked_key,
@@ -799,6 +943,109 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
}
+HValue* HGraphBuilder::BuildAllocateElements(HContext* context,
+ ElementsKind kind,
+ HValue* capacity) {
+ Zone* zone = this->zone();
+
+ int elements_size = IsFastDoubleElementsKind(kind)
+ ? kDoubleSize : kPointerSize;
+ HConstant* elements_size_value =
+ new(zone) HConstant(elements_size, Representation::Integer32());
+ AddInstruction(elements_size_value);
+ HValue* mul = AddInstruction(
+ new(zone) HMul(context, capacity, elements_size_value));
+ mul->ChangeRepresentation(Representation::Integer32());
+ mul->ClearFlag(HValue::kCanOverflow);
+
+ HConstant* header_size =
+ new(zone) HConstant(FixedArray::kHeaderSize, Representation::Integer32());
+ AddInstruction(header_size);
+ HValue* total_size = AddInstruction(
+ new(zone) HAdd(context, mul, header_size));
+ total_size->ChangeRepresentation(Representation::Integer32());
+ total_size->ClearFlag(HValue::kCanOverflow);
+
+ HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE;
+ if (IsFastDoubleElementsKind(kind)) {
+ flags = static_cast<HAllocate::Flags>(
+ flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED);
+ }
+
+ HValue* elements =
+ AddInstruction(new(zone) HAllocate(context, total_size,
+ HType::JSArray(), flags));
+ Isolate* isolate = graph()->isolate();
+
+ Factory* factory = isolate->factory();
+ Handle<Map> map = IsFastDoubleElementsKind(kind)
+ ? factory->fixed_double_array_map()
+ : factory->fixed_array_map();
+ BuildStoreMap(elements, map, BailoutId::StubEntry());
+
+ Handle<String> fixed_array_length_field_name =
+ isolate->factory()->length_field_symbol();
+ HInstruction* store_length =
+ new(zone) HStoreNamedField(elements, fixed_array_length_field_name,
+ capacity, true, FixedArray::kLengthOffset);
+ AddInstruction(store_length);
+ AddSimulate(BailoutId::StubEntry(), FIXED_SIMULATE);
+
+ return elements;
+}
+
+
+HInstruction* HGraphBuilder::BuildStoreMap(HValue* object,
+ HValue* map,
+ BailoutId id) {
+ Zone* zone = this->zone();
+ Isolate* isolate = graph()->isolate();
+ Factory* factory = isolate->factory();
+ Handle<String> map_field_name = factory->map_field_symbol();
+ HInstruction* store_map =
+ new(zone) HStoreNamedField(object, map_field_name, map,
+ true, JSObject::kMapOffset);
+ store_map->SetGVNFlag(kChangesMaps);
+ AddInstruction(store_map);
+ AddSimulate(id, FIXED_SIMULATE);
+ return store_map;
+}
+
+
+HInstruction* HGraphBuilder::BuildStoreMap(HValue* object,
+ Handle<Map> map,
+ BailoutId id) {
+ Zone* zone = this->zone();
+ HValue* map_constant =
+ AddInstruction(new(zone) HConstant(map, Representation::Tagged()));
+ return BuildStoreMap(object, map_constant, id);
+}
+
+
+void HGraphBuilder::BuildCopyElements(HContext* context,
+ HValue* from_elements,
+ ElementsKind from_elements_kind,
+ HValue* to_elements,
+ ElementsKind to_elements_kind,
+ HValue* length) {
+ LoopBuilder builder(this, context, LoopBuilder::kPostIncrement);
+
+ HValue* key = builder.BeginBody(graph()->GetConstant0(),
+ length, Token::LT);
+
+ HValue* element =
+ AddInstruction(new(zone()) HLoadKeyed(from_elements, key, NULL,
+ from_elements_kind,
+ ALLOW_RETURN_HOLE));
+
+ AddInstruction(new(zone()) HStoreKeyed(to_elements, key, element,
+ to_elements_kind));
+ AddSimulate(BailoutId::StubEntry(), REMOVABLE_SIMULATE);
+
+ builder.EndBody();
+}
+
+
HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info,
TypeFeedbackOracle* oracle)
: HGraphBuilder(info),
@@ -2258,7 +2505,7 @@ void HGlobalValueNumberer::ProcessLoopBlock(
bool HGlobalValueNumberer::AllowCodeMotion() {
- return info()->opt_count() + 1 < FLAG_max_opt_count;
+ return info()->IsStub() || info()->opt_count() + 1 < FLAG_max_opt_count;
}
@@ -3510,6 +3757,23 @@ bool HOptimizedGraphBuilder::BuildGraph() {
}
+void HGraph::GlobalValueNumbering() {
+ // Perform common subexpression elimination and loop-invariant code motion.
+ if (FLAG_use_gvn) {
+ HPhase phase("H_Global value numbering", this);
+ HGlobalValueNumberer gvn(this, info());
+ bool removed_side_effects = gvn.Analyze();
+ // Trigger a second analysis pass to further eliminate duplicate values that
+ // could only be discovered by removing side-effect-generating instructions
+ // during the first pass.
+ if (FLAG_smi_only_arrays && removed_side_effects) {
+ removed_side_effects = gvn.Analyze();
+ ASSERT(!removed_side_effects);
+ }
+ }
+}
+
+
bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
*bailout_reason = SmartArrayPointer<char>();
OrderBlocks();
@@ -3563,19 +3827,7 @@ bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
Canonicalize();
- // Perform common subexpression elimination and loop-invariant code motion.
- if (FLAG_use_gvn) {
- HPhase phase("H_Global value numbering", this);
- HGlobalValueNumberer gvn(this, info());
- bool removed_side_effects = gvn.Analyze();
- // Trigger a second analysis pass to further eliminate duplicate values that
- // could only be discovered by removing side-effect-generating instructions
- // during the first pass.
- if (FLAG_smi_only_arrays && removed_side_effects) {
- removed_side_effects = gvn.Analyze();
- ASSERT(!removed_side_effects);
- }
- }
+ GlobalValueNumbering();
if (FLAG_use_range) {
HRangeAnalysis rangeAnalysis(this);
@@ -4201,22 +4453,6 @@ void HOptimizedGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) {
}
-HBasicBlock* HOptimizedGraphBuilder::CreateBasicBlock(HEnvironment* env) {
- HBasicBlock* b = graph()->CreateBasicBlock();
- b->SetInitialEnvironment(env);
- return b;
-}
-
-
-HBasicBlock* HOptimizedGraphBuilder::CreateLoopHeaderBlock() {
- HBasicBlock* header = graph()->CreateBasicBlock();
- HEnvironment* entry_env = environment()->CopyAsLoopHeader(header);
- header->SetInitialEnvironment(entry_env);
- header->AttachLoopInformation();
- return header;
-}
-
-
void HOptimizedGraphBuilder::VisitBlock(Block* stmt) {
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
@@ -6538,8 +6774,9 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
ASSERT(Map::IsValidElementsTransition(
map->elements_kind(),
transition_target.at(i)->elements_kind()));
+ HValue* context = environment()->LookupContext();
transition = new(zone()) HTransitionElementsKind(
- object, map, transition_target.at(i));
+ context, object, map, transition_target.at(i));
AddInstruction(transition);
} else {
type_todo[map->elements_kind()] = true;
@@ -9791,7 +10028,7 @@ HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone)
: values_(0, zone),
frame_type_(JS_FUNCTION),
parameter_count_(0),
- specials_count_(1),
+ specials_count_(0),
local_count_(0),
outer_(NULL),
entry_(NULL),
@@ -9846,6 +10083,7 @@ void HEnvironment::Initialize(const HEnvironment* other) {
entry_ = other->entry_;
pop_count_ = other->pop_count_;
push_count_ = other->push_count_;
+ specials_count_ = other->specials_count_;
ast_id_ = other->ast_id_;
}
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698