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