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

Side by Side Diff: src/hydrogen.cc

Issue 6800012: Version 3.2.8... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 first_instruction_index_(-1), 68 first_instruction_index_(-1),
69 last_instruction_index_(-1), 69 last_instruction_index_(-1),
70 deleted_phis_(4), 70 deleted_phis_(4),
71 parent_loop_header_(NULL), 71 parent_loop_header_(NULL),
72 is_inline_return_target_(false) { 72 is_inline_return_target_(false) {
73 } 73 }
74 74
75 75
76 void HBasicBlock::AttachLoopInformation() { 76 void HBasicBlock::AttachLoopInformation() {
77 ASSERT(!IsLoopHeader()); 77 ASSERT(!IsLoopHeader());
78 loop_information_ = new HLoopInformation(this); 78 loop_information_ = new(zone()) HLoopInformation(this);
79 } 79 }
80 80
81 81
82 void HBasicBlock::DetachLoopInformation() { 82 void HBasicBlock::DetachLoopInformation() {
83 ASSERT(IsLoopHeader()); 83 ASSERT(IsLoopHeader());
84 loop_information_ = NULL; 84 loop_information_ = NULL;
85 } 85 }
86 86
87 87
88 void HBasicBlock::AddPhi(HPhi* phi) { 88 void HBasicBlock::AddPhi(HPhi* phi) {
(...skipping 11 matching lines...) Expand all
100 phis_.RemoveElement(phi); 100 phis_.RemoveElement(phi);
101 phi->SetBlock(NULL); 101 phi->SetBlock(NULL);
102 } 102 }
103 103
104 104
105 void HBasicBlock::AddInstruction(HInstruction* instr) { 105 void HBasicBlock::AddInstruction(HInstruction* instr) {
106 ASSERT(!IsStartBlock() || !IsFinished()); 106 ASSERT(!IsStartBlock() || !IsFinished());
107 ASSERT(!instr->IsLinked()); 107 ASSERT(!instr->IsLinked());
108 ASSERT(!IsFinished()); 108 ASSERT(!IsFinished());
109 if (first_ == NULL) { 109 if (first_ == NULL) {
110 HBlockEntry* entry = new HBlockEntry(); 110 HBlockEntry* entry = new(zone()) HBlockEntry();
111 entry->InitializeAsFirst(this); 111 entry->InitializeAsFirst(this);
112 first_ = last_ = entry; 112 first_ = last_ = entry;
113 } 113 }
114 instr->InsertAfter(last_); 114 instr->InsertAfter(last_);
115 last_ = instr; 115 last_ = instr;
116 } 116 }
117 117
118 118
119 HDeoptimize* HBasicBlock::CreateDeoptimize() { 119 HDeoptimize* HBasicBlock::CreateDeoptimize() {
120 ASSERT(HasEnvironment()); 120 ASSERT(HasEnvironment());
121 HEnvironment* environment = last_environment(); 121 HEnvironment* environment = last_environment();
122 122
123 HDeoptimize* instr = new HDeoptimize(environment->length()); 123 HDeoptimize* instr = new(zone()) HDeoptimize(environment->length());
124 124
125 for (int i = 0; i < environment->length(); i++) { 125 for (int i = 0; i < environment->length(); i++) {
126 HValue* val = environment->values()->at(i); 126 HValue* val = environment->values()->at(i);
127 instr->AddEnvironmentValue(val); 127 instr->AddEnvironmentValue(val);
128 } 128 }
129 129
130 return instr; 130 return instr;
131 } 131 }
132 132
133 133
134 HSimulate* HBasicBlock::CreateSimulate(int id) { 134 HSimulate* HBasicBlock::CreateSimulate(int id) {
135 ASSERT(HasEnvironment()); 135 ASSERT(HasEnvironment());
136 HEnvironment* environment = last_environment(); 136 HEnvironment* environment = last_environment();
137 ASSERT(id == AstNode::kNoNumber || 137 ASSERT(id == AstNode::kNoNumber ||
138 environment->closure()->shared()->VerifyBailoutId(id)); 138 environment->closure()->shared()->VerifyBailoutId(id));
139 139
140 int push_count = environment->push_count(); 140 int push_count = environment->push_count();
141 int pop_count = environment->pop_count(); 141 int pop_count = environment->pop_count();
142 142
143 int length = environment->length(); 143 HSimulate* instr = new(zone()) HSimulate(id, pop_count);
144 HSimulate* instr = new HSimulate(id, pop_count, length);
145 for (int i = push_count - 1; i >= 0; --i) { 144 for (int i = push_count - 1; i >= 0; --i) {
146 instr->AddPushedValue(environment->ExpressionStackAt(i)); 145 instr->AddPushedValue(environment->ExpressionStackAt(i));
147 } 146 }
148 for (int i = 0; i < environment->assigned_variables()->length(); ++i) { 147 for (int i = 0; i < environment->assigned_variables()->length(); ++i) {
149 int index = environment->assigned_variables()->at(i); 148 int index = environment->assigned_variables()->at(i);
150 instr->AddAssignedValue(index, environment->Lookup(index)); 149 instr->AddAssignedValue(index, environment->Lookup(index));
151 } 150 }
152 environment->ClearHistory(); 151 environment->ClearHistory();
153 return instr; 152 return instr;
154 } 153 }
155 154
156 155
157 void HBasicBlock::Finish(HControlInstruction* end) { 156 void HBasicBlock::Finish(HControlInstruction* end) {
158 ASSERT(!IsFinished()); 157 ASSERT(!IsFinished());
159 AddInstruction(end); 158 AddInstruction(end);
160 end_ = end; 159 end_ = end;
161 if (end->FirstSuccessor() != NULL) { 160 if (end->FirstSuccessor() != NULL) {
162 end->FirstSuccessor()->RegisterPredecessor(this); 161 end->FirstSuccessor()->RegisterPredecessor(this);
163 if (end->SecondSuccessor() != NULL) { 162 if (end->SecondSuccessor() != NULL) {
164 end->SecondSuccessor()->RegisterPredecessor(this); 163 end->SecondSuccessor()->RegisterPredecessor(this);
165 } 164 }
166 } 165 }
167 } 166 }
168 167
169 168
170 void HBasicBlock::Goto(HBasicBlock* block, bool include_stack_check) { 169 void HBasicBlock::Goto(HBasicBlock* block, bool include_stack_check) {
171 if (block->IsInlineReturnTarget()) { 170 if (block->IsInlineReturnTarget()) {
172 AddInstruction(new HLeaveInlined); 171 AddInstruction(new(zone()) HLeaveInlined);
173 last_environment_ = last_environment()->outer(); 172 last_environment_ = last_environment()->outer();
174 } 173 }
175 AddSimulate(AstNode::kNoNumber); 174 AddSimulate(AstNode::kNoNumber);
176 HGoto* instr = new HGoto(block); 175 HGoto* instr = new(zone()) HGoto(block);
177 instr->set_include_stack_check(include_stack_check); 176 instr->set_include_stack_check(include_stack_check);
178 Finish(instr); 177 Finish(instr);
179 } 178 }
180 179
181 180
182 void HBasicBlock::AddLeaveInlined(HValue* return_value, HBasicBlock* target) { 181 void HBasicBlock::AddLeaveInlined(HValue* return_value, HBasicBlock* target) {
183 ASSERT(target->IsInlineReturnTarget()); 182 ASSERT(target->IsInlineReturnTarget());
184 ASSERT(return_value != NULL); 183 ASSERT(return_value != NULL);
185 AddInstruction(new HLeaveInlined); 184 AddInstruction(new(zone()) HLeaveInlined);
186 last_environment_ = last_environment()->outer(); 185 last_environment_ = last_environment()->outer();
187 last_environment()->Push(return_value); 186 last_environment()->Push(return_value);
188 AddSimulate(AstNode::kNoNumber); 187 AddSimulate(AstNode::kNoNumber);
189 HGoto* instr = new HGoto(target); 188 HGoto* instr = new(zone()) HGoto(target);
190 Finish(instr); 189 Finish(instr);
191 } 190 }
192 191
193 192
194 void HBasicBlock::SetInitialEnvironment(HEnvironment* env) { 193 void HBasicBlock::SetInitialEnvironment(HEnvironment* env) {
195 ASSERT(!HasEnvironment()); 194 ASSERT(!HasEnvironment());
196 ASSERT(first() == NULL); 195 ASSERT(first() == NULL);
197 UpdateEnvironment(env); 196 UpdateEnvironment(env);
198 } 197 }
199 198
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 } 486 }
488 } 487 }
489 } 488 }
490 489
491 #endif 490 #endif
492 491
493 492
494 HConstant* HGraph::GetConstant(SetOncePointer<HConstant>* pointer, 493 HConstant* HGraph::GetConstant(SetOncePointer<HConstant>* pointer,
495 Object* value) { 494 Object* value) {
496 if (!pointer->is_set()) { 495 if (!pointer->is_set()) {
497 HConstant* constant = new HConstant(Handle<Object>(value), 496 HConstant* constant = new(zone()) HConstant(Handle<Object>(value),
498 Representation::Tagged()); 497 Representation::Tagged());
499 constant->InsertAfter(GetConstantUndefined()); 498 constant->InsertAfter(GetConstantUndefined());
500 pointer->set(constant); 499 pointer->set(constant);
501 } 500 }
502 return pointer->get(); 501 return pointer->get();
503 } 502 }
504 503
505 504
506 HConstant* HGraph::GetConstant1() { 505 HConstant* HGraph::GetConstant1() {
507 return GetConstant(&constant_1_, Smi::FromInt(1)); 506 return GetConstant(&constant_1_, Smi::FromInt(1));
508 } 507 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 } 573 }
575 574
576 575
577 HGraph::HGraph(CompilationInfo* info) 576 HGraph::HGraph(CompilationInfo* info)
578 : isolate_(info->isolate()), 577 : isolate_(info->isolate()),
579 next_block_id_(0), 578 next_block_id_(0),
580 entry_block_(NULL), 579 entry_block_(NULL),
581 blocks_(8), 580 blocks_(8),
582 values_(16), 581 values_(16),
583 phi_list_(NULL) { 582 phi_list_(NULL) {
584 start_environment_ = new HEnvironment(NULL, info->scope(), info->closure()); 583 start_environment_ =
584 new(zone()) HEnvironment(NULL, info->scope(), info->closure());
585 start_environment_->set_ast_id(info->function()->id()); 585 start_environment_->set_ast_id(info->function()->id());
586 entry_block_ = CreateBasicBlock(); 586 entry_block_ = CreateBasicBlock();
587 entry_block_->SetInitialEnvironment(start_environment_); 587 entry_block_->SetInitialEnvironment(start_environment_);
588 } 588 }
589 589
590 590
591 Handle<Code> HGraph::Compile(CompilationInfo* info) { 591 Handle<Code> HGraph::Compile(CompilationInfo* info) {
592 int values = GetMaximumValueID(); 592 int values = GetMaximumValueID();
593 if (values > LAllocator::max_initial_value_ids()) { 593 if (values > LAllocator::max_initial_value_ids()) {
594 if (FLAG_trace_bailout) PrintF("Function is too big\n"); 594 if (FLAG_trace_bailout) PrintF("Function is too big\n");
(...skipping 29 matching lines...) Expand all
624 CodeGenerator::MakeCodeEpilogue(&assembler, flags, info); 624 CodeGenerator::MakeCodeEpilogue(&assembler, flags, info);
625 generator.FinishCode(code); 625 generator.FinishCode(code);
626 CodeGenerator::PrintCode(code, info); 626 CodeGenerator::PrintCode(code, info);
627 return code; 627 return code;
628 } 628 }
629 return Handle<Code>::null(); 629 return Handle<Code>::null();
630 } 630 }
631 631
632 632
633 HBasicBlock* HGraph::CreateBasicBlock() { 633 HBasicBlock* HGraph::CreateBasicBlock() {
634 HBasicBlock* result = new HBasicBlock(this); 634 HBasicBlock* result = new(zone()) HBasicBlock(this);
635 blocks_.Add(result); 635 blocks_.Add(result);
636 return result; 636 return result;
637 } 637 }
638 638
639 639
640 void HGraph::Canonicalize() { 640 void HGraph::Canonicalize() {
641 if (!FLAG_use_canonicalizing) return; 641 if (!FLAG_use_canonicalizing) return;
642 HPhase phase("Canonicalize", this); 642 HPhase phase("Canonicalize", this);
643 for (int i = 0; i < blocks()->length(); ++i) { 643 for (int i = 0; i < blocks()->length(); ++i) {
644 HInstruction* instr = blocks()->at(i)->first(); 644 HInstruction* instr = blocks()->at(i)->first();
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 void ComputeBlockSideEffects(); 1266 void ComputeBlockSideEffects();
1267 void LoopInvariantCodeMotion(); 1267 void LoopInvariantCodeMotion();
1268 void ProcessLoopBlock(HBasicBlock* block, 1268 void ProcessLoopBlock(HBasicBlock* block,
1269 HBasicBlock* before_loop, 1269 HBasicBlock* before_loop,
1270 int loop_kills); 1270 int loop_kills);
1271 bool AllowCodeMotion(); 1271 bool AllowCodeMotion();
1272 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); 1272 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header);
1273 1273
1274 HGraph* graph() { return graph_; } 1274 HGraph* graph() { return graph_; }
1275 CompilationInfo* info() { return info_; } 1275 CompilationInfo* info() { return info_; }
1276 Zone* zone() { return graph_->zone(); }
1276 1277
1277 HGraph* graph_; 1278 HGraph* graph_;
1278 CompilationInfo* info_; 1279 CompilationInfo* info_;
1279 1280
1280 // A map of block IDs to their side effects. 1281 // A map of block IDs to their side effects.
1281 ZoneList<int> block_side_effects_; 1282 ZoneList<int> block_side_effects_;
1282 1283
1283 // A map of loop header block IDs to their loop's side effects. 1284 // A map of loop header block IDs to their loop's side effects.
1284 ZoneList<int> loop_side_effects_; 1285 ZoneList<int> loop_side_effects_;
1285 }; 1286 };
1286 1287
1287 1288
1288 void HGlobalValueNumberer::Analyze() { 1289 void HGlobalValueNumberer::Analyze() {
1289 ComputeBlockSideEffects(); 1290 ComputeBlockSideEffects();
1290 if (FLAG_loop_invariant_code_motion) { 1291 if (FLAG_loop_invariant_code_motion) {
1291 LoopInvariantCodeMotion(); 1292 LoopInvariantCodeMotion();
1292 } 1293 }
1293 HValueMap* map = new HValueMap(); 1294 HValueMap* map = new(zone()) HValueMap();
1294 AnalyzeBlock(graph_->blocks()->at(0), map); 1295 AnalyzeBlock(graph_->blocks()->at(0), map);
1295 } 1296 }
1296 1297
1297 1298
1298 void HGlobalValueNumberer::ComputeBlockSideEffects() { 1299 void HGlobalValueNumberer::ComputeBlockSideEffects() {
1299 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { 1300 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) {
1300 // Compute side effects for the block. 1301 // Compute side effects for the block.
1301 HBasicBlock* block = graph_->blocks()->at(i); 1302 HBasicBlock* block = graph_->blocks()->at(i);
1302 HInstruction* instr = block->first(); 1303 HInstruction* instr = block->first();
1303 int id = block->block_id(); 1304 int id = block->block_id();
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1450 } 1451 }
1451 } 1452 }
1452 instr = next; 1453 instr = next;
1453 } 1454 }
1454 1455
1455 // Recursively continue analysis for all immediately dominated blocks. 1456 // Recursively continue analysis for all immediately dominated blocks.
1456 int length = block->dominated_blocks()->length(); 1457 int length = block->dominated_blocks()->length();
1457 for (int i = 0; i < length; ++i) { 1458 for (int i = 0; i < length; ++i) {
1458 HBasicBlock* dominated = block->dominated_blocks()->at(i); 1459 HBasicBlock* dominated = block->dominated_blocks()->at(i);
1459 // No need to copy the map for the last child in the dominator tree. 1460 // No need to copy the map for the last child in the dominator tree.
1460 HValueMap* successor_map = (i == length - 1) ? map : map->Copy(); 1461 HValueMap* successor_map = (i == length - 1) ? map : map->Copy(zone());
1461 1462
1462 // If the dominated block is not a successor to this block we have to 1463 // If the dominated block is not a successor to this block we have to
1463 // kill everything killed on any path between this block and the 1464 // kill everything killed on any path between this block and the
1464 // dominated block. Note we rely on the block ordering. 1465 // dominated block. Note we rely on the block ordering.
1465 bool is_successor = false; 1466 bool is_successor = false;
1466 int predecessor_count = dominated->predecessors()->length(); 1467 int predecessor_count = dominated->predecessors()->length();
1467 for (int j = 0; !is_successor && j < predecessor_count; ++j) { 1468 for (int j = 0; !is_successor && j < predecessor_count; ++j) {
1468 is_successor = (dominated->predecessors()->at(j) == block); 1469 is_successor = (dominated->predecessors()->at(j) == block);
1469 } 1470 }
1470 1471
(...skipping 17 matching lines...) Expand all
1488 1489
1489 void Analyze(); 1490 void Analyze();
1490 1491
1491 private: 1492 private:
1492 Representation TryChange(HValue* current); 1493 Representation TryChange(HValue* current);
1493 void AddToWorklist(HValue* current); 1494 void AddToWorklist(HValue* current);
1494 void InferBasedOnInputs(HValue* current); 1495 void InferBasedOnInputs(HValue* current);
1495 void AddDependantsToWorklist(HValue* current); 1496 void AddDependantsToWorklist(HValue* current);
1496 void InferBasedOnUses(HValue* current); 1497 void InferBasedOnUses(HValue* current);
1497 1498
1499 Zone* zone() { return graph_->zone(); }
1500
1498 HGraph* graph_; 1501 HGraph* graph_;
1499 ZoneList<HValue*> worklist_; 1502 ZoneList<HValue*> worklist_;
1500 BitVector in_worklist_; 1503 BitVector in_worklist_;
1501 }; 1504 };
1502 1505
1503 1506
1504 void HInferRepresentation::AddToWorklist(HValue* current) { 1507 void HInferRepresentation::AddToWorklist(HValue* current) {
1505 if (current->representation().IsSpecialization()) return; 1508 if (current->representation().IsSpecialization()) return;
1506 if (!current->CheckFlag(HValue::kFlexibleRepresentation)) return; 1509 if (!current->CheckFlag(HValue::kFlexibleRepresentation)) return;
1507 if (in_worklist_.Contains(current->id())) return; 1510 if (in_worklist_.Contains(current->id())) return;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1599 void HInferRepresentation::Analyze() { 1602 void HInferRepresentation::Analyze() {
1600 HPhase phase("Infer representations", graph_); 1603 HPhase phase("Infer representations", graph_);
1601 1604
1602 // (1) Initialize bit vectors and count real uses. Each phi 1605 // (1) Initialize bit vectors and count real uses. Each phi
1603 // gets a bit-vector of length <number of phis>. 1606 // gets a bit-vector of length <number of phis>.
1604 const ZoneList<HPhi*>* phi_list = graph_->phi_list(); 1607 const ZoneList<HPhi*>* phi_list = graph_->phi_list();
1605 int num_phis = phi_list->length(); 1608 int num_phis = phi_list->length();
1606 ScopedVector<BitVector*> connected_phis(num_phis); 1609 ScopedVector<BitVector*> connected_phis(num_phis);
1607 for (int i = 0; i < num_phis; i++) { 1610 for (int i = 0; i < num_phis; i++) {
1608 phi_list->at(i)->InitRealUses(i); 1611 phi_list->at(i)->InitRealUses(i);
1609 connected_phis[i] = new BitVector(num_phis); 1612 connected_phis[i] = new(zone()) BitVector(num_phis);
1610 connected_phis[i]->Add(i); 1613 connected_phis[i]->Add(i);
1611 } 1614 }
1612 1615
1613 // (2) Do a fixed point iteration to find the set of connected phis. 1616 // (2) Do a fixed point iteration to find the set of connected phis.
1614 // A phi is connected to another phi if its value is used either 1617 // A phi is connected to another phi if its value is used either
1615 // directly or indirectly through a transitive closure of the def-use 1618 // directly or indirectly through a transitive closure of the def-use
1616 // relation. 1619 // relation.
1617 bool change = true; 1620 bool change = true;
1618 while (change) { 1621 while (change) {
1619 change = false; 1622 change = false;
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1764 bool is_truncating = use->CheckFlag(HValue::kTruncatingToInt32); 1767 bool is_truncating = use->CheckFlag(HValue::kTruncatingToInt32);
1765 if (value->IsConstant()) { 1768 if (value->IsConstant()) {
1766 HConstant* constant = HConstant::cast(value); 1769 HConstant* constant = HConstant::cast(value);
1767 // Try to create a new copy of the constant with the new representation. 1770 // Try to create a new copy of the constant with the new representation.
1768 new_value = is_truncating 1771 new_value = is_truncating
1769 ? constant->CopyToTruncatedInt32() 1772 ? constant->CopyToTruncatedInt32()
1770 : constant->CopyToRepresentation(to); 1773 : constant->CopyToRepresentation(to);
1771 } 1774 }
1772 1775
1773 if (new_value == NULL) { 1776 if (new_value == NULL) {
1774 new_value = new HChange(value, value->representation(), to, is_truncating); 1777 new_value =
1778 new(zone()) HChange(value, value->representation(), to, is_truncating);
1775 } 1779 }
1776 1780
1777 new_value->InsertBefore(next); 1781 new_value->InsertBefore(next);
1778 value->ReplaceFirstAtUse(use, new_value, to); 1782 value->ReplaceFirstAtUse(use, new_value, to);
1779 } 1783 }
1780 1784
1781 1785
1782 int CompareConversionUses(HValue* a, 1786 int CompareConversionUses(HValue* a,
1783 HValue* b, 1787 HValue* b,
1784 Representation a_rep, 1788 Representation a_rep,
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
2055 2059
2056 2060
2057 void TestContext::BuildBranch(HValue* value) { 2061 void TestContext::BuildBranch(HValue* value) {
2058 // We expect the graph to be in edge-split form: there is no edge that 2062 // We expect the graph to be in edge-split form: there is no edge that
2059 // connects a branch node to a join node. We conservatively ensure that 2063 // connects a branch node to a join node. We conservatively ensure that
2060 // property by always adding an empty block on the outgoing edges of this 2064 // property by always adding an empty block on the outgoing edges of this
2061 // branch. 2065 // branch.
2062 HGraphBuilder* builder = owner(); 2066 HGraphBuilder* builder = owner();
2063 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); 2067 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock();
2064 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); 2068 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock();
2065 HTest* test = new HTest(value, empty_true, empty_false); 2069 HTest* test = new(zone()) HTest(value, empty_true, empty_false);
2066 builder->current_block()->Finish(test); 2070 builder->current_block()->Finish(test);
2067 2071
2068 empty_true->Goto(if_true(), false); 2072 empty_true->Goto(if_true(), false);
2069 empty_false->Goto(if_false(), false); 2073 empty_false->Goto(if_false(), false);
2070 builder->set_current_block(NULL); 2074 builder->set_current_block(NULL);
2071 } 2075 }
2072 2076
2073 2077
2074 // HGraphBuilder infrastructure for bailing out and checking bailouts. 2078 // HGraphBuilder infrastructure for bailing out and checking bailouts.
2075 #define BAILOUT(reason) \ 2079 #define BAILOUT(reason) \
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2138 void HGraphBuilder::VisitForControl(Expression* expr, 2142 void HGraphBuilder::VisitForControl(Expression* expr,
2139 HBasicBlock* true_block, 2143 HBasicBlock* true_block,
2140 HBasicBlock* false_block) { 2144 HBasicBlock* false_block) {
2141 TestContext for_test(this, true_block, false_block); 2145 TestContext for_test(this, true_block, false_block);
2142 Visit(expr); 2146 Visit(expr);
2143 } 2147 }
2144 2148
2145 2149
2146 void HGraphBuilder::VisitArgument(Expression* expr) { 2150 void HGraphBuilder::VisitArgument(Expression* expr) {
2147 VISIT_FOR_VALUE(expr); 2151 VISIT_FOR_VALUE(expr);
2148 Push(AddInstruction(new HPushArgument(Pop()))); 2152 Push(AddInstruction(new(zone()) HPushArgument(Pop())));
2149 } 2153 }
2150 2154
2151 2155
2152 void HGraphBuilder::VisitArgumentList(ZoneList<Expression*>* arguments) { 2156 void HGraphBuilder::VisitArgumentList(ZoneList<Expression*>* arguments) {
2153 for (int i = 0; i < arguments->length(); i++) { 2157 for (int i = 0; i < arguments->length(); i++) {
2154 VisitArgument(arguments->at(i)); 2158 VisitArgument(arguments->at(i));
2155 if (HasStackOverflow() || current_block() == NULL) return; 2159 if (HasStackOverflow() || current_block() == NULL) return;
2156 } 2160 }
2157 } 2161 }
2158 2162
2159 2163
2160 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) { 2164 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) {
2161 for (int i = 0; i < exprs->length(); ++i) { 2165 for (int i = 0; i < exprs->length(); ++i) {
2162 VISIT_FOR_VALUE(exprs->at(i)); 2166 VISIT_FOR_VALUE(exprs->at(i));
2163 } 2167 }
2164 } 2168 }
2165 2169
2166 2170
2167 HGraph* HGraphBuilder::CreateGraph() { 2171 HGraph* HGraphBuilder::CreateGraph() {
2168 graph_ = new HGraph(info()); 2172 graph_ = new(zone()) HGraph(info());
2169 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info()); 2173 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info());
2170 2174
2171 { 2175 {
2172 HPhase phase("Block building"); 2176 HPhase phase("Block building");
2173 current_block_ = graph()->entry_block(); 2177 current_block_ = graph()->entry_block();
2174 2178
2175 Scope* scope = info()->scope(); 2179 Scope* scope = info()->scope();
2176 if (scope->HasIllegalRedeclaration()) { 2180 if (scope->HasIllegalRedeclaration()) {
2177 Bailout("function with illegal redeclaration"); 2181 Bailout("function with illegal redeclaration");
2178 return NULL; 2182 return NULL;
2179 } 2183 }
2180 SetupScope(scope); 2184 SetupScope(scope);
2181 VisitDeclarations(scope->declarations()); 2185 VisitDeclarations(scope->declarations());
2182 AddInstruction(new HStackCheck()); 2186 AddInstruction(new(zone()) HStackCheck());
2183 2187
2184 // Add an edge to the body entry. This is warty: the graph's start 2188 // Add an edge to the body entry. This is warty: the graph's start
2185 // environment will be used by the Lithium translation as the initial 2189 // environment will be used by the Lithium translation as the initial
2186 // environment on graph entry, but it has now been mutated by the 2190 // environment on graph entry, but it has now been mutated by the
2187 // Hydrogen translation of the instructions in the start block. This 2191 // Hydrogen translation of the instructions in the start block. This
2188 // environment uses values which have not been defined yet. These 2192 // environment uses values which have not been defined yet. These
2189 // Hydrogen instructions will then be replayed by the Lithium 2193 // Hydrogen instructions will then be replayed by the Lithium
2190 // translation, so they cannot have an environment effect. The edge to 2194 // translation, so they cannot have an environment effect. The edge to
2191 // the body's entry block (along with some special logic for the start 2195 // the body's entry block (along with some special logic for the start
2192 // block in HInstruction::InsertAfter) seals the start block from 2196 // block in HInstruction::InsertAfter) seals the start block from
2193 // getting unwanted instructions inserted. 2197 // getting unwanted instructions inserted.
2194 // 2198 //
2195 // TODO(kmillikin): Fix this. Stop mutating the initial environment. 2199 // TODO(kmillikin): Fix this. Stop mutating the initial environment.
2196 // Make the Hydrogen instructions in the initial block into Hydrogen 2200 // Make the Hydrogen instructions in the initial block into Hydrogen
2197 // values (but not instructions), present in the initial environment and 2201 // values (but not instructions), present in the initial environment and
2198 // not replayed by the Lithium translation. 2202 // not replayed by the Lithium translation.
2199 HEnvironment* initial_env = environment()->CopyWithoutHistory(); 2203 HEnvironment* initial_env = environment()->CopyWithoutHistory();
2200 HBasicBlock* body_entry = CreateBasicBlock(initial_env); 2204 HBasicBlock* body_entry = CreateBasicBlock(initial_env);
2201 current_block()->Goto(body_entry); 2205 current_block()->Goto(body_entry);
2202 body_entry->SetJoinId(info()->function()->id()); 2206 body_entry->SetJoinId(info()->function()->id());
2203 set_current_block(body_entry); 2207 set_current_block(body_entry);
2204 VisitStatements(info()->function()->body()); 2208 VisitStatements(info()->function()->body());
2205 if (HasStackOverflow()) return NULL; 2209 if (HasStackOverflow()) return NULL;
2206 2210
2207 if (current_block() != NULL) { 2211 if (current_block() != NULL) {
2208 HReturn* instr = new HReturn(graph()->GetConstantUndefined()); 2212 HReturn* instr = new(zone()) HReturn(graph()->GetConstantUndefined());
2209 current_block()->FinishExit(instr); 2213 current_block()->FinishExit(instr);
2210 set_current_block(NULL); 2214 set_current_block(NULL);
2211 } 2215 }
2212 } 2216 }
2213 2217
2214 graph()->OrderBlocks(); 2218 graph()->OrderBlocks();
2215 graph()->AssignDominators(); 2219 graph()->AssignDominators();
2216 graph()->EliminateRedundantPhis(); 2220 graph()->EliminateRedundantPhis();
2217 if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis(); 2221 if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis();
2218 if (!graph()->CollectPhis()) { 2222 if (!graph()->CollectPhis()) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2275 2279
2276 template <int V> 2280 template <int V>
2277 HInstruction* HGraphBuilder::PreProcessCall(HCall<V>* call) { 2281 HInstruction* HGraphBuilder::PreProcessCall(HCall<V>* call) {
2278 int count = call->argument_count(); 2282 int count = call->argument_count();
2279 ZoneList<HValue*> arguments(count); 2283 ZoneList<HValue*> arguments(count);
2280 for (int i = 0; i < count; ++i) { 2284 for (int i = 0; i < count; ++i) {
2281 arguments.Add(Pop()); 2285 arguments.Add(Pop());
2282 } 2286 }
2283 2287
2284 while (!arguments.is_empty()) { 2288 while (!arguments.is_empty()) {
2285 AddInstruction(new HPushArgument(arguments.RemoveLast())); 2289 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast()));
2286 } 2290 }
2287 return call; 2291 return call;
2288 } 2292 }
2289 2293
2290 2294
2291 void HGraphBuilder::SetupScope(Scope* scope) { 2295 void HGraphBuilder::SetupScope(Scope* scope) {
2292 // We don't yet handle the function name for named function expressions. 2296 // We don't yet handle the function name for named function expressions.
2293 if (scope->function() != NULL) BAILOUT("named function expression"); 2297 if (scope->function() != NULL) BAILOUT("named function expression");
2294 2298
2295 HConstant* undefined_constant = new HConstant( 2299 HConstant* undefined_constant = new(zone()) HConstant(
2296 isolate()->factory()->undefined_value(), Representation::Tagged()); 2300 isolate()->factory()->undefined_value(), Representation::Tagged());
2297 AddInstruction(undefined_constant); 2301 AddInstruction(undefined_constant);
2298 graph_->set_undefined_constant(undefined_constant); 2302 graph_->set_undefined_constant(undefined_constant);
2299 2303
2300 // Set the initial values of parameters including "this". "This" has 2304 // Set the initial values of parameters including "this". "This" has
2301 // parameter index 0. 2305 // parameter index 0.
2302 int count = scope->num_parameters() + 1; 2306 int count = scope->num_parameters() + 1;
2303 for (int i = 0; i < count; ++i) { 2307 for (int i = 0; i < count; ++i) {
2304 HInstruction* parameter = AddInstruction(new HParameter(i)); 2308 HInstruction* parameter = AddInstruction(new(zone()) HParameter(i));
2305 environment()->Bind(i, parameter); 2309 environment()->Bind(i, parameter);
2306 } 2310 }
2307 2311
2308 // Set the initial values of stack-allocated locals. 2312 // Set the initial values of stack-allocated locals.
2309 for (int i = count; i < environment()->length(); ++i) { 2313 for (int i = count; i < environment()->length(); ++i) {
2310 environment()->Bind(i, undefined_constant); 2314 environment()->Bind(i, undefined_constant);
2311 } 2315 }
2312 2316
2313 // Handle the arguments and arguments shadow variables specially (they do 2317 // Handle the arguments and arguments shadow variables specially (they do
2314 // not have declarations). 2318 // not have declarations).
2315 if (scope->arguments() != NULL) { 2319 if (scope->arguments() != NULL) {
2316 if (!scope->arguments()->IsStackAllocated() || 2320 if (!scope->arguments()->IsStackAllocated() ||
2317 (scope->arguments_shadow() != NULL && 2321 (scope->arguments_shadow() != NULL &&
2318 !scope->arguments_shadow()->IsStackAllocated())) { 2322 !scope->arguments_shadow()->IsStackAllocated())) {
2319 BAILOUT("context-allocated arguments"); 2323 BAILOUT("context-allocated arguments");
2320 } 2324 }
2321 HArgumentsObject* object = new HArgumentsObject; 2325 HArgumentsObject* object = new(zone()) HArgumentsObject;
2322 AddInstruction(object); 2326 AddInstruction(object);
2323 graph()->SetArgumentsObject(object); 2327 graph()->SetArgumentsObject(object);
2324 environment()->Bind(scope->arguments(), object); 2328 environment()->Bind(scope->arguments(), object);
2325 if (scope->arguments_shadow() != NULL) { 2329 if (scope->arguments_shadow() != NULL) {
2326 environment()->Bind(scope->arguments_shadow(), object); 2330 environment()->Bind(scope->arguments_shadow(), object);
2327 } 2331 }
2328 } 2332 }
2329 } 2333 }
2330 2334
2331 2335
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2450 set_current_block(NULL); 2454 set_current_block(NULL);
2451 } 2455 }
2452 2456
2453 2457
2454 void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { 2458 void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
2455 AstContext* context = call_context(); 2459 AstContext* context = call_context();
2456 if (context == NULL) { 2460 if (context == NULL) {
2457 // Not an inlined return, so an actual one. 2461 // Not an inlined return, so an actual one.
2458 VISIT_FOR_VALUE(stmt->expression()); 2462 VISIT_FOR_VALUE(stmt->expression());
2459 HValue* result = environment()->Pop(); 2463 HValue* result = environment()->Pop();
2460 current_block()->FinishExit(new HReturn(result)); 2464 current_block()->FinishExit(new(zone()) HReturn(result));
2461 set_current_block(NULL); 2465 set_current_block(NULL);
2462 } else { 2466 } else {
2463 // Return from an inlined function, visit the subexpression in the 2467 // Return from an inlined function, visit the subexpression in the
2464 // expression context of the call. 2468 // expression context of the call.
2465 if (context->IsTest()) { 2469 if (context->IsTest()) {
2466 TestContext* test = TestContext::cast(context); 2470 TestContext* test = TestContext::cast(context);
2467 VisitForControl(stmt->expression(), 2471 VisitForControl(stmt->expression(),
2468 test->if_true(), 2472 test->if_true(),
2469 test->if_false()); 2473 test->if_false());
2470 } else if (context->IsEffect()) { 2474 } else if (context->IsEffect()) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2519 clause->RecordTypeFeedback(oracle()); 2523 clause->RecordTypeFeedback(oracle());
2520 if (!clause->IsSmiCompare()) { 2524 if (!clause->IsSmiCompare()) {
2521 current_block()->FinishExitWithDeoptimization(); 2525 current_block()->FinishExitWithDeoptimization();
2522 set_current_block(NULL); 2526 set_current_block(NULL);
2523 break; 2527 break;
2524 } 2528 }
2525 2529
2526 // Otherwise generate a compare and branch. 2530 // Otherwise generate a compare and branch.
2527 VISIT_FOR_VALUE(clause->label()); 2531 VISIT_FOR_VALUE(clause->label());
2528 HValue* label_value = Pop(); 2532 HValue* label_value = Pop();
2529 HCompare* compare = new HCompare(tag_value, label_value, Token::EQ_STRICT); 2533 HCompare* compare =
2534 new(zone()) HCompare(tag_value, label_value, Token::EQ_STRICT);
2530 compare->SetInputRepresentation(Representation::Integer32()); 2535 compare->SetInputRepresentation(Representation::Integer32());
2531 ASSERT(!compare->HasSideEffects()); 2536 ASSERT(!compare->HasSideEffects());
2532 AddInstruction(compare); 2537 AddInstruction(compare);
2533 HBasicBlock* body_block = graph()->CreateBasicBlock(); 2538 HBasicBlock* body_block = graph()->CreateBasicBlock();
2534 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); 2539 HBasicBlock* next_test_block = graph()->CreateBasicBlock();
2535 HTest* branch = new HTest(compare, body_block, next_test_block); 2540 HTest* branch = new(zone()) HTest(compare, body_block, next_test_block);
2536 current_block()->Finish(branch); 2541 current_block()->Finish(branch);
2537 set_current_block(next_test_block); 2542 set_current_block(next_test_block);
2538 } 2543 }
2539 2544
2540 // Save the current block to use for the default or to join with the 2545 // Save the current block to use for the default or to join with the
2541 // exit. This block is NULL if we deoptimized. 2546 // exit. This block is NULL if we deoptimized.
2542 HBasicBlock* last_block = current_block(); 2547 HBasicBlock* last_block = current_block();
2543 2548
2544 // 2. Loop over the clauses and the linked list of tests in lockstep, 2549 // 2. Loop over the clauses and the linked list of tests in lockstep,
2545 // translating the clause bodies. 2550 // translating the clause bodies.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2611 return statement->OsrEntryId() == info()->osr_ast_id(); 2616 return statement->OsrEntryId() == info()->osr_ast_id();
2612 } 2617 }
2613 2618
2614 2619
2615 void HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) { 2620 void HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) {
2616 if (!HasOsrEntryAt(statement)) return; 2621 if (!HasOsrEntryAt(statement)) return;
2617 2622
2618 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); 2623 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock();
2619 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); 2624 HBasicBlock* osr_entry = graph()->CreateBasicBlock();
2620 HValue* true_value = graph()->GetConstantTrue(); 2625 HValue* true_value = graph()->GetConstantTrue();
2621 HTest* test = new HTest(true_value, non_osr_entry, osr_entry); 2626 HTest* test = new(zone()) HTest(true_value, non_osr_entry, osr_entry);
2622 current_block()->Finish(test); 2627 current_block()->Finish(test);
2623 2628
2624 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); 2629 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock();
2625 non_osr_entry->Goto(loop_predecessor); 2630 non_osr_entry->Goto(loop_predecessor);
2626 2631
2627 set_current_block(osr_entry); 2632 set_current_block(osr_entry);
2628 int osr_entry_id = statement->OsrEntryId(); 2633 int osr_entry_id = statement->OsrEntryId();
2629 // We want the correct environment at the OsrEntry instruction. Build 2634 // We want the correct environment at the OsrEntry instruction. Build
2630 // it explicitly. The expression stack should be empty. 2635 // it explicitly. The expression stack should be empty.
2631 int count = environment()->length(); 2636 int count = environment()->length();
2632 ASSERT(count == 2637 ASSERT(count ==
2633 (environment()->parameter_count() + environment()->local_count())); 2638 (environment()->parameter_count() + environment()->local_count()));
2634 for (int i = 0; i < count; ++i) { 2639 for (int i = 0; i < count; ++i) {
2635 HUnknownOSRValue* unknown = new HUnknownOSRValue; 2640 HUnknownOSRValue* unknown = new(zone()) HUnknownOSRValue;
2636 AddInstruction(unknown); 2641 AddInstruction(unknown);
2637 environment()->Bind(i, unknown); 2642 environment()->Bind(i, unknown);
2638 } 2643 }
2639 2644
2640 AddSimulate(osr_entry_id); 2645 AddSimulate(osr_entry_id);
2641 AddInstruction(new HOsrEntry(osr_entry_id)); 2646 AddInstruction(new(zone()) HOsrEntry(osr_entry_id));
2642 current_block()->Goto(loop_predecessor); 2647 current_block()->Goto(loop_predecessor);
2643 loop_predecessor->SetJoinId(statement->EntryId()); 2648 loop_predecessor->SetJoinId(statement->EntryId());
2644 set_current_block(loop_predecessor); 2649 set_current_block(loop_predecessor);
2645 } 2650 }
2646 2651
2647 2652
2648 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { 2653 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
2649 ASSERT(current_block() != NULL); 2654 ASSERT(current_block() != NULL);
2650 PreProcessOsrEntry(stmt); 2655 PreProcessOsrEntry(stmt);
2651 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); 2656 HBasicBlock* loop_entry = CreateLoopHeaderBlock();
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
2800 2805
2801 void HGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { 2806 void HGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
2802 Handle<SharedFunctionInfo> shared_info = 2807 Handle<SharedFunctionInfo> shared_info =
2803 SearchSharedFunctionInfo(info()->shared_info()->code(), 2808 SearchSharedFunctionInfo(info()->shared_info()->code(),
2804 expr); 2809 expr);
2805 if (shared_info.is_null()) { 2810 if (shared_info.is_null()) {
2806 shared_info = Compiler::BuildFunctionInfo(expr, info()->script()); 2811 shared_info = Compiler::BuildFunctionInfo(expr, info()->script());
2807 } 2812 }
2808 CHECK_BAILOUT; 2813 CHECK_BAILOUT;
2809 HFunctionLiteral* instr = 2814 HFunctionLiteral* instr =
2810 new HFunctionLiteral(shared_info, expr->pretenure()); 2815 new(zone()) HFunctionLiteral(shared_info, expr->pretenure());
2811 ast_context()->ReturnInstruction(instr, expr->id()); 2816 ast_context()->ReturnInstruction(instr, expr->id());
2812 } 2817 }
2813 2818
2814 2819
2815 void HGraphBuilder::VisitSharedFunctionInfoLiteral( 2820 void HGraphBuilder::VisitSharedFunctionInfoLiteral(
2816 SharedFunctionInfoLiteral* expr) { 2821 SharedFunctionInfoLiteral* expr) {
2817 BAILOUT("SharedFunctionInfoLiteral"); 2822 BAILOUT("SharedFunctionInfoLiteral");
2818 } 2823 }
2819 2824
2820 2825
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2857 lookup->holder() != *global) { 2862 lookup->holder() != *global) {
2858 return kUseGeneric; 2863 return kUseGeneric;
2859 } 2864 }
2860 2865
2861 return kUseCell; 2866 return kUseCell;
2862 } 2867 }
2863 2868
2864 2869
2865 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) { 2870 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) {
2866 ASSERT(var->IsContextSlot()); 2871 ASSERT(var->IsContextSlot());
2867 HInstruction* context = new HContext; 2872 HInstruction* context = new(zone()) HContext;
2868 AddInstruction(context); 2873 AddInstruction(context);
2869 int length = info()->scope()->ContextChainLength(var->scope()); 2874 int length = info()->scope()->ContextChainLength(var->scope());
2870 while (length-- > 0) { 2875 while (length-- > 0) {
2871 context = new HOuterContext(context); 2876 context = new(zone()) HOuterContext(context);
2872 AddInstruction(context); 2877 AddInstruction(context);
2873 } 2878 }
2874 return context; 2879 return context;
2875 } 2880 }
2876 2881
2877 2882
2878 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 2883 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
2879 Variable* variable = expr->AsVariable(); 2884 Variable* variable = expr->AsVariable();
2880 if (variable == NULL) { 2885 if (variable == NULL) {
2881 BAILOUT("reference to rewritten variable"); 2886 BAILOUT("reference to rewritten variable");
2882 } else if (variable->IsStackAllocated()) { 2887 } else if (variable->IsStackAllocated()) {
2883 if (environment()->Lookup(variable)->CheckFlag(HValue::kIsArguments)) { 2888 if (environment()->Lookup(variable)->CheckFlag(HValue::kIsArguments)) {
2884 BAILOUT("unsupported context for arguments object"); 2889 BAILOUT("unsupported context for arguments object");
2885 } 2890 }
2886 ast_context()->ReturnValue(environment()->Lookup(variable)); 2891 ast_context()->ReturnValue(environment()->Lookup(variable));
2887 } else if (variable->IsContextSlot()) { 2892 } else if (variable->IsContextSlot()) {
2888 if (variable->mode() == Variable::CONST) { 2893 if (variable->mode() == Variable::CONST) {
2889 BAILOUT("reference to const context slot"); 2894 BAILOUT("reference to const context slot");
2890 } 2895 }
2891 HValue* context = BuildContextChainWalk(variable); 2896 HValue* context = BuildContextChainWalk(variable);
2892 int index = variable->AsSlot()->index(); 2897 int index = variable->AsSlot()->index();
2893 HLoadContextSlot* instr = new HLoadContextSlot(context, index); 2898 HLoadContextSlot* instr = new(zone()) HLoadContextSlot(context, index);
2894 ast_context()->ReturnInstruction(instr, expr->id()); 2899 ast_context()->ReturnInstruction(instr, expr->id());
2895 } else if (variable->is_global()) { 2900 } else if (variable->is_global()) {
2896 LookupResult lookup; 2901 LookupResult lookup;
2897 GlobalPropertyAccess type = LookupGlobalProperty(variable, &lookup, false); 2902 GlobalPropertyAccess type = LookupGlobalProperty(variable, &lookup, false);
2898 2903
2899 if (type == kUseCell && 2904 if (type == kUseCell &&
2900 info()->global_object()->IsAccessCheckNeeded()) { 2905 info()->global_object()->IsAccessCheckNeeded()) {
2901 type = kUseGeneric; 2906 type = kUseGeneric;
2902 } 2907 }
2903 2908
2904 if (type == kUseCell) { 2909 if (type == kUseCell) {
2905 Handle<GlobalObject> global(info()->global_object()); 2910 Handle<GlobalObject> global(info()->global_object());
2906 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); 2911 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
2907 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); 2912 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly();
2908 HLoadGlobalCell* instr = new HLoadGlobalCell(cell, check_hole); 2913 HLoadGlobalCell* instr = new(zone()) HLoadGlobalCell(cell, check_hole);
2909 ast_context()->ReturnInstruction(instr, expr->id()); 2914 ast_context()->ReturnInstruction(instr, expr->id());
2910 } else { 2915 } else {
2911 HContext* context = new HContext; 2916 HContext* context = new(zone()) HContext;
2912 AddInstruction(context); 2917 AddInstruction(context);
2913 HGlobalObject* global_object = new HGlobalObject(context); 2918 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
2914 AddInstruction(global_object); 2919 AddInstruction(global_object);
2915 HLoadGlobalGeneric* instr = 2920 HLoadGlobalGeneric* instr =
2916 new HLoadGlobalGeneric(context, 2921 new(zone()) HLoadGlobalGeneric(context,
2917 global_object, 2922 global_object,
2918 variable->name(), 2923 variable->name(),
2919 ast_context()->is_for_typeof()); 2924 ast_context()->is_for_typeof());
2920 instr->set_position(expr->position()); 2925 instr->set_position(expr->position());
2921 ASSERT(instr->HasSideEffects()); 2926 ASSERT(instr->HasSideEffects());
2922 ast_context()->ReturnInstruction(instr, expr->id()); 2927 ast_context()->ReturnInstruction(instr, expr->id());
2923 } 2928 }
2924 } else { 2929 } else {
2925 BAILOUT("reference to a variable which requires dynamic lookup"); 2930 BAILOUT("reference to a variable which requires dynamic lookup");
2926 } 2931 }
2927 } 2932 }
2928 2933
2929 2934
2930 void HGraphBuilder::VisitLiteral(Literal* expr) { 2935 void HGraphBuilder::VisitLiteral(Literal* expr) {
2931 HConstant* instr = new HConstant(expr->handle(), Representation::Tagged()); 2936 HConstant* instr =
2937 new(zone()) HConstant(expr->handle(), Representation::Tagged());
2932 ast_context()->ReturnInstruction(instr, expr->id()); 2938 ast_context()->ReturnInstruction(instr, expr->id());
2933 } 2939 }
2934 2940
2935 2941
2936 void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 2942 void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
2937 HRegExpLiteral* instr = new HRegExpLiteral(expr->pattern(), 2943 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(expr->pattern(),
2938 expr->flags(), 2944 expr->flags(),
2939 expr->literal_index()); 2945 expr->literal_index());
2940 ast_context()->ReturnInstruction(instr, expr->id()); 2946 ast_context()->ReturnInstruction(instr, expr->id());
2941 } 2947 }
2942 2948
2943 2949
2944 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { 2950 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
2945 HContext* context = new HContext; 2951 HContext* context = new(zone()) HContext;
2946 AddInstruction(context); 2952 AddInstruction(context);
2947 HObjectLiteral* literal = (new HObjectLiteral(context, 2953 HObjectLiteral* literal =
2948 expr->constant_properties(), 2954 new(zone()) HObjectLiteral(context,
2949 expr->fast_elements(), 2955 expr->constant_properties(),
2950 expr->literal_index(), 2956 expr->fast_elements(),
2951 expr->depth(), 2957 expr->literal_index(),
2952 expr->has_function())); 2958 expr->depth(),
2959 expr->has_function());
2953 // The object is expected in the bailout environment during computation 2960 // The object is expected in the bailout environment during computation
2954 // of the property values and is the value of the entire expression. 2961 // of the property values and is the value of the entire expression.
2955 PushAndAdd(literal); 2962 PushAndAdd(literal);
2956 2963
2957 expr->CalculateEmitStore(); 2964 expr->CalculateEmitStore();
2958 2965
2959 for (int i = 0; i < expr->properties()->length(); i++) { 2966 for (int i = 0; i < expr->properties()->length(); i++) {
2960 ObjectLiteral::Property* property = expr->properties()->at(i); 2967 ObjectLiteral::Property* property = expr->properties()->at(i);
2961 if (property->IsCompileTimeValue()) continue; 2968 if (property->IsCompileTimeValue()) continue;
2962 2969
2963 Literal* key = property->key(); 2970 Literal* key = property->key();
2964 Expression* value = property->value(); 2971 Expression* value = property->value();
2965 2972
2966 switch (property->kind()) { 2973 switch (property->kind()) {
2967 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2974 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2968 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 2975 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
2969 // Fall through. 2976 // Fall through.
2970 case ObjectLiteral::Property::COMPUTED: 2977 case ObjectLiteral::Property::COMPUTED:
2971 if (key->handle()->IsSymbol()) { 2978 if (key->handle()->IsSymbol()) {
2972 if (property->emit_store()) { 2979 if (property->emit_store()) {
2973 VISIT_FOR_VALUE(value); 2980 VISIT_FOR_VALUE(value);
2974 HValue* value = Pop(); 2981 HValue* value = Pop();
2975 Handle<String> name = Handle<String>::cast(key->handle()); 2982 Handle<String> name = Handle<String>::cast(key->handle());
2976 HStoreNamedGeneric* store = 2983 HStoreNamedGeneric* store =
2977 new HStoreNamedGeneric(context, literal, name, value); 2984 new(zone()) HStoreNamedGeneric(context, literal, name, value);
2978 AddInstruction(store); 2985 AddInstruction(store);
2979 AddSimulate(key->id()); 2986 AddSimulate(key->id());
2980 } else { 2987 } else {
2981 VISIT_FOR_EFFECT(value); 2988 VISIT_FOR_EFFECT(value);
2982 } 2989 }
2983 break; 2990 break;
2984 } 2991 }
2985 // Fall through. 2992 // Fall through.
2986 case ObjectLiteral::Property::PROTOTYPE: 2993 case ObjectLiteral::Property::PROTOTYPE:
2987 case ObjectLiteral::Property::SETTER: 2994 case ObjectLiteral::Property::SETTER:
2988 case ObjectLiteral::Property::GETTER: 2995 case ObjectLiteral::Property::GETTER:
2989 BAILOUT("Object literal with complex property"); 2996 BAILOUT("Object literal with complex property");
2990 default: UNREACHABLE(); 2997 default: UNREACHABLE();
2991 } 2998 }
2992 } 2999 }
2993 3000
2994 if (expr->has_function()) { 3001 if (expr->has_function()) {
2995 // Return the result of the transformation to fast properties 3002 // Return the result of the transformation to fast properties
2996 // instead of the original since this operation changes the map 3003 // instead of the original since this operation changes the map
2997 // of the object. This makes sure that the original object won't 3004 // of the object. This makes sure that the original object won't
2998 // be used by other optimized code before it is transformed 3005 // be used by other optimized code before it is transformed
2999 // (e.g. because of code motion). 3006 // (e.g. because of code motion).
3000 HToFastProperties* result = new HToFastProperties(Pop()); 3007 HToFastProperties* result = new(zone()) HToFastProperties(Pop());
3001 AddInstruction(result); 3008 AddInstruction(result);
3002 ast_context()->ReturnValue(result); 3009 ast_context()->ReturnValue(result);
3003 } else { 3010 } else {
3004 ast_context()->ReturnValue(Pop()); 3011 ast_context()->ReturnValue(Pop());
3005 } 3012 }
3006 } 3013 }
3007 3014
3008 3015
3009 void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { 3016 void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
3010 ZoneList<Expression*>* subexprs = expr->values(); 3017 ZoneList<Expression*>* subexprs = expr->values();
3011 int length = subexprs->length(); 3018 int length = subexprs->length();
3012 3019
3013 HArrayLiteral* literal = new HArrayLiteral(expr->constant_elements(), 3020 HArrayLiteral* literal = new(zone()) HArrayLiteral(expr->constant_elements(),
3014 length, 3021 length,
3015 expr->literal_index(), 3022 expr->literal_index(),
3016 expr->depth()); 3023 expr->depth());
3017 // The array is expected in the bailout environment during computation 3024 // The array is expected in the bailout environment during computation
3018 // of the property values and is the value of the entire expression. 3025 // of the property values and is the value of the entire expression.
3019 PushAndAdd(literal); 3026 PushAndAdd(literal);
3020 3027
3021 HLoadElements* elements = NULL; 3028 HLoadElements* elements = NULL;
3022 3029
3023 for (int i = 0; i < length; i++) { 3030 for (int i = 0; i < length; i++) {
3024 Expression* subexpr = subexprs->at(i); 3031 Expression* subexpr = subexprs->at(i);
3025 // If the subexpression is a literal or a simple materialized literal it 3032 // If the subexpression is a literal or a simple materialized literal it
3026 // is already set in the cloned array. 3033 // is already set in the cloned array.
3027 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 3034 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
3028 3035
3029 VISIT_FOR_VALUE(subexpr); 3036 VISIT_FOR_VALUE(subexpr);
3030 HValue* value = Pop(); 3037 HValue* value = Pop();
3031 if (!Smi::IsValid(i)) BAILOUT("Non-smi key in array literal"); 3038 if (!Smi::IsValid(i)) BAILOUT("Non-smi key in array literal");
3032 3039
3033 // Load the elements array before the first store. 3040 // Load the elements array before the first store.
3034 if (elements == NULL) { 3041 if (elements == NULL) {
3035 elements = new HLoadElements(literal); 3042 elements = new(zone()) HLoadElements(literal);
3036 AddInstruction(elements); 3043 AddInstruction(elements);
3037 } 3044 }
3038 3045
3039 HValue* key = AddInstruction(new HConstant(Handle<Object>(Smi::FromInt(i)), 3046 HValue* key = AddInstruction(
3040 Representation::Integer32())); 3047 new(zone()) HConstant(Handle<Object>(Smi::FromInt(i)),
3041 AddInstruction(new HStoreKeyedFastElement(elements, key, value)); 3048 Representation::Integer32()));
3049 AddInstruction(new(zone()) HStoreKeyedFastElement(elements, key, value));
3042 AddSimulate(expr->GetIdForElement(i)); 3050 AddSimulate(expr->GetIdForElement(i));
3043 } 3051 }
3044 ast_context()->ReturnValue(Pop()); 3052 ast_context()->ReturnValue(Pop());
3045 } 3053 }
3046 3054
3047 3055
3048 void HGraphBuilder::VisitCatchExtensionObject(CatchExtensionObject* expr) { 3056 void HGraphBuilder::VisitCatchExtensionObject(CatchExtensionObject* expr) {
3049 BAILOUT("CatchExtensionObject"); 3057 BAILOUT("CatchExtensionObject");
3050 } 3058 }
3051 3059
(...skipping 23 matching lines...) Expand all
3075 } 3083 }
3076 3084
3077 3085
3078 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, 3086 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object,
3079 Handle<String> name, 3087 Handle<String> name,
3080 HValue* value, 3088 HValue* value,
3081 Handle<Map> type, 3089 Handle<Map> type,
3082 LookupResult* lookup, 3090 LookupResult* lookup,
3083 bool smi_and_map_check) { 3091 bool smi_and_map_check) {
3084 if (smi_and_map_check) { 3092 if (smi_and_map_check) {
3085 AddInstruction(new HCheckNonSmi(object)); 3093 AddInstruction(new(zone()) HCheckNonSmi(object));
3086 AddInstruction(new HCheckMap(object, type)); 3094 AddInstruction(new(zone()) HCheckMap(object, type));
3087 } 3095 }
3088 3096
3089 int index = ComputeStoredFieldIndex(type, name, lookup); 3097 int index = ComputeStoredFieldIndex(type, name, lookup);
3090 bool is_in_object = index < 0; 3098 bool is_in_object = index < 0;
3091 int offset = index * kPointerSize; 3099 int offset = index * kPointerSize;
3092 if (index < 0) { 3100 if (index < 0) {
3093 // Negative property indices are in-object properties, indexed 3101 // Negative property indices are in-object properties, indexed
3094 // from the end of the fixed part of the object. 3102 // from the end of the fixed part of the object.
3095 offset += type->instance_size(); 3103 offset += type->instance_size();
3096 } else { 3104 } else {
3097 offset += FixedArray::kHeaderSize; 3105 offset += FixedArray::kHeaderSize;
3098 } 3106 }
3099 HStoreNamedField* instr = 3107 HStoreNamedField* instr =
3100 new HStoreNamedField(object, name, value, is_in_object, offset); 3108 new(zone()) HStoreNamedField(object, name, value, is_in_object, offset);
3101 if (lookup->type() == MAP_TRANSITION) { 3109 if (lookup->type() == MAP_TRANSITION) {
3102 Handle<Map> transition(lookup->GetTransitionMapFromMap(*type)); 3110 Handle<Map> transition(lookup->GetTransitionMapFromMap(*type));
3103 instr->set_transition(transition); 3111 instr->set_transition(transition);
3104 // TODO(fschneider): Record the new map type of the object in the IR to 3112 // TODO(fschneider): Record the new map type of the object in the IR to
3105 // enable elimination of redundant checks after the transition store. 3113 // enable elimination of redundant checks after the transition store.
3106 instr->SetFlag(HValue::kChangesMaps); 3114 instr->SetFlag(HValue::kChangesMaps);
3107 } 3115 }
3108 return instr; 3116 return instr;
3109 } 3117 }
3110 3118
3111 3119
3112 HInstruction* HGraphBuilder::BuildStoreNamedGeneric(HValue* object, 3120 HInstruction* HGraphBuilder::BuildStoreNamedGeneric(HValue* object,
3113 Handle<String> name, 3121 Handle<String> name,
3114 HValue* value) { 3122 HValue* value) {
3115 HContext* context = new HContext; 3123 HContext* context = new(zone()) HContext;
3116 AddInstruction(context); 3124 AddInstruction(context);
3117 return new HStoreNamedGeneric(context, object, name, value); 3125 return new(zone()) HStoreNamedGeneric(context, object, name, value);
3118 } 3126 }
3119 3127
3120 3128
3121 HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object, 3129 HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object,
3122 HValue* value, 3130 HValue* value,
3123 Expression* expr) { 3131 Expression* expr) {
3124 Property* prop = (expr->AsProperty() != NULL) 3132 Property* prop = (expr->AsProperty() != NULL)
3125 ? expr->AsProperty() 3133 ? expr->AsProperty()
3126 : expr->AsAssignment()->target()->AsProperty(); 3134 : expr->AsAssignment()->target()->AsProperty();
3127 Literal* key = prop->key()->AsLiteral(); 3135 Literal* key = prop->key()->AsLiteral();
(...skipping 20 matching lines...) Expand all
3148 // TODO(ager): We should recognize when the prototype chains for different 3156 // TODO(ager): We should recognize when the prototype chains for different
3149 // maps are identical. In that case we can avoid repeatedly generating the 3157 // maps are identical. In that case we can avoid repeatedly generating the
3150 // same prototype map checks. 3158 // same prototype map checks.
3151 int count = 0; 3159 int count = 0;
3152 HBasicBlock* join = NULL; 3160 HBasicBlock* join = NULL;
3153 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { 3161 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) {
3154 Handle<Map> map = types->at(i); 3162 Handle<Map> map = types->at(i);
3155 LookupResult lookup; 3163 LookupResult lookup;
3156 if (ComputeStoredField(map, name, &lookup)) { 3164 if (ComputeStoredField(map, name, &lookup)) {
3157 if (count == 0) { 3165 if (count == 0) {
3158 AddInstruction(new HCheckNonSmi(object)); // Only needed once. 3166 AddInstruction(new(zone()) HCheckNonSmi(object)); // Only needed once.
3159 join = graph()->CreateBasicBlock(); 3167 join = graph()->CreateBasicBlock();
3160 } 3168 }
3161 ++count; 3169 ++count;
3162 HBasicBlock* if_true = graph()->CreateBasicBlock(); 3170 HBasicBlock* if_true = graph()->CreateBasicBlock();
3163 HBasicBlock* if_false = graph()->CreateBasicBlock(); 3171 HBasicBlock* if_false = graph()->CreateBasicBlock();
3164 HCompareMap* compare = new HCompareMap(object, map, if_true, if_false); 3172 HCompareMap* compare =
3173 new(zone()) HCompareMap(object, map, if_true, if_false);
3165 current_block()->Finish(compare); 3174 current_block()->Finish(compare);
3166 3175
3167 set_current_block(if_true); 3176 set_current_block(if_true);
3168 HInstruction* instr = 3177 HInstruction* instr =
3169 BuildStoreNamedField(object, name, value, map, &lookup, false); 3178 BuildStoreNamedField(object, name, value, map, &lookup, false);
3170 instr->set_position(expr->position()); 3179 instr->set_position(expr->position());
3171 // Goto will add the HSimulate for the store. 3180 // Goto will add the HSimulate for the store.
3172 AddInstruction(instr); 3181 AddInstruction(instr);
3173 if (!ast_context()->IsEffect()) Push(value); 3182 if (!ast_context()->IsEffect()) Push(value);
3174 current_block()->Goto(join); 3183 current_block()->Goto(join);
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
3289 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, 3298 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var,
3290 HValue* value, 3299 HValue* value,
3291 int position, 3300 int position,
3292 int ast_id) { 3301 int ast_id) {
3293 LookupResult lookup; 3302 LookupResult lookup;
3294 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); 3303 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true);
3295 if (type == kUseCell) { 3304 if (type == kUseCell) {
3296 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); 3305 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly();
3297 Handle<GlobalObject> global(info()->global_object()); 3306 Handle<GlobalObject> global(info()->global_object());
3298 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); 3307 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
3299 HInstruction* instr = new HStoreGlobal(value, cell, check_hole); 3308 HInstruction* instr = new(zone()) HStoreGlobalCell(value, cell, check_hole);
3300 instr->set_position(position); 3309 instr->set_position(position);
3301 AddInstruction(instr); 3310 AddInstruction(instr);
3302 if (instr->HasSideEffects()) AddSimulate(ast_id); 3311 if (instr->HasSideEffects()) AddSimulate(ast_id);
3303 } else { 3312 } else {
3304 BAILOUT("global store only supported for cells"); 3313 HContext* context = new(zone()) HContext;
3314 AddInstruction(context);
3315 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
3316 AddInstruction(global_object);
3317 HStoreGlobalGeneric* instr =
3318 new(zone()) HStoreGlobalGeneric(context,
3319 global_object,
3320 var->name(),
3321 value);
3322 instr->set_position(position);
3323 AddInstruction(instr);
3324 ASSERT(instr->HasSideEffects());
3325 if (instr->HasSideEffects()) AddSimulate(ast_id);
3305 } 3326 }
3306 } 3327 }
3307 3328
3308 3329
3309 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 3330 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
3310 Expression* target = expr->target(); 3331 Expression* target = expr->target();
3311 VariableProxy* proxy = target->AsVariableProxy(); 3332 VariableProxy* proxy = target->AsVariableProxy();
3312 Variable* var = proxy->AsVariable(); 3333 Variable* var = proxy->AsVariable();
3313 Property* prop = target->AsProperty(); 3334 Property* prop = target->AsProperty();
3314 ASSERT(var == NULL || prop == NULL); 3335 ASSERT(var == NULL || prop == NULL);
3315 3336
3316 // We have a second position recorded in the FullCodeGenerator to have 3337 // We have a second position recorded in the FullCodeGenerator to have
3317 // type feedback for the binary operation. 3338 // type feedback for the binary operation.
3318 BinaryOperation* operation = expr->binary_operation(); 3339 BinaryOperation* operation = expr->binary_operation();
3319 3340
3320 if (var != NULL) { 3341 if (var != NULL) {
3321 VISIT_FOR_VALUE(operation); 3342 VISIT_FOR_VALUE(operation);
3322 3343
3323 if (var->is_global()) { 3344 if (var->is_global()) {
3324 HandleGlobalVariableAssignment(var, 3345 HandleGlobalVariableAssignment(var,
3325 Top(), 3346 Top(),
3326 expr->position(), 3347 expr->position(),
3327 expr->AssignmentId()); 3348 expr->AssignmentId());
3328 } else if (var->IsStackAllocated()) { 3349 } else if (var->IsStackAllocated()) {
3329 Bind(var, Top()); 3350 Bind(var, Top());
3330 } else if (var->IsContextSlot()) { 3351 } else if (var->IsContextSlot()) {
3331 HValue* context = BuildContextChainWalk(var); 3352 HValue* context = BuildContextChainWalk(var);
3332 int index = var->AsSlot()->index(); 3353 int index = var->AsSlot()->index();
3333 HStoreContextSlot* instr = new HStoreContextSlot(context, index, Top()); 3354 HStoreContextSlot* instr =
3355 new(zone()) HStoreContextSlot(context, index, Top());
3334 AddInstruction(instr); 3356 AddInstruction(instr);
3335 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); 3357 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
3336 } else { 3358 } else {
3337 BAILOUT("compound assignment to lookup slot"); 3359 BAILOUT("compound assignment to lookup slot");
3338 } 3360 }
3339 ast_context()->ReturnValue(Pop()); 3361 ast_context()->ReturnValue(Pop());
3340 3362
3341 } else if (prop != NULL) { 3363 } else if (prop != NULL) {
3342 prop->RecordTypeFeedback(oracle()); 3364 prop->RecordTypeFeedback(oracle());
3343 3365
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
3442 VISIT_FOR_VALUE(expr->value()); 3464 VISIT_FOR_VALUE(expr->value());
3443 value = Pop(); 3465 value = Pop();
3444 } 3466 }
3445 Bind(var, value); 3467 Bind(var, value);
3446 ast_context()->ReturnValue(value); 3468 ast_context()->ReturnValue(value);
3447 3469
3448 } else if (var->IsContextSlot() && var->mode() != Variable::CONST) { 3470 } else if (var->IsContextSlot() && var->mode() != Variable::CONST) {
3449 VISIT_FOR_VALUE(expr->value()); 3471 VISIT_FOR_VALUE(expr->value());
3450 HValue* context = BuildContextChainWalk(var); 3472 HValue* context = BuildContextChainWalk(var);
3451 int index = var->AsSlot()->index(); 3473 int index = var->AsSlot()->index();
3452 HStoreContextSlot* instr = new HStoreContextSlot(context, index, Top()); 3474 HStoreContextSlot* instr =
3475 new(zone()) HStoreContextSlot(context, index, Top());
3453 AddInstruction(instr); 3476 AddInstruction(instr);
3454 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); 3477 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
3455 ast_context()->ReturnValue(Pop()); 3478 ast_context()->ReturnValue(Pop());
3456 3479
3457 } else if (var->is_global()) { 3480 } else if (var->is_global()) {
3458 VISIT_FOR_VALUE(expr->value()); 3481 VISIT_FOR_VALUE(expr->value());
3459 HandleGlobalVariableAssignment(var, 3482 HandleGlobalVariableAssignment(var,
3460 Top(), 3483 Top(),
3461 expr->position(), 3484 expr->position(),
3462 expr->AssignmentId()); 3485 expr->AssignmentId());
(...skipping 12 matching lines...) Expand all
3475 3498
3476 3499
3477 void HGraphBuilder::VisitThrow(Throw* expr) { 3500 void HGraphBuilder::VisitThrow(Throw* expr) {
3478 // We don't optimize functions with invalid left-hand sides in 3501 // We don't optimize functions with invalid left-hand sides in
3479 // assignments, count operations, or for-in. Consequently throw can 3502 // assignments, count operations, or for-in. Consequently throw can
3480 // currently only occur in an effect context. 3503 // currently only occur in an effect context.
3481 ASSERT(ast_context()->IsEffect()); 3504 ASSERT(ast_context()->IsEffect());
3482 VISIT_FOR_VALUE(expr->exception()); 3505 VISIT_FOR_VALUE(expr->exception());
3483 3506
3484 HValue* value = environment()->Pop(); 3507 HValue* value = environment()->Pop();
3485 HThrow* instr = new HThrow(value); 3508 HThrow* instr = new(zone()) HThrow(value);
3486 instr->set_position(expr->position()); 3509 instr->set_position(expr->position());
3487 AddInstruction(instr); 3510 AddInstruction(instr);
3488 AddSimulate(expr->id()); 3511 AddSimulate(expr->id());
3489 current_block()->FinishExit(new HAbnormalExit); 3512 current_block()->FinishExit(new(zone()) HAbnormalExit);
3490 set_current_block(NULL); 3513 set_current_block(NULL);
3491 } 3514 }
3492 3515
3493 3516
3494 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, 3517 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
3495 Property* expr, 3518 Property* expr,
3496 Handle<Map> type, 3519 Handle<Map> type,
3497 LookupResult* lookup, 3520 LookupResult* lookup,
3498 bool smi_and_map_check) { 3521 bool smi_and_map_check) {
3499 if (smi_and_map_check) { 3522 if (smi_and_map_check) {
3500 AddInstruction(new HCheckNonSmi(object)); 3523 AddInstruction(new(zone()) HCheckNonSmi(object));
3501 AddInstruction(new HCheckMap(object, type)); 3524 AddInstruction(new(zone()) HCheckMap(object, type));
3502 } 3525 }
3503 3526
3504 int index = lookup->GetLocalFieldIndexFromMap(*type); 3527 int index = lookup->GetLocalFieldIndexFromMap(*type);
3505 if (index < 0) { 3528 if (index < 0) {
3506 // Negative property indices are in-object properties, indexed 3529 // Negative property indices are in-object properties, indexed
3507 // from the end of the fixed part of the object. 3530 // from the end of the fixed part of the object.
3508 int offset = (index * kPointerSize) + type->instance_size(); 3531 int offset = (index * kPointerSize) + type->instance_size();
3509 return new HLoadNamedField(object, true, offset); 3532 return new(zone()) HLoadNamedField(object, true, offset);
3510 } else { 3533 } else {
3511 // Non-negative property indices are in the properties array. 3534 // Non-negative property indices are in the properties array.
3512 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; 3535 int offset = (index * kPointerSize) + FixedArray::kHeaderSize;
3513 return new HLoadNamedField(object, false, offset); 3536 return new(zone()) HLoadNamedField(object, false, offset);
3514 } 3537 }
3515 } 3538 }
3516 3539
3517 3540
3518 HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* obj, 3541 HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* obj,
3519 Property* expr) { 3542 Property* expr) {
3520 ASSERT(expr->key()->IsPropertyName()); 3543 ASSERT(expr->key()->IsPropertyName());
3521 Handle<Object> name = expr->key()->AsLiteral()->handle(); 3544 Handle<Object> name = expr->key()->AsLiteral()->handle();
3522 HContext* context = new HContext; 3545 HContext* context = new(zone()) HContext;
3523 AddInstruction(context); 3546 AddInstruction(context);
3524 return new HLoadNamedGeneric(context, obj, name); 3547 return new(zone()) HLoadNamedGeneric(context, obj, name);
3525 } 3548 }
3526 3549
3527 3550
3528 HInstruction* HGraphBuilder::BuildLoadNamed(HValue* obj, 3551 HInstruction* HGraphBuilder::BuildLoadNamed(HValue* obj,
3529 Property* expr, 3552 Property* expr,
3530 Handle<Map> map, 3553 Handle<Map> map,
3531 Handle<String> name) { 3554 Handle<String> name) {
3532 LookupResult lookup; 3555 LookupResult lookup;
3533 map->LookupInDescriptors(NULL, *name, &lookup); 3556 map->LookupInDescriptors(NULL, *name, &lookup);
3534 if (lookup.IsProperty() && lookup.type() == FIELD) { 3557 if (lookup.IsProperty() && lookup.type() == FIELD) {
3535 return BuildLoadNamedField(obj, 3558 return BuildLoadNamedField(obj,
3536 expr, 3559 expr,
3537 map, 3560 map,
3538 &lookup, 3561 &lookup,
3539 true); 3562 true);
3540 } else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) { 3563 } else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) {
3541 AddInstruction(new HCheckNonSmi(obj)); 3564 AddInstruction(new(zone()) HCheckNonSmi(obj));
3542 AddInstruction(new HCheckMap(obj, map)); 3565 AddInstruction(new(zone()) HCheckMap(obj, map));
3543 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); 3566 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map));
3544 return new HConstant(function, Representation::Tagged()); 3567 return new(zone()) HConstant(function, Representation::Tagged());
3545 } else { 3568 } else {
3546 return BuildLoadNamedGeneric(obj, expr); 3569 return BuildLoadNamedGeneric(obj, expr);
3547 } 3570 }
3548 } 3571 }
3549 3572
3550 3573
3551 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, 3574 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object,
3552 HValue* key) { 3575 HValue* key) {
3553 HContext* context = new HContext; 3576 HContext* context = new(zone()) HContext;
3554 AddInstruction(context); 3577 AddInstruction(context);
3555 return new HLoadKeyedGeneric(context, object, key); 3578 return new(zone()) HLoadKeyedGeneric(context, object, key);
3556 } 3579 }
3557 3580
3558 3581
3559 HInstruction* HGraphBuilder::BuildLoadKeyedFastElement(HValue* object, 3582 HInstruction* HGraphBuilder::BuildLoadKeyedFastElement(HValue* object,
3560 HValue* key, 3583 HValue* key,
3561 Property* expr) { 3584 Property* expr) {
3562 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic()); 3585 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic());
3563 AddInstruction(new HCheckNonSmi(object)); 3586 AddInstruction(new(zone()) HCheckNonSmi(object));
3564 Handle<Map> map = expr->GetMonomorphicReceiverType(); 3587 Handle<Map> map = expr->GetMonomorphicReceiverType();
3565 ASSERT(map->has_fast_elements()); 3588 ASSERT(map->has_fast_elements());
3566 AddInstruction(new HCheckMap(object, map)); 3589 AddInstruction(new(zone()) HCheckMap(object, map));
3567 bool is_array = (map->instance_type() == JS_ARRAY_TYPE); 3590 bool is_array = (map->instance_type() == JS_ARRAY_TYPE);
3568 HLoadElements* elements = new HLoadElements(object); 3591 HLoadElements* elements = new(zone()) HLoadElements(object);
3569 HInstruction* length = NULL; 3592 HInstruction* length = NULL;
3570 if (is_array) { 3593 if (is_array) {
3571 length = AddInstruction(new HJSArrayLength(object)); 3594 length = AddInstruction(new(zone()) HJSArrayLength(object));
3572 AddInstruction(new HBoundsCheck(key, length)); 3595 AddInstruction(new(zone()) HBoundsCheck(key, length));
3573 AddInstruction(elements); 3596 AddInstruction(elements);
3574 } else { 3597 } else {
3575 AddInstruction(elements); 3598 AddInstruction(elements);
3576 length = AddInstruction(new HFixedArrayLength(elements)); 3599 length = AddInstruction(new(zone()) HFixedArrayLength(elements));
3577 AddInstruction(new HBoundsCheck(key, length)); 3600 AddInstruction(new(zone()) HBoundsCheck(key, length));
3578 } 3601 }
3579 return new HLoadKeyedFastElement(elements, key); 3602 return new(zone()) HLoadKeyedFastElement(elements, key);
3580 } 3603 }
3581 3604
3582 3605
3583 HInstruction* HGraphBuilder::BuildLoadKeyedSpecializedArrayElement( 3606 HInstruction* HGraphBuilder::BuildLoadKeyedSpecializedArrayElement(
3584 HValue* object, 3607 HValue* object,
3585 HValue* key, 3608 HValue* key,
3586 Property* expr) { 3609 Property* expr) {
3587 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic()); 3610 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic());
3588 AddInstruction(new HCheckNonSmi(object)); 3611 AddInstruction(new(zone()) HCheckNonSmi(object));
3589 Handle<Map> map = expr->GetMonomorphicReceiverType(); 3612 Handle<Map> map = expr->GetMonomorphicReceiverType();
3590 ASSERT(!map->has_fast_elements()); 3613 ASSERT(!map->has_fast_elements());
3591 ASSERT(map->has_external_array_elements()); 3614 ASSERT(map->has_external_array_elements());
3592 AddInstruction(new HCheckMap(object, map)); 3615 AddInstruction(new(zone()) HCheckMap(object, map));
3593 HLoadElements* elements = new HLoadElements(object); 3616 HLoadElements* elements = new(zone()) HLoadElements(object);
3594 AddInstruction(elements); 3617 AddInstruction(elements);
3595 HInstruction* length = new HExternalArrayLength(elements); 3618 HInstruction* length = new(zone()) HExternalArrayLength(elements);
3596 AddInstruction(length); 3619 AddInstruction(length);
3597 AddInstruction(new HBoundsCheck(key, length)); 3620 AddInstruction(new(zone()) HBoundsCheck(key, length));
3598 HLoadExternalArrayPointer* external_elements = 3621 HLoadExternalArrayPointer* external_elements =
3599 new HLoadExternalArrayPointer(elements); 3622 new(zone()) HLoadExternalArrayPointer(elements);
3600 AddInstruction(external_elements); 3623 AddInstruction(external_elements);
3601 HLoadKeyedSpecializedArrayElement* pixel_array_value = 3624 HLoadKeyedSpecializedArrayElement* pixel_array_value =
3602 new HLoadKeyedSpecializedArrayElement(external_elements, 3625 new(zone()) HLoadKeyedSpecializedArrayElement(
3603 key, 3626 external_elements, key, expr->GetExternalArrayType());
3604 expr->GetExternalArrayType());
3605 return pixel_array_value; 3627 return pixel_array_value;
3606 } 3628 }
3607 3629
3608 3630
3609 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, 3631 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object,
3610 HValue* key, 3632 HValue* key,
3611 HValue* value) { 3633 HValue* value) {
3612 HContext* context = new HContext; 3634 HContext* context = new(zone()) HContext;
3613 AddInstruction(context); 3635 AddInstruction(context);
3614 return new HStoreKeyedGeneric(context, object, key, value); 3636 return new(zone()) HStoreKeyedGeneric(context, object, key, value);
3615 } 3637 }
3616 3638
3617 3639
3618 HInstruction* HGraphBuilder::BuildStoreKeyedFastElement(HValue* object, 3640 HInstruction* HGraphBuilder::BuildStoreKeyedFastElement(HValue* object,
3619 HValue* key, 3641 HValue* key,
3620 HValue* val, 3642 HValue* val,
3621 Expression* expr) { 3643 Expression* expr) {
3622 ASSERT(expr->IsMonomorphic()); 3644 ASSERT(expr->IsMonomorphic());
3623 AddInstruction(new HCheckNonSmi(object)); 3645 AddInstruction(new(zone()) HCheckNonSmi(object));
3624 Handle<Map> map = expr->GetMonomorphicReceiverType(); 3646 Handle<Map> map = expr->GetMonomorphicReceiverType();
3625 ASSERT(map->has_fast_elements()); 3647 ASSERT(map->has_fast_elements());
3626 AddInstruction(new HCheckMap(object, map)); 3648 AddInstruction(new(zone()) HCheckMap(object, map));
3627 HInstruction* elements = AddInstruction(new HLoadElements(object)); 3649 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object));
3628 AddInstruction(new HCheckMap(elements, 3650 AddInstruction(new(zone()) HCheckMap(
3629 isolate()->factory()->fixed_array_map())); 3651 elements, isolate()->factory()->fixed_array_map()));
3630 bool is_array = (map->instance_type() == JS_ARRAY_TYPE); 3652 bool is_array = (map->instance_type() == JS_ARRAY_TYPE);
3631 HInstruction* length = NULL; 3653 HInstruction* length = NULL;
3632 if (is_array) { 3654 if (is_array) {
3633 length = AddInstruction(new HJSArrayLength(object)); 3655 length = AddInstruction(new(zone()) HJSArrayLength(object));
3634 } else { 3656 } else {
3635 length = AddInstruction(new HFixedArrayLength(elements)); 3657 length = AddInstruction(new(zone()) HFixedArrayLength(elements));
3636 } 3658 }
3637 AddInstruction(new HBoundsCheck(key, length)); 3659 AddInstruction(new(zone()) HBoundsCheck(key, length));
3638 return new HStoreKeyedFastElement(elements, key, val); 3660 return new(zone()) HStoreKeyedFastElement(elements, key, val);
3639 } 3661 }
3640 3662
3641 3663
3642 HInstruction* HGraphBuilder::BuildStoreKeyedSpecializedArrayElement( 3664 HInstruction* HGraphBuilder::BuildStoreKeyedSpecializedArrayElement(
3643 HValue* object, 3665 HValue* object,
3644 HValue* key, 3666 HValue* key,
3645 HValue* val, 3667 HValue* val,
3646 Assignment* expr) { 3668 Assignment* expr) {
3647 ASSERT(expr->IsMonomorphic()); 3669 ASSERT(expr->IsMonomorphic());
3648 AddInstruction(new HCheckNonSmi(object)); 3670 AddInstruction(new(zone()) HCheckNonSmi(object));
3649 Handle<Map> map = expr->GetMonomorphicReceiverType(); 3671 Handle<Map> map = expr->GetMonomorphicReceiverType();
3650 ASSERT(!map->has_fast_elements()); 3672 ASSERT(!map->has_fast_elements());
3651 ASSERT(map->has_external_array_elements()); 3673 ASSERT(map->has_external_array_elements());
3652 AddInstruction(new HCheckMap(object, map)); 3674 AddInstruction(new(zone()) HCheckMap(object, map));
3653 HLoadElements* elements = new HLoadElements(object); 3675 HLoadElements* elements = new(zone()) HLoadElements(object);
3654 AddInstruction(elements); 3676 AddInstruction(elements);
3655 HInstruction* length = AddInstruction(new HExternalArrayLength(elements)); 3677 HInstruction* length = AddInstruction(
3656 AddInstruction(new HBoundsCheck(key, length)); 3678 new(zone()) HExternalArrayLength(elements));
3679 AddInstruction(new(zone()) HBoundsCheck(key, length));
3657 HLoadExternalArrayPointer* external_elements = 3680 HLoadExternalArrayPointer* external_elements =
3658 new HLoadExternalArrayPointer(elements); 3681 new(zone()) HLoadExternalArrayPointer(elements);
3659 AddInstruction(external_elements); 3682 AddInstruction(external_elements);
3660 return new HStoreKeyedSpecializedArrayElement( 3683 return new(zone()) HStoreKeyedSpecializedArrayElement(
3661 external_elements, 3684 external_elements,
3662 key, 3685 key,
3663 val, 3686 val,
3664 expr->GetExternalArrayType()); 3687 expr->GetExternalArrayType());
3665 } 3688 }
3666 3689
3667 3690
3668 bool HGraphBuilder::TryArgumentsAccess(Property* expr) { 3691 bool HGraphBuilder::TryArgumentsAccess(Property* expr) {
3669 VariableProxy* proxy = expr->obj()->AsVariableProxy(); 3692 VariableProxy* proxy = expr->obj()->AsVariableProxy();
3670 if (proxy == NULL) return false; 3693 if (proxy == NULL) return false;
3671 if (!proxy->var()->IsStackAllocated()) return false; 3694 if (!proxy->var()->IsStackAllocated()) return false;
3672 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { 3695 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) {
3673 return false; 3696 return false;
3674 } 3697 }
3675 3698
3676 HInstruction* result = NULL; 3699 HInstruction* result = NULL;
3677 if (expr->key()->IsPropertyName()) { 3700 if (expr->key()->IsPropertyName()) {
3678 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 3701 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
3679 if (!name->IsEqualTo(CStrVector("length"))) return false; 3702 if (!name->IsEqualTo(CStrVector("length"))) return false;
3680 HInstruction* elements = AddInstruction(new HArgumentsElements); 3703 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
3681 result = new HArgumentsLength(elements); 3704 result = new(zone()) HArgumentsLength(elements);
3682 } else { 3705 } else {
3683 Push(graph()->GetArgumentsObject()); 3706 Push(graph()->GetArgumentsObject());
3684 VisitForValue(expr->key()); 3707 VisitForValue(expr->key());
3685 if (HasStackOverflow()) return false; 3708 if (HasStackOverflow()) return false;
3686 HValue* key = Pop(); 3709 HValue* key = Pop();
3687 Drop(1); // Arguments object. 3710 Drop(1); // Arguments object.
3688 HInstruction* elements = AddInstruction(new HArgumentsElements); 3711 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
3689 HInstruction* length = AddInstruction(new HArgumentsLength(elements)); 3712 HInstruction* length = AddInstruction(
3690 AddInstruction(new HBoundsCheck(key, length)); 3713 new(zone()) HArgumentsLength(elements));
3691 result = new HAccessArgumentsAt(elements, length, key); 3714 AddInstruction(new(zone()) HBoundsCheck(key, length));
3715 result = new(zone()) HAccessArgumentsAt(elements, length, key);
3692 } 3716 }
3693 ast_context()->ReturnInstruction(result, expr->id()); 3717 ast_context()->ReturnInstruction(result, expr->id());
3694 return true; 3718 return true;
3695 } 3719 }
3696 3720
3697 3721
3698 void HGraphBuilder::VisitProperty(Property* expr) { 3722 void HGraphBuilder::VisitProperty(Property* expr) {
3699 expr->RecordTypeFeedback(oracle()); 3723 expr->RecordTypeFeedback(oracle());
3700 3724
3701 if (TryArgumentsAccess(expr)) return; 3725 if (TryArgumentsAccess(expr)) return;
3702 CHECK_BAILOUT; 3726 CHECK_BAILOUT;
3703 3727
3704 VISIT_FOR_VALUE(expr->obj()); 3728 VISIT_FOR_VALUE(expr->obj());
3705 3729
3706 HInstruction* instr = NULL; 3730 HInstruction* instr = NULL;
3707 if (expr->IsArrayLength()) { 3731 if (expr->IsArrayLength()) {
3708 HValue* array = Pop(); 3732 HValue* array = Pop();
3709 AddInstruction(new HCheckNonSmi(array)); 3733 AddInstruction(new(zone()) HCheckNonSmi(array));
3710 AddInstruction(new HCheckInstanceType(array, JS_ARRAY_TYPE, JS_ARRAY_TYPE)); 3734 AddInstruction(new(zone()) HCheckInstanceType(array,
3711 instr = new HJSArrayLength(array); 3735 JS_ARRAY_TYPE,
3736 JS_ARRAY_TYPE));
3737 instr = new(zone()) HJSArrayLength(array);
3712 3738
3713 } else if (expr->IsStringLength()) { 3739 } else if (expr->IsStringLength()) {
3714 HValue* string = Pop(); 3740 HValue* string = Pop();
3715 AddInstruction(new HCheckNonSmi(string)); 3741 AddInstruction(new(zone()) HCheckNonSmi(string));
3716 AddInstruction(new HCheckInstanceType(string, 3742 AddInstruction(new(zone()) HCheckInstanceType(string,
3717 FIRST_STRING_TYPE, 3743 FIRST_STRING_TYPE,
3718 LAST_STRING_TYPE)); 3744 LAST_STRING_TYPE));
3719 instr = new HStringLength(string); 3745 instr = new(zone()) HStringLength(string);
3720 } else if (expr->IsStringAccess()) { 3746 } else if (expr->IsStringAccess()) {
3721 VISIT_FOR_VALUE(expr->key()); 3747 VISIT_FOR_VALUE(expr->key());
3722 HValue* index = Pop(); 3748 HValue* index = Pop();
3723 HValue* string = Pop(); 3749 HValue* string = Pop();
3724 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index); 3750 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index);
3725 AddInstruction(char_code); 3751 AddInstruction(char_code);
3726 instr = new HStringCharFromCode(char_code); 3752 instr = new(zone()) HStringCharFromCode(char_code);
3727 3753
3728 } else if (expr->IsFunctionPrototype()) { 3754 } else if (expr->IsFunctionPrototype()) {
3729 HValue* function = Pop(); 3755 HValue* function = Pop();
3730 AddInstruction(new HCheckNonSmi(function)); 3756 AddInstruction(new(zone()) HCheckNonSmi(function));
3731 instr = new HLoadFunctionPrototype(function); 3757 instr = new(zone()) HLoadFunctionPrototype(function);
3732 3758
3733 } else if (expr->key()->IsPropertyName()) { 3759 } else if (expr->key()->IsPropertyName()) {
3734 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 3760 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
3735 ZoneMapList* types = expr->GetReceiverTypes(); 3761 ZoneMapList* types = expr->GetReceiverTypes();
3736 3762
3737 HValue* obj = Pop(); 3763 HValue* obj = Pop();
3738 if (expr->IsMonomorphic()) { 3764 if (expr->IsMonomorphic()) {
3739 instr = BuildLoadNamed(obj, expr, types->first(), name); 3765 instr = BuildLoadNamed(obj, expr, types->first(), name);
3740 } else if (types != NULL && types->length() > 1) { 3766 } else if (types != NULL && types->length() > 1) {
3741 AddInstruction(new HCheckNonSmi(obj)); 3767 AddInstruction(new(zone()) HCheckNonSmi(obj));
3742 instr = new HLoadNamedFieldPolymorphic(obj, types, name); 3768 instr = new(zone()) HLoadNamedFieldPolymorphic(obj, types, name);
3743 } else { 3769 } else {
3744 instr = BuildLoadNamedGeneric(obj, expr); 3770 instr = BuildLoadNamedGeneric(obj, expr);
3745 } 3771 }
3746 3772
3747 } else { 3773 } else {
3748 VISIT_FOR_VALUE(expr->key()); 3774 VISIT_FOR_VALUE(expr->key());
3749 3775
3750 HValue* key = Pop(); 3776 HValue* key = Pop();
3751 HValue* obj = Pop(); 3777 HValue* obj = Pop();
3752 3778
(...skipping 18 matching lines...) Expand all
3771 3797
3772 3798
3773 void HGraphBuilder::AddCheckConstantFunction(Call* expr, 3799 void HGraphBuilder::AddCheckConstantFunction(Call* expr,
3774 HValue* receiver, 3800 HValue* receiver,
3775 Handle<Map> receiver_map, 3801 Handle<Map> receiver_map,
3776 bool smi_and_map_check) { 3802 bool smi_and_map_check) {
3777 // Constant functions have the nice property that the map will change if they 3803 // Constant functions have the nice property that the map will change if they
3778 // are overwritten. Therefore it is enough to check the map of the holder and 3804 // are overwritten. Therefore it is enough to check the map of the holder and
3779 // its prototypes. 3805 // its prototypes.
3780 if (smi_and_map_check) { 3806 if (smi_and_map_check) {
3781 AddInstruction(new HCheckNonSmi(receiver)); 3807 AddInstruction(new(zone()) HCheckNonSmi(receiver));
3782 AddInstruction(new HCheckMap(receiver, receiver_map)); 3808 AddInstruction(new(zone()) HCheckMap(receiver, receiver_map));
3783 } 3809 }
3784 if (!expr->holder().is_null()) { 3810 if (!expr->holder().is_null()) {
3785 AddInstruction(new HCheckPrototypeMaps( 3811 AddInstruction(new(zone()) HCheckPrototypeMaps(
3786 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), 3812 Handle<JSObject>(JSObject::cast(receiver_map->prototype())),
3787 expr->holder())); 3813 expr->holder()));
3788 } 3814 }
3789 } 3815 }
3790 3816
3791 3817
3792 void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr, 3818 void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
3793 HValue* receiver, 3819 HValue* receiver,
3794 ZoneMapList* types, 3820 ZoneMapList* types,
3795 Handle<String> name) { 3821 Handle<String> name) {
3796 // TODO(ager): We should recognize when the prototype chains for different 3822 // TODO(ager): We should recognize when the prototype chains for different
3797 // maps are identical. In that case we can avoid repeatedly generating the 3823 // maps are identical. In that case we can avoid repeatedly generating the
3798 // same prototype map checks. 3824 // same prototype map checks.
3799 int argument_count = expr->arguments()->length() + 1; // Includes receiver. 3825 int argument_count = expr->arguments()->length() + 1; // Includes receiver.
3800 int count = 0; 3826 int count = 0;
3801 HBasicBlock* join = NULL; 3827 HBasicBlock* join = NULL;
3802 for (int i = 0; i < types->length() && count < kMaxCallPolymorphism; ++i) { 3828 for (int i = 0; i < types->length() && count < kMaxCallPolymorphism; ++i) {
3803 Handle<Map> map = types->at(i); 3829 Handle<Map> map = types->at(i);
3804 if (expr->ComputeTarget(map, name)) { 3830 if (expr->ComputeTarget(map, name)) {
3805 if (count == 0) { 3831 if (count == 0) {
3806 AddInstruction(new HCheckNonSmi(receiver)); // Only needed once. 3832 // Only needed once.
3833 AddInstruction(new(zone()) HCheckNonSmi(receiver));
3807 join = graph()->CreateBasicBlock(); 3834 join = graph()->CreateBasicBlock();
3808 } 3835 }
3809 ++count; 3836 ++count;
3810 HBasicBlock* if_true = graph()->CreateBasicBlock(); 3837 HBasicBlock* if_true = graph()->CreateBasicBlock();
3811 HBasicBlock* if_false = graph()->CreateBasicBlock(); 3838 HBasicBlock* if_false = graph()->CreateBasicBlock();
3812 HCompareMap* compare = new HCompareMap(receiver, map, if_true, if_false); 3839 HCompareMap* compare =
3840 new(zone()) HCompareMap(receiver, map, if_true, if_false);
3813 current_block()->Finish(compare); 3841 current_block()->Finish(compare);
3814 3842
3815 set_current_block(if_true); 3843 set_current_block(if_true);
3816 AddCheckConstantFunction(expr, receiver, map, false); 3844 AddCheckConstantFunction(expr, receiver, map, false);
3817 if (FLAG_trace_inlining && FLAG_polymorphic_inlining) { 3845 if (FLAG_trace_inlining && FLAG_polymorphic_inlining) {
3818 PrintF("Trying to inline the polymorphic call to %s\n", 3846 PrintF("Trying to inline the polymorphic call to %s\n",
3819 *name->ToCString()); 3847 *name->ToCString());
3820 } 3848 }
3821 if (!FLAG_polymorphic_inlining || !TryInline(expr)) { 3849 if (!FLAG_polymorphic_inlining || !TryInline(expr)) {
3822 // Check for bailout, as trying to inline might fail due to bailout 3850 // Check for bailout, as trying to inline might fail due to bailout
3823 // during hydrogen processing. 3851 // during hydrogen processing.
3824 CHECK_BAILOUT; 3852 CHECK_BAILOUT;
3825 HCallConstantFunction* call = 3853 HCallConstantFunction* call =
3826 new HCallConstantFunction(expr->target(), argument_count); 3854 new(zone()) HCallConstantFunction(expr->target(), argument_count);
3827 call->set_position(expr->position()); 3855 call->set_position(expr->position());
3828 PreProcessCall(call); 3856 PreProcessCall(call);
3829 AddInstruction(call); 3857 AddInstruction(call);
3830 if (!ast_context()->IsEffect()) Push(call); 3858 if (!ast_context()->IsEffect()) Push(call);
3831 } 3859 }
3832 3860
3833 if (current_block() != NULL) current_block()->Goto(join); 3861 if (current_block() != NULL) current_block()->Goto(join);
3834 set_current_block(if_false); 3862 set_current_block(if_false);
3835 } 3863 }
3836 } 3864 }
3837 3865
3838 // Finish up. Unconditionally deoptimize if we've handled all the maps we 3866 // Finish up. Unconditionally deoptimize if we've handled all the maps we
3839 // know about and do not want to handle ones we've never seen. Otherwise 3867 // know about and do not want to handle ones we've never seen. Otherwise
3840 // use a generic IC. 3868 // use a generic IC.
3841 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { 3869 if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
3842 current_block()->FinishExitWithDeoptimization(); 3870 current_block()->FinishExitWithDeoptimization();
3843 } else { 3871 } else {
3844 HContext* context = new HContext; 3872 HContext* context = new(zone()) HContext;
3845 AddInstruction(context); 3873 AddInstruction(context);
3846 HCallNamed* call = new HCallNamed(context, name, argument_count); 3874 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count);
3847 call->set_position(expr->position()); 3875 call->set_position(expr->position());
3848 PreProcessCall(call); 3876 PreProcessCall(call);
3849 3877
3850 if (join != NULL) { 3878 if (join != NULL) {
3851 AddInstruction(call); 3879 AddInstruction(call);
3852 if (!ast_context()->IsEffect()) Push(call); 3880 if (!ast_context()->IsEffect()) Push(call);
3853 current_block()->Goto(join); 3881 current_block()->Goto(join);
3854 } else { 3882 } else {
3855 ast_context()->ReturnInstruction(call, expr->id()); 3883 ast_context()->ReturnInstruction(call, expr->id());
3856 return; 3884 return;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
3912 3940
3913 // No context change required. 3941 // No context change required.
3914 CompilationInfo* outer_info = info(); 3942 CompilationInfo* outer_info = info();
3915 if (target->context() != outer_info->closure()->context() || 3943 if (target->context() != outer_info->closure()->context() ||
3916 outer_info->scope()->contains_with() || 3944 outer_info->scope()->contains_with() ||
3917 outer_info->scope()->num_heap_slots() > 0) { 3945 outer_info->scope()->num_heap_slots() > 0) {
3918 TraceInline(target, "target requires context change"); 3946 TraceInline(target, "target requires context change");
3919 return false; 3947 return false;
3920 } 3948 }
3921 3949
3922 // Don't inline deeper than two calls. 3950 // Don't inline deeper than kMaxInliningLevels calls.
3923 HEnvironment* env = environment(); 3951 HEnvironment* env = environment();
3924 if (env->outer() != NULL && env->outer()->outer() != NULL) { 3952 int current_level = 1;
3925 TraceInline(target, "inline depth limit reached"); 3953 while (env->outer() != NULL) {
3926 return false; 3954 if (current_level == Compiler::kMaxInliningLevels) {
3955 TraceInline(target, "inline depth limit reached");
3956 return false;
3957 }
3958 current_level++;
3959 env = env->outer();
3927 } 3960 }
3928 3961
3929 // Don't inline recursive functions. 3962 // Don't inline recursive functions.
3930 if (target->shared() == outer_info->closure()->shared()) { 3963 if (target->shared() == outer_info->closure()->shared()) {
3931 TraceInline(target, "target is recursive"); 3964 TraceInline(target, "target is recursive");
3932 return false; 3965 return false;
3933 } 3966 }
3934 3967
3935 // We don't want to add more than a certain number of nodes from inlining. 3968 // We don't want to add more than a certain number of nodes from inlining.
3936 if (FLAG_limit_inlining && inlined_count_ > kMaxInlinedNodes) { 3969 if (FLAG_limit_inlining && inlined_count_ > kMaxInlinedNodes) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
4018 FunctionState target_state(this, &target_info, &target_oracle); 4051 FunctionState target_state(this, &target_info, &target_oracle);
4019 4052
4020 HConstant* undefined = graph()->GetConstantUndefined(); 4053 HConstant* undefined = graph()->GetConstantUndefined();
4021 HEnvironment* inner_env = 4054 HEnvironment* inner_env =
4022 environment()->CopyForInlining(target, function, true, undefined); 4055 environment()->CopyForInlining(target, function, true, undefined);
4023 HBasicBlock* body_entry = CreateBasicBlock(inner_env); 4056 HBasicBlock* body_entry = CreateBasicBlock(inner_env);
4024 current_block()->Goto(body_entry); 4057 current_block()->Goto(body_entry);
4025 4058
4026 body_entry->SetJoinId(expr->ReturnId()); 4059 body_entry->SetJoinId(expr->ReturnId());
4027 set_current_block(body_entry); 4060 set_current_block(body_entry);
4028 AddInstruction(new HEnterInlined(target, function)); 4061 AddInstruction(new(zone()) HEnterInlined(target, function));
4029 VisitStatements(function->body()); 4062 VisitStatements(function->body());
4030 if (HasStackOverflow()) { 4063 if (HasStackOverflow()) {
4031 // Bail out if the inline function did, as we cannot residualize a call 4064 // Bail out if the inline function did, as we cannot residualize a call
4032 // instead. 4065 // instead.
4033 TraceInline(target, "inline graph construction failed"); 4066 TraceInline(target, "inline graph construction failed");
4034 return false; 4067 return false;
4035 } 4068 }
4036 4069
4037 // Update inlined nodes count. 4070 // Update inlined nodes count.
4038 inlined_count_ += nodes_added; 4071 inlined_count_ += nodes_added;
(...skipping 12 matching lines...) Expand all
4051 current_block()->AddLeaveInlined(undefined, function_return()); 4084 current_block()->AddLeaveInlined(undefined, function_return());
4052 } 4085 }
4053 } else { 4086 } else {
4054 // The graph builder assumes control can reach both branches of a 4087 // The graph builder assumes control can reach both branches of a
4055 // test, so we materialize the undefined value and test it rather than 4088 // test, so we materialize the undefined value and test it rather than
4056 // simply jumping to the false target. 4089 // simply jumping to the false target.
4057 // 4090 //
4058 // TODO(3168478): refactor to avoid this. 4091 // TODO(3168478): refactor to avoid this.
4059 HBasicBlock* empty_true = graph()->CreateBasicBlock(); 4092 HBasicBlock* empty_true = graph()->CreateBasicBlock();
4060 HBasicBlock* empty_false = graph()->CreateBasicBlock(); 4093 HBasicBlock* empty_false = graph()->CreateBasicBlock();
4061 HTest* test = new HTest(undefined, empty_true, empty_false); 4094 HTest* test = new(zone()) HTest(undefined, empty_true, empty_false);
4062 current_block()->Finish(test); 4095 current_block()->Finish(test);
4063 4096
4064 empty_true->Goto(inlined_test_context()->if_true(), false); 4097 empty_true->Goto(inlined_test_context()->if_true(), false);
4065 empty_false->Goto(inlined_test_context()->if_false(), false); 4098 empty_false->Goto(inlined_test_context()->if_false(), false);
4066 } 4099 }
4067 } 4100 }
4068 4101
4069 // Fix up the function exits. 4102 // Fix up the function exits.
4070 if (inlined_test_context() != NULL) { 4103 if (inlined_test_context() != NULL) {
4071 HBasicBlock* if_true = inlined_test_context()->if_true(); 4104 HBasicBlock* if_true = inlined_test_context()->if_true();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
4105 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; 4138 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
4106 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); 4139 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
4107 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 4140 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
4108 switch (id) { 4141 switch (id) {
4109 case kStringCharCodeAt: 4142 case kStringCharCodeAt:
4110 case kStringCharAt: 4143 case kStringCharAt:
4111 if (argument_count == 2 && check_type == STRING_CHECK) { 4144 if (argument_count == 2 && check_type == STRING_CHECK) {
4112 HValue* index = Pop(); 4145 HValue* index = Pop();
4113 HValue* string = Pop(); 4146 HValue* string = Pop();
4114 ASSERT(!expr->holder().is_null()); 4147 ASSERT(!expr->holder().is_null());
4115 AddInstruction(new HCheckPrototypeMaps( 4148 AddInstruction(new(zone()) HCheckPrototypeMaps(
4116 oracle()->GetPrototypeForPrimitiveCheck(STRING_CHECK), 4149 oracle()->GetPrototypeForPrimitiveCheck(STRING_CHECK),
4117 expr->holder())); 4150 expr->holder()));
4118 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index); 4151 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index);
4119 if (id == kStringCharCodeAt) { 4152 if (id == kStringCharCodeAt) {
4120 ast_context()->ReturnInstruction(char_code, expr->id()); 4153 ast_context()->ReturnInstruction(char_code, expr->id());
4121 return true; 4154 return true;
4122 } 4155 }
4123 AddInstruction(char_code); 4156 AddInstruction(char_code);
4124 HStringCharFromCode* result = new HStringCharFromCode(char_code); 4157 HStringCharFromCode* result =
4158 new(zone()) HStringCharFromCode(char_code);
4125 ast_context()->ReturnInstruction(result, expr->id()); 4159 ast_context()->ReturnInstruction(result, expr->id());
4126 return true; 4160 return true;
4127 } 4161 }
4128 break; 4162 break;
4129 case kMathRound: 4163 case kMathRound:
4130 case kMathFloor: 4164 case kMathFloor:
4131 case kMathAbs: 4165 case kMathAbs:
4132 case kMathSqrt: 4166 case kMathSqrt:
4133 case kMathLog: 4167 case kMathLog:
4134 case kMathSin: 4168 case kMathSin:
4135 case kMathCos: 4169 case kMathCos:
4136 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { 4170 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) {
4137 AddCheckConstantFunction(expr, receiver, receiver_map, true); 4171 AddCheckConstantFunction(expr, receiver, receiver_map, true);
4138 HValue* argument = Pop(); 4172 HValue* argument = Pop();
4139 Drop(1); // Receiver. 4173 Drop(1); // Receiver.
4140 HUnaryMathOperation* op = new HUnaryMathOperation(argument, id); 4174 HUnaryMathOperation* op = new(zone()) HUnaryMathOperation(argument, id);
4141 op->set_position(expr->position()); 4175 op->set_position(expr->position());
4142 ast_context()->ReturnInstruction(op, expr->id()); 4176 ast_context()->ReturnInstruction(op, expr->id());
4143 return true; 4177 return true;
4144 } 4178 }
4145 break; 4179 break;
4146 case kMathPow: 4180 case kMathPow:
4147 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { 4181 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
4148 AddCheckConstantFunction(expr, receiver, receiver_map, true); 4182 AddCheckConstantFunction(expr, receiver, receiver_map, true);
4149 HValue* right = Pop(); 4183 HValue* right = Pop();
4150 HValue* left = Pop(); 4184 HValue* left = Pop();
4151 Pop(); // Pop receiver. 4185 Pop(); // Pop receiver.
4152 HInstruction* result = NULL; 4186 HInstruction* result = NULL;
4153 // Use sqrt() if exponent is 0.5 or -0.5. 4187 // Use sqrt() if exponent is 0.5 or -0.5.
4154 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { 4188 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) {
4155 double exponent = HConstant::cast(right)->DoubleValue(); 4189 double exponent = HConstant::cast(right)->DoubleValue();
4156 if (exponent == 0.5) { 4190 if (exponent == 0.5) {
4157 result = new HUnaryMathOperation(left, kMathPowHalf); 4191 result = new(zone()) HUnaryMathOperation(left, kMathPowHalf);
4158 } else if (exponent == -0.5) { 4192 } else if (exponent == -0.5) {
4159 HConstant* double_one = 4193 HConstant* double_one =
4160 new HConstant(Handle<Object>(Smi::FromInt(1)), 4194 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1)),
4161 Representation::Double()); 4195 Representation::Double());
4162 AddInstruction(double_one); 4196 AddInstruction(double_one);
4163 HUnaryMathOperation* square_root = 4197 HUnaryMathOperation* square_root =
4164 new HUnaryMathOperation(left, kMathPowHalf); 4198 new(zone()) HUnaryMathOperation(left, kMathPowHalf);
4165 AddInstruction(square_root); 4199 AddInstruction(square_root);
4166 // MathPowHalf doesn't have side effects so there's no need for 4200 // MathPowHalf doesn't have side effects so there's no need for
4167 // an environment simulation here. 4201 // an environment simulation here.
4168 ASSERT(!square_root->HasSideEffects()); 4202 ASSERT(!square_root->HasSideEffects());
4169 result = new HDiv(double_one, square_root); 4203 result = new(zone()) HDiv(double_one, square_root);
4170 } else if (exponent == 2.0) { 4204 } else if (exponent == 2.0) {
4171 result = new HMul(left, left); 4205 result = new(zone()) HMul(left, left);
4172 } 4206 }
4173 } else if (right->IsConstant() && 4207 } else if (right->IsConstant() &&
4174 HConstant::cast(right)->HasInteger32Value() && 4208 HConstant::cast(right)->HasInteger32Value() &&
4175 HConstant::cast(right)->Integer32Value() == 2) { 4209 HConstant::cast(right)->Integer32Value() == 2) {
4176 result = new HMul(left, left); 4210 result = new(zone()) HMul(left, left);
4177 } 4211 }
4178 4212
4179 if (result == NULL) { 4213 if (result == NULL) {
4180 result = new HPower(left, right); 4214 result = new(zone()) HPower(left, right);
4181 } 4215 }
4182 ast_context()->ReturnInstruction(result, expr->id()); 4216 ast_context()->ReturnInstruction(result, expr->id());
4183 return true; 4217 return true;
4184 } 4218 }
4185 break; 4219 break;
4186 default: 4220 default:
4187 // Not yet supported for inlining. 4221 // Not yet supported for inlining.
4188 break; 4222 break;
4189 } 4223 }
4190 return false; 4224 return false;
(...skipping 21 matching lines...) Expand all
4212 if (!expr->IsMonomorphic() || 4246 if (!expr->IsMonomorphic() ||
4213 expr->check_type() != RECEIVER_MAP_CHECK) return false; 4247 expr->check_type() != RECEIVER_MAP_CHECK) return false;
4214 4248
4215 // Found pattern f.apply(receiver, arguments). 4249 // Found pattern f.apply(receiver, arguments).
4216 VisitForValue(prop->obj()); 4250 VisitForValue(prop->obj());
4217 if (HasStackOverflow()) return false; 4251 if (HasStackOverflow()) return false;
4218 HValue* function = Pop(); 4252 HValue* function = Pop();
4219 VisitForValue(args->at(0)); 4253 VisitForValue(args->at(0));
4220 if (HasStackOverflow()) return false; 4254 if (HasStackOverflow()) return false;
4221 HValue* receiver = Pop(); 4255 HValue* receiver = Pop();
4222 HInstruction* elements = AddInstruction(new HArgumentsElements); 4256 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
4223 HInstruction* length = AddInstruction(new HArgumentsLength(elements)); 4257 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
4224 AddCheckConstantFunction(expr, 4258 AddCheckConstantFunction(expr,
4225 function, 4259 function,
4226 expr->GetReceiverTypes()->first(), 4260 expr->GetReceiverTypes()->first(),
4227 true); 4261 true);
4228 HInstruction* result = 4262 HInstruction* result =
4229 new HApplyArguments(function, receiver, length, elements); 4263 new(zone()) HApplyArguments(function, receiver, length, elements);
4230 result->set_position(expr->position()); 4264 result->set_position(expr->position());
4231 ast_context()->ReturnInstruction(result, expr->id()); 4265 ast_context()->ReturnInstruction(result, expr->id());
4232 return true; 4266 return true;
4233 } 4267 }
4234 4268
4235 4269
4236 void HGraphBuilder::VisitCall(Call* expr) { 4270 void HGraphBuilder::VisitCall(Call* expr) {
4237 Expression* callee = expr->expression(); 4271 Expression* callee = expr->expression();
4238 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 4272 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
4239 HInstruction* call = NULL; 4273 HInstruction* call = NULL;
4240 4274
4241 Property* prop = callee->AsProperty(); 4275 Property* prop = callee->AsProperty();
4242 if (prop != NULL) { 4276 if (prop != NULL) {
4243 if (!prop->key()->IsPropertyName()) { 4277 if (!prop->key()->IsPropertyName()) {
4244 // Keyed function call. 4278 // Keyed function call.
4245 VISIT_FOR_VALUE(prop->obj()); 4279 VISIT_FOR_VALUE(prop->obj());
4246 4280
4247 VISIT_FOR_VALUE(prop->key()); 4281 VISIT_FOR_VALUE(prop->key());
4248 // Push receiver and key like the non-optimized code generator expects it. 4282 // Push receiver and key like the non-optimized code generator expects it.
4249 HValue* key = Pop(); 4283 HValue* key = Pop();
4250 HValue* receiver = Pop(); 4284 HValue* receiver = Pop();
4251 Push(key); 4285 Push(key);
4252 Push(receiver); 4286 Push(receiver);
4253 4287
4254 VisitExpressions(expr->arguments()); 4288 VisitExpressions(expr->arguments());
4255 CHECK_BAILOUT; 4289 CHECK_BAILOUT;
4256 4290
4257 HContext* context = new HContext; 4291 HContext* context = new(zone()) HContext;
4258 AddInstruction(context); 4292 AddInstruction(context);
4259 call = PreProcessCall(new HCallKeyed(context, key, argument_count)); 4293 call = PreProcessCall(
4294 new(zone()) HCallKeyed(context, key, argument_count));
4260 call->set_position(expr->position()); 4295 call->set_position(expr->position());
4261 Drop(1); // Key. 4296 Drop(1); // Key.
4262 ast_context()->ReturnInstruction(call, expr->id()); 4297 ast_context()->ReturnInstruction(call, expr->id());
4263 return; 4298 return;
4264 } 4299 }
4265 4300
4266 // Named function call. 4301 // Named function call.
4267 expr->RecordTypeFeedback(oracle()); 4302 expr->RecordTypeFeedback(oracle());
4268 4303
4269 if (TryCallApply(expr)) return; 4304 if (TryCallApply(expr)) return;
(...skipping 18 matching lines...) Expand all
4288 receiver_map, 4323 receiver_map,
4289 expr->check_type())) { 4324 expr->check_type())) {
4290 return; 4325 return;
4291 } 4326 }
4292 4327
4293 if (CallStubCompiler::HasCustomCallGenerator(*expr->target()) || 4328 if (CallStubCompiler::HasCustomCallGenerator(*expr->target()) ||
4294 expr->check_type() != RECEIVER_MAP_CHECK) { 4329 expr->check_type() != RECEIVER_MAP_CHECK) {
4295 // When the target has a custom call IC generator, use the IC, 4330 // When the target has a custom call IC generator, use the IC,
4296 // because it is likely to generate better code. Also use the IC 4331 // because it is likely to generate better code. Also use the IC
4297 // when a primitive receiver check is required. 4332 // when a primitive receiver check is required.
4298 HContext* context = new HContext; 4333 HContext* context = new(zone()) HContext;
4299 AddInstruction(context); 4334 AddInstruction(context);
4300 call = PreProcessCall(new HCallNamed(context, name, argument_count)); 4335 call = PreProcessCall(
4336 new(zone()) HCallNamed(context, name, argument_count));
4301 } else { 4337 } else {
4302 AddCheckConstantFunction(expr, receiver, receiver_map, true); 4338 AddCheckConstantFunction(expr, receiver, receiver_map, true);
4303 4339
4304 if (TryInline(expr)) { 4340 if (TryInline(expr)) {
4305 return; 4341 return;
4306 } else { 4342 } else {
4307 // Check for bailout, as the TryInline call in the if condition above 4343 // Check for bailout, as the TryInline call in the if condition above
4308 // might return false due to bailout during hydrogen processing. 4344 // might return false due to bailout during hydrogen processing.
4309 CHECK_BAILOUT; 4345 CHECK_BAILOUT;
4310 call = PreProcessCall(new HCallConstantFunction(expr->target(), 4346 call = PreProcessCall(
4311 argument_count)); 4347 new(zone()) HCallConstantFunction(expr->target(),
4348 argument_count));
4312 } 4349 }
4313 } 4350 }
4314 } else if (types != NULL && types->length() > 1) { 4351 } else if (types != NULL && types->length() > 1) {
4315 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); 4352 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK);
4316 HandlePolymorphicCallNamed(expr, receiver, types, name); 4353 HandlePolymorphicCallNamed(expr, receiver, types, name);
4317 return; 4354 return;
4318 4355
4319 } else { 4356 } else {
4320 HContext* context = new HContext; 4357 HContext* context = new(zone()) HContext;
4321 AddInstruction(context); 4358 AddInstruction(context);
4322 call = PreProcessCall(new HCallNamed(context, name, argument_count)); 4359 call = PreProcessCall(
4360 new(zone()) HCallNamed(context, name, argument_count));
4323 } 4361 }
4324 4362
4325 } else { 4363 } else {
4326 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); 4364 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
4327 bool global_call = (var != NULL) && var->is_global() && !var->is_this(); 4365 bool global_call = (var != NULL) && var->is_global() && !var->is_this();
4328 4366
4329 if (!global_call) { 4367 if (!global_call) {
4330 ++argument_count; 4368 ++argument_count;
4331 VISIT_FOR_VALUE(expr->expression()); 4369 VISIT_FOR_VALUE(expr->expression());
4332 } 4370 }
4333 4371
4334 if (global_call) { 4372 if (global_call) {
4335 bool known_global_function = false; 4373 bool known_global_function = false;
4336 // If there is a global property cell for the name at compile time and 4374 // If there is a global property cell for the name at compile time and
4337 // access check is not enabled we assume that the function will not change 4375 // access check is not enabled we assume that the function will not change
4338 // and generate optimized code for calling the function. 4376 // and generate optimized code for calling the function.
4339 LookupResult lookup; 4377 LookupResult lookup;
4340 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); 4378 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false);
4341 if (type == kUseCell && 4379 if (type == kUseCell &&
4342 !info()->global_object()->IsAccessCheckNeeded()) { 4380 !info()->global_object()->IsAccessCheckNeeded()) {
4343 Handle<GlobalObject> global(info()->global_object()); 4381 Handle<GlobalObject> global(info()->global_object());
4344 known_global_function = expr->ComputeGlobalTarget(global, &lookup); 4382 known_global_function = expr->ComputeGlobalTarget(global, &lookup);
4345 } 4383 }
4346 if (known_global_function) { 4384 if (known_global_function) {
4347 // Push the global object instead of the global receiver because 4385 // Push the global object instead of the global receiver because
4348 // code generated by the full code generator expects it. 4386 // code generated by the full code generator expects it.
4349 HContext* context = new HContext; 4387 HContext* context = new(zone()) HContext;
4350 HGlobalObject* global_object = new HGlobalObject(context); 4388 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
4351 AddInstruction(context); 4389 AddInstruction(context);
4352 PushAndAdd(global_object); 4390 PushAndAdd(global_object);
4353 VisitExpressions(expr->arguments()); 4391 VisitExpressions(expr->arguments());
4354 CHECK_BAILOUT; 4392 CHECK_BAILOUT;
4355 4393
4356 VISIT_FOR_VALUE(expr->expression()); 4394 VISIT_FOR_VALUE(expr->expression());
4357 HValue* function = Pop(); 4395 HValue* function = Pop();
4358 AddInstruction(new HCheckFunction(function, expr->target())); 4396 AddInstruction(new(zone()) HCheckFunction(function, expr->target()));
4359 4397
4360 // Replace the global object with the global receiver. 4398 // Replace the global object with the global receiver.
4361 HGlobalReceiver* global_receiver = new HGlobalReceiver(global_object); 4399 HGlobalReceiver* global_receiver =
4400 new(zone()) HGlobalReceiver(global_object);
4362 // Index of the receiver from the top of the expression stack. 4401 // Index of the receiver from the top of the expression stack.
4363 const int receiver_index = argument_count - 1; 4402 const int receiver_index = argument_count - 1;
4364 AddInstruction(global_receiver); 4403 AddInstruction(global_receiver);
4365 ASSERT(environment()->ExpressionStackAt(receiver_index)-> 4404 ASSERT(environment()->ExpressionStackAt(receiver_index)->
4366 IsGlobalObject()); 4405 IsGlobalObject());
4367 environment()->SetExpressionStackAt(receiver_index, global_receiver); 4406 environment()->SetExpressionStackAt(receiver_index, global_receiver);
4368 4407
4369 if (TryInline(expr)) { 4408 if (TryInline(expr)) {
4370 return; 4409 return;
4371 } 4410 }
4372 // Check for bailout, as trying to inline might fail due to bailout 4411 // Check for bailout, as trying to inline might fail due to bailout
4373 // during hydrogen processing. 4412 // during hydrogen processing.
4374 CHECK_BAILOUT; 4413 CHECK_BAILOUT;
4375 4414
4376 call = PreProcessCall(new HCallKnownGlobal(expr->target(), 4415 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(),
4377 argument_count)); 4416 argument_count));
4378 } else { 4417 } else {
4379 HContext* context = new HContext; 4418 HContext* context = new(zone()) HContext;
4380 AddInstruction(context); 4419 AddInstruction(context);
4381 PushAndAdd(new HGlobalObject(context)); 4420 PushAndAdd(new(zone()) HGlobalObject(context));
4382 VisitExpressions(expr->arguments()); 4421 VisitExpressions(expr->arguments());
4383 CHECK_BAILOUT; 4422 CHECK_BAILOUT;
4384 4423
4385 call = PreProcessCall(new HCallGlobal(context, 4424 call = PreProcessCall(new(zone()) HCallGlobal(context,
4386 var->name(), 4425 var->name(),
4387 argument_count)); 4426 argument_count));
4388 } 4427 }
4389 4428
4390 } else { 4429 } else {
4391 HContext* context = new HContext; 4430 HContext* context = new(zone()) HContext;
4392 HGlobalObject* global_object = new HGlobalObject(context); 4431 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
4393 AddInstruction(context); 4432 AddInstruction(context);
4394 AddInstruction(global_object); 4433 AddInstruction(global_object);
4395 PushAndAdd(new HGlobalReceiver(global_object)); 4434 PushAndAdd(new(zone()) HGlobalReceiver(global_object));
4396 VisitExpressions(expr->arguments()); 4435 VisitExpressions(expr->arguments());
4397 CHECK_BAILOUT; 4436 CHECK_BAILOUT;
4398 4437
4399 call = PreProcessCall(new HCallFunction(context, argument_count)); 4438 call = PreProcessCall(new(zone()) HCallFunction(context, argument_count));
4400 } 4439 }
4401 } 4440 }
4402 4441
4403 call->set_position(expr->position()); 4442 call->set_position(expr->position());
4404 ast_context()->ReturnInstruction(call, expr->id()); 4443 ast_context()->ReturnInstruction(call, expr->id());
4405 } 4444 }
4406 4445
4407 4446
4408 void HGraphBuilder::VisitCallNew(CallNew* expr) { 4447 void HGraphBuilder::VisitCallNew(CallNew* expr) {
4409 // The constructor function is also used as the receiver argument to the 4448 // The constructor function is also used as the receiver argument to the
4410 // JS construct call builtin. 4449 // JS construct call builtin.
4411 VISIT_FOR_VALUE(expr->expression()); 4450 VISIT_FOR_VALUE(expr->expression());
4412 VisitExpressions(expr->arguments()); 4451 VisitExpressions(expr->arguments());
4413 CHECK_BAILOUT; 4452 CHECK_BAILOUT;
4414 4453
4415 HContext* context = new HContext; 4454 HContext* context = new(zone()) HContext;
4416 AddInstruction(context); 4455 AddInstruction(context);
4417 4456
4418 // The constructor is both an operand to the instruction and an argument 4457 // The constructor is both an operand to the instruction and an argument
4419 // to the construct call. 4458 // to the construct call.
4420 int arg_count = expr->arguments()->length() + 1; // Plus constructor. 4459 int arg_count = expr->arguments()->length() + 1; // Plus constructor.
4421 HValue* constructor = environment()->ExpressionStackAt(arg_count - 1); 4460 HValue* constructor = environment()->ExpressionStackAt(arg_count - 1);
4422 HCallNew* call = new HCallNew(context, constructor, arg_count); 4461 HCallNew* call = new(zone()) HCallNew(context, constructor, arg_count);
4423 call->set_position(expr->position()); 4462 call->set_position(expr->position());
4424 PreProcessCall(call); 4463 PreProcessCall(call);
4425 ast_context()->ReturnInstruction(call, expr->id()); 4464 ast_context()->ReturnInstruction(call, expr->id());
4426 } 4465 }
4427 4466
4428 4467
4429 // Support for generating inlined runtime functions. 4468 // Support for generating inlined runtime functions.
4430 4469
4431 // Lookup table for generators for runtime calls that are generated inline. 4470 // Lookup table for generators for runtime calls that are generated inline.
4432 // Elements of the table are member pointers to functions of HGraphBuilder. 4471 // Elements of the table are member pointers to functions of HGraphBuilder.
(...skipping 28 matching lines...) Expand all
4461 4500
4462 // Call the inline code generator using the pointer-to-member. 4501 // Call the inline code generator using the pointer-to-member.
4463 (this->*generator)(expr); 4502 (this->*generator)(expr);
4464 } else { 4503 } else {
4465 ASSERT(function->intrinsic_type == Runtime::RUNTIME); 4504 ASSERT(function->intrinsic_type == Runtime::RUNTIME);
4466 VisitArgumentList(expr->arguments()); 4505 VisitArgumentList(expr->arguments());
4467 CHECK_BAILOUT; 4506 CHECK_BAILOUT;
4468 4507
4469 Handle<String> name = expr->name(); 4508 Handle<String> name = expr->name();
4470 int argument_count = expr->arguments()->length(); 4509 int argument_count = expr->arguments()->length();
4471 HCallRuntime* call = new HCallRuntime(name, function, argument_count); 4510 HCallRuntime* call =
4511 new(zone()) HCallRuntime(name, function, argument_count);
4472 call->set_position(RelocInfo::kNoPosition); 4512 call->set_position(RelocInfo::kNoPosition);
4473 Drop(argument_count); 4513 Drop(argument_count);
4474 ast_context()->ReturnInstruction(call, expr->id()); 4514 ast_context()->ReturnInstruction(call, expr->id());
4475 } 4515 }
4476 } 4516 }
4477 4517
4478 4518
4479 void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { 4519 void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
4480 Token::Value op = expr->op(); 4520 Token::Value op = expr->op();
4481 if (op == Token::VOID) { 4521 if (op == Token::VOID) {
(...skipping 17 matching lines...) Expand all
4499 } else if (prop != NULL) { 4539 } else if (prop != NULL) {
4500 if (prop->is_synthetic()) { 4540 if (prop->is_synthetic()) {
4501 // Result of deleting parameters is false, even when they rewrite 4541 // Result of deleting parameters is false, even when they rewrite
4502 // to accesses on the arguments object. 4542 // to accesses on the arguments object.
4503 ast_context()->ReturnValue(graph()->GetConstantFalse()); 4543 ast_context()->ReturnValue(graph()->GetConstantFalse());
4504 } else { 4544 } else {
4505 VISIT_FOR_VALUE(prop->obj()); 4545 VISIT_FOR_VALUE(prop->obj());
4506 VISIT_FOR_VALUE(prop->key()); 4546 VISIT_FOR_VALUE(prop->key());
4507 HValue* key = Pop(); 4547 HValue* key = Pop();
4508 HValue* obj = Pop(); 4548 HValue* obj = Pop();
4509 HDeleteProperty* instr = new HDeleteProperty(obj, key); 4549 HDeleteProperty* instr = new(zone()) HDeleteProperty(obj, key);
4510 ast_context()->ReturnInstruction(instr, expr->id()); 4550 ast_context()->ReturnInstruction(instr, expr->id());
4511 } 4551 }
4512 } else if (var->is_global()) { 4552 } else if (var->is_global()) {
4513 BAILOUT("delete with global variable"); 4553 BAILOUT("delete with global variable");
4514 } else { 4554 } else {
4515 BAILOUT("delete with non-global variable"); 4555 BAILOUT("delete with non-global variable");
4516 } 4556 }
4517 } else if (op == Token::NOT) { 4557 } else if (op == Token::NOT) {
4518 if (ast_context()->IsTest()) { 4558 if (ast_context()->IsTest()) {
4519 TestContext* context = TestContext::cast(ast_context()); 4559 TestContext* context = TestContext::cast(ast_context());
(...skipping 20 matching lines...) Expand all
4540 ast_context()->ReturnValue(Pop()); 4580 ast_context()->ReturnValue(Pop());
4541 } else { 4581 } else {
4542 ASSERT(ast_context()->IsEffect()); 4582 ASSERT(ast_context()->IsEffect());
4543 VisitForEffect(expr->expression()); 4583 VisitForEffect(expr->expression());
4544 } 4584 }
4545 4585
4546 } else if (op == Token::TYPEOF) { 4586 } else if (op == Token::TYPEOF) {
4547 VisitForTypeOf(expr->expression()); 4587 VisitForTypeOf(expr->expression());
4548 if (HasStackOverflow()) return; 4588 if (HasStackOverflow()) return;
4549 HValue* value = Pop(); 4589 HValue* value = Pop();
4550 ast_context()->ReturnInstruction(new HTypeof(value), expr->id()); 4590 ast_context()->ReturnInstruction(new(zone()) HTypeof(value), expr->id());
4551 4591
4552 } else { 4592 } else {
4553 VISIT_FOR_VALUE(expr->expression()); 4593 VISIT_FOR_VALUE(expr->expression());
4554 HValue* value = Pop(); 4594 HValue* value = Pop();
4555 HInstruction* instr = NULL; 4595 HInstruction* instr = NULL;
4556 switch (op) { 4596 switch (op) {
4557 case Token::BIT_NOT: 4597 case Token::BIT_NOT:
4558 instr = new HBitNot(value); 4598 instr = new(zone()) HBitNot(value);
4559 break; 4599 break;
4560 case Token::SUB: 4600 case Token::SUB:
4561 instr = new HMul(value, graph_->GetConstantMinus1()); 4601 instr = new(zone()) HMul(value, graph_->GetConstantMinus1());
4562 break; 4602 break;
4563 case Token::ADD: 4603 case Token::ADD:
4564 instr = new HMul(value, graph_->GetConstant1()); 4604 instr = new(zone()) HMul(value, graph_->GetConstant1());
4565 break; 4605 break;
4566 default: 4606 default:
4567 BAILOUT("Value: unsupported unary operation"); 4607 BAILOUT("Value: unsupported unary operation");
4568 break; 4608 break;
4569 } 4609 }
4570 ast_context()->ReturnInstruction(instr, expr->id()); 4610 ast_context()->ReturnInstruction(instr, expr->id());
4571 } 4611 }
4572 } 4612 }
4573 4613
4574 4614
4575 void HGraphBuilder::VisitIncrementOperation(IncrementOperation* expr) { 4615 void HGraphBuilder::VisitIncrementOperation(IncrementOperation* expr) {
4576 // IncrementOperation is never visited by the visitor. It only 4616 // IncrementOperation is never visited by the visitor. It only
4577 // occurs as a subexpression of CountOperation. 4617 // occurs as a subexpression of CountOperation.
4578 UNREACHABLE(); 4618 UNREACHABLE();
4579 } 4619 }
4580 4620
4581 4621
4582 HInstruction* HGraphBuilder::BuildIncrement(HValue* value, bool increment) { 4622 HInstruction* HGraphBuilder::BuildIncrement(HValue* value, bool increment) {
4583 HConstant* delta = increment 4623 HConstant* delta = increment
4584 ? graph_->GetConstant1() 4624 ? graph_->GetConstant1()
4585 : graph_->GetConstantMinus1(); 4625 : graph_->GetConstantMinus1();
4586 HInstruction* instr = new HAdd(value, delta); 4626 HInstruction* instr = new(zone()) HAdd(value, delta);
4587 AssumeRepresentation(instr, Representation::Integer32()); 4627 AssumeRepresentation(instr, Representation::Integer32());
4588 return instr; 4628 return instr;
4589 } 4629 }
4590 4630
4591 4631
4592 void HGraphBuilder::VisitCountOperation(CountOperation* expr) { 4632 void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
4593 IncrementOperation* increment = expr->increment(); 4633 IncrementOperation* increment = expr->increment();
4594 Expression* target = increment->expression(); 4634 Expression* target = increment->expression();
4595 VariableProxy* proxy = target->AsVariableProxy(); 4635 VariableProxy* proxy = target->AsVariableProxy();
4596 Variable* var = proxy->AsVariable(); 4636 Variable* var = proxy->AsVariable();
(...skipping 15 matching lines...) Expand all
4612 if (var->is_global()) { 4652 if (var->is_global()) {
4613 HandleGlobalVariableAssignment(var, 4653 HandleGlobalVariableAssignment(var,
4614 after, 4654 after,
4615 expr->position(), 4655 expr->position(),
4616 expr->AssignmentId()); 4656 expr->AssignmentId());
4617 } else if (var->IsStackAllocated()) { 4657 } else if (var->IsStackAllocated()) {
4618 Bind(var, after); 4658 Bind(var, after);
4619 } else if (var->IsContextSlot()) { 4659 } else if (var->IsContextSlot()) {
4620 HValue* context = BuildContextChainWalk(var); 4660 HValue* context = BuildContextChainWalk(var);
4621 int index = var->AsSlot()->index(); 4661 int index = var->AsSlot()->index();
4622 HStoreContextSlot* instr = new HStoreContextSlot(context, index, after); 4662 HStoreContextSlot* instr =
4663 new(zone()) HStoreContextSlot(context, index, after);
4623 AddInstruction(instr); 4664 AddInstruction(instr);
4624 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); 4665 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
4625 } else { 4666 } else {
4626 BAILOUT("lookup variable in count operation"); 4667 BAILOUT("lookup variable in count operation");
4627 } 4668 }
4628 Drop(has_extra ? 2 : 1); 4669 Drop(has_extra ? 2 : 1);
4629 ast_context()->ReturnValue(expr->is_postfix() ? before : after); 4670 ast_context()->ReturnValue(expr->is_postfix() ? before : after);
4630 4671
4631 } else if (prop != NULL) { 4672 } else if (prop != NULL) {
4632 prop->RecordTypeFeedback(oracle()); 4673 prop->RecordTypeFeedback(oracle());
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
4718 } 4759 }
4719 4760
4720 } else { 4761 } else {
4721 BAILOUT("invalid lhs in count operation"); 4762 BAILOUT("invalid lhs in count operation");
4722 } 4763 }
4723 } 4764 }
4724 4765
4725 4766
4726 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* string, 4767 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* string,
4727 HValue* index) { 4768 HValue* index) {
4728 AddInstruction(new HCheckNonSmi(string)); 4769 AddInstruction(new(zone()) HCheckNonSmi(string));
4729 AddInstruction(new HCheckInstanceType( 4770 AddInstruction(new(zone()) HCheckInstanceType(
4730 string, FIRST_STRING_TYPE, LAST_STRING_TYPE)); 4771 string, FIRST_STRING_TYPE, LAST_STRING_TYPE));
4731 HStringLength* length = new HStringLength(string); 4772 HStringLength* length = new(zone()) HStringLength(string);
4732 AddInstruction(length); 4773 AddInstruction(length);
4733 AddInstruction(new HBoundsCheck(index, length)); 4774 AddInstruction(new(zone()) HBoundsCheck(index, length));
4734 return new HStringCharCodeAt(string, index); 4775 return new(zone()) HStringCharCodeAt(string, index);
4735 } 4776 }
4736 4777
4737 4778
4738 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, 4779 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr,
4739 HValue* left, 4780 HValue* left,
4740 HValue* right) { 4781 HValue* right) {
4741 HInstruction* instr = NULL; 4782 HInstruction* instr = NULL;
4742 switch (expr->op()) { 4783 switch (expr->op()) {
4743 case Token::ADD: 4784 case Token::ADD:
4744 instr = new HAdd(left, right); 4785 instr = new(zone()) HAdd(left, right);
4745 break; 4786 break;
4746 case Token::SUB: 4787 case Token::SUB:
4747 instr = new HSub(left, right); 4788 instr = new(zone()) HSub(left, right);
4748 break; 4789 break;
4749 case Token::MUL: 4790 case Token::MUL:
4750 instr = new HMul(left, right); 4791 instr = new(zone()) HMul(left, right);
4751 break; 4792 break;
4752 case Token::MOD: 4793 case Token::MOD:
4753 instr = new HMod(left, right); 4794 instr = new(zone()) HMod(left, right);
4754 break; 4795 break;
4755 case Token::DIV: 4796 case Token::DIV:
4756 instr = new HDiv(left, right); 4797 instr = new(zone()) HDiv(left, right);
4757 break; 4798 break;
4758 case Token::BIT_XOR: 4799 case Token::BIT_XOR:
4759 instr = new HBitXor(left, right); 4800 instr = new(zone()) HBitXor(left, right);
4760 break; 4801 break;
4761 case Token::BIT_AND: 4802 case Token::BIT_AND:
4762 instr = new HBitAnd(left, right); 4803 instr = new(zone()) HBitAnd(left, right);
4763 break; 4804 break;
4764 case Token::BIT_OR: 4805 case Token::BIT_OR:
4765 instr = new HBitOr(left, right); 4806 instr = new(zone()) HBitOr(left, right);
4766 break; 4807 break;
4767 case Token::SAR: 4808 case Token::SAR:
4768 instr = new HSar(left, right); 4809 instr = new(zone()) HSar(left, right);
4769 break; 4810 break;
4770 case Token::SHR: 4811 case Token::SHR:
4771 instr = new HShr(left, right); 4812 instr = new(zone()) HShr(left, right);
4772 break; 4813 break;
4773 case Token::SHL: 4814 case Token::SHL:
4774 instr = new HShl(left, right); 4815 instr = new(zone()) HShl(left, right);
4775 break; 4816 break;
4776 default: 4817 default:
4777 UNREACHABLE(); 4818 UNREACHABLE();
4778 } 4819 }
4779 TypeInfo info = oracle()->BinaryType(expr); 4820 TypeInfo info = oracle()->BinaryType(expr);
4780 // If we hit an uninitialized binary op stub we will get type info 4821 // If we hit an uninitialized binary op stub we will get type info
4781 // for a smi operation. If one of the operands is a constant string 4822 // for a smi operation. If one of the operands is a constant string
4782 // do not generate code assuming it is a smi operation. 4823 // do not generate code assuming it is a smi operation.
4783 if (info.IsSmi() && 4824 if (info.IsSmi() &&
4784 ((left->IsConstant() && HConstant::cast(left)->HasStringValue()) || 4825 ((left->IsConstant() && HConstant::cast(left)->HasStringValue()) ||
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4838 Visit(expr->right()); 4879 Visit(expr->right());
4839 4880
4840 } else if (ast_context()->IsValue()) { 4881 } else if (ast_context()->IsValue()) {
4841 VISIT_FOR_VALUE(expr->left()); 4882 VISIT_FOR_VALUE(expr->left());
4842 ASSERT(current_block() != NULL); 4883 ASSERT(current_block() != NULL);
4843 4884
4844 // We need an extra block to maintain edge-split form. 4885 // We need an extra block to maintain edge-split form.
4845 HBasicBlock* empty_block = graph()->CreateBasicBlock(); 4886 HBasicBlock* empty_block = graph()->CreateBasicBlock();
4846 HBasicBlock* eval_right = graph()->CreateBasicBlock(); 4887 HBasicBlock* eval_right = graph()->CreateBasicBlock();
4847 HTest* test = is_logical_and 4888 HTest* test = is_logical_and
4848 ? new HTest(Top(), eval_right, empty_block) 4889 ? new(zone()) HTest(Top(), eval_right, empty_block)
4849 : new HTest(Top(), empty_block, eval_right); 4890 : new(zone()) HTest(Top(), empty_block, eval_right);
4850 current_block()->Finish(test); 4891 current_block()->Finish(test);
4851 4892
4852 set_current_block(eval_right); 4893 set_current_block(eval_right);
4853 Drop(1); // Value of the left subexpression. 4894 Drop(1); // Value of the left subexpression.
4854 VISIT_FOR_VALUE(expr->right()); 4895 VISIT_FOR_VALUE(expr->right());
4855 4896
4856 HBasicBlock* join_block = 4897 HBasicBlock* join_block =
4857 CreateJoin(empty_block, current_block(), expr->id()); 4898 CreateJoin(empty_block, current_block(), expr->id());
4858 set_current_block(join_block); 4899 set_current_block(join_block);
4859 ast_context()->ReturnValue(Pop()); 4900 ast_context()->ReturnValue(Pop());
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
4929 } 4970 }
4930 4971
4931 4972
4932 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 4973 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
4933 if (IsClassOfTest(expr)) { 4974 if (IsClassOfTest(expr)) {
4934 CallRuntime* call = expr->left()->AsCallRuntime(); 4975 CallRuntime* call = expr->left()->AsCallRuntime();
4935 VISIT_FOR_VALUE(call->arguments()->at(0)); 4976 VISIT_FOR_VALUE(call->arguments()->at(0));
4936 HValue* value = Pop(); 4977 HValue* value = Pop();
4937 Literal* literal = expr->right()->AsLiteral(); 4978 Literal* literal = expr->right()->AsLiteral();
4938 Handle<String> rhs = Handle<String>::cast(literal->handle()); 4979 Handle<String> rhs = Handle<String>::cast(literal->handle());
4939 HInstruction* instr = new HClassOfTest(value, rhs); 4980 HInstruction* instr = new(zone()) HClassOfTest(value, rhs);
4940 instr->set_position(expr->position()); 4981 instr->set_position(expr->position());
4941 ast_context()->ReturnInstruction(instr, expr->id()); 4982 ast_context()->ReturnInstruction(instr, expr->id());
4942 return; 4983 return;
4943 } 4984 }
4944 4985
4945 // Check for the pattern: typeof <expression> == <string literal>. 4986 // Check for the pattern: typeof <expression> == <string literal>.
4946 UnaryOperation* left_unary = expr->left()->AsUnaryOperation(); 4987 UnaryOperation* left_unary = expr->left()->AsUnaryOperation();
4947 Literal* right_literal = expr->right()->AsLiteral(); 4988 Literal* right_literal = expr->right()->AsLiteral();
4948 if ((expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT) && 4989 if ((expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT) &&
4949 left_unary != NULL && left_unary->op() == Token::TYPEOF && 4990 left_unary != NULL && left_unary->op() == Token::TYPEOF &&
4950 right_literal != NULL && right_literal->handle()->IsString()) { 4991 right_literal != NULL && right_literal->handle()->IsString()) {
4951 VisitForTypeOf(left_unary->expression()); 4992 VisitForTypeOf(left_unary->expression());
4952 if (HasStackOverflow()) return; 4993 if (HasStackOverflow()) return;
4953 HValue* left = Pop(); 4994 HValue* left = Pop();
4954 HInstruction* instr = new HTypeofIs(left, 4995 HInstruction* instr = new(zone()) HTypeofIs(left,
4955 Handle<String>::cast(right_literal->handle())); 4996 Handle<String>::cast(right_literal->handle()));
4956 instr->set_position(expr->position()); 4997 instr->set_position(expr->position());
4957 ast_context()->ReturnInstruction(instr, expr->id()); 4998 ast_context()->ReturnInstruction(instr, expr->id());
4958 return; 4999 return;
4959 } 5000 }
4960 5001
4961 VISIT_FOR_VALUE(expr->left()); 5002 VISIT_FOR_VALUE(expr->left());
4962 VISIT_FOR_VALUE(expr->right()); 5003 VISIT_FOR_VALUE(expr->right());
4963 5004
4964 HValue* right = Pop(); 5005 HValue* right = Pop();
(...skipping 24 matching lines...) Expand all
4989 // change and thus prefer the general IC code. 5030 // change and thus prefer the general IC code.
4990 if (!isolate()->heap()->InNewSpace(*candidate)) { 5031 if (!isolate()->heap()->InNewSpace(*candidate)) {
4991 target = candidate; 5032 target = candidate;
4992 } 5033 }
4993 } 5034 }
4994 } 5035 }
4995 5036
4996 // If the target is not null we have found a known global function that is 5037 // If the target is not null we have found a known global function that is
4997 // assumed to stay the same for this instanceof. 5038 // assumed to stay the same for this instanceof.
4998 if (target.is_null()) { 5039 if (target.is_null()) {
4999 HContext* context = new HContext; 5040 HContext* context = new(zone()) HContext;
5000 AddInstruction(context); 5041 AddInstruction(context);
5001 instr = new HInstanceOf(context, left, right); 5042 instr = new(zone()) HInstanceOf(context, left, right);
5002 } else { 5043 } else {
5003 AddInstruction(new HCheckFunction(right, target)); 5044 AddInstruction(new(zone()) HCheckFunction(right, target));
5004 instr = new HInstanceOfKnownGlobal(left, target); 5045 instr = new(zone()) HInstanceOfKnownGlobal(left, target);
5005 } 5046 }
5006 } else if (op == Token::IN) { 5047 } else if (op == Token::IN) {
5007 BAILOUT("Unsupported comparison: in"); 5048 BAILOUT("Unsupported comparison: in");
5008 } else if (type_info.IsNonPrimitive()) { 5049 } else if (type_info.IsNonPrimitive()) {
5009 switch (op) { 5050 switch (op) {
5010 case Token::EQ: 5051 case Token::EQ:
5011 case Token::EQ_STRICT: { 5052 case Token::EQ_STRICT: {
5012 AddInstruction(new HCheckNonSmi(left)); 5053 AddInstruction(new(zone()) HCheckNonSmi(left));
5013 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(left)); 5054 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(left));
5014 AddInstruction(new HCheckNonSmi(right)); 5055 AddInstruction(new(zone()) HCheckNonSmi(right));
5015 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(right)); 5056 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(right));
5016 instr = new HCompareJSObjectEq(left, right); 5057 instr = new(zone()) HCompareJSObjectEq(left, right);
5017 break; 5058 break;
5018 } 5059 }
5019 default: 5060 default:
5020 BAILOUT("Unsupported non-primitive compare"); 5061 BAILOUT("Unsupported non-primitive compare");
5021 break; 5062 break;
5022 } 5063 }
5023 } else { 5064 } else {
5024 HCompare* compare = new HCompare(left, right, op); 5065 HCompare* compare = new(zone()) HCompare(left, right, op);
5025 Representation r = ToRepresentation(type_info); 5066 Representation r = ToRepresentation(type_info);
5026 compare->SetInputRepresentation(r); 5067 compare->SetInputRepresentation(r);
5027 instr = compare; 5068 instr = compare;
5028 } 5069 }
5029 instr->set_position(expr->position()); 5070 instr->set_position(expr->position());
5030 ast_context()->ReturnInstruction(instr, expr->id()); 5071 ast_context()->ReturnInstruction(instr, expr->id());
5031 } 5072 }
5032 5073
5033 5074
5034 void HGraphBuilder::VisitCompareToNull(CompareToNull* expr) { 5075 void HGraphBuilder::VisitCompareToNull(CompareToNull* expr) {
5035 VISIT_FOR_VALUE(expr->expression()); 5076 VISIT_FOR_VALUE(expr->expression());
5036 5077
5037 HValue* value = Pop(); 5078 HValue* value = Pop();
5038 HIsNull* compare = new HIsNull(value, expr->is_strict()); 5079 HIsNull* compare = new(zone()) HIsNull(value, expr->is_strict());
5039 ast_context()->ReturnInstruction(compare, expr->id()); 5080 ast_context()->ReturnInstruction(compare, expr->id());
5040 } 5081 }
5041 5082
5042 5083
5043 void HGraphBuilder::VisitThisFunction(ThisFunction* expr) { 5084 void HGraphBuilder::VisitThisFunction(ThisFunction* expr) {
5044 BAILOUT("ThisFunction"); 5085 BAILOUT("ThisFunction");
5045 } 5086 }
5046 5087
5047 5088
5048 void HGraphBuilder::VisitDeclaration(Declaration* decl) { 5089 void HGraphBuilder::VisitDeclaration(Declaration* decl) {
(...skipping 11 matching lines...) Expand all
5060 } 5101 }
5061 } 5102 }
5062 5103
5063 5104
5064 // Generators for inline runtime functions. 5105 // Generators for inline runtime functions.
5065 // Support for types. 5106 // Support for types.
5066 void HGraphBuilder::GenerateIsSmi(CallRuntime* call) { 5107 void HGraphBuilder::GenerateIsSmi(CallRuntime* call) {
5067 ASSERT(call->arguments()->length() == 1); 5108 ASSERT(call->arguments()->length() == 1);
5068 VISIT_FOR_VALUE(call->arguments()->at(0)); 5109 VISIT_FOR_VALUE(call->arguments()->at(0));
5069 HValue* value = Pop(); 5110 HValue* value = Pop();
5070 HIsSmi* result = new HIsSmi(value); 5111 HIsSmi* result = new(zone()) HIsSmi(value);
5071 ast_context()->ReturnInstruction(result, call->id()); 5112 ast_context()->ReturnInstruction(result, call->id());
5072 } 5113 }
5073 5114
5074 5115
5075 void HGraphBuilder::GenerateIsSpecObject(CallRuntime* call) { 5116 void HGraphBuilder::GenerateIsSpecObject(CallRuntime* call) {
5076 ASSERT(call->arguments()->length() == 1); 5117 ASSERT(call->arguments()->length() == 1);
5077 VISIT_FOR_VALUE(call->arguments()->at(0)); 5118 VISIT_FOR_VALUE(call->arguments()->at(0));
5078 HValue* value = Pop(); 5119 HValue* value = Pop();
5079 HHasInstanceType* result = 5120 HHasInstanceType* result =
5080 new HHasInstanceType(value, FIRST_JS_OBJECT_TYPE, LAST_TYPE); 5121 new(zone()) HHasInstanceType(value, FIRST_JS_OBJECT_TYPE, LAST_TYPE);
5081 ast_context()->ReturnInstruction(result, call->id()); 5122 ast_context()->ReturnInstruction(result, call->id());
5082 } 5123 }
5083 5124
5084 5125
5085 void HGraphBuilder::GenerateIsFunction(CallRuntime* call) { 5126 void HGraphBuilder::GenerateIsFunction(CallRuntime* call) {
5086 ASSERT(call->arguments()->length() == 1); 5127 ASSERT(call->arguments()->length() == 1);
5087 VISIT_FOR_VALUE(call->arguments()->at(0)); 5128 VISIT_FOR_VALUE(call->arguments()->at(0));
5088 HValue* value = Pop(); 5129 HValue* value = Pop();
5089 HHasInstanceType* result = new HHasInstanceType(value, JS_FUNCTION_TYPE); 5130 HHasInstanceType* result =
5131 new(zone()) HHasInstanceType(value, JS_FUNCTION_TYPE);
5090 ast_context()->ReturnInstruction(result, call->id()); 5132 ast_context()->ReturnInstruction(result, call->id());
5091 } 5133 }
5092 5134
5093 5135
5094 void HGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) { 5136 void HGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) {
5095 ASSERT(call->arguments()->length() == 1); 5137 ASSERT(call->arguments()->length() == 1);
5096 VISIT_FOR_VALUE(call->arguments()->at(0)); 5138 VISIT_FOR_VALUE(call->arguments()->at(0));
5097 HValue* value = Pop(); 5139 HValue* value = Pop();
5098 HHasCachedArrayIndex* result = new HHasCachedArrayIndex(value); 5140 HHasCachedArrayIndex* result = new(zone()) HHasCachedArrayIndex(value);
5099 ast_context()->ReturnInstruction(result, call->id()); 5141 ast_context()->ReturnInstruction(result, call->id());
5100 } 5142 }
5101 5143
5102 5144
5103 void HGraphBuilder::GenerateIsArray(CallRuntime* call) { 5145 void HGraphBuilder::GenerateIsArray(CallRuntime* call) {
5104 ASSERT(call->arguments()->length() == 1); 5146 ASSERT(call->arguments()->length() == 1);
5105 VISIT_FOR_VALUE(call->arguments()->at(0)); 5147 VISIT_FOR_VALUE(call->arguments()->at(0));
5106 HValue* value = Pop(); 5148 HValue* value = Pop();
5107 HHasInstanceType* result = new HHasInstanceType(value, JS_ARRAY_TYPE); 5149 HHasInstanceType* result = new(zone()) HHasInstanceType(value, JS_ARRAY_TYPE);
5108 ast_context()->ReturnInstruction(result, call->id()); 5150 ast_context()->ReturnInstruction(result, call->id());
5109 } 5151 }
5110 5152
5111 5153
5112 void HGraphBuilder::GenerateIsRegExp(CallRuntime* call) { 5154 void HGraphBuilder::GenerateIsRegExp(CallRuntime* call) {
5113 ASSERT(call->arguments()->length() == 1); 5155 ASSERT(call->arguments()->length() == 1);
5114 VISIT_FOR_VALUE(call->arguments()->at(0)); 5156 VISIT_FOR_VALUE(call->arguments()->at(0));
5115 HValue* value = Pop(); 5157 HValue* value = Pop();
5116 HHasInstanceType* result = new HHasInstanceType(value, JS_REGEXP_TYPE); 5158 HHasInstanceType* result =
5159 new(zone()) HHasInstanceType(value, JS_REGEXP_TYPE);
5117 ast_context()->ReturnInstruction(result, call->id()); 5160 ast_context()->ReturnInstruction(result, call->id());
5118 } 5161 }
5119 5162
5120 5163
5121 void HGraphBuilder::GenerateIsObject(CallRuntime* call) { 5164 void HGraphBuilder::GenerateIsObject(CallRuntime* call) {
5122 ASSERT(call->arguments()->length() == 1); 5165 ASSERT(call->arguments()->length() == 1);
5123 VISIT_FOR_VALUE(call->arguments()->at(0)); 5166 VISIT_FOR_VALUE(call->arguments()->at(0));
5124 HValue* value = Pop(); 5167 HValue* value = Pop();
5125 HIsObject* test = new HIsObject(value); 5168 HIsObject* test = new(zone()) HIsObject(value);
5126 ast_context()->ReturnInstruction(test, call->id()); 5169 ast_context()->ReturnInstruction(test, call->id());
5127 } 5170 }
5128 5171
5129 5172
5130 void HGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) { 5173 void HGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) {
5131 BAILOUT("inlined runtime function: IsNonNegativeSmi"); 5174 BAILOUT("inlined runtime function: IsNonNegativeSmi");
5132 } 5175 }
5133 5176
5134 5177
5135 void HGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) { 5178 void HGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) {
5136 BAILOUT("inlined runtime function: IsUndetectableObject"); 5179 BAILOUT("inlined runtime function: IsUndetectableObject");
5137 } 5180 }
5138 5181
5139 5182
5140 void HGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf( 5183 void HGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf(
5141 CallRuntime* call) { 5184 CallRuntime* call) {
5142 BAILOUT("inlined runtime function: IsStringWrapperSafeForDefaultValueOf"); 5185 BAILOUT("inlined runtime function: IsStringWrapperSafeForDefaultValueOf");
5143 } 5186 }
5144 5187
5145 5188
5146 // Support for construct call checks. 5189 // Support for construct call checks.
5147 void HGraphBuilder::GenerateIsConstructCall(CallRuntime* call) { 5190 void HGraphBuilder::GenerateIsConstructCall(CallRuntime* call) {
5148 ASSERT(call->arguments()->length() == 0); 5191 ASSERT(call->arguments()->length() == 0);
5149 if (function_state()->outer() != NULL) { 5192 if (function_state()->outer() != NULL) {
5150 // We are generating graph for inlined function. Currently 5193 // We are generating graph for inlined function. Currently
5151 // constructor inlining is not supported and we can just return 5194 // constructor inlining is not supported and we can just return
5152 // false from %_IsConstructCall(). 5195 // false from %_IsConstructCall().
5153 ast_context()->ReturnValue(graph()->GetConstantFalse()); 5196 ast_context()->ReturnValue(graph()->GetConstantFalse());
5154 } else { 5197 } else {
5155 ast_context()->ReturnInstruction(new HIsConstructCall, call->id()); 5198 ast_context()->ReturnInstruction(new(zone()) HIsConstructCall, call->id());
5156 } 5199 }
5157 } 5200 }
5158 5201
5159 5202
5160 // Support for arguments.length and arguments[?]. 5203 // Support for arguments.length and arguments[?].
5161 void HGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { 5204 void HGraphBuilder::GenerateArgumentsLength(CallRuntime* call) {
5162 ASSERT(call->arguments()->length() == 0); 5205 ASSERT(call->arguments()->length() == 0);
5163 HInstruction* elements = AddInstruction(new HArgumentsElements); 5206 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
5164 HArgumentsLength* result = new HArgumentsLength(elements); 5207 HArgumentsLength* result = new(zone()) HArgumentsLength(elements);
5165 ast_context()->ReturnInstruction(result, call->id()); 5208 ast_context()->ReturnInstruction(result, call->id());
5166 } 5209 }
5167 5210
5168 5211
5169 void HGraphBuilder::GenerateArguments(CallRuntime* call) { 5212 void HGraphBuilder::GenerateArguments(CallRuntime* call) {
5170 ASSERT(call->arguments()->length() == 1); 5213 ASSERT(call->arguments()->length() == 1);
5171 VISIT_FOR_VALUE(call->arguments()->at(0)); 5214 VISIT_FOR_VALUE(call->arguments()->at(0));
5172 HValue* index = Pop(); 5215 HValue* index = Pop();
5173 HInstruction* elements = AddInstruction(new HArgumentsElements); 5216 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
5174 HInstruction* length = AddInstruction(new HArgumentsLength(elements)); 5217 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
5175 HAccessArgumentsAt* result = new HAccessArgumentsAt(elements, length, index); 5218 HAccessArgumentsAt* result =
5219 new(zone()) HAccessArgumentsAt(elements, length, index);
5176 ast_context()->ReturnInstruction(result, call->id()); 5220 ast_context()->ReturnInstruction(result, call->id());
5177 } 5221 }
5178 5222
5179 5223
5180 // Support for accessing the class and value fields of an object. 5224 // Support for accessing the class and value fields of an object.
5181 void HGraphBuilder::GenerateClassOf(CallRuntime* call) { 5225 void HGraphBuilder::GenerateClassOf(CallRuntime* call) {
5182 // The special form detected by IsClassOfTest is detected before we get here 5226 // The special form detected by IsClassOfTest is detected before we get here
5183 // and does not cause a bailout. 5227 // and does not cause a bailout.
5184 BAILOUT("inlined runtime function: ClassOf"); 5228 BAILOUT("inlined runtime function: ClassOf");
5185 } 5229 }
5186 5230
5187 5231
5188 void HGraphBuilder::GenerateValueOf(CallRuntime* call) { 5232 void HGraphBuilder::GenerateValueOf(CallRuntime* call) {
5189 ASSERT(call->arguments()->length() == 1); 5233 ASSERT(call->arguments()->length() == 1);
5190 VISIT_FOR_VALUE(call->arguments()->at(0)); 5234 VISIT_FOR_VALUE(call->arguments()->at(0));
5191 HValue* value = Pop(); 5235 HValue* value = Pop();
5192 HValueOf* result = new HValueOf(value); 5236 HValueOf* result = new(zone()) HValueOf(value);
5193 ast_context()->ReturnInstruction(result, call->id()); 5237 ast_context()->ReturnInstruction(result, call->id());
5194 } 5238 }
5195 5239
5196 5240
5197 void HGraphBuilder::GenerateSetValueOf(CallRuntime* call) { 5241 void HGraphBuilder::GenerateSetValueOf(CallRuntime* call) {
5198 BAILOUT("inlined runtime function: SetValueOf"); 5242 BAILOUT("inlined runtime function: SetValueOf");
5199 } 5243 }
5200 5244
5201 5245
5202 // Fast support for charCodeAt(n). 5246 // Fast support for charCodeAt(n).
5203 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { 5247 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) {
5204 ASSERT(call->arguments()->length() == 2); 5248 ASSERT(call->arguments()->length() == 2);
5205 VISIT_FOR_VALUE(call->arguments()->at(0)); 5249 VISIT_FOR_VALUE(call->arguments()->at(0));
5206 VISIT_FOR_VALUE(call->arguments()->at(1)); 5250 VISIT_FOR_VALUE(call->arguments()->at(1));
5207 HValue* index = Pop(); 5251 HValue* index = Pop();
5208 HValue* string = Pop(); 5252 HValue* string = Pop();
5209 HStringCharCodeAt* result = BuildStringCharCodeAt(string, index); 5253 HStringCharCodeAt* result = BuildStringCharCodeAt(string, index);
5210 ast_context()->ReturnInstruction(result, call->id()); 5254 ast_context()->ReturnInstruction(result, call->id());
5211 } 5255 }
5212 5256
5213 5257
5214 // Fast support for string.charAt(n) and string[n]. 5258 // Fast support for string.charAt(n) and string[n].
5215 void HGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { 5259 void HGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) {
5216 ASSERT(call->arguments()->length() == 1); 5260 ASSERT(call->arguments()->length() == 1);
5217 VISIT_FOR_VALUE(call->arguments()->at(0)); 5261 VISIT_FOR_VALUE(call->arguments()->at(0));
5218 HValue* char_code = Pop(); 5262 HValue* char_code = Pop();
5219 HStringCharFromCode* result = new HStringCharFromCode(char_code); 5263 HStringCharFromCode* result = new(zone()) HStringCharFromCode(char_code);
5220 ast_context()->ReturnInstruction(result, call->id()); 5264 ast_context()->ReturnInstruction(result, call->id());
5221 } 5265 }
5222 5266
5223 5267
5224 // Fast support for string.charAt(n) and string[n]. 5268 // Fast support for string.charAt(n) and string[n].
5225 void HGraphBuilder::GenerateStringCharAt(CallRuntime* call) { 5269 void HGraphBuilder::GenerateStringCharAt(CallRuntime* call) {
5226 ASSERT(call->arguments()->length() == 2); 5270 ASSERT(call->arguments()->length() == 2);
5227 VISIT_FOR_VALUE(call->arguments()->at(0)); 5271 VISIT_FOR_VALUE(call->arguments()->at(0));
5228 VISIT_FOR_VALUE(call->arguments()->at(1)); 5272 VISIT_FOR_VALUE(call->arguments()->at(1));
5229 HValue* index = Pop(); 5273 HValue* index = Pop();
5230 HValue* string = Pop(); 5274 HValue* string = Pop();
5231 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index); 5275 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index);
5232 AddInstruction(char_code); 5276 AddInstruction(char_code);
5233 HStringCharFromCode* result = new HStringCharFromCode(char_code); 5277 HStringCharFromCode* result = new(zone()) HStringCharFromCode(char_code);
5234 ast_context()->ReturnInstruction(result, call->id()); 5278 ast_context()->ReturnInstruction(result, call->id());
5235 } 5279 }
5236 5280
5237 5281
5238 // Fast support for object equality testing. 5282 // Fast support for object equality testing.
5239 void HGraphBuilder::GenerateObjectEquals(CallRuntime* call) { 5283 void HGraphBuilder::GenerateObjectEquals(CallRuntime* call) {
5240 ASSERT(call->arguments()->length() == 2); 5284 ASSERT(call->arguments()->length() == 2);
5241 VISIT_FOR_VALUE(call->arguments()->at(0)); 5285 VISIT_FOR_VALUE(call->arguments()->at(0));
5242 VISIT_FOR_VALUE(call->arguments()->at(1)); 5286 VISIT_FOR_VALUE(call->arguments()->at(1));
5243 HValue* right = Pop(); 5287 HValue* right = Pop();
5244 HValue* left = Pop(); 5288 HValue* left = Pop();
5245 HCompareJSObjectEq* result = new HCompareJSObjectEq(left, right); 5289 HCompareJSObjectEq* result = new(zone()) HCompareJSObjectEq(left, right);
5246 ast_context()->ReturnInstruction(result, call->id()); 5290 ast_context()->ReturnInstruction(result, call->id());
5247 } 5291 }
5248 5292
5249 5293
5250 void HGraphBuilder::GenerateLog(CallRuntime* call) { 5294 void HGraphBuilder::GenerateLog(CallRuntime* call) {
5251 // %_Log is ignored in optimized code. 5295 // %_Log is ignored in optimized code.
5252 ast_context()->ReturnValue(graph()->GetConstantUndefined()); 5296 ast_context()->ReturnValue(graph()->GetConstantUndefined());
5253 } 5297 }
5254 5298
5255 5299
5256 // Fast support for Math.random(). 5300 // Fast support for Math.random().
5257 void HGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { 5301 void HGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) {
5258 BAILOUT("inlined runtime function: RandomHeapNumber"); 5302 BAILOUT("inlined runtime function: RandomHeapNumber");
5259 } 5303 }
5260 5304
5261 5305
5262 // Fast support for StringAdd. 5306 // Fast support for StringAdd.
5263 void HGraphBuilder::GenerateStringAdd(CallRuntime* call) { 5307 void HGraphBuilder::GenerateStringAdd(CallRuntime* call) {
5264 ASSERT_EQ(2, call->arguments()->length()); 5308 ASSERT_EQ(2, call->arguments()->length());
5265 VisitArgumentList(call->arguments()); 5309 VisitArgumentList(call->arguments());
5266 CHECK_BAILOUT; 5310 CHECK_BAILOUT;
5267 HContext* context = new HContext; 5311 HContext* context = new(zone()) HContext;
5268 AddInstruction(context); 5312 AddInstruction(context);
5269 HCallStub* result = new HCallStub(context, CodeStub::StringAdd, 2); 5313 HCallStub* result = new(zone()) HCallStub(context, CodeStub::StringAdd, 2);
5270 Drop(2); 5314 Drop(2);
5271 ast_context()->ReturnInstruction(result, call->id()); 5315 ast_context()->ReturnInstruction(result, call->id());
5272 } 5316 }
5273 5317
5274 5318
5275 // Fast support for SubString. 5319 // Fast support for SubString.
5276 void HGraphBuilder::GenerateSubString(CallRuntime* call) { 5320 void HGraphBuilder::GenerateSubString(CallRuntime* call) {
5277 ASSERT_EQ(3, call->arguments()->length()); 5321 ASSERT_EQ(3, call->arguments()->length());
5278 VisitArgumentList(call->arguments()); 5322 VisitArgumentList(call->arguments());
5279 CHECK_BAILOUT; 5323 CHECK_BAILOUT;
5280 HContext* context = new HContext; 5324 HContext* context = new(zone()) HContext;
5281 AddInstruction(context); 5325 AddInstruction(context);
5282 HCallStub* result = new HCallStub(context, CodeStub::SubString, 3); 5326 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3);
5283 Drop(3); 5327 Drop(3);
5284 ast_context()->ReturnInstruction(result, call->id()); 5328 ast_context()->ReturnInstruction(result, call->id());
5285 } 5329 }
5286 5330
5287 5331
5288 // Fast support for StringCompare. 5332 // Fast support for StringCompare.
5289 void HGraphBuilder::GenerateStringCompare(CallRuntime* call) { 5333 void HGraphBuilder::GenerateStringCompare(CallRuntime* call) {
5290 ASSERT_EQ(2, call->arguments()->length()); 5334 ASSERT_EQ(2, call->arguments()->length());
5291 VisitArgumentList(call->arguments()); 5335 VisitArgumentList(call->arguments());
5292 CHECK_BAILOUT; 5336 CHECK_BAILOUT;
5293 HContext* context = new HContext; 5337 HContext* context = new(zone()) HContext;
5294 AddInstruction(context); 5338 AddInstruction(context);
5295 HCallStub* result = new HCallStub(context, CodeStub::StringCompare, 2); 5339 HCallStub* result =
5340 new(zone()) HCallStub(context, CodeStub::StringCompare, 2);
5296 Drop(2); 5341 Drop(2);
5297 ast_context()->ReturnInstruction(result, call->id()); 5342 ast_context()->ReturnInstruction(result, call->id());
5298 } 5343 }
5299 5344
5300 5345
5301 // Support for direct calls from JavaScript to native RegExp code. 5346 // Support for direct calls from JavaScript to native RegExp code.
5302 void HGraphBuilder::GenerateRegExpExec(CallRuntime* call) { 5347 void HGraphBuilder::GenerateRegExpExec(CallRuntime* call) {
5303 ASSERT_EQ(4, call->arguments()->length()); 5348 ASSERT_EQ(4, call->arguments()->length());
5304 VisitArgumentList(call->arguments()); 5349 VisitArgumentList(call->arguments());
5305 CHECK_BAILOUT; 5350 CHECK_BAILOUT;
5306 HContext* context = new HContext; 5351 HContext* context = new(zone()) HContext;
5307 AddInstruction(context); 5352 AddInstruction(context);
5308 HCallStub* result = new HCallStub(context, CodeStub::RegExpExec, 4); 5353 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4);
5309 Drop(4); 5354 Drop(4);
5310 ast_context()->ReturnInstruction(result, call->id()); 5355 ast_context()->ReturnInstruction(result, call->id());
5311 } 5356 }
5312 5357
5313 5358
5314 // Construct a RegExp exec result with two in-object properties. 5359 // Construct a RegExp exec result with two in-object properties.
5315 void HGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { 5360 void HGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) {
5316 ASSERT_EQ(3, call->arguments()->length()); 5361 ASSERT_EQ(3, call->arguments()->length());
5317 VisitArgumentList(call->arguments()); 5362 VisitArgumentList(call->arguments());
5318 CHECK_BAILOUT; 5363 CHECK_BAILOUT;
5319 HContext* context = new HContext; 5364 HContext* context = new(zone()) HContext;
5320 AddInstruction(context); 5365 AddInstruction(context);
5321 HCallStub* result = 5366 HCallStub* result =
5322 new HCallStub(context, CodeStub::RegExpConstructResult, 3); 5367 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3);
5323 Drop(3); 5368 Drop(3);
5324 ast_context()->ReturnInstruction(result, call->id()); 5369 ast_context()->ReturnInstruction(result, call->id());
5325 } 5370 }
5326 5371
5327 5372
5328 // Support for fast native caches. 5373 // Support for fast native caches.
5329 void HGraphBuilder::GenerateGetFromCache(CallRuntime* call) { 5374 void HGraphBuilder::GenerateGetFromCache(CallRuntime* call) {
5330 BAILOUT("inlined runtime function: GetFromCache"); 5375 BAILOUT("inlined runtime function: GetFromCache");
5331 } 5376 }
5332 5377
5333 5378
5334 // Fast support for number to string. 5379 // Fast support for number to string.
5335 void HGraphBuilder::GenerateNumberToString(CallRuntime* call) { 5380 void HGraphBuilder::GenerateNumberToString(CallRuntime* call) {
5336 ASSERT_EQ(1, call->arguments()->length()); 5381 ASSERT_EQ(1, call->arguments()->length());
5337 VisitArgumentList(call->arguments()); 5382 VisitArgumentList(call->arguments());
5338 CHECK_BAILOUT; 5383 CHECK_BAILOUT;
5339 HContext* context = new HContext; 5384 HContext* context = new(zone()) HContext;
5340 AddInstruction(context); 5385 AddInstruction(context);
5341 HCallStub* result = new HCallStub(context, CodeStub::NumberToString, 1); 5386 HCallStub* result =
5387 new(zone()) HCallStub(context, CodeStub::NumberToString, 1);
5342 Drop(1); 5388 Drop(1);
5343 ast_context()->ReturnInstruction(result, call->id()); 5389 ast_context()->ReturnInstruction(result, call->id());
5344 } 5390 }
5345 5391
5346 5392
5347 // Fast swapping of elements. Takes three expressions, the object and two 5393 // Fast swapping of elements. Takes three expressions, the object and two
5348 // indices. This should only be used if the indices are known to be 5394 // indices. This should only be used if the indices are known to be
5349 // non-negative and within bounds of the elements array at the call site. 5395 // non-negative and within bounds of the elements array at the call site.
5350 void HGraphBuilder::GenerateSwapElements(CallRuntime* call) { 5396 void HGraphBuilder::GenerateSwapElements(CallRuntime* call) {
5351 BAILOUT("inlined runtime function: SwapElements"); 5397 BAILOUT("inlined runtime function: SwapElements");
5352 } 5398 }
5353 5399
5354 5400
5355 // Fast call for custom callbacks. 5401 // Fast call for custom callbacks.
5356 void HGraphBuilder::GenerateCallFunction(CallRuntime* call) { 5402 void HGraphBuilder::GenerateCallFunction(CallRuntime* call) {
5357 BAILOUT("inlined runtime function: CallFunction"); 5403 BAILOUT("inlined runtime function: CallFunction");
5358 } 5404 }
5359 5405
5360 5406
5361 // Fast call to math functions. 5407 // Fast call to math functions.
5362 void HGraphBuilder::GenerateMathPow(CallRuntime* call) { 5408 void HGraphBuilder::GenerateMathPow(CallRuntime* call) {
5363 ASSERT_EQ(2, call->arguments()->length()); 5409 ASSERT_EQ(2, call->arguments()->length());
5364 VISIT_FOR_VALUE(call->arguments()->at(0)); 5410 VISIT_FOR_VALUE(call->arguments()->at(0));
5365 VISIT_FOR_VALUE(call->arguments()->at(1)); 5411 VISIT_FOR_VALUE(call->arguments()->at(1));
5366 HValue* right = Pop(); 5412 HValue* right = Pop();
5367 HValue* left = Pop(); 5413 HValue* left = Pop();
5368 HPower* result = new HPower(left, right); 5414 HPower* result = new(zone()) HPower(left, right);
5369 ast_context()->ReturnInstruction(result, call->id()); 5415 ast_context()->ReturnInstruction(result, call->id());
5370 } 5416 }
5371 5417
5372 5418
5373 void HGraphBuilder::GenerateMathSin(CallRuntime* call) { 5419 void HGraphBuilder::GenerateMathSin(CallRuntime* call) {
5374 ASSERT_EQ(1, call->arguments()->length()); 5420 ASSERT_EQ(1, call->arguments()->length());
5375 VisitArgumentList(call->arguments()); 5421 VisitArgumentList(call->arguments());
5376 CHECK_BAILOUT; 5422 CHECK_BAILOUT;
5377 HContext* context = new HContext; 5423 HContext* context = new(zone()) HContext;
5378 AddInstruction(context); 5424 AddInstruction(context);
5379 HCallStub* result = new HCallStub(context, CodeStub::TranscendentalCache, 1); 5425 HCallStub* result =
5426 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
5380 result->set_transcendental_type(TranscendentalCache::SIN); 5427 result->set_transcendental_type(TranscendentalCache::SIN);
5381 Drop(1); 5428 Drop(1);
5382 ast_context()->ReturnInstruction(result, call->id()); 5429 ast_context()->ReturnInstruction(result, call->id());
5383 } 5430 }
5384 5431
5385 5432
5386 void HGraphBuilder::GenerateMathCos(CallRuntime* call) { 5433 void HGraphBuilder::GenerateMathCos(CallRuntime* call) {
5387 ASSERT_EQ(1, call->arguments()->length()); 5434 ASSERT_EQ(1, call->arguments()->length());
5388 VisitArgumentList(call->arguments()); 5435 VisitArgumentList(call->arguments());
5389 CHECK_BAILOUT; 5436 CHECK_BAILOUT;
5390 HContext* context = new HContext; 5437 HContext* context = new(zone()) HContext;
5391 AddInstruction(context); 5438 AddInstruction(context);
5392 HCallStub* result = new HCallStub(context, CodeStub::TranscendentalCache, 1); 5439 HCallStub* result =
5440 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
5393 result->set_transcendental_type(TranscendentalCache::COS); 5441 result->set_transcendental_type(TranscendentalCache::COS);
5394 Drop(1); 5442 Drop(1);
5395 ast_context()->ReturnInstruction(result, call->id()); 5443 ast_context()->ReturnInstruction(result, call->id());
5396 } 5444 }
5397 5445
5398 5446
5399 void HGraphBuilder::GenerateMathLog(CallRuntime* call) { 5447 void HGraphBuilder::GenerateMathLog(CallRuntime* call) {
5400 ASSERT_EQ(1, call->arguments()->length()); 5448 ASSERT_EQ(1, call->arguments()->length());
5401 VisitArgumentList(call->arguments()); 5449 VisitArgumentList(call->arguments());
5402 CHECK_BAILOUT; 5450 CHECK_BAILOUT;
5403 HContext* context = new HContext; 5451 HContext* context = new(zone()) HContext;
5404 AddInstruction(context); 5452 AddInstruction(context);
5405 HCallStub* result = new HCallStub(context, CodeStub::TranscendentalCache, 1); 5453 HCallStub* result =
5454 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
5406 result->set_transcendental_type(TranscendentalCache::LOG); 5455 result->set_transcendental_type(TranscendentalCache::LOG);
5407 Drop(1); 5456 Drop(1);
5408 ast_context()->ReturnInstruction(result, call->id()); 5457 ast_context()->ReturnInstruction(result, call->id());
5409 } 5458 }
5410 5459
5411 5460
5412 void HGraphBuilder::GenerateMathSqrt(CallRuntime* call) { 5461 void HGraphBuilder::GenerateMathSqrt(CallRuntime* call) {
5413 BAILOUT("inlined runtime function: MathSqrt"); 5462 BAILOUT("inlined runtime function: MathSqrt");
5414 } 5463 }
5415 5464
5416 5465
5417 // Check whether two RegExps are equivalent 5466 // Check whether two RegExps are equivalent
5418 void HGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) { 5467 void HGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) {
5419 BAILOUT("inlined runtime function: IsRegExpEquivalent"); 5468 BAILOUT("inlined runtime function: IsRegExpEquivalent");
5420 } 5469 }
5421 5470
5422 5471
5423 void HGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) { 5472 void HGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) {
5424 ASSERT(call->arguments()->length() == 1); 5473 ASSERT(call->arguments()->length() == 1);
5425 VISIT_FOR_VALUE(call->arguments()->at(0)); 5474 VISIT_FOR_VALUE(call->arguments()->at(0));
5426 HValue* value = Pop(); 5475 HValue* value = Pop();
5427 HGetCachedArrayIndex* result = new HGetCachedArrayIndex(value); 5476 HGetCachedArrayIndex* result = new(zone()) HGetCachedArrayIndex(value);
5428 ast_context()->ReturnInstruction(result, call->id()); 5477 ast_context()->ReturnInstruction(result, call->id());
5429 } 5478 }
5430 5479
5431 5480
5432 void HGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) { 5481 void HGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) {
5433 BAILOUT("inlined runtime function: FastAsciiArrayJoin"); 5482 BAILOUT("inlined runtime function: FastAsciiArrayJoin");
5434 } 5483 }
5435 5484
5436 5485
5437 #undef BAILOUT 5486 #undef BAILOUT
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
5506 if (value != NULL && value->IsPhi() && value->block() == block) { 5555 if (value != NULL && value->IsPhi() && value->block() == block) {
5507 // There is already a phi for the i'th value. 5556 // There is already a phi for the i'th value.
5508 HPhi* phi = HPhi::cast(value); 5557 HPhi* phi = HPhi::cast(value);
5509 // Assert index is correct and that we haven't missed an incoming edge. 5558 // Assert index is correct and that we haven't missed an incoming edge.
5510 ASSERT(phi->merged_index() == i); 5559 ASSERT(phi->merged_index() == i);
5511 ASSERT(phi->OperandCount() == block->predecessors()->length()); 5560 ASSERT(phi->OperandCount() == block->predecessors()->length());
5512 phi->AddInput(other->values_[i]); 5561 phi->AddInput(other->values_[i]);
5513 } else if (values_[i] != other->values_[i]) { 5562 } else if (values_[i] != other->values_[i]) {
5514 // There is a fresh value on the incoming edge, a phi is needed. 5563 // There is a fresh value on the incoming edge, a phi is needed.
5515 ASSERT(values_[i] != NULL && other->values_[i] != NULL); 5564 ASSERT(values_[i] != NULL && other->values_[i] != NULL);
5516 HPhi* phi = new HPhi(i); 5565 HPhi* phi = new(block->zone()) HPhi(i);
5517 HValue* old_value = values_[i]; 5566 HValue* old_value = values_[i];
5518 for (int j = 0; j < block->predecessors()->length(); j++) { 5567 for (int j = 0; j < block->predecessors()->length(); j++) {
5519 phi->AddInput(old_value); 5568 phi->AddInput(old_value);
5520 } 5569 }
5521 phi->AddInput(other->values_[i]); 5570 phi->AddInput(other->values_[i]);
5522 this->values_[i] = phi; 5571 this->values_[i] = phi;
5523 block->AddPhi(phi); 5572 block->AddPhi(phi);
5524 } 5573 }
5525 } 5574 }
5526 } 5575 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
5563 5612
5564 5613
5565 void HEnvironment::Drop(int count) { 5614 void HEnvironment::Drop(int count) {
5566 for (int i = 0; i < count; ++i) { 5615 for (int i = 0; i < count; ++i) {
5567 Pop(); 5616 Pop();
5568 } 5617 }
5569 } 5618 }
5570 5619
5571 5620
5572 HEnvironment* HEnvironment::Copy() const { 5621 HEnvironment* HEnvironment::Copy() const {
5573 return new HEnvironment(this); 5622 return new(closure()->GetIsolate()->zone()) HEnvironment(this);
5574 } 5623 }
5575 5624
5576 5625
5577 HEnvironment* HEnvironment::CopyWithoutHistory() const { 5626 HEnvironment* HEnvironment::CopyWithoutHistory() const {
5578 HEnvironment* result = Copy(); 5627 HEnvironment* result = Copy();
5579 result->ClearHistory(); 5628 result->ClearHistory();
5580 return result; 5629 return result;
5581 } 5630 }
5582 5631
5583 5632
5584 HEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const { 5633 HEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const {
5585 HEnvironment* new_env = Copy(); 5634 HEnvironment* new_env = Copy();
5586 for (int i = 0; i < values_.length(); ++i) { 5635 for (int i = 0; i < values_.length(); ++i) {
5587 HPhi* phi = new HPhi(i); 5636 HPhi* phi = new(loop_header->zone()) HPhi(i);
5588 phi->AddInput(values_[i]); 5637 phi->AddInput(values_[i]);
5589 new_env->values_[i] = phi; 5638 new_env->values_[i] = phi;
5590 loop_header->AddPhi(phi); 5639 loop_header->AddPhi(phi);
5591 } 5640 }
5592 new_env->ClearHistory(); 5641 new_env->ClearHistory();
5593 return new_env; 5642 return new_env;
5594 } 5643 }
5595 5644
5596 5645
5597 HEnvironment* HEnvironment::CopyForInlining(Handle<JSFunction> target, 5646 HEnvironment* HEnvironment::CopyForInlining(Handle<JSFunction> target,
5598 FunctionLiteral* function, 5647 FunctionLiteral* function,
5599 bool is_speculative, 5648 bool is_speculative,
5600 HConstant* undefined) const { 5649 HConstant* undefined) const {
5601 // Outer environment is a copy of this one without the arguments. 5650 // Outer environment is a copy of this one without the arguments.
5602 int arity = function->scope()->num_parameters(); 5651 int arity = function->scope()->num_parameters();
5603 HEnvironment* outer = Copy(); 5652 HEnvironment* outer = Copy();
5604 outer->Drop(arity + 1); // Including receiver. 5653 outer->Drop(arity + 1); // Including receiver.
5605 outer->ClearHistory(); 5654 outer->ClearHistory();
5606 HEnvironment* inner = new HEnvironment(outer, function->scope(), target); 5655 Zone* zone = closure()->GetIsolate()->zone();
5656 HEnvironment* inner =
5657 new(zone) HEnvironment(outer, function->scope(), target);
5607 // Get the argument values from the original environment. 5658 // Get the argument values from the original environment.
5608 if (is_speculative) { 5659 if (is_speculative) {
5609 for (int i = 0; i <= arity; ++i) { // Include receiver. 5660 for (int i = 0; i <= arity; ++i) { // Include receiver.
5610 HValue* push = ExpressionStackAt(arity - i); 5661 HValue* push = ExpressionStackAt(arity - i);
5611 inner->SetValueAt(i, push); 5662 inner->SetValueAt(i, push);
5612 } 5663 }
5613 } else { 5664 } else {
5614 for (int i = 0; i <= arity; ++i) { // Include receiver. 5665 for (int i = 0; i <= arity; ++i) { // Include receiver.
5615 inner->SetValueAt(i, ExpressionStackAt(arity - i)); 5666 inner->SetValueAt(i, ExpressionStackAt(arity - i));
5616 } 5667 }
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
5951 } 6002 }
5952 } 6003 }
5953 6004
5954 #ifdef DEBUG 6005 #ifdef DEBUG
5955 if (graph_ != NULL) graph_->Verify(); 6006 if (graph_ != NULL) graph_->Verify();
5956 if (allocator_ != NULL) allocator_->Verify(); 6007 if (allocator_ != NULL) allocator_->Verify();
5957 #endif 6008 #endif
5958 } 6009 }
5959 6010
5960 } } // namespace v8::internal 6011 } } // namespace v8::internal
OLDNEW
« 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