OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 37 matching lines...) Loading... | |
48 #else | 48 #else |
49 #error Unsupported target architecture. | 49 #error Unsupported target architecture. |
50 #endif | 50 #endif |
51 | 51 |
52 namespace v8 { | 52 namespace v8 { |
53 namespace internal { | 53 namespace internal { |
54 | 54 |
55 HBasicBlock::HBasicBlock(HGraph* graph) | 55 HBasicBlock::HBasicBlock(HGraph* graph) |
56 : block_id_(graph->GetNextBlockID()), | 56 : block_id_(graph->GetNextBlockID()), |
57 graph_(graph), | 57 graph_(graph), |
58 phis_(4), | 58 phis_(4, graph->zone()), |
59 first_(NULL), | 59 first_(NULL), |
60 last_(NULL), | 60 last_(NULL), |
61 end_(NULL), | 61 end_(NULL), |
62 loop_information_(NULL), | 62 loop_information_(NULL), |
63 predecessors_(2), | 63 predecessors_(2, graph->zone()), |
64 dominator_(NULL), | 64 dominator_(NULL), |
65 dominated_blocks_(4), | 65 dominated_blocks_(4, graph->zone()), |
66 last_environment_(NULL), | 66 last_environment_(NULL), |
67 argument_count_(-1), | 67 argument_count_(-1), |
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, graph->zone()), |
71 parent_loop_header_(NULL), | 71 parent_loop_header_(NULL), |
72 is_inline_return_target_(false), | 72 is_inline_return_target_(false), |
73 is_deoptimizing_(false), | 73 is_deoptimizing_(false), |
74 dominates_loop_successors_(false) { } | 74 dominates_loop_successors_(false) { } |
75 | 75 |
76 | 76 |
77 void HBasicBlock::AttachLoopInformation() { | 77 void HBasicBlock::AttachLoopInformation() { |
78 ASSERT(!IsLoopHeader()); | 78 ASSERT(!IsLoopHeader()); |
79 loop_information_ = new(zone()) HLoopInformation(this); | 79 loop_information_ = new(zone()) HLoopInformation(this, zone()); |
80 } | 80 } |
81 | 81 |
82 | 82 |
83 void HBasicBlock::DetachLoopInformation() { | 83 void HBasicBlock::DetachLoopInformation() { |
84 ASSERT(IsLoopHeader()); | 84 ASSERT(IsLoopHeader()); |
85 loop_information_ = NULL; | 85 loop_information_ = NULL; |
86 } | 86 } |
87 | 87 |
88 | 88 |
89 void HBasicBlock::AddPhi(HPhi* phi) { | 89 void HBasicBlock::AddPhi(HPhi* phi) { |
90 ASSERT(!IsStartBlock()); | 90 ASSERT(!IsStartBlock()); |
91 phis_.Add(phi); | 91 phis_.Add(phi, zone()); |
92 phi->SetBlock(this); | 92 phi->SetBlock(this); |
93 } | 93 } |
94 | 94 |
95 | 95 |
96 void HBasicBlock::RemovePhi(HPhi* phi) { | 96 void HBasicBlock::RemovePhi(HPhi* phi) { |
97 ASSERT(phi->block() == this); | 97 ASSERT(phi->block() == this); |
98 ASSERT(phis_.Contains(phi)); | 98 ASSERT(phis_.Contains(phi)); |
99 ASSERT(phi->HasNoUses() || !phi->is_live()); | 99 ASSERT(phi->HasNoUses() || !phi->is_live()); |
100 phi->Kill(); | 100 phi->Kill(); |
101 phis_.RemoveElement(phi); | 101 phis_.RemoveElement(phi); |
(...skipping 10 matching lines...) Loading... | |
112 entry->InitializeAsFirst(this); | 112 entry->InitializeAsFirst(this); |
113 first_ = last_ = entry; | 113 first_ = last_ = entry; |
114 } | 114 } |
115 instr->InsertAfter(last_); | 115 instr->InsertAfter(last_); |
116 } | 116 } |
117 | 117 |
118 | 118 |
119 HDeoptimize* HBasicBlock::CreateDeoptimize( | 119 HDeoptimize* HBasicBlock::CreateDeoptimize( |
120 HDeoptimize::UseEnvironment has_uses) { | 120 HDeoptimize::UseEnvironment has_uses) { |
121 ASSERT(HasEnvironment()); | 121 ASSERT(HasEnvironment()); |
122 if (has_uses == HDeoptimize::kNoUses) return new(zone()) HDeoptimize(0); | 122 if (has_uses == HDeoptimize::kNoUses) |
123 return new(zone()) HDeoptimize(0, zone()); | |
123 | 124 |
124 HEnvironment* environment = last_environment(); | 125 HEnvironment* environment = last_environment(); |
125 HDeoptimize* instr = new(zone()) HDeoptimize(environment->length()); | 126 HDeoptimize* instr = new(zone()) HDeoptimize(environment->length(), zone()); |
126 for (int i = 0; i < environment->length(); i++) { | 127 for (int i = 0; i < environment->length(); i++) { |
127 HValue* val = environment->values()->at(i); | 128 HValue* val = environment->values()->at(i); |
128 instr->AddEnvironmentValue(val); | 129 instr->AddEnvironmentValue(val, zone()); |
129 } | 130 } |
130 | 131 |
131 return instr; | 132 return instr; |
132 } | 133 } |
133 | 134 |
134 | 135 |
135 HSimulate* HBasicBlock::CreateSimulate(int ast_id) { | 136 HSimulate* HBasicBlock::CreateSimulate(int ast_id) { |
136 ASSERT(HasEnvironment()); | 137 ASSERT(HasEnvironment()); |
137 HEnvironment* environment = last_environment(); | 138 HEnvironment* environment = last_environment(); |
138 ASSERT(ast_id == AstNode::kNoNumber || | 139 ASSERT(ast_id == AstNode::kNoNumber || |
139 environment->closure()->shared()->VerifyBailoutId(ast_id)); | 140 environment->closure()->shared()->VerifyBailoutId(ast_id)); |
140 | 141 |
141 int push_count = environment->push_count(); | 142 int push_count = environment->push_count(); |
142 int pop_count = environment->pop_count(); | 143 int pop_count = environment->pop_count(); |
143 | 144 |
144 HSimulate* instr = new(zone()) HSimulate(ast_id, pop_count); | 145 HSimulate* instr = new(zone()) HSimulate(ast_id, pop_count, zone()); |
145 for (int i = push_count - 1; i >= 0; --i) { | 146 for (int i = push_count - 1; i >= 0; --i) { |
146 instr->AddPushedValue(environment->ExpressionStackAt(i)); | 147 instr->AddPushedValue(environment->ExpressionStackAt(i)); |
147 } | 148 } |
148 for (int i = 0; i < environment->assigned_variables()->length(); ++i) { | 149 for (int i = 0; i < environment->assigned_variables()->length(); ++i) { |
149 int index = environment->assigned_variables()->at(i); | 150 int index = environment->assigned_variables()->at(i); |
150 instr->AddAssignedValue(index, environment->Lookup(index)); | 151 instr->AddAssignedValue(index, environment->Lookup(index)); |
151 } | 152 } |
152 environment->ClearHistory(); | 153 environment->ClearHistory(); |
153 return instr; | 154 return instr; |
154 } | 155 } |
(...skipping 116 matching lines...) Loading... | |
271 phis_[i]->AddInput(incoming_env->values()->at(i)); | 272 phis_[i]->AddInput(incoming_env->values()->at(i)); |
272 } | 273 } |
273 } else { | 274 } else { |
274 last_environment()->AddIncomingEdge(this, pred->last_environment()); | 275 last_environment()->AddIncomingEdge(this, pred->last_environment()); |
275 } | 276 } |
276 } else if (!HasEnvironment() && !IsFinished()) { | 277 } else if (!HasEnvironment() && !IsFinished()) { |
277 ASSERT(!IsLoopHeader()); | 278 ASSERT(!IsLoopHeader()); |
278 SetInitialEnvironment(pred->last_environment()->Copy()); | 279 SetInitialEnvironment(pred->last_environment()->Copy()); |
279 } | 280 } |
280 | 281 |
281 predecessors_.Add(pred); | 282 predecessors_.Add(pred, zone()); |
282 } | 283 } |
283 | 284 |
284 | 285 |
285 void HBasicBlock::AddDominatedBlock(HBasicBlock* block) { | 286 void HBasicBlock::AddDominatedBlock(HBasicBlock* block) { |
286 ASSERT(!dominated_blocks_.Contains(block)); | 287 ASSERT(!dominated_blocks_.Contains(block)); |
287 // Keep the list of dominated blocks sorted such that if there is two | 288 // Keep the list of dominated blocks sorted such that if there is two |
288 // succeeding block in this list, the predecessor is before the successor. | 289 // succeeding block in this list, the predecessor is before the successor. |
289 int index = 0; | 290 int index = 0; |
290 while (index < dominated_blocks_.length() && | 291 while (index < dominated_blocks_.length() && |
291 dominated_blocks_[index]->block_id() < block->block_id()) { | 292 dominated_blocks_[index]->block_id() < block->block_id()) { |
292 ++index; | 293 ++index; |
293 } | 294 } |
294 dominated_blocks_.InsertAt(index, block); | 295 dominated_blocks_.InsertAt(index, block, zone()); |
295 } | 296 } |
296 | 297 |
297 | 298 |
298 void HBasicBlock::AssignCommonDominator(HBasicBlock* other) { | 299 void HBasicBlock::AssignCommonDominator(HBasicBlock* other) { |
299 if (dominator_ == NULL) { | 300 if (dominator_ == NULL) { |
300 dominator_ = other; | 301 dominator_ = other; |
301 other->AddDominatedBlock(this); | 302 other->AddDominatedBlock(this); |
302 } else if (other->dominator() != NULL) { | 303 } else if (other->dominator() != NULL) { |
303 HBasicBlock* first = dominator_; | 304 HBasicBlock* first = dominator_; |
304 HBasicBlock* second = other; | 305 HBasicBlock* second = other; |
(...skipping 92 matching lines...) Loading... | |
397 if (predecessors_.length() > 1) { | 398 if (predecessors_.length() > 1) { |
398 for (int i = 0; i < predecessors_.length(); ++i) { | 399 for (int i = 0; i < predecessors_.length(); ++i) { |
399 ASSERT(predecessors_[i]->end()->SecondSuccessor() == NULL); | 400 ASSERT(predecessors_[i]->end()->SecondSuccessor() == NULL); |
400 } | 401 } |
401 } | 402 } |
402 } | 403 } |
403 #endif | 404 #endif |
404 | 405 |
405 | 406 |
406 void HLoopInformation::RegisterBackEdge(HBasicBlock* block) { | 407 void HLoopInformation::RegisterBackEdge(HBasicBlock* block) { |
407 this->back_edges_.Add(block); | 408 this->back_edges_.Add(block, block->zone()); |
408 AddBlock(block); | 409 AddBlock(block); |
409 } | 410 } |
410 | 411 |
411 | 412 |
412 HBasicBlock* HLoopInformation::GetLastBackEdge() const { | 413 HBasicBlock* HLoopInformation::GetLastBackEdge() const { |
413 int max_id = -1; | 414 int max_id = -1; |
414 HBasicBlock* result = NULL; | 415 HBasicBlock* result = NULL; |
415 for (int i = 0; i < back_edges_.length(); ++i) { | 416 for (int i = 0; i < back_edges_.length(); ++i) { |
416 HBasicBlock* cur = back_edges_[i]; | 417 HBasicBlock* cur = back_edges_[i]; |
417 if (cur->block_id() > max_id) { | 418 if (cur->block_id() > max_id) { |
418 max_id = cur->block_id(); | 419 max_id = cur->block_id(); |
419 result = cur; | 420 result = cur; |
420 } | 421 } |
421 } | 422 } |
422 return result; | 423 return result; |
423 } | 424 } |
424 | 425 |
425 | 426 |
426 void HLoopInformation::AddBlock(HBasicBlock* block) { | 427 void HLoopInformation::AddBlock(HBasicBlock* block) { |
427 if (block == loop_header()) return; | 428 if (block == loop_header()) return; |
428 if (block->parent_loop_header() == loop_header()) return; | 429 if (block->parent_loop_header() == loop_header()) return; |
429 if (block->parent_loop_header() != NULL) { | 430 if (block->parent_loop_header() != NULL) { |
430 AddBlock(block->parent_loop_header()); | 431 AddBlock(block->parent_loop_header()); |
431 } else { | 432 } else { |
432 block->set_parent_loop_header(loop_header()); | 433 block->set_parent_loop_header(loop_header()); |
433 blocks_.Add(block); | 434 blocks_.Add(block, block->zone()); |
434 for (int i = 0; i < block->predecessors()->length(); ++i) { | 435 for (int i = 0; i < block->predecessors()->length(); ++i) { |
435 AddBlock(block->predecessors()->at(i)); | 436 AddBlock(block->predecessors()->at(i)); |
436 } | 437 } |
437 } | 438 } |
438 } | 439 } |
439 | 440 |
440 | 441 |
441 #ifdef DEBUG | 442 #ifdef DEBUG |
442 | 443 |
443 // Checks reachability of the blocks in this graph and stores a bit in | 444 // Checks reachability of the blocks in this graph and stores a bit in |
444 // the BitVector "reachable()" for every block that can be reached | 445 // the BitVector "reachable()" for every block that can be reached |
445 // from the start block of the graph. If "dont_visit" is non-null, the given | 446 // from the start block of the graph. If "dont_visit" is non-null, the given |
446 // block is treated as if it would not be part of the graph. "visited_count()" | 447 // block is treated as if it would not be part of the graph. "visited_count()" |
447 // returns the number of reachable blocks. | 448 // returns the number of reachable blocks. |
448 class ReachabilityAnalyzer BASE_EMBEDDED { | 449 class ReachabilityAnalyzer BASE_EMBEDDED { |
449 public: | 450 public: |
450 ReachabilityAnalyzer(HBasicBlock* entry_block, | 451 ReachabilityAnalyzer(HBasicBlock* entry_block, |
451 int block_count, | 452 int block_count, |
452 HBasicBlock* dont_visit) | 453 HBasicBlock* dont_visit) |
453 : visited_count_(0), | 454 : visited_count_(0), |
454 stack_(16), | 455 stack_(16, entry_block->zone()), |
455 reachable_(block_count, ZONE), | 456 reachable_(block_count, entry_block->zone()), |
456 dont_visit_(dont_visit) { | 457 dont_visit_(dont_visit) { |
457 PushBlock(entry_block); | 458 PushBlock(entry_block); |
458 Analyze(); | 459 Analyze(); |
459 } | 460 } |
460 | 461 |
461 int visited_count() const { return visited_count_; } | 462 int visited_count() const { return visited_count_; } |
462 const BitVector* reachable() const { return &reachable_; } | 463 const BitVector* reachable() const { return &reachable_; } |
463 | 464 |
464 private: | 465 private: |
465 void PushBlock(HBasicBlock* block) { | 466 void PushBlock(HBasicBlock* block) { |
466 if (block != NULL && block != dont_visit_ && | 467 if (block != NULL && block != dont_visit_ && |
467 !reachable_.Contains(block->block_id())) { | 468 !reachable_.Contains(block->block_id())) { |
468 reachable_.Add(block->block_id()); | 469 reachable_.Add(block->block_id()); |
469 stack_.Add(block); | 470 stack_.Add(block, block->zone()); |
470 visited_count_++; | 471 visited_count_++; |
471 } | 472 } |
472 } | 473 } |
473 | 474 |
474 void Analyze() { | 475 void Analyze() { |
475 while (!stack_.is_empty()) { | 476 while (!stack_.is_empty()) { |
476 HControlInstruction* end = stack_.RemoveLast()->end(); | 477 HControlInstruction* end = stack_.RemoveLast()->end(); |
477 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { | 478 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { |
478 PushBlock(it.Current()); | 479 PushBlock(it.Current()); |
479 } | 480 } |
(...skipping 117 matching lines...) Loading... | |
597 return GetConstant(&constant_false_, isolate()->heap()->false_value()); | 598 return GetConstant(&constant_false_, isolate()->heap()->false_value()); |
598 } | 599 } |
599 | 600 |
600 | 601 |
601 HConstant* HGraph::GetConstantHole() { | 602 HConstant* HGraph::GetConstantHole() { |
602 return GetConstant(&constant_hole_, isolate()->heap()->the_hole_value()); | 603 return GetConstant(&constant_hole_, isolate()->heap()->the_hole_value()); |
603 } | 604 } |
604 | 605 |
605 | 606 |
606 HGraphBuilder::HGraphBuilder(CompilationInfo* info, | 607 HGraphBuilder::HGraphBuilder(CompilationInfo* info, |
607 TypeFeedbackOracle* oracle) | 608 TypeFeedbackOracle* oracle, |
609 Zone* zone) | |
608 : function_state_(NULL), | 610 : function_state_(NULL), |
609 initial_function_state_(this, info, oracle, NORMAL_RETURN), | 611 initial_function_state_(this, info, oracle, NORMAL_RETURN), |
610 ast_context_(NULL), | 612 ast_context_(NULL), |
611 break_scope_(NULL), | 613 break_scope_(NULL), |
612 graph_(NULL), | 614 graph_(NULL), |
613 current_block_(NULL), | 615 current_block_(NULL), |
614 inlined_count_(0), | 616 inlined_count_(0), |
615 globals_(10), | 617 globals_(10, zone), |
616 zone_(info->isolate()->zone()), | 618 zone_(zone), |
617 inline_bailout_(false) { | 619 inline_bailout_(false) { |
618 // This is not initialized in the initializer list because the | 620 // This is not initialized in the initializer list because the |
619 // constructor for the initial state relies on function_state_ == NULL | 621 // constructor for the initial state relies on function_state_ == NULL |
620 // to know it's the initial state. | 622 // to know it's the initial state. |
621 function_state_= &initial_function_state_; | 623 function_state_= &initial_function_state_; |
622 } | 624 } |
623 | 625 |
624 HBasicBlock* HGraphBuilder::CreateJoin(HBasicBlock* first, | 626 HBasicBlock* HGraphBuilder::CreateJoin(HBasicBlock* first, |
625 HBasicBlock* second, | 627 HBasicBlock* second, |
626 int join_id) { | 628 int join_id) { |
(...skipping 38 matching lines...) Loading... | |
665 return loop_successor; | 667 return loop_successor; |
666 } | 668 } |
667 | 669 |
668 | 670 |
669 void HBasicBlock::FinishExit(HControlInstruction* instruction) { | 671 void HBasicBlock::FinishExit(HControlInstruction* instruction) { |
670 Finish(instruction); | 672 Finish(instruction); |
671 ClearEnvironment(); | 673 ClearEnvironment(); |
672 } | 674 } |
673 | 675 |
674 | 676 |
675 HGraph::HGraph(CompilationInfo* info) | 677 HGraph::HGraph(CompilationInfo* info, Zone* zone) |
676 : isolate_(info->isolate()), | 678 : isolate_(info->isolate()), |
677 next_block_id_(0), | 679 next_block_id_(0), |
678 entry_block_(NULL), | 680 entry_block_(NULL), |
679 blocks_(8), | 681 blocks_(8, zone), |
680 values_(16), | 682 values_(16, zone), |
681 phi_list_(NULL) { | 683 phi_list_(NULL), |
684 zone_(zone) { | |
682 start_environment_ = | 685 start_environment_ = |
683 new(zone()) HEnvironment(NULL, info->scope(), info->closure()); | 686 new(zone) HEnvironment(NULL, info->scope(), info->closure(), zone); |
684 start_environment_->set_ast_id(AstNode::kFunctionEntryId); | 687 start_environment_->set_ast_id(AstNode::kFunctionEntryId); |
685 entry_block_ = CreateBasicBlock(); | 688 entry_block_ = CreateBasicBlock(); |
686 entry_block_->SetInitialEnvironment(start_environment_); | 689 entry_block_->SetInitialEnvironment(start_environment_); |
687 } | 690 } |
688 | 691 |
689 | 692 |
690 Handle<Code> HGraph::Compile(CompilationInfo* info, Zone* zone) { | 693 Handle<Code> HGraph::Compile(CompilationInfo* info, Zone* zone) { |
691 int values = GetMaximumValueID(); | 694 int values = GetMaximumValueID(); |
692 if (values > LUnallocated::kMaxVirtualRegisters) { | 695 if (values > LUnallocated::kMaxVirtualRegisters) { |
693 if (FLAG_trace_bailout) { | 696 if (FLAG_trace_bailout) { |
(...skipping 29 matching lines...) Loading... | |
723 generator.FinishCode(code); | 726 generator.FinishCode(code); |
724 CodeGenerator::PrintCode(code, info); | 727 CodeGenerator::PrintCode(code, info); |
725 return code; | 728 return code; |
726 } | 729 } |
727 return Handle<Code>::null(); | 730 return Handle<Code>::null(); |
728 } | 731 } |
729 | 732 |
730 | 733 |
731 HBasicBlock* HGraph::CreateBasicBlock() { | 734 HBasicBlock* HGraph::CreateBasicBlock() { |
732 HBasicBlock* result = new(zone()) HBasicBlock(this); | 735 HBasicBlock* result = new(zone()) HBasicBlock(this); |
733 blocks_.Add(result); | 736 blocks_.Add(result, zone()); |
734 return result; | 737 return result; |
735 } | 738 } |
736 | 739 |
737 | 740 |
738 void HGraph::Canonicalize() { | 741 void HGraph::Canonicalize() { |
739 if (!FLAG_use_canonicalizing) return; | 742 if (!FLAG_use_canonicalizing) return; |
740 HPhase phase("H_Canonicalize", this); | 743 HPhase phase("H_Canonicalize", this); |
741 for (int i = 0; i < blocks()->length(); ++i) { | 744 for (int i = 0; i < blocks()->length(); ++i) { |
742 HInstruction* instr = blocks()->at(i)->first(); | 745 HInstruction* instr = blocks()->at(i)->first(); |
743 while (instr != NULL) { | 746 while (instr != NULL) { |
744 HValue* value = instr->Canonicalize(); | 747 HValue* value = instr->Canonicalize(); |
745 if (value != instr) instr->DeleteAndReplaceWith(value); | 748 if (value != instr) instr->DeleteAndReplaceWith(value); |
746 instr = instr->next(); | 749 instr = instr->next(); |
747 } | 750 } |
748 } | 751 } |
749 } | 752 } |
750 | 753 |
751 | 754 |
752 void HGraph::OrderBlocks() { | 755 void HGraph::OrderBlocks() { |
753 HPhase phase("H_Block ordering"); | 756 HPhase phase("H_Block ordering"); |
754 BitVector visited(blocks_.length(), zone()); | 757 BitVector visited(blocks_.length(), zone()); |
755 | 758 |
756 ZoneList<HBasicBlock*> reverse_result(8); | 759 ZoneList<HBasicBlock*> reverse_result(8, zone()); |
757 HBasicBlock* start = blocks_[0]; | 760 HBasicBlock* start = blocks_[0]; |
758 Postorder(start, &visited, &reverse_result, NULL); | 761 Postorder(start, &visited, &reverse_result, NULL); |
759 | 762 |
760 blocks_.Rewind(0); | 763 blocks_.Rewind(0); |
761 int index = 0; | 764 int index = 0; |
762 for (int i = reverse_result.length() - 1; i >= 0; --i) { | 765 for (int i = reverse_result.length() - 1; i >= 0; --i) { |
763 HBasicBlock* b = reverse_result[i]; | 766 HBasicBlock* b = reverse_result[i]; |
764 blocks_.Add(b); | 767 blocks_.Add(b, zone()); |
765 b->set_block_id(index++); | 768 b->set_block_id(index++); |
766 } | 769 } |
767 } | 770 } |
768 | 771 |
769 | 772 |
770 void HGraph::PostorderLoopBlocks(HLoopInformation* loop, | 773 void HGraph::PostorderLoopBlocks(HLoopInformation* loop, |
771 BitVector* visited, | 774 BitVector* visited, |
772 ZoneList<HBasicBlock*>* order, | 775 ZoneList<HBasicBlock*>* order, |
773 HBasicBlock* loop_header) { | 776 HBasicBlock* loop_header) { |
774 for (int i = 0; i < loop->blocks()->length(); ++i) { | 777 for (int i = 0; i < loop->blocks()->length(); ++i) { |
(...skipping 25 matching lines...) Loading... | |
800 for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) { | 803 for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) { |
801 Postorder(it.Current(), visited, order, loop_header); | 804 Postorder(it.Current(), visited, order, loop_header); |
802 } | 805 } |
803 } | 806 } |
804 ASSERT(block->end()->FirstSuccessor() == NULL || | 807 ASSERT(block->end()->FirstSuccessor() == NULL || |
805 order->Contains(block->end()->FirstSuccessor()) || | 808 order->Contains(block->end()->FirstSuccessor()) || |
806 block->end()->FirstSuccessor()->IsLoopHeader()); | 809 block->end()->FirstSuccessor()->IsLoopHeader()); |
807 ASSERT(block->end()->SecondSuccessor() == NULL || | 810 ASSERT(block->end()->SecondSuccessor() == NULL || |
808 order->Contains(block->end()->SecondSuccessor()) || | 811 order->Contains(block->end()->SecondSuccessor()) || |
809 block->end()->SecondSuccessor()->IsLoopHeader()); | 812 block->end()->SecondSuccessor()->IsLoopHeader()); |
810 order->Add(block); | 813 order->Add(block, zone()); |
811 } | 814 } |
812 | 815 |
813 | 816 |
814 void HGraph::AssignDominators() { | 817 void HGraph::AssignDominators() { |
815 HPhase phase("H_Assign dominators", this); | 818 HPhase phase("H_Assign dominators", this); |
816 for (int i = 0; i < blocks_.length(); ++i) { | 819 for (int i = 0; i < blocks_.length(); ++i) { |
817 HBasicBlock* block = blocks_[i]; | 820 HBasicBlock* block = blocks_[i]; |
818 if (block->IsLoopHeader()) { | 821 if (block->IsLoopHeader()) { |
819 // Only the first predecessor of a loop header is from outside the loop. | 822 // Only the first predecessor of a loop header is from outside the loop. |
820 // All others are back edges, and thus cannot dominate the loop header. | 823 // All others are back edges, and thus cannot dominate the loop header. |
(...skipping 21 matching lines...) Loading... | |
842 MarkAsDeoptimizingRecursively(dominated); | 845 MarkAsDeoptimizingRecursively(dominated); |
843 } | 846 } |
844 } | 847 } |
845 | 848 |
846 void HGraph::EliminateRedundantPhis() { | 849 void HGraph::EliminateRedundantPhis() { |
847 HPhase phase("H_Redundant phi elimination", this); | 850 HPhase phase("H_Redundant phi elimination", this); |
848 | 851 |
849 // Worklist of phis that can potentially be eliminated. Initialized with | 852 // Worklist of phis that can potentially be eliminated. Initialized with |
850 // all phi nodes. When elimination of a phi node modifies another phi node | 853 // all phi nodes. When elimination of a phi node modifies another phi node |
851 // the modified phi node is added to the worklist. | 854 // the modified phi node is added to the worklist. |
852 ZoneList<HPhi*> worklist(blocks_.length()); | 855 ZoneList<HPhi*> worklist(blocks_.length(), zone()); |
853 for (int i = 0; i < blocks_.length(); ++i) { | 856 for (int i = 0; i < blocks_.length(); ++i) { |
854 worklist.AddAll(*blocks_[i]->phis()); | 857 worklist.AddAll(*blocks_[i]->phis(), zone()); |
855 } | 858 } |
856 | 859 |
857 while (!worklist.is_empty()) { | 860 while (!worklist.is_empty()) { |
858 HPhi* phi = worklist.RemoveLast(); | 861 HPhi* phi = worklist.RemoveLast(); |
859 HBasicBlock* block = phi->block(); | 862 HBasicBlock* block = phi->block(); |
860 | 863 |
861 // Skip phi node if it was already replaced. | 864 // Skip phi node if it was already replaced. |
862 if (block == NULL) continue; | 865 if (block == NULL) continue; |
863 | 866 |
864 // Get replacement value if phi is redundant. | 867 // Get replacement value if phi is redundant. |
865 HValue* replacement = phi->GetRedundantReplacement(); | 868 HValue* replacement = phi->GetRedundantReplacement(); |
866 | 869 |
867 if (replacement != NULL) { | 870 if (replacement != NULL) { |
868 // Iterate through the uses and replace them all. | 871 // Iterate through the uses and replace them all. |
869 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { | 872 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { |
870 HValue* value = it.value(); | 873 HValue* value = it.value(); |
871 value->SetOperandAt(it.index(), replacement); | 874 value->SetOperandAt(it.index(), replacement); |
872 if (value->IsPhi()) worklist.Add(HPhi::cast(value)); | 875 if (value->IsPhi()) worklist.Add(HPhi::cast(value), zone()); |
873 } | 876 } |
874 block->RemovePhi(phi); | 877 block->RemovePhi(phi); |
875 } | 878 } |
876 } | 879 } |
877 } | 880 } |
878 | 881 |
879 | 882 |
880 void HGraph::EliminateUnreachablePhis() { | 883 void HGraph::EliminateUnreachablePhis() { |
881 HPhase phase("H_Unreachable phi elimination", this); | 884 HPhase phase("H_Unreachable phi elimination", this); |
882 | 885 |
883 // Initialize worklist. | 886 // Initialize worklist. |
884 ZoneList<HPhi*> phi_list(blocks_.length()); | 887 ZoneList<HPhi*> phi_list(blocks_.length(), zone()); |
885 ZoneList<HPhi*> worklist(blocks_.length()); | 888 ZoneList<HPhi*> worklist(blocks_.length(), zone()); |
886 for (int i = 0; i < blocks_.length(); ++i) { | 889 for (int i = 0; i < blocks_.length(); ++i) { |
887 for (int j = 0; j < blocks_[i]->phis()->length(); j++) { | 890 for (int j = 0; j < blocks_[i]->phis()->length(); j++) { |
888 HPhi* phi = blocks_[i]->phis()->at(j); | 891 HPhi* phi = blocks_[i]->phis()->at(j); |
889 phi_list.Add(phi); | 892 phi_list.Add(phi, zone()); |
890 // We can't eliminate phis in the receiver position in the environment | 893 // We can't eliminate phis in the receiver position in the environment |
891 // because in case of throwing an error we need this value to | 894 // because in case of throwing an error we need this value to |
892 // construct a stack trace. | 895 // construct a stack trace. |
893 if (phi->HasRealUses() || phi->IsReceiver()) { | 896 if (phi->HasRealUses() || phi->IsReceiver()) { |
894 phi->set_is_live(true); | 897 phi->set_is_live(true); |
895 worklist.Add(phi); | 898 worklist.Add(phi, zone()); |
896 } | 899 } |
897 } | 900 } |
898 } | 901 } |
899 | 902 |
900 // Iteratively mark live phis. | 903 // Iteratively mark live phis. |
901 while (!worklist.is_empty()) { | 904 while (!worklist.is_empty()) { |
902 HPhi* phi = worklist.RemoveLast(); | 905 HPhi* phi = worklist.RemoveLast(); |
903 for (int i = 0; i < phi->OperandCount(); i++) { | 906 for (int i = 0; i < phi->OperandCount(); i++) { |
904 HValue* operand = phi->OperandAt(i); | 907 HValue* operand = phi->OperandAt(i); |
905 if (operand->IsPhi() && !HPhi::cast(operand)->is_live()) { | 908 if (operand->IsPhi() && !HPhi::cast(operand)->is_live()) { |
906 HPhi::cast(operand)->set_is_live(true); | 909 HPhi::cast(operand)->set_is_live(true); |
907 worklist.Add(HPhi::cast(operand)); | 910 worklist.Add(HPhi::cast(operand), zone()); |
908 } | 911 } |
909 } | 912 } |
910 } | 913 } |
911 | 914 |
912 // Remove unreachable phis. | 915 // Remove unreachable phis. |
913 for (int i = 0; i < phi_list.length(); i++) { | 916 for (int i = 0; i < phi_list.length(); i++) { |
914 HPhi* phi = phi_list[i]; | 917 HPhi* phi = phi_list[i]; |
915 if (!phi->is_live()) { | 918 if (!phi->is_live()) { |
916 HBasicBlock* block = phi->block(); | 919 HBasicBlock* block = phi->block(); |
917 block->RemovePhi(phi); | 920 block->RemovePhi(phi); |
(...skipping 26 matching lines...) Loading... | |
944 if (phi->OperandAt(k) == GetConstantHole()) return false; | 947 if (phi->OperandAt(k) == GetConstantHole()) return false; |
945 } | 948 } |
946 } | 949 } |
947 } | 950 } |
948 return true; | 951 return true; |
949 } | 952 } |
950 | 953 |
951 | 954 |
952 void HGraph::CollectPhis() { | 955 void HGraph::CollectPhis() { |
953 int block_count = blocks_.length(); | 956 int block_count = blocks_.length(); |
954 phi_list_ = new ZoneList<HPhi*>(block_count); | 957 phi_list_ = new(zone()) ZoneList<HPhi*>(block_count, zone()); |
955 for (int i = 0; i < block_count; ++i) { | 958 for (int i = 0; i < block_count; ++i) { |
956 for (int j = 0; j < blocks_[i]->phis()->length(); ++j) { | 959 for (int j = 0; j < blocks_[i]->phis()->length(); ++j) { |
957 HPhi* phi = blocks_[i]->phis()->at(j); | 960 HPhi* phi = blocks_[i]->phis()->at(j); |
958 phi_list_->Add(phi); | 961 phi_list_->Add(phi, zone()); |
959 } | 962 } |
960 } | 963 } |
961 } | 964 } |
962 | 965 |
963 | 966 |
964 void HGraph::InferTypes(ZoneList<HValue*>* worklist) { | 967 void HGraph::InferTypes(ZoneList<HValue*>* worklist) { |
965 BitVector in_worklist(GetMaximumValueID(), zone()); | 968 BitVector in_worklist(GetMaximumValueID(), zone()); |
966 for (int i = 0; i < worklist->length(); ++i) { | 969 for (int i = 0; i < worklist->length(); ++i) { |
967 ASSERT(!in_worklist.Contains(worklist->at(i)->id())); | 970 ASSERT(!in_worklist.Contains(worklist->at(i)->id())); |
968 in_worklist.Add(worklist->at(i)->id()); | 971 in_worklist.Add(worklist->at(i)->id()); |
969 } | 972 } |
970 | 973 |
971 while (!worklist->is_empty()) { | 974 while (!worklist->is_empty()) { |
972 HValue* current = worklist->RemoveLast(); | 975 HValue* current = worklist->RemoveLast(); |
973 in_worklist.Remove(current->id()); | 976 in_worklist.Remove(current->id()); |
974 if (current->UpdateInferredType()) { | 977 if (current->UpdateInferredType()) { |
975 for (HUseIterator it(current->uses()); !it.Done(); it.Advance()) { | 978 for (HUseIterator it(current->uses()); !it.Done(); it.Advance()) { |
976 HValue* use = it.value(); | 979 HValue* use = it.value(); |
977 if (!in_worklist.Contains(use->id())) { | 980 if (!in_worklist.Contains(use->id())) { |
978 in_worklist.Add(use->id()); | 981 in_worklist.Add(use->id()); |
979 worklist->Add(use); | 982 worklist->Add(use, zone()); |
980 } | 983 } |
981 } | 984 } |
982 } | 985 } |
983 } | 986 } |
984 } | 987 } |
985 | 988 |
986 | 989 |
987 class HRangeAnalysis BASE_EMBEDDED { | 990 class HRangeAnalysis BASE_EMBEDDED { |
988 public: | 991 public: |
989 explicit HRangeAnalysis(HGraph* graph) : | 992 explicit HRangeAnalysis(HGraph* graph) : |
990 graph_(graph), zone_(graph->isolate()->zone()), changed_ranges_(16) { } | 993 graph_(graph), zone_(graph->zone()), changed_ranges_(16, zone_) { } |
991 | 994 |
992 void Analyze(); | 995 void Analyze(); |
993 | 996 |
994 private: | 997 private: |
995 void TraceRange(const char* msg, ...); | 998 void TraceRange(const char* msg, ...); |
996 void Analyze(HBasicBlock* block); | 999 void Analyze(HBasicBlock* block); |
997 void InferControlFlowRange(HCompareIDAndBranch* test, HBasicBlock* dest); | 1000 void InferControlFlowRange(HCompareIDAndBranch* test, HBasicBlock* dest); |
998 void UpdateControlFlowRange(Token::Value op, HValue* value, HValue* other); | 1001 void UpdateControlFlowRange(Token::Value op, HValue* value, HValue* other); |
999 void InferRange(HValue* value); | 1002 void InferRange(HValue* value); |
1000 void RollBackTo(int index); | 1003 void RollBackTo(int index); |
(...skipping 124 matching lines...) Loading... | |
1125 for (int i = index + 1; i < changed_ranges_.length(); ++i) { | 1128 for (int i = index + 1; i < changed_ranges_.length(); ++i) { |
1126 changed_ranges_[i]->RemoveLastAddedRange(); | 1129 changed_ranges_[i]->RemoveLastAddedRange(); |
1127 } | 1130 } |
1128 changed_ranges_.Rewind(index + 1); | 1131 changed_ranges_.Rewind(index + 1); |
1129 } | 1132 } |
1130 | 1133 |
1131 | 1134 |
1132 void HRangeAnalysis::AddRange(HValue* value, Range* range) { | 1135 void HRangeAnalysis::AddRange(HValue* value, Range* range) { |
1133 Range* original_range = value->range(); | 1136 Range* original_range = value->range(); |
1134 value->AddNewRange(range, zone_); | 1137 value->AddNewRange(range, zone_); |
1135 changed_ranges_.Add(value); | 1138 changed_ranges_.Add(value, zone_); |
1136 Range* new_range = value->range(); | 1139 Range* new_range = value->range(); |
1137 TraceRange("Updated range of %d set to [%d,%d]\n", | 1140 TraceRange("Updated range of %d set to [%d,%d]\n", |
1138 value->id(), | 1141 value->id(), |
1139 new_range->lower(), | 1142 new_range->lower(), |
1140 new_range->upper()); | 1143 new_range->upper()); |
1141 if (original_range != NULL) { | 1144 if (original_range != NULL) { |
1142 TraceRange("Original range was [%d,%d]\n", | 1145 TraceRange("Original range was [%d,%d]\n", |
1143 original_range->lower(), | 1146 original_range->lower(), |
1144 original_range->upper()); | 1147 original_range->upper()); |
1145 } | 1148 } |
(...skipping 107 matching lines...) Loading... | |
1253 int next = array_[pos].next; | 1256 int next = array_[pos].next; |
1254 while (next != kNil) { | 1257 while (next != kNil) { |
1255 if (lists_[next].value->Equals(value)) return lists_[next].value; | 1258 if (lists_[next].value->Equals(value)) return lists_[next].value; |
1256 next = lists_[next].next; | 1259 next = lists_[next].next; |
1257 } | 1260 } |
1258 } | 1261 } |
1259 return NULL; | 1262 return NULL; |
1260 } | 1263 } |
1261 | 1264 |
1262 | 1265 |
1263 void HValueMap::Resize(int new_size) { | 1266 void HValueMap::Resize(int new_size, Zone* zone) { |
1264 ASSERT(new_size > count_); | 1267 ASSERT(new_size > count_); |
1265 // Hashing the values into the new array has no more collisions than in the | 1268 // Hashing the values into the new array has no more collisions than in the |
1266 // old hash map, so we can use the existing lists_ array, if we are careful. | 1269 // old hash map, so we can use the existing lists_ array, if we are careful. |
1267 | 1270 |
1268 // Make sure we have at least one free element. | 1271 // Make sure we have at least one free element. |
1269 if (free_list_head_ == kNil) { | 1272 if (free_list_head_ == kNil) { |
1270 ResizeLists(lists_size_ << 1); | 1273 ResizeLists(lists_size_ << 1, zone); |
1271 } | 1274 } |
1272 | 1275 |
1273 HValueMapListElement* new_array = | 1276 HValueMapListElement* new_array = |
1274 ZONE->NewArray<HValueMapListElement>(new_size); | 1277 zone->NewArray<HValueMapListElement>(new_size); |
1275 memset(new_array, 0, sizeof(HValueMapListElement) * new_size); | 1278 memset(new_array, 0, sizeof(HValueMapListElement) * new_size); |
1276 | 1279 |
1277 HValueMapListElement* old_array = array_; | 1280 HValueMapListElement* old_array = array_; |
1278 int old_size = array_size_; | 1281 int old_size = array_size_; |
1279 | 1282 |
1280 int old_count = count_; | 1283 int old_count = count_; |
1281 count_ = 0; | 1284 count_ = 0; |
1282 // Do not modify present_flags_. It is currently correct. | 1285 // Do not modify present_flags_. It is currently correct. |
1283 array_size_ = new_size; | 1286 array_size_ = new_size; |
1284 array_ = new_array; | 1287 array_ = new_array; |
1285 | 1288 |
1286 if (old_array != NULL) { | 1289 if (old_array != NULL) { |
1287 // Iterate over all the elements in lists, rehashing them. | 1290 // Iterate over all the elements in lists, rehashing them. |
1288 for (int i = 0; i < old_size; ++i) { | 1291 for (int i = 0; i < old_size; ++i) { |
1289 if (old_array[i].value != NULL) { | 1292 if (old_array[i].value != NULL) { |
1290 int current = old_array[i].next; | 1293 int current = old_array[i].next; |
1291 while (current != kNil) { | 1294 while (current != kNil) { |
1292 Insert(lists_[current].value); | 1295 Insert(lists_[current].value, zone); |
1293 int next = lists_[current].next; | 1296 int next = lists_[current].next; |
1294 lists_[current].next = free_list_head_; | 1297 lists_[current].next = free_list_head_; |
1295 free_list_head_ = current; | 1298 free_list_head_ = current; |
1296 current = next; | 1299 current = next; |
1297 } | 1300 } |
1298 // Rehash the directly stored value. | 1301 // Rehash the directly stored value. |
1299 Insert(old_array[i].value); | 1302 Insert(old_array[i].value, zone); |
1300 } | 1303 } |
1301 } | 1304 } |
1302 } | 1305 } |
1303 USE(old_count); | 1306 USE(old_count); |
1304 ASSERT(count_ == old_count); | 1307 ASSERT(count_ == old_count); |
1305 } | 1308 } |
1306 | 1309 |
1307 | 1310 |
1308 void HValueMap::ResizeLists(int new_size) { | 1311 void HValueMap::ResizeLists(int new_size, Zone* zone) { |
1309 ASSERT(new_size > lists_size_); | 1312 ASSERT(new_size > lists_size_); |
1310 | 1313 |
1311 HValueMapListElement* new_lists = | 1314 HValueMapListElement* new_lists = |
1312 ZONE->NewArray<HValueMapListElement>(new_size); | 1315 zone->NewArray<HValueMapListElement>(new_size); |
1313 memset(new_lists, 0, sizeof(HValueMapListElement) * new_size); | 1316 memset(new_lists, 0, sizeof(HValueMapListElement) * new_size); |
1314 | 1317 |
1315 HValueMapListElement* old_lists = lists_; | 1318 HValueMapListElement* old_lists = lists_; |
1316 int old_size = lists_size_; | 1319 int old_size = lists_size_; |
1317 | 1320 |
1318 lists_size_ = new_size; | 1321 lists_size_ = new_size; |
1319 lists_ = new_lists; | 1322 lists_ = new_lists; |
1320 | 1323 |
1321 if (old_lists != NULL) { | 1324 if (old_lists != NULL) { |
1322 memcpy(lists_, old_lists, old_size * sizeof(HValueMapListElement)); | 1325 memcpy(lists_, old_lists, old_size * sizeof(HValueMapListElement)); |
1323 } | 1326 } |
1324 for (int i = old_size; i < lists_size_; ++i) { | 1327 for (int i = old_size; i < lists_size_; ++i) { |
1325 lists_[i].next = free_list_head_; | 1328 lists_[i].next = free_list_head_; |
1326 free_list_head_ = i; | 1329 free_list_head_ = i; |
1327 } | 1330 } |
1328 } | 1331 } |
1329 | 1332 |
1330 | 1333 |
1331 void HValueMap::Insert(HValue* value) { | 1334 void HValueMap::Insert(HValue* value, Zone* zone) { |
1332 ASSERT(value != NULL); | 1335 ASSERT(value != NULL); |
1333 // Resizing when half of the hashtable is filled up. | 1336 // Resizing when half of the hashtable is filled up. |
1334 if (count_ >= array_size_ >> 1) Resize(array_size_ << 1); | 1337 if (count_ >= array_size_ >> 1) Resize(array_size_ << 1, zone); |
1335 ASSERT(count_ < array_size_); | 1338 ASSERT(count_ < array_size_); |
1336 count_++; | 1339 count_++; |
1337 uint32_t pos = Bound(static_cast<uint32_t>(value->Hashcode())); | 1340 uint32_t pos = Bound(static_cast<uint32_t>(value->Hashcode())); |
1338 if (array_[pos].value == NULL) { | 1341 if (array_[pos].value == NULL) { |
1339 array_[pos].value = value; | 1342 array_[pos].value = value; |
1340 array_[pos].next = kNil; | 1343 array_[pos].next = kNil; |
1341 } else { | 1344 } else { |
1342 if (free_list_head_ == kNil) { | 1345 if (free_list_head_ == kNil) { |
1343 ResizeLists(lists_size_ << 1); | 1346 ResizeLists(lists_size_ << 1, zone); |
1344 } | 1347 } |
1345 int new_element_pos = free_list_head_; | 1348 int new_element_pos = free_list_head_; |
1346 ASSERT(new_element_pos != kNil); | 1349 ASSERT(new_element_pos != kNil); |
1347 free_list_head_ = lists_[free_list_head_].next; | 1350 free_list_head_ = lists_[free_list_head_].next; |
1348 lists_[new_element_pos].value = value; | 1351 lists_[new_element_pos].value = value; |
1349 lists_[new_element_pos].next = array_[pos].next; | 1352 lists_[new_element_pos].next = array_[pos].next; |
1350 ASSERT(array_[pos].next == kNil || lists_[array_[pos].next].value != NULL); | 1353 ASSERT(array_[pos].next == kNil || lists_[array_[pos].next].value != NULL); |
1351 array_[pos].next = new_element_pos; | 1354 array_[pos].next = new_element_pos; |
1352 } | 1355 } |
1353 } | 1356 } |
(...skipping 117 matching lines...) Loading... | |
1471 DISALLOW_COPY_AND_ASSIGN(SparseSet); | 1474 DISALLOW_COPY_AND_ASSIGN(SparseSet); |
1472 }; | 1475 }; |
1473 | 1476 |
1474 | 1477 |
1475 class HGlobalValueNumberer BASE_EMBEDDED { | 1478 class HGlobalValueNumberer BASE_EMBEDDED { |
1476 public: | 1479 public: |
1477 explicit HGlobalValueNumberer(HGraph* graph, CompilationInfo* info) | 1480 explicit HGlobalValueNumberer(HGraph* graph, CompilationInfo* info) |
1478 : graph_(graph), | 1481 : graph_(graph), |
1479 info_(info), | 1482 info_(info), |
1480 removed_side_effects_(false), | 1483 removed_side_effects_(false), |
1481 block_side_effects_(graph->blocks()->length()), | 1484 block_side_effects_(graph->blocks()->length(), graph->zone()), |
1482 loop_side_effects_(graph->blocks()->length()), | 1485 loop_side_effects_(graph->blocks()->length(), graph->zone()), |
1483 visited_on_paths_(graph->zone(), graph->blocks()->length()) { | 1486 visited_on_paths_(graph->zone(), graph->blocks()->length()) { |
1484 ASSERT(info->isolate()->heap()->allow_allocation(false)); | 1487 ASSERT(info->isolate()->heap()->allow_allocation(false)); |
1485 block_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length()); | 1488 block_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length(), |
1486 loop_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length()); | 1489 graph_->zone()); |
1490 loop_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length(), | |
1491 graph_->zone()); | |
1487 } | 1492 } |
1488 ~HGlobalValueNumberer() { | 1493 ~HGlobalValueNumberer() { |
1489 ASSERT(!info_->isolate()->heap()->allow_allocation(true)); | 1494 ASSERT(!info_->isolate()->heap()->allow_allocation(true)); |
1490 } | 1495 } |
1491 | 1496 |
1492 // Returns true if values with side effects are removed. | 1497 // Returns true if values with side effects are removed. |
1493 bool Analyze(); | 1498 bool Analyze(); |
1494 | 1499 |
1495 private: | 1500 private: |
1496 GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock( | 1501 GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock( |
(...skipping 445 matching lines...) Loading... | |
1942 int dominated_index_; | 1947 int dominated_index_; |
1943 int length_; | 1948 int length_; |
1944 }; | 1949 }; |
1945 | 1950 |
1946 // This is a recursive traversal of the dominator tree but it has been turned | 1951 // This is a recursive traversal of the dominator tree but it has been turned |
1947 // into a loop to avoid stack overflows. | 1952 // into a loop to avoid stack overflows. |
1948 // The logical "stack frames" of the recursion are kept in a list of | 1953 // The logical "stack frames" of the recursion are kept in a list of |
1949 // GvnBasicBlockState instances. | 1954 // GvnBasicBlockState instances. |
1950 void HGlobalValueNumberer::AnalyzeGraph() { | 1955 void HGlobalValueNumberer::AnalyzeGraph() { |
1951 HBasicBlock* entry_block = graph_->entry_block(); | 1956 HBasicBlock* entry_block = graph_->entry_block(); |
1952 HValueMap* entry_map = new(zone()) HValueMap(); | 1957 HValueMap* entry_map = new(zone()) HValueMap(zone()); |
1953 GvnBasicBlockState* current = | 1958 GvnBasicBlockState* current = |
1954 GvnBasicBlockState::CreateEntry(zone(), entry_block, entry_map); | 1959 GvnBasicBlockState::CreateEntry(zone(), entry_block, entry_map); |
1955 | 1960 |
1956 while (current != NULL) { | 1961 while (current != NULL) { |
1957 HBasicBlock* block = current->block(); | 1962 HBasicBlock* block = current->block(); |
1958 HValueMap* map = current->map(); | 1963 HValueMap* map = current->map(); |
1959 HSideEffectMap* dominators = current->dominators(); | 1964 HSideEffectMap* dominators = current->dominators(); |
1960 | 1965 |
1961 TRACE_GVN_2("Analyzing block B%d%s\n", | 1966 TRACE_GVN_2("Analyzing block B%d%s\n", |
1962 block->block_id(), | 1967 block->block_id(), |
(...skipping 23 matching lines...) Loading... | |
1986 if (other != NULL) { | 1991 if (other != NULL) { |
1987 ASSERT(instr->Equals(other) && other->Equals(instr)); | 1992 ASSERT(instr->Equals(other) && other->Equals(instr)); |
1988 TRACE_GVN_4("Replacing value %d (%s) with value %d (%s)\n", | 1993 TRACE_GVN_4("Replacing value %d (%s) with value %d (%s)\n", |
1989 instr->id(), | 1994 instr->id(), |
1990 instr->Mnemonic(), | 1995 instr->Mnemonic(), |
1991 other->id(), | 1996 other->id(), |
1992 other->Mnemonic()); | 1997 other->Mnemonic()); |
1993 if (instr->HasSideEffects()) removed_side_effects_ = true; | 1998 if (instr->HasSideEffects()) removed_side_effects_ = true; |
1994 instr->DeleteAndReplaceWith(other); | 1999 instr->DeleteAndReplaceWith(other); |
1995 } else { | 2000 } else { |
1996 map->Add(instr); | 2001 map->Add(instr, zone()); |
1997 } | 2002 } |
1998 } | 2003 } |
1999 if (instr->CheckFlag(HValue::kTrackSideEffectDominators)) { | 2004 if (instr->CheckFlag(HValue::kTrackSideEffectDominators)) { |
2000 for (int i = 0; i < kNumberOfTrackedSideEffects; i++) { | 2005 for (int i = 0; i < kNumberOfTrackedSideEffects; i++) { |
2001 HValue* other = dominators->at(i); | 2006 HValue* other = dominators->at(i); |
2002 GVNFlag changes_flag = HValue::ChangesFlagFromInt(i); | 2007 GVNFlag changes_flag = HValue::ChangesFlagFromInt(i); |
2003 GVNFlag depends_on_flag = HValue::DependsOnFlagFromInt(i); | 2008 GVNFlag depends_on_flag = HValue::DependsOnFlagFromInt(i); |
2004 if (instr->DependsOnFlags().Contains(depends_on_flag) && | 2009 if (instr->DependsOnFlags().Contains(depends_on_flag) && |
2005 (other != NULL)) { | 2010 (other != NULL)) { |
2006 TRACE_GVN_5("Side-effect #%d in %d (%s) is dominated by %d (%s)\n", | 2011 TRACE_GVN_5("Side-effect #%d in %d (%s) is dominated by %d (%s)\n", |
(...skipping 35 matching lines...) Loading... | |
2042 } | 2047 } |
2043 current = next; | 2048 current = next; |
2044 } | 2049 } |
2045 } | 2050 } |
2046 | 2051 |
2047 | 2052 |
2048 class HInferRepresentation BASE_EMBEDDED { | 2053 class HInferRepresentation BASE_EMBEDDED { |
2049 public: | 2054 public: |
2050 explicit HInferRepresentation(HGraph* graph) | 2055 explicit HInferRepresentation(HGraph* graph) |
2051 : graph_(graph), | 2056 : graph_(graph), |
2052 worklist_(8), | 2057 worklist_(8, graph->zone()), |
2053 in_worklist_(graph->GetMaximumValueID(), graph->zone()) { } | 2058 in_worklist_(graph->GetMaximumValueID(), graph->zone()) { } |
2054 | 2059 |
2055 void Analyze(); | 2060 void Analyze(); |
2056 | 2061 |
2057 private: | 2062 private: |
2058 Representation TryChange(HValue* current); | 2063 Representation TryChange(HValue* current); |
2059 void AddToWorklist(HValue* current); | 2064 void AddToWorklist(HValue* current); |
2060 void InferBasedOnInputs(HValue* current); | 2065 void InferBasedOnInputs(HValue* current); |
2061 void AddDependantsToWorklist(HValue* current); | 2066 void AddDependantsToWorklist(HValue* current); |
2062 void InferBasedOnUses(HValue* current); | 2067 void InferBasedOnUses(HValue* current); |
2063 | 2068 |
2064 Zone* zone() { return graph_->zone(); } | 2069 Zone* zone() { return graph_->zone(); } |
2065 | 2070 |
2066 HGraph* graph_; | 2071 HGraph* graph_; |
2067 ZoneList<HValue*> worklist_; | 2072 ZoneList<HValue*> worklist_; |
2068 BitVector in_worklist_; | 2073 BitVector in_worklist_; |
2069 }; | 2074 }; |
2070 | 2075 |
2071 | 2076 |
2072 void HInferRepresentation::AddToWorklist(HValue* current) { | 2077 void HInferRepresentation::AddToWorklist(HValue* current) { |
2073 if (current->representation().IsSpecialization()) return; | 2078 if (current->representation().IsSpecialization()) return; |
2074 if (!current->CheckFlag(HValue::kFlexibleRepresentation)) return; | 2079 if (!current->CheckFlag(HValue::kFlexibleRepresentation)) return; |
2075 if (in_worklist_.Contains(current->id())) return; | 2080 if (in_worklist_.Contains(current->id())) return; |
2076 worklist_.Add(current); | 2081 worklist_.Add(current, zone()); |
2077 in_worklist_.Add(current->id()); | 2082 in_worklist_.Add(current->id()); |
2078 } | 2083 } |
2079 | 2084 |
2080 | 2085 |
2081 // This method tries to specialize the representation type of the value | 2086 // This method tries to specialize the representation type of the value |
2082 // given as a parameter. The value is asked to infer its representation type | 2087 // given as a parameter. The value is asked to infer its representation type |
2083 // based on its inputs. If the inferred type is more specialized, then this | 2088 // based on its inputs. If the inferred type is more specialized, then this |
2084 // becomes the new representation type of the node. | 2089 // becomes the new representation type of the node. |
2085 void HInferRepresentation::InferBasedOnInputs(HValue* current) { | 2090 void HInferRepresentation::InferBasedOnInputs(HValue* current) { |
2086 Representation r = current->representation(); | 2091 Representation r = current->representation(); |
(...skipping 82 matching lines...) Loading... | |
2169 } | 2174 } |
2170 | 2175 |
2171 | 2176 |
2172 void HInferRepresentation::Analyze() { | 2177 void HInferRepresentation::Analyze() { |
2173 HPhase phase("H_Infer representations", graph_); | 2178 HPhase phase("H_Infer representations", graph_); |
2174 | 2179 |
2175 // (1) Initialize bit vectors and count real uses. Each phi gets a | 2180 // (1) Initialize bit vectors and count real uses. Each phi gets a |
2176 // bit-vector of length <number of phis>. | 2181 // bit-vector of length <number of phis>. |
2177 const ZoneList<HPhi*>* phi_list = graph_->phi_list(); | 2182 const ZoneList<HPhi*>* phi_list = graph_->phi_list(); |
2178 int phi_count = phi_list->length(); | 2183 int phi_count = phi_list->length(); |
2179 ZoneList<BitVector*> connected_phis(phi_count); | 2184 ZoneList<BitVector*> connected_phis(phi_count, graph_->zone()); |
2180 for (int i = 0; i < phi_count; ++i) { | 2185 for (int i = 0; i < phi_count; ++i) { |
2181 phi_list->at(i)->InitRealUses(i); | 2186 phi_list->at(i)->InitRealUses(i); |
2182 BitVector* connected_set = new(zone()) BitVector(phi_count, graph_->zone()); | 2187 BitVector* connected_set = new(zone()) BitVector(phi_count, graph_->zone()); |
2183 connected_set->Add(i); | 2188 connected_set->Add(i); |
2184 connected_phis.Add(connected_set); | 2189 connected_phis.Add(connected_set, zone()); |
2185 } | 2190 } |
2186 | 2191 |
2187 // (2) Do a fixed point iteration to find the set of connected phis. A | 2192 // (2) Do a fixed point iteration to find the set of connected phis. A |
2188 // phi is connected to another phi if its value is used either directly or | 2193 // phi is connected to another phi if its value is used either directly or |
2189 // indirectly through a transitive closure of the def-use relation. | 2194 // indirectly through a transitive closure of the def-use relation. |
2190 bool change = true; | 2195 bool change = true; |
2191 while (change) { | 2196 while (change) { |
2192 change = false; | 2197 change = false; |
2193 // We normally have far more "forward edges" than "backward edges", | 2198 // We normally have far more "forward edges" than "backward edges", |
2194 // so we terminate faster when we walk backwards. | 2199 // so we terminate faster when we walk backwards. |
(...skipping 75 matching lines...) Loading... | |
2270 } | 2275 } |
2271 | 2276 |
2272 if (block->IsLoopHeader()) { | 2277 if (block->IsLoopHeader()) { |
2273 HBasicBlock* last_back_edge = | 2278 HBasicBlock* last_back_edge = |
2274 block->loop_information()->GetLastBackEdge(); | 2279 block->loop_information()->GetLastBackEdge(); |
2275 InitializeInferredTypes(i + 1, last_back_edge->block_id()); | 2280 InitializeInferredTypes(i + 1, last_back_edge->block_id()); |
2276 // Skip all blocks already processed by the recursive call. | 2281 // Skip all blocks already processed by the recursive call. |
2277 i = last_back_edge->block_id(); | 2282 i = last_back_edge->block_id(); |
2278 // Update phis of the loop header now after the whole loop body is | 2283 // Update phis of the loop header now after the whole loop body is |
2279 // guaranteed to be processed. | 2284 // guaranteed to be processed. |
2280 ZoneList<HValue*> worklist(block->phis()->length()); | 2285 ZoneList<HValue*> worklist(block->phis()->length(), zone()); |
2281 for (int j = 0; j < block->phis()->length(); ++j) { | 2286 for (int j = 0; j < block->phis()->length(); ++j) { |
2282 worklist.Add(block->phis()->at(j)); | 2287 worklist.Add(block->phis()->at(j), zone()); |
2283 } | 2288 } |
2284 InferTypes(&worklist); | 2289 InferTypes(&worklist); |
2285 } | 2290 } |
2286 } | 2291 } |
2287 } | 2292 } |
2288 | 2293 |
2289 | 2294 |
2290 void HGraph::PropagateMinusZeroChecks(HValue* value, BitVector* visited) { | 2295 void HGraph::PropagateMinusZeroChecks(HValue* value, BitVector* visited) { |
2291 HValue* current = value; | 2296 HValue* current = value; |
2292 while (current != NULL) { | 2297 while (current != NULL) { |
(...skipping 46 matching lines...) Loading... | |
2339 // information we treat constants like normal instructions and insert the | 2344 // information we treat constants like normal instructions and insert the |
2340 // change instructions for them. | 2345 // change instructions for them. |
2341 HInstruction* new_value = NULL; | 2346 HInstruction* new_value = NULL; |
2342 bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32); | 2347 bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32); |
2343 bool deoptimize_on_undefined = | 2348 bool deoptimize_on_undefined = |
2344 use_value->CheckFlag(HValue::kDeoptimizeOnUndefined); | 2349 use_value->CheckFlag(HValue::kDeoptimizeOnUndefined); |
2345 if (value->IsConstant()) { | 2350 if (value->IsConstant()) { |
2346 HConstant* constant = HConstant::cast(value); | 2351 HConstant* constant = HConstant::cast(value); |
2347 // Try to create a new copy of the constant with the new representation. | 2352 // Try to create a new copy of the constant with the new representation. |
2348 new_value = is_truncating | 2353 new_value = is_truncating |
2349 ? constant->CopyToTruncatedInt32() | 2354 ? constant->CopyToTruncatedInt32(zone()) |
2350 : constant->CopyToRepresentation(to); | 2355 : constant->CopyToRepresentation(to, zone()); |
2351 } | 2356 } |
2352 | 2357 |
2353 if (new_value == NULL) { | 2358 if (new_value == NULL) { |
2354 new_value = new(zone()) HChange(value, to, | 2359 new_value = new(zone()) HChange(value, to, |
2355 is_truncating, deoptimize_on_undefined); | 2360 is_truncating, deoptimize_on_undefined); |
2356 } | 2361 } |
2357 | 2362 |
2358 new_value->InsertBefore(next); | 2363 new_value->InsertBefore(next); |
2359 use_value->SetOperandAt(use_index, new_value); | 2364 use_value->SetOperandAt(use_index, new_value); |
2360 } | 2365 } |
(...skipping 398 matching lines...) Loading... | |
2759 | 2764 |
2760 | 2765 |
2761 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) { | 2766 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) { |
2762 for (int i = 0; i < exprs->length(); ++i) { | 2767 for (int i = 0; i < exprs->length(); ++i) { |
2763 CHECK_ALIVE(VisitForValue(exprs->at(i))); | 2768 CHECK_ALIVE(VisitForValue(exprs->at(i))); |
2764 } | 2769 } |
2765 } | 2770 } |
2766 | 2771 |
2767 | 2772 |
2768 HGraph* HGraphBuilder::CreateGraph() { | 2773 HGraph* HGraphBuilder::CreateGraph() { |
2769 graph_ = new(zone()) HGraph(info()); | 2774 graph_ = new(zone()) HGraph(info(), zone()); |
2770 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info()); | 2775 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info()); |
2771 | 2776 |
2772 { | 2777 { |
2773 HPhase phase("H_Block building"); | 2778 HPhase phase("H_Block building"); |
2774 current_block_ = graph()->entry_block(); | 2779 current_block_ = graph()->entry_block(); |
2775 | 2780 |
2776 Scope* scope = info()->scope(); | 2781 Scope* scope = info()->scope(); |
2777 if (scope->HasIllegalRedeclaration()) { | 2782 if (scope->HasIllegalRedeclaration()) { |
2778 Bailout("function with illegal redeclaration"); | 2783 Bailout("function with illegal redeclaration"); |
2779 return NULL; | 2784 return NULL; |
(...skipping 330 matching lines...) Loading... | |
3110 | 3115 |
3111 static bool BoundsCheckKeyMatch(void* key1, void* key2) { | 3116 static bool BoundsCheckKeyMatch(void* key1, void* key2) { |
3112 BoundsCheckKey* k1 = static_cast<BoundsCheckKey*>(key1); | 3117 BoundsCheckKey* k1 = static_cast<BoundsCheckKey*>(key1); |
3113 BoundsCheckKey* k2 = static_cast<BoundsCheckKey*>(key2); | 3118 BoundsCheckKey* k2 = static_cast<BoundsCheckKey*>(key2); |
3114 return k1->IndexBase() == k2->IndexBase() && k1->Length() == k2->Length(); | 3119 return k1->IndexBase() == k2->IndexBase() && k1->Length() == k2->Length(); |
3115 } | 3120 } |
3116 | 3121 |
3117 | 3122 |
3118 class BoundsCheckTable : private ZoneHashMap { | 3123 class BoundsCheckTable : private ZoneHashMap { |
3119 public: | 3124 public: |
3120 BoundsCheckBbData** LookupOrInsert(BoundsCheckKey* key) { | 3125 BoundsCheckBbData** LookupOrInsert(BoundsCheckKey* key, Zone* zone) { |
3121 return reinterpret_cast<BoundsCheckBbData**>( | 3126 return reinterpret_cast<BoundsCheckBbData**>( |
3122 &(Lookup(key, key->Hash(), true)->value)); | 3127 &(Lookup(key, key->Hash(), true, ZoneAllocationPolicy(zone))->value)); |
3123 } | 3128 } |
3124 | 3129 |
3125 void Insert(BoundsCheckKey* key, BoundsCheckBbData* data) { | 3130 void Insert(BoundsCheckKey* key, BoundsCheckBbData* data, Zone* zone) { |
3126 Lookup(key, key->Hash(), true)->value = data; | 3131 Lookup(key, key->Hash(), true, ZoneAllocationPolicy(zone))->value = data; |
3127 } | 3132 } |
3128 | 3133 |
3129 void Delete(BoundsCheckKey* key) { | 3134 void Delete(BoundsCheckKey* key) { |
3130 Remove(key, key->Hash()); | 3135 Remove(key, key->Hash()); |
3131 } | 3136 } |
3132 | 3137 |
3133 BoundsCheckTable() : ZoneHashMap(BoundsCheckKeyMatch) { } | 3138 explicit BoundsCheckTable(Zone* zone) : ZoneHashMap(BoundsCheckKeyMatch, 8, |
danno
2012/06/05 13:42:35
Make this a shared constant. Also, weird formattin
sanjoy
2012/06/05 14:21:39
Fixed.
| |
3139 ZoneAllocationPolicy( | |
3140 zone)) { } | |
3134 }; | 3141 }; |
3135 | 3142 |
3136 | 3143 |
3137 // Eliminates checks in bb and recursively in the dominated blocks. | 3144 // Eliminates checks in bb and recursively in the dominated blocks. |
3138 // Also replace the results of check instructions with the original value, if | 3145 // Also replace the results of check instructions with the original value, if |
3139 // the result is used. This is safe now, since we don't do code motion after | 3146 // the result is used. This is safe now, since we don't do code motion after |
3140 // this point. It enables better register allocation since the value produced | 3147 // this point. It enables better register allocation since the value produced |
3141 // by check instructions is really a copy of the original value. | 3148 // by check instructions is really a copy of the original value. |
3142 void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, | 3149 void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, |
3143 BoundsCheckTable* table) { | 3150 BoundsCheckTable* table) { |
3144 BoundsCheckBbData* bb_data_list = NULL; | 3151 BoundsCheckBbData* bb_data_list = NULL; |
3145 | 3152 |
3146 for (HInstruction* i = bb->first(); i != NULL; i = i->next()) { | 3153 for (HInstruction* i = bb->first(); i != NULL; i = i->next()) { |
3147 if (!i->IsBoundsCheck()) continue; | 3154 if (!i->IsBoundsCheck()) continue; |
3148 | 3155 |
3149 HBoundsCheck* check = HBoundsCheck::cast(i); | 3156 HBoundsCheck* check = HBoundsCheck::cast(i); |
3150 check->ReplaceAllUsesWith(check->index()); | 3157 check->ReplaceAllUsesWith(check->index()); |
3151 | 3158 |
3152 if (!FLAG_array_bounds_checks_elimination) continue; | 3159 if (!FLAG_array_bounds_checks_elimination) continue; |
3153 | 3160 |
3154 int32_t offset; | 3161 int32_t offset; |
3155 BoundsCheckKey* key = | 3162 BoundsCheckKey* key = |
3156 BoundsCheckKey::Create(bb->zone(), check, &offset); | 3163 BoundsCheckKey::Create(zone(), check, &offset); |
3157 BoundsCheckBbData** data_p = table->LookupOrInsert(key); | 3164 BoundsCheckBbData** data_p = table->LookupOrInsert(key, zone()); |
3158 BoundsCheckBbData* data = *data_p; | 3165 BoundsCheckBbData* data = *data_p; |
3159 if (data == NULL) { | 3166 if (data == NULL) { |
3160 bb_data_list = new(zone()) BoundsCheckBbData(key, | 3167 bb_data_list = new(zone()) BoundsCheckBbData(key, |
3161 offset, | 3168 offset, |
3162 offset, | 3169 offset, |
3163 bb, | 3170 bb, |
3164 check, | 3171 check, |
3165 bb_data_list, | 3172 bb_data_list, |
3166 NULL); | 3173 NULL); |
3167 *data_p = bb_data_list; | 3174 *data_p = bb_data_list; |
3168 } else if (data->OffsetIsCovered(offset)) { | 3175 } else if (data->OffsetIsCovered(offset)) { |
3169 check->DeleteAndReplaceWith(NULL); | 3176 check->DeleteAndReplaceWith(NULL); |
3170 } else if (data->BasicBlock() == bb) { | 3177 } else if (data->BasicBlock() == bb) { |
3171 data->CoverCheck(check, offset); | 3178 data->CoverCheck(check, offset); |
3172 } else { | 3179 } else { |
3173 int32_t new_lower_offset = offset < data->LowerOffset() | 3180 int32_t new_lower_offset = offset < data->LowerOffset() |
3174 ? offset | 3181 ? offset |
3175 : data->LowerOffset(); | 3182 : data->LowerOffset(); |
3176 int32_t new_upper_offset = offset > data->UpperOffset() | 3183 int32_t new_upper_offset = offset > data->UpperOffset() |
3177 ? offset | 3184 ? offset |
3178 : data->UpperOffset(); | 3185 : data->UpperOffset(); |
3179 bb_data_list = new(bb->zone()) BoundsCheckBbData(key, | 3186 bb_data_list = new(zone()) BoundsCheckBbData(key, |
3180 new_lower_offset, | 3187 new_lower_offset, |
3181 new_upper_offset, | 3188 new_upper_offset, |
3182 bb, | 3189 bb, |
3183 check, | 3190 check, |
3184 bb_data_list, | 3191 bb_data_list, |
3185 data); | 3192 data); |
3186 table->Insert(key, bb_data_list); | 3193 table->Insert(key, bb_data_list, zone()); |
3187 } | 3194 } |
3188 } | 3195 } |
3189 | 3196 |
3190 for (int i = 0; i < bb->dominated_blocks()->length(); ++i) { | 3197 for (int i = 0; i < bb->dominated_blocks()->length(); ++i) { |
3191 EliminateRedundantBoundsChecks(bb->dominated_blocks()->at(i), table); | 3198 EliminateRedundantBoundsChecks(bb->dominated_blocks()->at(i), table); |
3192 } | 3199 } |
3193 | 3200 |
3194 for (BoundsCheckBbData* data = bb_data_list; | 3201 for (BoundsCheckBbData* data = bb_data_list; |
3195 data != NULL; | 3202 data != NULL; |
3196 data = data->NextInBasicBlock()) { | 3203 data = data->NextInBasicBlock()) { |
3197 data->RemoveZeroOperations(); | 3204 data->RemoveZeroOperations(); |
3198 if (data->FatherInDominatorTree()) { | 3205 if (data->FatherInDominatorTree()) { |
3199 table->Insert(data->Key(), data->FatherInDominatorTree()); | 3206 table->Insert(data->Key(), data->FatherInDominatorTree(), zone()); |
3200 } else { | 3207 } else { |
3201 table->Delete(data->Key()); | 3208 table->Delete(data->Key()); |
3202 } | 3209 } |
3203 } | 3210 } |
3204 } | 3211 } |
3205 | 3212 |
3206 | 3213 |
3207 void HGraph::EliminateRedundantBoundsChecks() { | 3214 void HGraph::EliminateRedundantBoundsChecks() { |
3208 HPhase phase("H_Eliminate bounds checks", this); | 3215 HPhase phase("H_Eliminate bounds checks", this); |
3209 AssertNoAllocation no_gc; | 3216 AssertNoAllocation no_gc; |
3210 BoundsCheckTable checks_table; | 3217 BoundsCheckTable checks_table(zone()); |
3211 EliminateRedundantBoundsChecks(entry_block(), &checks_table); | 3218 EliminateRedundantBoundsChecks(entry_block(), &checks_table); |
3212 } | 3219 } |
3213 | 3220 |
3214 | 3221 |
3215 static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) { | 3222 static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) { |
3216 HValue* index = array_operation->GetKey(); | 3223 HValue* index = array_operation->GetKey(); |
3217 | 3224 |
3218 HConstant* constant; | 3225 HConstant* constant; |
3219 HValue* subexpression; | 3226 HValue* subexpression; |
3220 int32_t sign; | 3227 int32_t sign; |
(...skipping 99 matching lines...) Loading... | |
3320 | 3327 |
3321 void HGraphBuilder::PushAndAdd(HInstruction* instr) { | 3328 void HGraphBuilder::PushAndAdd(HInstruction* instr) { |
3322 Push(instr); | 3329 Push(instr); |
3323 AddInstruction(instr); | 3330 AddInstruction(instr); |
3324 } | 3331 } |
3325 | 3332 |
3326 | 3333 |
3327 template <class Instruction> | 3334 template <class Instruction> |
3328 HInstruction* HGraphBuilder::PreProcessCall(Instruction* call) { | 3335 HInstruction* HGraphBuilder::PreProcessCall(Instruction* call) { |
3329 int count = call->argument_count(); | 3336 int count = call->argument_count(); |
3330 ZoneList<HValue*> arguments(count); | 3337 ZoneList<HValue*> arguments(count, zone()); |
3331 for (int i = 0; i < count; ++i) { | 3338 for (int i = 0; i < count; ++i) { |
3332 arguments.Add(Pop()); | 3339 arguments.Add(Pop(), zone()); |
3333 } | 3340 } |
3334 | 3341 |
3335 while (!arguments.is_empty()) { | 3342 while (!arguments.is_empty()) { |
3336 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); | 3343 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); |
3337 } | 3344 } |
3338 return call; | 3345 return call; |
3339 } | 3346 } |
3340 | 3347 |
3341 | 3348 |
3342 void HGraphBuilder::SetUpScope(Scope* scope) { | 3349 void HGraphBuilder::SetUpScope(Scope* scope) { |
(...skipping 479 matching lines...) Loading... | |
3822 current_block()->Finish(test); | 3829 current_block()->Finish(test); |
3823 | 3830 |
3824 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); | 3831 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); |
3825 non_osr_entry->Goto(loop_predecessor); | 3832 non_osr_entry->Goto(loop_predecessor); |
3826 | 3833 |
3827 set_current_block(osr_entry); | 3834 set_current_block(osr_entry); |
3828 int osr_entry_id = statement->OsrEntryId(); | 3835 int osr_entry_id = statement->OsrEntryId(); |
3829 int first_expression_index = environment()->first_expression_index(); | 3836 int first_expression_index = environment()->first_expression_index(); |
3830 int length = environment()->length(); | 3837 int length = environment()->length(); |
3831 ZoneList<HUnknownOSRValue*>* osr_values = | 3838 ZoneList<HUnknownOSRValue*>* osr_values = |
3832 new(zone()) ZoneList<HUnknownOSRValue*>(length); | 3839 new(zone()) ZoneList<HUnknownOSRValue*>(length, zone()); |
3833 | 3840 |
3834 for (int i = 0; i < first_expression_index; ++i) { | 3841 for (int i = 0; i < first_expression_index; ++i) { |
3835 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 3842 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; |
3836 AddInstruction(osr_value); | 3843 AddInstruction(osr_value); |
3837 environment()->Bind(i, osr_value); | 3844 environment()->Bind(i, osr_value); |
3838 osr_values->Add(osr_value); | 3845 osr_values->Add(osr_value, zone()); |
3839 } | 3846 } |
3840 | 3847 |
3841 if (first_expression_index != length) { | 3848 if (first_expression_index != length) { |
3842 environment()->Drop(length - first_expression_index); | 3849 environment()->Drop(length - first_expression_index); |
3843 for (int i = first_expression_index; i < length; ++i) { | 3850 for (int i = first_expression_index; i < length; ++i) { |
3844 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 3851 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; |
3845 AddInstruction(osr_value); | 3852 AddInstruction(osr_value); |
3846 environment()->Push(osr_value); | 3853 environment()->Push(osr_value); |
3847 osr_values->Add(osr_value); | 3854 osr_values->Add(osr_value, zone()); |
3848 } | 3855 } |
3849 } | 3856 } |
3850 | 3857 |
3851 graph()->set_osr_values(osr_values); | 3858 graph()->set_osr_values(osr_values); |
3852 | 3859 |
3853 AddSimulate(osr_entry_id); | 3860 AddSimulate(osr_entry_id); |
3854 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); | 3861 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); |
3855 HContext* context = new(zone()) HContext; | 3862 HContext* context = new(zone()) HContext; |
3856 AddInstruction(context); | 3863 AddInstruction(context); |
3857 environment()->BindContext(context); | 3864 environment()->BindContext(context); |
(...skipping 607 matching lines...) Loading... | |
4465 expr->fast_elements(), | 4472 expr->fast_elements(), |
4466 expr->literal_index(), | 4473 expr->literal_index(), |
4467 expr->depth(), | 4474 expr->depth(), |
4468 expr->has_function()); | 4475 expr->has_function()); |
4469 } | 4476 } |
4470 | 4477 |
4471 // The object is expected in the bailout environment during computation | 4478 // The object is expected in the bailout environment during computation |
4472 // of the property values and is the value of the entire expression. | 4479 // of the property values and is the value of the entire expression. |
4473 PushAndAdd(literal); | 4480 PushAndAdd(literal); |
4474 | 4481 |
4475 expr->CalculateEmitStore(); | 4482 expr->CalculateEmitStore(zone()); |
4476 | 4483 |
4477 for (int i = 0; i < expr->properties()->length(); i++) { | 4484 for (int i = 0; i < expr->properties()->length(); i++) { |
4478 ObjectLiteral::Property* property = expr->properties()->at(i); | 4485 ObjectLiteral::Property* property = expr->properties()->at(i); |
4479 if (property->IsCompileTimeValue()) continue; | 4486 if (property->IsCompileTimeValue()) continue; |
4480 | 4487 |
4481 Literal* key = property->key(); | 4488 Literal* key = property->key(); |
4482 Expression* value = property->value(); | 4489 Expression* value = property->value(); |
4483 | 4490 |
4484 switch (property->kind()) { | 4491 switch (property->kind()) { |
4485 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 4492 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
(...skipping 169 matching lines...) Loading... | |
4655 | 4662 |
4656 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, | 4663 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, |
4657 Handle<String> name, | 4664 Handle<String> name, |
4658 HValue* value, | 4665 HValue* value, |
4659 Handle<Map> type, | 4666 Handle<Map> type, |
4660 LookupResult* lookup, | 4667 LookupResult* lookup, |
4661 bool smi_and_map_check) { | 4668 bool smi_and_map_check) { |
4662 ASSERT(lookup->IsFound()); | 4669 ASSERT(lookup->IsFound()); |
4663 if (smi_and_map_check) { | 4670 if (smi_and_map_check) { |
4664 AddInstruction(new(zone()) HCheckNonSmi(object)); | 4671 AddInstruction(new(zone()) HCheckNonSmi(object)); |
4665 AddInstruction(HCheckMaps::NewWithTransitions(object, type)); | 4672 AddInstruction(HCheckMaps::NewWithTransitions(object, type, zone())); |
4666 } | 4673 } |
4667 | 4674 |
4668 // If the property does not exist yet, we have to check that it wasn't made | 4675 // If the property does not exist yet, we have to check that it wasn't made |
4669 // readonly or turned into a setter by some meanwhile modifications on the | 4676 // readonly or turned into a setter by some meanwhile modifications on the |
4670 // prototype chain. | 4677 // prototype chain. |
4671 if (!lookup->IsProperty()) { | 4678 if (!lookup->IsProperty()) { |
4672 Object* proto = type->prototype(); | 4679 Object* proto = type->prototype(); |
4673 // First check that the prototype chain isn't affected already. | 4680 // First check that the prototype chain isn't affected already. |
4674 LookupResult proto_result(isolate()); | 4681 LookupResult proto_result(isolate()); |
4675 proto->Lookup(*name, &proto_result); | 4682 proto->Lookup(*name, &proto_result); |
(...skipping 123 matching lines...) Loading... | |
4799 (is_in_object == previous_field_is_in_object); | 4806 (is_in_object == previous_field_is_in_object); |
4800 } | 4807 } |
4801 ++count; | 4808 ++count; |
4802 } | 4809 } |
4803 } | 4810 } |
4804 | 4811 |
4805 // Use monomorphic load if property lookup results in the same field index | 4812 // Use monomorphic load if property lookup results in the same field index |
4806 // for all maps. Requires special map check on the set of all handled maps. | 4813 // for all maps. Requires special map check on the set of all handled maps. |
4807 HInstruction* instr; | 4814 HInstruction* instr; |
4808 if (count == types->length() && is_monomorphic_field) { | 4815 if (count == types->length() && is_monomorphic_field) { |
4809 AddInstruction(new(zone()) HCheckMaps(object, types)); | 4816 AddInstruction(new(zone()) HCheckMaps(object, types, zone())); |
4810 instr = BuildLoadNamedField(object, expr, map, &lookup, false); | 4817 instr = BuildLoadNamedField(object, expr, map, &lookup, false); |
4811 } else { | 4818 } else { |
4812 HValue* context = environment()->LookupContext(); | 4819 HValue* context = environment()->LookupContext(); |
4813 instr = new(zone()) HLoadNamedFieldPolymorphic(context, | 4820 instr = new(zone()) HLoadNamedFieldPolymorphic(context, |
4814 object, | 4821 object, |
4815 types, | 4822 types, |
4816 name); | 4823 name, |
4824 zone()); | |
4817 } | 4825 } |
4818 | 4826 |
4819 instr->set_position(expr->position()); | 4827 instr->set_position(expr->position()); |
4820 return ast_context()->ReturnInstruction(instr, expr->id()); | 4828 return ast_context()->ReturnInstruction(instr, expr->id()); |
4821 } | 4829 } |
4822 | 4830 |
4823 | 4831 |
4824 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, | 4832 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, |
4825 HValue* object, | 4833 HValue* object, |
4826 HValue* value, | 4834 HValue* value, |
(...skipping 66 matching lines...) Loading... | |
4893 ASSERT(join != NULL); | 4901 ASSERT(join != NULL); |
4894 join->SetJoinId(expr->id()); | 4902 join->SetJoinId(expr->id()); |
4895 set_current_block(join); | 4903 set_current_block(join); |
4896 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); | 4904 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); |
4897 } | 4905 } |
4898 | 4906 |
4899 | 4907 |
4900 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { | 4908 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { |
4901 Property* prop = expr->target()->AsProperty(); | 4909 Property* prop = expr->target()->AsProperty(); |
4902 ASSERT(prop != NULL); | 4910 ASSERT(prop != NULL); |
4903 expr->RecordTypeFeedback(oracle()); | 4911 expr->RecordTypeFeedback(oracle(), zone()); |
4904 CHECK_ALIVE(VisitForValue(prop->obj())); | 4912 CHECK_ALIVE(VisitForValue(prop->obj())); |
4905 | 4913 |
4906 HValue* value = NULL; | 4914 HValue* value = NULL; |
4907 HInstruction* instr = NULL; | 4915 HInstruction* instr = NULL; |
4908 | 4916 |
4909 if (prop->key()->IsPropertyName()) { | 4917 if (prop->key()->IsPropertyName()) { |
4910 // Named store. | 4918 // Named store. |
4911 CHECK_ALIVE(VisitForValue(expr->value())); | 4919 CHECK_ALIVE(VisitForValue(expr->value())); |
4912 value = Pop(); | 4920 value = Pop(); |
4913 HValue* object = Pop(); | 4921 HValue* object = Pop(); |
(...skipping 150 matching lines...) Loading... | |
5064 } | 5072 } |
5065 break; | 5073 break; |
5066 } | 5074 } |
5067 | 5075 |
5068 case Variable::LOOKUP: | 5076 case Variable::LOOKUP: |
5069 return Bailout("compound assignment to lookup slot"); | 5077 return Bailout("compound assignment to lookup slot"); |
5070 } | 5078 } |
5071 return ast_context()->ReturnValue(Pop()); | 5079 return ast_context()->ReturnValue(Pop()); |
5072 | 5080 |
5073 } else if (prop != NULL) { | 5081 } else if (prop != NULL) { |
5074 prop->RecordTypeFeedback(oracle()); | 5082 prop->RecordTypeFeedback(oracle(), zone()); |
5075 | 5083 |
5076 if (prop->key()->IsPropertyName()) { | 5084 if (prop->key()->IsPropertyName()) { |
5077 // Named property. | 5085 // Named property. |
5078 CHECK_ALIVE(VisitForValue(prop->obj())); | 5086 CHECK_ALIVE(VisitForValue(prop->obj())); |
5079 HValue* obj = Top(); | 5087 HValue* obj = Top(); |
5080 | 5088 |
5081 HInstruction* load = NULL; | 5089 HInstruction* load = NULL; |
5082 if (prop->IsMonomorphic()) { | 5090 if (prop->IsMonomorphic()) { |
5083 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 5091 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
5084 Handle<Map> map = prop->GetReceiverTypes()->first(); | 5092 Handle<Map> map = prop->GetReceiverTypes()->first(); |
(...skipping 38 matching lines...) Loading... | |
5123 | 5131 |
5124 | 5132 |
5125 CHECK_ALIVE(VisitForValue(expr->value())); | 5133 CHECK_ALIVE(VisitForValue(expr->value())); |
5126 HValue* right = Pop(); | 5134 HValue* right = Pop(); |
5127 HValue* left = Pop(); | 5135 HValue* left = Pop(); |
5128 | 5136 |
5129 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 5137 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
5130 PushAndAdd(instr); | 5138 PushAndAdd(instr); |
5131 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); | 5139 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); |
5132 | 5140 |
5133 expr->RecordTypeFeedback(oracle()); | 5141 expr->RecordTypeFeedback(oracle(), zone()); |
5134 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), | 5142 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), |
5135 RelocInfo::kNoPosition, | 5143 RelocInfo::kNoPosition, |
5136 true, // is_store | 5144 true, // is_store |
5137 &has_side_effects); | 5145 &has_side_effects); |
5138 | 5146 |
5139 // Drop the simulated receiver, key, and value. Return the value. | 5147 // Drop the simulated receiver, key, and value. Return the value. |
5140 Drop(3); | 5148 Drop(3); |
5141 Push(instr); | 5149 Push(instr); |
5142 ASSERT(has_side_effects); // Stores always have side effects. | 5150 ASSERT(has_side_effects); // Stores always have side effects. |
5143 AddSimulate(expr->AssignmentId()); | 5151 AddSimulate(expr->AssignmentId()); |
(...skipping 27 matching lines...) Loading... | |
5171 if (var->mode() == CONST) { | 5179 if (var->mode() == CONST) { |
5172 if (expr->op() != Token::INIT_CONST) { | 5180 if (expr->op() != Token::INIT_CONST) { |
5173 CHECK_ALIVE(VisitForValue(expr->value())); | 5181 CHECK_ALIVE(VisitForValue(expr->value())); |
5174 return ast_context()->ReturnValue(Pop()); | 5182 return ast_context()->ReturnValue(Pop()); |
5175 } | 5183 } |
5176 | 5184 |
5177 if (var->IsStackAllocated()) { | 5185 if (var->IsStackAllocated()) { |
5178 // We insert a use of the old value to detect unsupported uses of const | 5186 // We insert a use of the old value to detect unsupported uses of const |
5179 // variables (e.g. initialization inside a loop). | 5187 // variables (e.g. initialization inside a loop). |
5180 HValue* old_value = environment()->Lookup(var); | 5188 HValue* old_value = environment()->Lookup(var); |
5181 AddInstruction(new HUseConst(old_value)); | 5189 AddInstruction(new(zone()) HUseConst(old_value)); |
5182 } | 5190 } |
5183 } else if (var->mode() == CONST_HARMONY) { | 5191 } else if (var->mode() == CONST_HARMONY) { |
5184 if (expr->op() != Token::INIT_CONST_HARMONY) { | 5192 if (expr->op() != Token::INIT_CONST_HARMONY) { |
5185 return Bailout("non-initializer assignment to const"); | 5193 return Bailout("non-initializer assignment to const"); |
5186 } | 5194 } |
5187 } | 5195 } |
5188 | 5196 |
5189 if (proxy->IsArguments()) return Bailout("assignment to arguments"); | 5197 if (proxy->IsArguments()) return Bailout("assignment to arguments"); |
5190 | 5198 |
5191 // Handle the assignment. | 5199 // Handle the assignment. |
(...skipping 106 matching lines...) Loading... | |
5298 } | 5306 } |
5299 | 5307 |
5300 | 5308 |
5301 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, | 5309 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, |
5302 Property* expr, | 5310 Property* expr, |
5303 Handle<Map> type, | 5311 Handle<Map> type, |
5304 LookupResult* lookup, | 5312 LookupResult* lookup, |
5305 bool smi_and_map_check) { | 5313 bool smi_and_map_check) { |
5306 if (smi_and_map_check) { | 5314 if (smi_and_map_check) { |
5307 AddInstruction(new(zone()) HCheckNonSmi(object)); | 5315 AddInstruction(new(zone()) HCheckNonSmi(object)); |
5308 AddInstruction(HCheckMaps::NewWithTransitions(object, type)); | 5316 AddInstruction(HCheckMaps::NewWithTransitions(object, type, zone())); |
5309 } | 5317 } |
5310 | 5318 |
5311 int index = lookup->GetLocalFieldIndexFromMap(*type); | 5319 int index = lookup->GetLocalFieldIndexFromMap(*type); |
5312 if (index < 0) { | 5320 if (index < 0) { |
5313 // Negative property indices are in-object properties, indexed | 5321 // Negative property indices are in-object properties, indexed |
5314 // from the end of the fixed part of the object. | 5322 // from the end of the fixed part of the object. |
5315 int offset = (index * kPointerSize) + type->instance_size(); | 5323 int offset = (index * kPointerSize) + type->instance_size(); |
5316 return new(zone()) HLoadNamedField(object, true, offset); | 5324 return new(zone()) HLoadNamedField(object, true, offset); |
5317 } else { | 5325 } else { |
5318 // Non-negative property indices are in the properties array. | 5326 // Non-negative property indices are in the properties array. |
(...skipping 23 matching lines...) Loading... | |
5342 LookupResult lookup(isolate()); | 5350 LookupResult lookup(isolate()); |
5343 map->LookupInDescriptors(NULL, *name, &lookup); | 5351 map->LookupInDescriptors(NULL, *name, &lookup); |
5344 if (lookup.IsFound() && lookup.type() == FIELD) { | 5352 if (lookup.IsFound() && lookup.type() == FIELD) { |
5345 return BuildLoadNamedField(obj, | 5353 return BuildLoadNamedField(obj, |
5346 expr, | 5354 expr, |
5347 map, | 5355 map, |
5348 &lookup, | 5356 &lookup, |
5349 true); | 5357 true); |
5350 } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) { | 5358 } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) { |
5351 AddInstruction(new(zone()) HCheckNonSmi(obj)); | 5359 AddInstruction(new(zone()) HCheckNonSmi(obj)); |
5352 AddInstruction(HCheckMaps::NewWithTransitions(obj, map)); | 5360 AddInstruction(HCheckMaps::NewWithTransitions(obj, map, zone())); |
5353 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); | 5361 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); |
5354 return new(zone()) HConstant(function, Representation::Tagged()); | 5362 return new(zone()) HConstant(function, Representation::Tagged()); |
5355 } else { | 5363 } else { |
5356 return BuildLoadNamedGeneric(obj, expr); | 5364 return BuildLoadNamedGeneric(obj, expr); |
5357 } | 5365 } |
5358 } | 5366 } |
5359 | 5367 |
5360 | 5368 |
5361 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 5369 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
5362 HValue* key) { | 5370 HValue* key) { |
(...skipping 92 matching lines...) Loading... | |
5455 } | 5463 } |
5456 | 5464 |
5457 | 5465 |
5458 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, | 5466 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, |
5459 HValue* key, | 5467 HValue* key, |
5460 HValue* val, | 5468 HValue* val, |
5461 HValue* dependency, | 5469 HValue* dependency, |
5462 Handle<Map> map, | 5470 Handle<Map> map, |
5463 bool is_store) { | 5471 bool is_store) { |
5464 HInstruction* mapcheck = | 5472 HInstruction* mapcheck = |
5465 AddInstruction(new(zone()) HCheckMaps(object, map, dependency)); | 5473 AddInstruction(new(zone()) HCheckMaps(object, map, zone(), dependency)); |
5466 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency | 5474 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency |
5467 // on a HElementsTransition instruction. The flag can also be removed if the | 5475 // on a HElementsTransition instruction. The flag can also be removed if the |
5468 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further | 5476 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further |
5469 // ElementsKind transitions. Finally, the dependency can be removed for stores | 5477 // ElementsKind transitions. Finally, the dependency can be removed for stores |
5470 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the | 5478 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the |
5471 // generated store code. | 5479 // generated store code. |
5472 if (dependency || | 5480 if (dependency || |
5473 (map->elements_kind() == FAST_HOLEY_ELEMENTS) || | 5481 (map->elements_kind() == FAST_HOLEY_ELEMENTS) || |
5474 (map->elements_kind() == FAST_ELEMENTS && is_store)) { | 5482 (map->elements_kind() == FAST_ELEMENTS && is_store)) { |
5475 mapcheck->ClearGVNFlag(kDependsOnElementsKind); | 5483 mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
5476 } | 5484 } |
5477 bool fast_smi_only_elements = map->has_fast_smi_elements(); | 5485 bool fast_smi_only_elements = map->has_fast_smi_elements(); |
5478 bool fast_elements = map->has_fast_object_elements(); | 5486 bool fast_elements = map->has_fast_object_elements(); |
5479 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); | 5487 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); |
5480 if (is_store && (fast_elements || fast_smi_only_elements)) { | 5488 if (is_store && (fast_elements || fast_smi_only_elements)) { |
5481 HCheckMaps* check_cow_map = new(zone()) HCheckMaps( | 5489 HCheckMaps* check_cow_map = new(zone()) HCheckMaps( |
5482 elements, isolate()->factory()->fixed_array_map()); | 5490 elements, isolate()->factory()->fixed_array_map(), zone()); |
5483 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 5491 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
5484 AddInstruction(check_cow_map); | 5492 AddInstruction(check_cow_map); |
5485 } | 5493 } |
5486 HInstruction* length = NULL; | 5494 HInstruction* length = NULL; |
5487 HInstruction* checked_key = NULL; | 5495 HInstruction* checked_key = NULL; |
5488 if (map->has_external_array_elements()) { | 5496 if (map->has_external_array_elements()) { |
5489 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 5497 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
5490 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 5498 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
5491 HLoadExternalArrayPointer* external_elements = | 5499 HLoadExternalArrayPointer* external_elements = |
5492 new(zone()) HLoadExternalArrayPointer(elements); | 5500 new(zone()) HLoadExternalArrayPointer(elements); |
(...skipping 86 matching lines...) Loading... | |
5579 : BuildLoadKeyedGeneric(object, key)); | 5587 : BuildLoadKeyedGeneric(object, key)); |
5580 } else { | 5588 } else { |
5581 instr = AddInstruction(BuildMonomorphicElementAccess( | 5589 instr = AddInstruction(BuildMonomorphicElementAccess( |
5582 object, key, val, transition, untransitionable_map, is_store)); | 5590 object, key, val, transition, untransitionable_map, is_store)); |
5583 } | 5591 } |
5584 *has_side_effects |= instr->HasObservableSideEffects(); | 5592 *has_side_effects |= instr->HasObservableSideEffects(); |
5585 instr->set_position(position); | 5593 instr->set_position(position); |
5586 return is_store ? NULL : instr; | 5594 return is_store ? NULL : instr; |
5587 } | 5595 } |
5588 | 5596 |
5589 AddInstruction(HCheckInstanceType::NewIsSpecObject(object)); | 5597 AddInstruction(HCheckInstanceType::NewIsSpecObject(object, graph()->zone())); |
danno
2012/06/05 13:42:35
use just zone()
sanjoy
2012/06/05 14:21:39
Fixed.
| |
5590 HBasicBlock* join = graph()->CreateBasicBlock(); | 5598 HBasicBlock* join = graph()->CreateBasicBlock(); |
5591 | 5599 |
5592 HInstruction* elements_kind_instr = | 5600 HInstruction* elements_kind_instr = |
5593 AddInstruction(new(zone()) HElementsKind(object)); | 5601 AddInstruction(new(zone()) HElementsKind(object)); |
5594 HCompareConstantEqAndBranch* elements_kind_branch = NULL; | 5602 HCompareConstantEqAndBranch* elements_kind_branch = NULL; |
5595 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); | 5603 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); |
5596 HLoadExternalArrayPointer* external_elements = NULL; | 5604 HLoadExternalArrayPointer* external_elements = NULL; |
5597 HInstruction* checked_key = NULL; | 5605 HInstruction* checked_key = NULL; |
5598 | 5606 |
5599 // Generated code assumes that FAST_* and DICTIONARY_ELEMENTS ElementsKinds | 5607 // Generated code assumes that FAST_* and DICTIONARY_ELEMENTS ElementsKinds |
(...skipping 26 matching lines...) Loading... | |
5626 elements_kind_branch->SetSuccessorAt(0, if_true); | 5634 elements_kind_branch->SetSuccessorAt(0, if_true); |
5627 elements_kind_branch->SetSuccessorAt(1, if_false); | 5635 elements_kind_branch->SetSuccessorAt(1, if_false); |
5628 current_block()->Finish(elements_kind_branch); | 5636 current_block()->Finish(elements_kind_branch); |
5629 | 5637 |
5630 set_current_block(if_true); | 5638 set_current_block(if_true); |
5631 HInstruction* access; | 5639 HInstruction* access; |
5632 if (IsFastElementsKind(elements_kind)) { | 5640 if (IsFastElementsKind(elements_kind)) { |
5633 if (is_store && !IsFastDoubleElementsKind(elements_kind)) { | 5641 if (is_store && !IsFastDoubleElementsKind(elements_kind)) { |
5634 AddInstruction(new(zone()) HCheckMaps( | 5642 AddInstruction(new(zone()) HCheckMaps( |
5635 elements, isolate()->factory()->fixed_array_map(), | 5643 elements, isolate()->factory()->fixed_array_map(), |
5636 elements_kind_branch)); | 5644 zone(), elements_kind_branch)); |
5637 } | 5645 } |
5638 // TODO(jkummerow): The need for these two blocks could be avoided | 5646 // TODO(jkummerow): The need for these two blocks could be avoided |
5639 // in one of two ways: | 5647 // in one of two ways: |
5640 // (1) Introduce ElementsKinds for JSArrays that are distinct from | 5648 // (1) Introduce ElementsKinds for JSArrays that are distinct from |
5641 // those for fast objects. | 5649 // those for fast objects. |
5642 // (2) Put the common instructions into a third "join" block. This | 5650 // (2) Put the common instructions into a third "join" block. This |
5643 // requires additional AST IDs that we can deopt to from inside | 5651 // requires additional AST IDs that we can deopt to from inside |
5644 // that join block. They must be added to the Property class (when | 5652 // that join block. They must be added to the Property class (when |
5645 // it's a keyed property) and registered in the full codegen. | 5653 // it's a keyed property) and registered in the full codegen. |
5646 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); | 5654 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); |
(...skipping 186 matching lines...) Loading... | |
5833 } | 5841 } |
5834 ast_context()->ReturnInstruction(result, expr->id()); | 5842 ast_context()->ReturnInstruction(result, expr->id()); |
5835 return true; | 5843 return true; |
5836 } | 5844 } |
5837 | 5845 |
5838 | 5846 |
5839 void HGraphBuilder::VisitProperty(Property* expr) { | 5847 void HGraphBuilder::VisitProperty(Property* expr) { |
5840 ASSERT(!HasStackOverflow()); | 5848 ASSERT(!HasStackOverflow()); |
5841 ASSERT(current_block() != NULL); | 5849 ASSERT(current_block() != NULL); |
5842 ASSERT(current_block()->HasPredecessor()); | 5850 ASSERT(current_block()->HasPredecessor()); |
5843 expr->RecordTypeFeedback(oracle()); | 5851 expr->RecordTypeFeedback(oracle(), zone()); |
5844 | 5852 |
5845 if (TryArgumentsAccess(expr)) return; | 5853 if (TryArgumentsAccess(expr)) return; |
5846 | 5854 |
5847 CHECK_ALIVE(VisitForValue(expr->obj())); | 5855 CHECK_ALIVE(VisitForValue(expr->obj())); |
5848 | 5856 |
5849 HInstruction* instr = NULL; | 5857 HInstruction* instr = NULL; |
5850 if (expr->AsProperty()->IsArrayLength()) { | 5858 if (expr->AsProperty()->IsArrayLength()) { |
5851 HValue* array = Pop(); | 5859 HValue* array = Pop(); |
5852 AddInstruction(new(zone()) HCheckNonSmi(array)); | 5860 AddInstruction(new(zone()) HCheckNonSmi(array)); |
5853 HInstruction* mapcheck = | 5861 HInstruction* mapcheck = |
5854 AddInstruction(HCheckInstanceType::NewIsJSArray(array)); | 5862 AddInstruction(HCheckInstanceType::NewIsJSArray(array, zone())); |
5855 instr = new(zone()) HJSArrayLength(array, mapcheck); | 5863 instr = new(zone()) HJSArrayLength(array, mapcheck); |
5856 | 5864 |
5857 } else if (expr->IsStringLength()) { | 5865 } else if (expr->IsStringLength()) { |
5858 HValue* string = Pop(); | 5866 HValue* string = Pop(); |
5859 AddInstruction(new(zone()) HCheckNonSmi(string)); | 5867 AddInstruction(new(zone()) HCheckNonSmi(string)); |
5860 AddInstruction(HCheckInstanceType::NewIsString(string)); | 5868 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
5861 instr = new(zone()) HStringLength(string); | 5869 instr = new(zone()) HStringLength(string); |
5862 } else if (expr->IsStringAccess()) { | 5870 } else if (expr->IsStringAccess()) { |
5863 CHECK_ALIVE(VisitForValue(expr->key())); | 5871 CHECK_ALIVE(VisitForValue(expr->key())); |
5864 HValue* index = Pop(); | 5872 HValue* index = Pop(); |
5865 HValue* string = Pop(); | 5873 HValue* string = Pop(); |
5866 HValue* context = environment()->LookupContext(); | 5874 HValue* context = environment()->LookupContext(); |
5867 HStringCharCodeAt* char_code = | 5875 HStringCharCodeAt* char_code = |
5868 BuildStringCharCodeAt(context, string, index); | 5876 BuildStringCharCodeAt(context, string, index); |
5869 AddInstruction(char_code); | 5877 AddInstruction(char_code); |
5870 instr = new(zone()) HStringCharFromCode(context, char_code); | 5878 instr = new(zone()) HStringCharFromCode(context, char_code); |
(...skipping 47 matching lines...) Loading... | |
5918 | 5926 |
5919 void HGraphBuilder::AddCheckConstantFunction(Call* expr, | 5927 void HGraphBuilder::AddCheckConstantFunction(Call* expr, |
5920 HValue* receiver, | 5928 HValue* receiver, |
5921 Handle<Map> receiver_map, | 5929 Handle<Map> receiver_map, |
5922 bool smi_and_map_check) { | 5930 bool smi_and_map_check) { |
5923 // Constant functions have the nice property that the map will change if they | 5931 // Constant functions have the nice property that the map will change if they |
5924 // are overwritten. Therefore it is enough to check the map of the holder and | 5932 // are overwritten. Therefore it is enough to check the map of the holder and |
5925 // its prototypes. | 5933 // its prototypes. |
5926 if (smi_and_map_check) { | 5934 if (smi_and_map_check) { |
5927 AddInstruction(new(zone()) HCheckNonSmi(receiver)); | 5935 AddInstruction(new(zone()) HCheckNonSmi(receiver)); |
5928 AddInstruction(HCheckMaps::NewWithTransitions(receiver, receiver_map)); | 5936 AddInstruction(HCheckMaps::NewWithTransitions(receiver, receiver_map, |
5937 zone())); | |
5929 } | 5938 } |
5930 if (!expr->holder().is_null()) { | 5939 if (!expr->holder().is_null()) { |
5931 AddInstruction(new(zone()) HCheckPrototypeMaps( | 5940 AddInstruction(new(zone()) HCheckPrototypeMaps( |
5932 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), | 5941 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), |
5933 expr->holder())); | 5942 expr->holder())); |
5934 } | 5943 } |
5935 } | 5944 } |
5936 | 5945 |
5937 | 5946 |
5938 class FunctionSorter { | 5947 class FunctionSorter { |
(...skipping 314 matching lines...) Loading... | |
6253 // generating the optimized inline code. | 6262 // generating the optimized inline code. |
6254 target_info.EnableDeoptimizationSupport(); | 6263 target_info.EnableDeoptimizationSupport(); |
6255 if (!FullCodeGenerator::MakeCode(&target_info)) { | 6264 if (!FullCodeGenerator::MakeCode(&target_info)) { |
6256 TraceInline(target, caller, "could not generate deoptimization info"); | 6265 TraceInline(target, caller, "could not generate deoptimization info"); |
6257 return false; | 6266 return false; |
6258 } | 6267 } |
6259 if (target_shared->scope_info() == ScopeInfo::Empty()) { | 6268 if (target_shared->scope_info() == ScopeInfo::Empty()) { |
6260 // The scope info might not have been set if a lazily compiled | 6269 // The scope info might not have been set if a lazily compiled |
6261 // function is inlined before being called for the first time. | 6270 // function is inlined before being called for the first time. |
6262 Handle<ScopeInfo> target_scope_info = | 6271 Handle<ScopeInfo> target_scope_info = |
6263 ScopeInfo::Create(target_info.scope()); | 6272 ScopeInfo::Create(target_info.scope(), zone()); |
6264 target_shared->set_scope_info(*target_scope_info); | 6273 target_shared->set_scope_info(*target_scope_info); |
6265 } | 6274 } |
6266 target_shared->EnableDeoptimizationSupport(*target_info.code()); | 6275 target_shared->EnableDeoptimizationSupport(*target_info.code()); |
6267 Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG, | 6276 Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG, |
6268 &target_info, | 6277 &target_info, |
6269 target_shared); | 6278 target_shared); |
6270 } | 6279 } |
6271 | 6280 |
6272 // ---------------------------------------------------------------- | 6281 // ---------------------------------------------------------------- |
6273 // After this point, we've made a decision to inline this function (so | 6282 // After this point, we've made a decision to inline this function (so |
6274 // TryInline should always return true). | 6283 // TryInline should always return true). |
6275 | 6284 |
6276 // Save the pending call context and type feedback oracle. Set up new ones | 6285 // Save the pending call context and type feedback oracle. Set up new ones |
6277 // for the inlined function. | 6286 // for the inlined function. |
6278 ASSERT(target_shared->has_deoptimization_support()); | 6287 ASSERT(target_shared->has_deoptimization_support()); |
6279 TypeFeedbackOracle target_oracle( | 6288 TypeFeedbackOracle target_oracle( |
6280 Handle<Code>(target_shared->code()), | 6289 Handle<Code>(target_shared->code()), |
6281 Handle<Context>(target->context()->global_context()), | 6290 Handle<Context>(target->context()->global_context()), |
6282 isolate()); | 6291 isolate(), |
6292 zone()); | |
6283 // The function state is new-allocated because we need to delete it | 6293 // The function state is new-allocated because we need to delete it |
6284 // in two different places. | 6294 // in two different places. |
6285 FunctionState* target_state = new FunctionState( | 6295 FunctionState* target_state = new FunctionState( |
6286 this, &target_info, &target_oracle, return_handling); | 6296 this, &target_info, &target_oracle, return_handling); |
6287 | 6297 |
6288 HConstant* undefined = graph()->GetConstantUndefined(); | 6298 HConstant* undefined = graph()->GetConstantUndefined(); |
6289 HEnvironment* inner_env = | 6299 HEnvironment* inner_env = |
6290 environment()->CopyForInlining(target, | 6300 environment()->CopyForInlining(target, |
6291 arguments->length(), | 6301 arguments->length(), |
6292 function, | 6302 function, |
6293 undefined, | 6303 undefined, |
6294 call_kind, | 6304 call_kind, |
6295 function_state()->is_construct()); | 6305 function_state()->is_construct()); |
6296 #ifdef V8_TARGET_ARCH_IA32 | 6306 #ifdef V8_TARGET_ARCH_IA32 |
6297 // IA32 only, overwrite the caller's context in the deoptimization | 6307 // IA32 only, overwrite the caller's context in the deoptimization |
6298 // environment with the correct one. | 6308 // environment with the correct one. |
6299 // | 6309 // |
6300 // TODO(kmillikin): implement the same inlining on other platforms so we | 6310 // TODO(kmillikin): implement the same inlining on other platforms so we |
6301 // can remove the unsightly ifdefs in this function. | 6311 // can remove the unsightly ifdefs in this function. |
6302 HConstant* context = new HConstant(Handle<Context>(target->context()), | 6312 HConstant* context = |
6303 Representation::Tagged()); | 6313 new(isolate()->zone()) HConstant(Handle<Context>(target->context()), |
danno
2012/06/05 13:42:35
why not just zone()?
sanjoy
2012/06/05 14:21:39
Fixed.
| |
6314 Representation::Tagged()); | |
6304 AddInstruction(context); | 6315 AddInstruction(context); |
6305 inner_env->BindContext(context); | 6316 inner_env->BindContext(context); |
6306 #endif | 6317 #endif |
6307 | 6318 |
6308 AddSimulate(return_id); | 6319 AddSimulate(return_id); |
6309 current_block()->UpdateEnvironment(inner_env); | 6320 current_block()->UpdateEnvironment(inner_env); |
6310 | 6321 |
6311 ZoneList<HValue*>* arguments_values = NULL; | 6322 ZoneList<HValue*>* arguments_values = NULL; |
6312 | 6323 |
6313 // If the function uses arguments copy current arguments values | 6324 // If the function uses arguments copy current arguments values |
6314 // to use them for materialization. | 6325 // to use them for materialization. |
6315 if (function->scope()->arguments() != NULL) { | 6326 if (function->scope()->arguments() != NULL) { |
6316 HEnvironment* arguments_env = inner_env->arguments_environment(); | 6327 HEnvironment* arguments_env = inner_env->arguments_environment(); |
6317 int arguments_count = arguments_env->parameter_count(); | 6328 int arguments_count = arguments_env->parameter_count(); |
6318 arguments_values = new(zone()) ZoneList<HValue*>(arguments_count); | 6329 arguments_values = new(zone()) ZoneList<HValue*>(arguments_count, zone()); |
6319 for (int i = 0; i < arguments_count; i++) { | 6330 for (int i = 0; i < arguments_count; i++) { |
6320 arguments_values->Add(arguments_env->Lookup(i)); | 6331 arguments_values->Add(arguments_env->Lookup(i), zone()); |
6321 } | 6332 } |
6322 } | 6333 } |
6323 | 6334 |
6324 HEnterInlined* enter_inlined = | 6335 HEnterInlined* enter_inlined = |
6325 new(zone()) HEnterInlined(target, | 6336 new(zone()) HEnterInlined(target, |
6326 arguments->length(), | 6337 arguments->length(), |
6327 function, | 6338 function, |
6328 call_kind, | 6339 call_kind, |
6329 function_state()->is_construct(), | 6340 function_state()->is_construct(), |
6330 function->scope()->arguments(), | 6341 function->scope()->arguments(), |
(...skipping 574 matching lines...) Loading... | |
6905 Drop(argument_count); | 6916 Drop(argument_count); |
6906 } | 6917 } |
6907 | 6918 |
6908 } else if (expr->IsMonomorphic()) { | 6919 } else if (expr->IsMonomorphic()) { |
6909 // The function is on the stack in the unoptimized code during | 6920 // The function is on the stack in the unoptimized code during |
6910 // evaluation of the arguments. | 6921 // evaluation of the arguments. |
6911 CHECK_ALIVE(VisitForValue(expr->expression())); | 6922 CHECK_ALIVE(VisitForValue(expr->expression())); |
6912 HValue* function = Top(); | 6923 HValue* function = Top(); |
6913 HValue* context = environment()->LookupContext(); | 6924 HValue* context = environment()->LookupContext(); |
6914 HGlobalObject* global = new(zone()) HGlobalObject(context); | 6925 HGlobalObject* global = new(zone()) HGlobalObject(context); |
6926 AddInstruction(global); | |
sanjoy
2012/06/05 13:02:49
This needs to be done so that the HGlobalReceiver
| |
6915 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global); | 6927 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global); |
6916 AddInstruction(global); | |
6917 PushAndAdd(receiver); | 6928 PushAndAdd(receiver); |
6918 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 6929 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
6919 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); | 6930 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); |
6920 | 6931 |
6921 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. | 6932 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. |
6922 if (FLAG_trace_inlining) { | 6933 if (FLAG_trace_inlining) { |
6923 PrintF("Inlining builtin "); | 6934 PrintF("Inlining builtin "); |
6924 expr->target()->ShortPrint(); | 6935 expr->target()->ShortPrint(); |
6925 PrintF("\n"); | 6936 PrintF("\n"); |
6926 } | 6937 } |
6927 return; | 6938 return; |
6928 } | 6939 } |
6929 | 6940 |
6930 if (TryInlineCall(expr, true)) { // Drop function from environment. | 6941 if (TryInlineCall(expr, true)) { // Drop function from environment. |
6931 return; | 6942 return; |
6932 } else { | 6943 } else { |
6933 call = PreProcessCall( | 6944 call = PreProcessCall( |
6934 new(zone()) HInvokeFunction(context, | 6945 new(zone()) HInvokeFunction(context, |
6935 function, | 6946 function, |
6936 expr->target(), | 6947 expr->target(), |
6937 argument_count)); | 6948 argument_count)); |
6938 Drop(1); // The function. | 6949 Drop(1); // The function. |
6939 } | 6950 } |
6940 | 6951 |
6941 } else { | 6952 } else { |
6942 CHECK_ALIVE(VisitForValue(expr->expression())); | 6953 CHECK_ALIVE(VisitForValue(expr->expression())); |
6943 HValue* function = Top(); | 6954 HValue* function = Top(); |
6944 HValue* context = environment()->LookupContext(); | 6955 HValue* context = environment()->LookupContext(); |
6945 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 6956 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
6957 AddInstruction(global_object); | |
6946 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global_object); | 6958 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global_object); |
6947 AddInstruction(global_object); | |
6948 AddInstruction(receiver); | 6959 AddInstruction(receiver); |
6949 PushAndAdd(new(zone()) HPushArgument(receiver)); | 6960 PushAndAdd(new(zone()) HPushArgument(receiver)); |
6950 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 6961 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
6951 | 6962 |
6952 call = new(zone()) HCallFunction(context, function, argument_count); | 6963 call = new(zone()) HCallFunction(context, function, argument_count); |
6953 Drop(argument_count + 1); | 6964 Drop(argument_count + 1); |
6954 } | 6965 } |
6955 } | 6966 } |
6956 | 6967 |
6957 call->set_position(expr->position()); | 6968 call->set_position(expr->position()); |
(...skipping 385 matching lines...) Loading... | |
7343 break; | 7354 break; |
7344 } | 7355 } |
7345 | 7356 |
7346 case Variable::LOOKUP: | 7357 case Variable::LOOKUP: |
7347 return Bailout("lookup variable in count operation"); | 7358 return Bailout("lookup variable in count operation"); |
7348 } | 7359 } |
7349 | 7360 |
7350 } else { | 7361 } else { |
7351 // Argument of the count operation is a property. | 7362 // Argument of the count operation is a property. |
7352 ASSERT(prop != NULL); | 7363 ASSERT(prop != NULL); |
7353 prop->RecordTypeFeedback(oracle()); | 7364 prop->RecordTypeFeedback(oracle(), zone()); |
7354 | 7365 |
7355 if (prop->key()->IsPropertyName()) { | 7366 if (prop->key()->IsPropertyName()) { |
7356 // Named property. | 7367 // Named property. |
7357 if (returns_original_input) Push(graph_->GetConstantUndefined()); | 7368 if (returns_original_input) Push(graph_->GetConstantUndefined()); |
7358 | 7369 |
7359 CHECK_ALIVE(VisitForValue(prop->obj())); | 7370 CHECK_ALIVE(VisitForValue(prop->obj())); |
7360 HValue* obj = Top(); | 7371 HValue* obj = Top(); |
7361 | 7372 |
7362 HInstruction* load = NULL; | 7373 HInstruction* load = NULL; |
7363 if (prop->IsMonomorphic()) { | 7374 if (prop->IsMonomorphic()) { |
(...skipping 33 matching lines...) Loading... | |
7397 HValue* load = HandleKeyedElementAccess( | 7408 HValue* load = HandleKeyedElementAccess( |
7398 obj, key, NULL, prop, expr->CountId(), RelocInfo::kNoPosition, | 7409 obj, key, NULL, prop, expr->CountId(), RelocInfo::kNoPosition, |
7399 false, // is_store | 7410 false, // is_store |
7400 &has_side_effects); | 7411 &has_side_effects); |
7401 Push(load); | 7412 Push(load); |
7402 if (has_side_effects) AddSimulate(expr->CountId()); | 7413 if (has_side_effects) AddSimulate(expr->CountId()); |
7403 | 7414 |
7404 after = BuildIncrement(returns_original_input, expr); | 7415 after = BuildIncrement(returns_original_input, expr); |
7405 input = Pop(); | 7416 input = Pop(); |
7406 | 7417 |
7407 expr->RecordTypeFeedback(oracle()); | 7418 expr->RecordTypeFeedback(oracle(), zone()); |
7408 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(), | 7419 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(), |
7409 RelocInfo::kNoPosition, | 7420 RelocInfo::kNoPosition, |
7410 true, // is_store | 7421 true, // is_store |
7411 &has_side_effects); | 7422 &has_side_effects); |
7412 | 7423 |
7413 // Drop the key from the bailout environment. Overwrite the receiver | 7424 // Drop the key from the bailout environment. Overwrite the receiver |
7414 // with the result of the operation, and the placeholder with the | 7425 // with the result of the operation, and the placeholder with the |
7415 // original value if necessary. | 7426 // original value if necessary. |
7416 Drop(1); | 7427 Drop(1); |
7417 environment()->SetExpressionStackAt(0, after); | 7428 environment()->SetExpressionStackAt(0, after); |
7418 if (returns_original_input) environment()->SetExpressionStackAt(1, input); | 7429 if (returns_original_input) environment()->SetExpressionStackAt(1, input); |
7419 ASSERT(has_side_effects); // Stores always have side effects. | 7430 ASSERT(has_side_effects); // Stores always have side effects. |
7420 AddSimulate(expr->AssignmentId()); | 7431 AddSimulate(expr->AssignmentId()); |
7421 } | 7432 } |
7422 } | 7433 } |
7423 | 7434 |
7424 Drop(returns_original_input ? 2 : 1); | 7435 Drop(returns_original_input ? 2 : 1); |
7425 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); | 7436 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); |
7426 } | 7437 } |
7427 | 7438 |
7428 | 7439 |
7429 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* context, | 7440 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* context, |
7430 HValue* string, | 7441 HValue* string, |
7431 HValue* index) { | 7442 HValue* index) { |
7432 AddInstruction(new(zone()) HCheckNonSmi(string)); | 7443 AddInstruction(new(zone()) HCheckNonSmi(string)); |
7433 AddInstruction(HCheckInstanceType::NewIsString(string)); | 7444 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
7434 HStringLength* length = new(zone()) HStringLength(string); | 7445 HStringLength* length = new(zone()) HStringLength(string); |
7435 AddInstruction(length); | 7446 AddInstruction(length); |
7436 HInstruction* checked_index = | 7447 HInstruction* checked_index = |
7437 AddInstruction(new(zone()) HBoundsCheck(index, length)); | 7448 AddInstruction(new(zone()) HBoundsCheck(index, length)); |
7438 return new(zone()) HStringCharCodeAt(context, string, checked_index); | 7449 return new(zone()) HStringCharCodeAt(context, string, checked_index); |
7439 } | 7450 } |
7440 | 7451 |
7441 | 7452 |
7442 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, | 7453 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, |
7443 HValue* left, | 7454 HValue* left, |
7444 HValue* right) { | 7455 HValue* right) { |
7445 HValue* context = environment()->LookupContext(); | 7456 HValue* context = environment()->LookupContext(); |
7446 TypeInfo info = oracle()->BinaryType(expr); | 7457 TypeInfo info = oracle()->BinaryType(expr); |
7447 if (info.IsUninitialized()) { | 7458 if (info.IsUninitialized()) { |
7448 AddInstruction(new(zone()) HSoftDeoptimize); | 7459 AddInstruction(new(zone()) HSoftDeoptimize); |
7449 current_block()->MarkAsDeoptimizing(); | 7460 current_block()->MarkAsDeoptimizing(); |
7450 info = TypeInfo::Unknown(); | 7461 info = TypeInfo::Unknown(); |
7451 } | 7462 } |
7452 HInstruction* instr = NULL; | 7463 HInstruction* instr = NULL; |
7453 switch (expr->op()) { | 7464 switch (expr->op()) { |
7454 case Token::ADD: | 7465 case Token::ADD: |
7455 if (info.IsString()) { | 7466 if (info.IsString()) { |
7456 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7467 AddInstruction(new(zone()) HCheckNonSmi(left)); |
7457 AddInstruction(HCheckInstanceType::NewIsString(left)); | 7468 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); |
7458 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7469 AddInstruction(new(zone()) HCheckNonSmi(right)); |
7459 AddInstruction(HCheckInstanceType::NewIsString(right)); | 7470 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); |
7460 instr = new(zone()) HStringAdd(context, left, right); | 7471 instr = new(zone()) HStringAdd(context, left, right); |
7461 } else { | 7472 } else { |
7462 instr = HAdd::NewHAdd(zone(), context, left, right); | 7473 instr = HAdd::NewHAdd(zone(), context, left, right); |
7463 } | 7474 } |
7464 break; | 7475 break; |
7465 case Token::SUB: | 7476 case Token::SUB: |
7466 instr = HSub::NewHSub(zone(), context, left, right); | 7477 instr = HSub::NewHSub(zone(), context, left, right); |
7467 break; | 7478 break; |
7468 case Token::MUL: | 7479 case Token::MUL: |
7469 instr = HMul::NewHMul(zone(), context, left, right); | 7480 instr = HMul::NewHMul(zone(), context, left, right); |
(...skipping 379 matching lines...) Loading... | |
7849 result->set_position(expr->position()); | 7860 result->set_position(expr->position()); |
7850 return ast_context()->ReturnInstruction(result, expr->id()); | 7861 return ast_context()->ReturnInstruction(result, expr->id()); |
7851 } else if (type_info.IsNonPrimitive()) { | 7862 } else if (type_info.IsNonPrimitive()) { |
7852 switch (op) { | 7863 switch (op) { |
7853 case Token::EQ: | 7864 case Token::EQ: |
7854 case Token::EQ_STRICT: { | 7865 case Token::EQ_STRICT: { |
7855 // Can we get away with map check and not instance type check? | 7866 // Can we get away with map check and not instance type check? |
7856 Handle<Map> map = oracle()->GetCompareMap(expr); | 7867 Handle<Map> map = oracle()->GetCompareMap(expr); |
7857 if (!map.is_null()) { | 7868 if (!map.is_null()) { |
7858 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7869 AddInstruction(new(zone()) HCheckNonSmi(left)); |
7859 AddInstruction(HCheckMaps::NewWithTransitions(left, map)); | 7870 AddInstruction(HCheckMaps::NewWithTransitions(left, map, zone())); |
7860 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7871 AddInstruction(new(zone()) HCheckNonSmi(right)); |
7861 AddInstruction(HCheckMaps::NewWithTransitions(right, map)); | 7872 AddInstruction(HCheckMaps::NewWithTransitions(right, map, zone())); |
7862 HCompareObjectEqAndBranch* result = | 7873 HCompareObjectEqAndBranch* result = |
7863 new(zone()) HCompareObjectEqAndBranch(left, right); | 7874 new(zone()) HCompareObjectEqAndBranch(left, right); |
7864 result->set_position(expr->position()); | 7875 result->set_position(expr->position()); |
7865 return ast_context()->ReturnControl(result, expr->id()); | 7876 return ast_context()->ReturnControl(result, expr->id()); |
7866 } else { | 7877 } else { |
7867 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7878 AddInstruction(new(zone()) HCheckNonSmi(left)); |
7868 AddInstruction(HCheckInstanceType::NewIsSpecObject(left)); | 7879 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); |
7869 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7880 AddInstruction(new(zone()) HCheckNonSmi(right)); |
7870 AddInstruction(HCheckInstanceType::NewIsSpecObject(right)); | 7881 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); |
7871 HCompareObjectEqAndBranch* result = | 7882 HCompareObjectEqAndBranch* result = |
7872 new(zone()) HCompareObjectEqAndBranch(left, right); | 7883 new(zone()) HCompareObjectEqAndBranch(left, right); |
7873 result->set_position(expr->position()); | 7884 result->set_position(expr->position()); |
7874 return ast_context()->ReturnControl(result, expr->id()); | 7885 return ast_context()->ReturnControl(result, expr->id()); |
7875 } | 7886 } |
7876 } | 7887 } |
7877 default: | 7888 default: |
7878 return Bailout("Unsupported non-primitive compare"); | 7889 return Bailout("Unsupported non-primitive compare"); |
7879 } | 7890 } |
7880 } else if (type_info.IsString() && oracle()->IsSymbolCompare(expr) && | 7891 } else if (type_info.IsString() && oracle()->IsSymbolCompare(expr) && |
7881 (op == Token::EQ || op == Token::EQ_STRICT)) { | 7892 (op == Token::EQ || op == Token::EQ_STRICT)) { |
7882 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7893 AddInstruction(new(zone()) HCheckNonSmi(left)); |
7883 AddInstruction(HCheckInstanceType::NewIsSymbol(left)); | 7894 AddInstruction(HCheckInstanceType::NewIsSymbol(left, zone())); |
7884 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7895 AddInstruction(new(zone()) HCheckNonSmi(right)); |
7885 AddInstruction(HCheckInstanceType::NewIsSymbol(right)); | 7896 AddInstruction(HCheckInstanceType::NewIsSymbol(right, zone())); |
7886 HCompareObjectEqAndBranch* result = | 7897 HCompareObjectEqAndBranch* result = |
7887 new(zone()) HCompareObjectEqAndBranch(left, right); | 7898 new(zone()) HCompareObjectEqAndBranch(left, right); |
7888 result->set_position(expr->position()); | 7899 result->set_position(expr->position()); |
7889 return ast_context()->ReturnControl(result, expr->id()); | 7900 return ast_context()->ReturnControl(result, expr->id()); |
7890 } else { | 7901 } else { |
7891 Representation r = ToRepresentation(type_info); | 7902 Representation r = ToRepresentation(type_info); |
7892 if (r.IsTagged()) { | 7903 if (r.IsTagged()) { |
7893 HCompareGeneric* result = | 7904 HCompareGeneric* result = |
7894 new(zone()) HCompareGeneric(context, left, right, op); | 7905 new(zone()) HCompareGeneric(context, left, right, op); |
7895 result->set_position(expr->position()); | 7906 result->set_position(expr->position()); |
(...skipping 51 matching lines...) Loading... | |
7947 } | 7958 } |
7948 | 7959 |
7949 | 7960 |
7950 void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) { | 7961 void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) { |
7951 VariableProxy* proxy = declaration->proxy(); | 7962 VariableProxy* proxy = declaration->proxy(); |
7952 VariableMode mode = declaration->mode(); | 7963 VariableMode mode = declaration->mode(); |
7953 Variable* variable = proxy->var(); | 7964 Variable* variable = proxy->var(); |
7954 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; | 7965 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; |
7955 switch (variable->location()) { | 7966 switch (variable->location()) { |
7956 case Variable::UNALLOCATED: | 7967 case Variable::UNALLOCATED: |
7957 globals_.Add(variable->name()); | 7968 globals_.Add(variable->name(), zone()); |
7958 globals_.Add(variable->binding_needs_init() | 7969 globals_.Add(variable->binding_needs_init() |
7959 ? isolate()->factory()->the_hole_value() | 7970 ? isolate()->factory()->the_hole_value() |
7960 : isolate()->factory()->undefined_value()); | 7971 : isolate()->factory()->undefined_value(), zone()); |
7961 return; | 7972 return; |
7962 case Variable::PARAMETER: | 7973 case Variable::PARAMETER: |
7963 case Variable::LOCAL: | 7974 case Variable::LOCAL: |
7964 if (hole_init) { | 7975 if (hole_init) { |
7965 HValue* value = graph()->GetConstantHole(); | 7976 HValue* value = graph()->GetConstantHole(); |
7966 environment()->Bind(variable, value); | 7977 environment()->Bind(variable, value); |
7967 } | 7978 } |
7968 break; | 7979 break; |
7969 case Variable::CONTEXT: | 7980 case Variable::CONTEXT: |
7970 if (hole_init) { | 7981 if (hole_init) { |
7971 HValue* value = graph()->GetConstantHole(); | 7982 HValue* value = graph()->GetConstantHole(); |
7972 HValue* context = environment()->LookupContext(); | 7983 HValue* context = environment()->LookupContext(); |
7973 HStoreContextSlot* store = new HStoreContextSlot( | 7984 HStoreContextSlot* store = new(zone()) HStoreContextSlot( |
7974 context, variable->index(), HStoreContextSlot::kNoCheck, value); | 7985 context, variable->index(), HStoreContextSlot::kNoCheck, value); |
7975 AddInstruction(store); | 7986 AddInstruction(store); |
7976 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); | 7987 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); |
7977 } | 7988 } |
7978 break; | 7989 break; |
7979 case Variable::LOOKUP: | 7990 case Variable::LOOKUP: |
7980 return Bailout("unsupported lookup slot in declaration"); | 7991 return Bailout("unsupported lookup slot in declaration"); |
7981 } | 7992 } |
7982 } | 7993 } |
7983 | 7994 |
7984 | 7995 |
7985 void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) { | 7996 void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) { |
7986 VariableProxy* proxy = declaration->proxy(); | 7997 VariableProxy* proxy = declaration->proxy(); |
7987 Variable* variable = proxy->var(); | 7998 Variable* variable = proxy->var(); |
7988 switch (variable->location()) { | 7999 switch (variable->location()) { |
7989 case Variable::UNALLOCATED: { | 8000 case Variable::UNALLOCATED: { |
7990 globals_.Add(variable->name()); | 8001 globals_.Add(variable->name(), zone()); |
7991 Handle<SharedFunctionInfo> function = | 8002 Handle<SharedFunctionInfo> function = |
7992 Compiler::BuildFunctionInfo(declaration->fun(), info()->script()); | 8003 Compiler::BuildFunctionInfo(declaration->fun(), info()->script()); |
7993 // Check for stack-overflow exception. | 8004 // Check for stack-overflow exception. |
7994 if (function.is_null()) return SetStackOverflow(); | 8005 if (function.is_null()) return SetStackOverflow(); |
7995 globals_.Add(function); | 8006 globals_.Add(function, zone()); |
7996 return; | 8007 return; |
7997 } | 8008 } |
7998 case Variable::PARAMETER: | 8009 case Variable::PARAMETER: |
7999 case Variable::LOCAL: { | 8010 case Variable::LOCAL: { |
8000 CHECK_ALIVE(VisitForValue(declaration->fun())); | 8011 CHECK_ALIVE(VisitForValue(declaration->fun())); |
8001 HValue* value = Pop(); | 8012 HValue* value = Pop(); |
8002 environment()->Bind(variable, value); | 8013 environment()->Bind(variable, value); |
8003 break; | 8014 break; |
8004 } | 8015 } |
8005 case Variable::CONTEXT: { | 8016 case Variable::CONTEXT: { |
8006 CHECK_ALIVE(VisitForValue(declaration->fun())); | 8017 CHECK_ALIVE(VisitForValue(declaration->fun())); |
8007 HValue* value = Pop(); | 8018 HValue* value = Pop(); |
8008 HValue* context = environment()->LookupContext(); | 8019 HValue* context = environment()->LookupContext(); |
8009 HStoreContextSlot* store = new HStoreContextSlot( | 8020 HStoreContextSlot* store = new(zone()) HStoreContextSlot( |
8010 context, variable->index(), HStoreContextSlot::kNoCheck, value); | 8021 context, variable->index(), HStoreContextSlot::kNoCheck, value); |
8011 AddInstruction(store); | 8022 AddInstruction(store); |
8012 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); | 8023 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); |
8013 break; | 8024 break; |
8014 } | 8025 } |
8015 case Variable::LOOKUP: | 8026 case Variable::LOOKUP: |
8016 return Bailout("unsupported lookup slot in declaration"); | 8027 return Bailout("unsupported lookup slot in declaration"); |
8017 } | 8028 } |
8018 } | 8029 } |
8019 | 8030 |
(...skipping 225 matching lines...) Loading... | |
8245 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); | 8256 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); |
8246 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); | 8257 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); |
8247 typecheck->SetSuccessorAt(0, if_js_value); | 8258 typecheck->SetSuccessorAt(0, if_js_value); |
8248 typecheck->SetSuccessorAt(1, not_js_value); | 8259 typecheck->SetSuccessorAt(1, not_js_value); |
8249 current_block()->Finish(typecheck); | 8260 current_block()->Finish(typecheck); |
8250 not_js_value->Goto(join); | 8261 not_js_value->Goto(join); |
8251 | 8262 |
8252 // Create in-object property store to kValueOffset. | 8263 // Create in-object property store to kValueOffset. |
8253 set_current_block(if_js_value); | 8264 set_current_block(if_js_value); |
8254 Handle<String> name = isolate()->factory()->undefined_symbol(); | 8265 Handle<String> name = isolate()->factory()->undefined_symbol(); |
8255 AddInstruction(new HStoreNamedField(object, | 8266 AddInstruction(new(zone()) HStoreNamedField(object, |
8256 name, | 8267 name, |
8257 value, | 8268 value, |
8258 true, // in-object store. | 8269 true, // in-object store. |
8259 JSValue::kValueOffset)); | 8270 JSValue::kValueOffset)); |
8260 if_js_value->Goto(join); | 8271 if_js_value->Goto(join); |
8261 join->SetJoinId(call->id()); | 8272 join->SetJoinId(call->id()); |
8262 set_current_block(join); | 8273 set_current_block(join); |
8263 return ast_context()->ReturnValue(value); | 8274 return ast_context()->ReturnValue(value); |
8264 } | 8275 } |
8265 | 8276 |
8266 | 8277 |
8267 // Fast support for charCodeAt(n). | 8278 // Fast support for charCodeAt(n). |
8268 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { | 8279 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { |
8269 ASSERT(call->arguments()->length() == 2); | 8280 ASSERT(call->arguments()->length() == 2); |
(...skipping 267 matching lines...) Loading... | |
8537 return Bailout("inlined runtime function: FastAsciiArrayJoin"); | 8548 return Bailout("inlined runtime function: FastAsciiArrayJoin"); |
8538 } | 8549 } |
8539 | 8550 |
8540 | 8551 |
8541 #undef CHECK_BAILOUT | 8552 #undef CHECK_BAILOUT |
8542 #undef CHECK_ALIVE | 8553 #undef CHECK_ALIVE |
8543 | 8554 |
8544 | 8555 |
8545 HEnvironment::HEnvironment(HEnvironment* outer, | 8556 HEnvironment::HEnvironment(HEnvironment* outer, |
8546 Scope* scope, | 8557 Scope* scope, |
8547 Handle<JSFunction> closure) | 8558 Handle<JSFunction> closure, |
8559 Zone* zone) | |
8548 : closure_(closure), | 8560 : closure_(closure), |
8549 values_(0), | 8561 values_(0, zone), |
8550 assigned_variables_(4), | 8562 assigned_variables_(4, zone), |
8551 frame_type_(JS_FUNCTION), | 8563 frame_type_(JS_FUNCTION), |
8552 parameter_count_(0), | 8564 parameter_count_(0), |
8553 specials_count_(1), | 8565 specials_count_(1), |
8554 local_count_(0), | 8566 local_count_(0), |
8555 outer_(outer), | 8567 outer_(outer), |
8556 pop_count_(0), | 8568 pop_count_(0), |
8557 push_count_(0), | 8569 push_count_(0), |
8558 ast_id_(AstNode::kNoNumber) { | 8570 ast_id_(AstNode::kNoNumber), |
8571 zone_(zone) { | |
8559 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); | 8572 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); |
8560 } | 8573 } |
8561 | 8574 |
8562 | 8575 |
8563 HEnvironment::HEnvironment(const HEnvironment* other) | 8576 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) |
8564 : values_(0), | 8577 : values_(0, zone), |
8565 assigned_variables_(0), | 8578 assigned_variables_(0, zone), |
8566 frame_type_(JS_FUNCTION), | 8579 frame_type_(JS_FUNCTION), |
8567 parameter_count_(0), | 8580 parameter_count_(0), |
8568 specials_count_(1), | 8581 specials_count_(1), |
8569 local_count_(0), | 8582 local_count_(0), |
8570 outer_(NULL), | 8583 outer_(NULL), |
8571 pop_count_(0), | 8584 pop_count_(0), |
8572 push_count_(0), | 8585 push_count_(0), |
8573 ast_id_(other->ast_id()) { | 8586 ast_id_(other->ast_id()), |
8587 zone_(zone) { | |
8574 Initialize(other); | 8588 Initialize(other); |
8575 } | 8589 } |
8576 | 8590 |
8577 | 8591 |
8578 HEnvironment::HEnvironment(HEnvironment* outer, | 8592 HEnvironment::HEnvironment(HEnvironment* outer, |
8579 Handle<JSFunction> closure, | 8593 Handle<JSFunction> closure, |
8580 FrameType frame_type, | 8594 FrameType frame_type, |
8581 int arguments) | 8595 int arguments, |
8596 Zone* zone) | |
8582 : closure_(closure), | 8597 : closure_(closure), |
8583 values_(arguments), | 8598 values_(arguments, zone), |
8584 assigned_variables_(0), | 8599 assigned_variables_(0, zone), |
8585 frame_type_(frame_type), | 8600 frame_type_(frame_type), |
8586 parameter_count_(arguments), | 8601 parameter_count_(arguments), |
8587 local_count_(0), | 8602 local_count_(0), |
8588 outer_(outer), | 8603 outer_(outer), |
8589 pop_count_(0), | 8604 pop_count_(0), |
8590 push_count_(0), | 8605 push_count_(0), |
8591 ast_id_(AstNode::kNoNumber) { | 8606 ast_id_(AstNode::kNoNumber), |
8607 zone_(zone) { | |
8592 } | 8608 } |
8593 | 8609 |
8594 | 8610 |
8595 void HEnvironment::Initialize(int parameter_count, | 8611 void HEnvironment::Initialize(int parameter_count, |
8596 int local_count, | 8612 int local_count, |
8597 int stack_height) { | 8613 int stack_height) { |
8598 parameter_count_ = parameter_count; | 8614 parameter_count_ = parameter_count; |
8599 local_count_ = local_count; | 8615 local_count_ = local_count; |
8600 | 8616 |
8601 // Avoid reallocating the temporaries' backing store on the first Push. | 8617 // Avoid reallocating the temporaries' backing store on the first Push. |
8602 int total = parameter_count + specials_count_ + local_count + stack_height; | 8618 int total = parameter_count + specials_count_ + local_count + stack_height; |
8603 values_.Initialize(total + 4); | 8619 values_.Initialize(total + 4, zone()); |
8604 for (int i = 0; i < total; ++i) values_.Add(NULL); | 8620 for (int i = 0; i < total; ++i) values_.Add(NULL, zone()); |
8605 } | 8621 } |
8606 | 8622 |
8607 | 8623 |
8608 void HEnvironment::Initialize(const HEnvironment* other) { | 8624 void HEnvironment::Initialize(const HEnvironment* other) { |
8609 closure_ = other->closure(); | 8625 closure_ = other->closure(); |
8610 values_.AddAll(other->values_); | 8626 values_.AddAll(other->values_, zone()); |
8611 assigned_variables_.AddAll(other->assigned_variables_); | 8627 assigned_variables_.AddAll(other->assigned_variables_, zone()); |
8612 frame_type_ = other->frame_type_; | 8628 frame_type_ = other->frame_type_; |
8613 parameter_count_ = other->parameter_count_; | 8629 parameter_count_ = other->parameter_count_; |
8614 local_count_ = other->local_count_; | 8630 local_count_ = other->local_count_; |
8615 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. | 8631 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. |
8616 pop_count_ = other->pop_count_; | 8632 pop_count_ = other->pop_count_; |
8617 push_count_ = other->push_count_; | 8633 push_count_ = other->push_count_; |
8618 ast_id_ = other->ast_id_; | 8634 ast_id_ = other->ast_id_; |
8619 } | 8635 } |
8620 | 8636 |
8621 | 8637 |
8622 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { | 8638 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { |
8623 ASSERT(!block->IsLoopHeader()); | 8639 ASSERT(!block->IsLoopHeader()); |
8624 ASSERT(values_.length() == other->values_.length()); | 8640 ASSERT(values_.length() == other->values_.length()); |
8625 | 8641 |
8626 int length = values_.length(); | 8642 int length = values_.length(); |
8627 for (int i = 0; i < length; ++i) { | 8643 for (int i = 0; i < length; ++i) { |
8628 HValue* value = values_[i]; | 8644 HValue* value = values_[i]; |
8629 if (value != NULL && value->IsPhi() && value->block() == block) { | 8645 if (value != NULL && value->IsPhi() && value->block() == block) { |
8630 // There is already a phi for the i'th value. | 8646 // There is already a phi for the i'th value. |
8631 HPhi* phi = HPhi::cast(value); | 8647 HPhi* phi = HPhi::cast(value); |
8632 // Assert index is correct and that we haven't missed an incoming edge. | 8648 // Assert index is correct and that we haven't missed an incoming edge. |
8633 ASSERT(phi->merged_index() == i); | 8649 ASSERT(phi->merged_index() == i); |
8634 ASSERT(phi->OperandCount() == block->predecessors()->length()); | 8650 ASSERT(phi->OperandCount() == block->predecessors()->length()); |
8635 phi->AddInput(other->values_[i]); | 8651 phi->AddInput(other->values_[i]); |
8636 } else if (values_[i] != other->values_[i]) { | 8652 } else if (values_[i] != other->values_[i]) { |
8637 // There is a fresh value on the incoming edge, a phi is needed. | 8653 // There is a fresh value on the incoming edge, a phi is needed. |
8638 ASSERT(values_[i] != NULL && other->values_[i] != NULL); | 8654 ASSERT(values_[i] != NULL && other->values_[i] != NULL); |
8639 HPhi* phi = new(block->zone()) HPhi(i); | 8655 HPhi* phi = new(zone()) HPhi(i, zone()); |
8640 HValue* old_value = values_[i]; | 8656 HValue* old_value = values_[i]; |
8641 for (int j = 0; j < block->predecessors()->length(); j++) { | 8657 for (int j = 0; j < block->predecessors()->length(); j++) { |
8642 phi->AddInput(old_value); | 8658 phi->AddInput(old_value); |
8643 } | 8659 } |
8644 phi->AddInput(other->values_[i]); | 8660 phi->AddInput(other->values_[i]); |
8645 this->values_[i] = phi; | 8661 this->values_[i] = phi; |
8646 block->AddPhi(phi); | 8662 block->AddPhi(phi); |
8647 } | 8663 } |
8648 } | 8664 } |
8649 } | 8665 } |
8650 | 8666 |
8651 | 8667 |
8652 void HEnvironment::Bind(int index, HValue* value) { | 8668 void HEnvironment::Bind(int index, HValue* value) { |
8653 ASSERT(value != NULL); | 8669 ASSERT(value != NULL); |
8654 if (!assigned_variables_.Contains(index)) { | 8670 if (!assigned_variables_.Contains(index)) { |
8655 assigned_variables_.Add(index); | 8671 assigned_variables_.Add(index, zone()); |
8656 } | 8672 } |
8657 values_[index] = value; | 8673 values_[index] = value; |
8658 } | 8674 } |
8659 | 8675 |
8660 | 8676 |
8661 bool HEnvironment::HasExpressionAt(int index) const { | 8677 bool HEnvironment::HasExpressionAt(int index) const { |
8662 return index >= parameter_count_ + specials_count_ + local_count_; | 8678 return index >= parameter_count_ + specials_count_ + local_count_; |
8663 } | 8679 } |
8664 | 8680 |
8665 | 8681 |
(...skipping 19 matching lines...) Loading... | |
8685 | 8701 |
8686 | 8702 |
8687 void HEnvironment::Drop(int count) { | 8703 void HEnvironment::Drop(int count) { |
8688 for (int i = 0; i < count; ++i) { | 8704 for (int i = 0; i < count; ++i) { |
8689 Pop(); | 8705 Pop(); |
8690 } | 8706 } |
8691 } | 8707 } |
8692 | 8708 |
8693 | 8709 |
8694 HEnvironment* HEnvironment::Copy() const { | 8710 HEnvironment* HEnvironment::Copy() const { |
8695 return new(closure()->GetIsolate()->zone()) HEnvironment(this); | 8711 return new(zone()) HEnvironment(this, zone()); |
8696 } | 8712 } |
8697 | 8713 |
8698 | 8714 |
8699 HEnvironment* HEnvironment::CopyWithoutHistory() const { | 8715 HEnvironment* HEnvironment::CopyWithoutHistory() const { |
8700 HEnvironment* result = Copy(); | 8716 HEnvironment* result = Copy(); |
8701 result->ClearHistory(); | 8717 result->ClearHistory(); |
8702 return result; | 8718 return result; |
8703 } | 8719 } |
8704 | 8720 |
8705 | 8721 |
8706 HEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const { | 8722 HEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const { |
8707 HEnvironment* new_env = Copy(); | 8723 HEnvironment* new_env = Copy(); |
8708 for (int i = 0; i < values_.length(); ++i) { | 8724 for (int i = 0; i < values_.length(); ++i) { |
8709 HPhi* phi = new(loop_header->zone()) HPhi(i); | 8725 HPhi* phi = new(zone()) HPhi(i, zone()); |
8710 phi->AddInput(values_[i]); | 8726 phi->AddInput(values_[i]); |
8711 new_env->values_[i] = phi; | 8727 new_env->values_[i] = phi; |
8712 loop_header->AddPhi(phi); | 8728 loop_header->AddPhi(phi); |
8713 } | 8729 } |
8714 new_env->ClearHistory(); | 8730 new_env->ClearHistory(); |
8715 return new_env; | 8731 return new_env; |
8716 } | 8732 } |
8717 | 8733 |
8718 | 8734 |
8719 HEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer, | 8735 HEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer, |
8720 Handle<JSFunction> target, | 8736 Handle<JSFunction> target, |
8721 FrameType frame_type, | 8737 FrameType frame_type, |
8722 int arguments) const { | 8738 int arguments) const { |
8723 HEnvironment* new_env = new(closure()->GetIsolate()->zone()) | 8739 HEnvironment* new_env = |
8724 HEnvironment(outer, target, frame_type, arguments + 1); | 8740 new(zone()) HEnvironment(outer, target, frame_type, |
8741 arguments + 1, zone()); | |
8725 for (int i = 0; i <= arguments; ++i) { // Include receiver. | 8742 for (int i = 0; i <= arguments; ++i) { // Include receiver. |
8726 new_env->Push(ExpressionStackAt(arguments - i)); | 8743 new_env->Push(ExpressionStackAt(arguments - i)); |
8727 } | 8744 } |
8728 new_env->ClearHistory(); | 8745 new_env->ClearHistory(); |
8729 return new_env; | 8746 return new_env; |
8730 } | 8747 } |
8731 | 8748 |
8732 | 8749 |
8733 HEnvironment* HEnvironment::CopyForInlining( | 8750 HEnvironment* HEnvironment::CopyForInlining( |
8734 Handle<JSFunction> target, | 8751 Handle<JSFunction> target, |
(...skipping 19 matching lines...) Loading... | |
8754 // object instead, DoComputeConstructStubFrame() relies on that. | 8771 // object instead, DoComputeConstructStubFrame() relies on that. |
8755 outer = CreateStubEnvironment(outer, target, JS_CONSTRUCT, arguments); | 8772 outer = CreateStubEnvironment(outer, target, JS_CONSTRUCT, arguments); |
8756 } | 8773 } |
8757 | 8774 |
8758 if (arity != arguments) { | 8775 if (arity != arguments) { |
8759 // Create artificial arguments adaptation environment. | 8776 // Create artificial arguments adaptation environment. |
8760 outer = CreateStubEnvironment(outer, target, ARGUMENTS_ADAPTOR, arguments); | 8777 outer = CreateStubEnvironment(outer, target, ARGUMENTS_ADAPTOR, arguments); |
8761 } | 8778 } |
8762 | 8779 |
8763 HEnvironment* inner = | 8780 HEnvironment* inner = |
8764 new(zone) HEnvironment(outer, function->scope(), target); | 8781 new(zone) HEnvironment(outer, function->scope(), target, zone); |
8765 // Get the argument values from the original environment. | 8782 // Get the argument values from the original environment. |
8766 for (int i = 0; i <= arity; ++i) { // Include receiver. | 8783 for (int i = 0; i <= arity; ++i) { // Include receiver. |
8767 HValue* push = (i <= arguments) ? | 8784 HValue* push = (i <= arguments) ? |
8768 ExpressionStackAt(arguments - i) : undefined; | 8785 ExpressionStackAt(arguments - i) : undefined; |
8769 inner->SetValueAt(i, push); | 8786 inner->SetValueAt(i, push); |
8770 } | 8787 } |
8771 // If the function we are inlining is a strict mode function or a | 8788 // If the function we are inlining is a strict mode function or a |
8772 // builtin function, pass undefined as the receiver for function | 8789 // builtin function, pass undefined as the receiver for function |
8773 // calls (instead of the global receiver). | 8790 // calls (instead of the global receiver). |
8774 if ((target->shared()->native() || !function->is_classic_mode()) && | 8791 if ((target->shared()->native() || !function->is_classic_mode()) && |
(...skipping 169 matching lines...) Loading... | |
8944 } | 8961 } |
8945 } | 8962 } |
8946 | 8963 |
8947 | 8964 |
8948 void HTracer::TraceLiveRanges(const char* name, LAllocator* allocator) { | 8965 void HTracer::TraceLiveRanges(const char* name, LAllocator* allocator) { |
8949 Tag tag(this, "intervals"); | 8966 Tag tag(this, "intervals"); |
8950 PrintStringProperty("name", name); | 8967 PrintStringProperty("name", name); |
8951 | 8968 |
8952 const Vector<LiveRange*>* fixed_d = allocator->fixed_double_live_ranges(); | 8969 const Vector<LiveRange*>* fixed_d = allocator->fixed_double_live_ranges(); |
8953 for (int i = 0; i < fixed_d->length(); ++i) { | 8970 for (int i = 0; i < fixed_d->length(); ++i) { |
8954 TraceLiveRange(fixed_d->at(i), "fixed"); | 8971 TraceLiveRange(fixed_d->at(i), "fixed", allocator->zone()); |
8955 } | 8972 } |
8956 | 8973 |
8957 const Vector<LiveRange*>* fixed = allocator->fixed_live_ranges(); | 8974 const Vector<LiveRange*>* fixed = allocator->fixed_live_ranges(); |
8958 for (int i = 0; i < fixed->length(); ++i) { | 8975 for (int i = 0; i < fixed->length(); ++i) { |
8959 TraceLiveRange(fixed->at(i), "fixed"); | 8976 TraceLiveRange(fixed->at(i), "fixed", allocator->zone()); |
8960 } | 8977 } |
8961 | 8978 |
8962 const ZoneList<LiveRange*>* live_ranges = allocator->live_ranges(); | 8979 const ZoneList<LiveRange*>* live_ranges = allocator->live_ranges(); |
8963 for (int i = 0; i < live_ranges->length(); ++i) { | 8980 for (int i = 0; i < live_ranges->length(); ++i) { |
8964 TraceLiveRange(live_ranges->at(i), "object"); | 8981 TraceLiveRange(live_ranges->at(i), "object", allocator->zone()); |
8965 } | 8982 } |
8966 } | 8983 } |
8967 | 8984 |
8968 | 8985 |
8969 void HTracer::TraceLiveRange(LiveRange* range, const char* type) { | 8986 void HTracer::TraceLiveRange(LiveRange* range, const char* type, |
8987 Zone* zone) { | |
8970 if (range != NULL && !range->IsEmpty()) { | 8988 if (range != NULL && !range->IsEmpty()) { |
8971 PrintIndent(); | 8989 PrintIndent(); |
8972 trace_.Add("%d %s", range->id(), type); | 8990 trace_.Add("%d %s", range->id(), type); |
8973 if (range->HasRegisterAssigned()) { | 8991 if (range->HasRegisterAssigned()) { |
8974 LOperand* op = range->CreateAssignedOperand(ZONE); | 8992 LOperand* op = range->CreateAssignedOperand(zone); |
8975 int assigned_reg = op->index(); | 8993 int assigned_reg = op->index(); |
8976 if (op->IsDoubleRegister()) { | 8994 if (op->IsDoubleRegister()) { |
8977 trace_.Add(" \"%s\"", | 8995 trace_.Add(" \"%s\"", |
8978 DoubleRegister::AllocationIndexToString(assigned_reg)); | 8996 DoubleRegister::AllocationIndexToString(assigned_reg)); |
8979 } else { | 8997 } else { |
8980 ASSERT(op->IsRegister()); | 8998 ASSERT(op->IsRegister()); |
8981 trace_.Add(" \"%s\"", Register::AllocationIndexToString(assigned_reg)); | 8999 trace_.Add(" \"%s\"", Register::AllocationIndexToString(assigned_reg)); |
8982 } | 9000 } |
8983 } else if (range->IsSpilled()) { | 9001 } else if (range->IsSpilled()) { |
8984 LOperand* op = range->TopLevel()->GetSpillOperand(); | 9002 LOperand* op = range->TopLevel()->GetSpillOperand(); |
(...skipping 141 matching lines...) Loading... | |
9126 } | 9144 } |
9127 } | 9145 } |
9128 | 9146 |
9129 #ifdef DEBUG | 9147 #ifdef DEBUG |
9130 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 9148 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
9131 if (allocator_ != NULL) allocator_->Verify(); | 9149 if (allocator_ != NULL) allocator_->Verify(); |
9132 #endif | 9150 #endif |
9133 } | 9151 } |
9134 | 9152 |
9135 } } // namespace v8::internal | 9153 } } // namespace v8::internal |
OLD | NEW |