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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand all 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand all 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...) Expand all 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...) Expand all 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...) Expand all 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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( |
1497 HBasicBlock* dominator, | 1502 HBasicBlock* dominator, |
1498 HBasicBlock* dominated); | 1503 HBasicBlock* dominated); |
1499 void AnalyzeGraph(); | 1504 void AnalyzeGraph(); |
1500 void ComputeBlockSideEffects(); | 1505 void ComputeBlockSideEffects(); |
1501 void LoopInvariantCodeMotion(); | 1506 void LoopInvariantCodeMotion(); |
1502 void ProcessLoopBlock(HBasicBlock* block, | 1507 void ProcessLoopBlock(HBasicBlock* block, |
1503 HBasicBlock* before_loop, | 1508 HBasicBlock* before_loop, |
1504 GVNFlagSet loop_kills, | 1509 GVNFlagSet loop_kills, |
1505 GVNFlagSet* accumulated_first_time_depends, | 1510 GVNFlagSet* accumulated_first_time_depends, |
1506 GVNFlagSet* accumulated_first_time_changes); | 1511 GVNFlagSet* accumulated_first_time_changes); |
1507 bool AllowCodeMotion(); | 1512 bool AllowCodeMotion(); |
1508 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); | 1513 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); |
1509 | 1514 |
1510 HGraph* graph() { return graph_; } | 1515 HGraph* graph() { return graph_; } |
1511 CompilationInfo* info() { return info_; } | 1516 CompilationInfo* info() { return info_; } |
1512 Zone* zone() { return graph_->zone(); } | 1517 Zone* zone() const { return graph_->zone(); } |
1513 | 1518 |
1514 HGraph* graph_; | 1519 HGraph* graph_; |
1515 CompilationInfo* info_; | 1520 CompilationInfo* info_; |
1516 bool removed_side_effects_; | 1521 bool removed_side_effects_; |
1517 | 1522 |
1518 // A map of block IDs to their side effects. | 1523 // A map of block IDs to their side effects. |
1519 ZoneList<GVNFlagSet> block_side_effects_; | 1524 ZoneList<GVNFlagSet> block_side_effects_; |
1520 | 1525 |
1521 // A map of loop header block IDs to their loop's side effects. | 1526 // A map of loop header block IDs to their loop's side effects. |
1522 ZoneList<GVNFlagSet> loop_side_effects_; | 1527 ZoneList<GVNFlagSet> loop_side_effects_; |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after 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...) Expand all 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...) Expand 10 before | Expand all | Expand 10 after 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() const { 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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2177 } | 2182 } |
2178 | 2183 |
2179 | 2184 |
2180 void HInferRepresentation::Analyze() { | 2185 void HInferRepresentation::Analyze() { |
2181 HPhase phase("H_Infer representations", graph_); | 2186 HPhase phase("H_Infer representations", graph_); |
2182 | 2187 |
2183 // (1) Initialize bit vectors and count real uses. Each phi gets a | 2188 // (1) Initialize bit vectors and count real uses. Each phi gets a |
2184 // bit-vector of length <number of phis>. | 2189 // bit-vector of length <number of phis>. |
2185 const ZoneList<HPhi*>* phi_list = graph_->phi_list(); | 2190 const ZoneList<HPhi*>* phi_list = graph_->phi_list(); |
2186 int phi_count = phi_list->length(); | 2191 int phi_count = phi_list->length(); |
2187 ZoneList<BitVector*> connected_phis(phi_count); | 2192 ZoneList<BitVector*> connected_phis(phi_count, graph_->zone()); |
2188 for (int i = 0; i < phi_count; ++i) { | 2193 for (int i = 0; i < phi_count; ++i) { |
2189 phi_list->at(i)->InitRealUses(i); | 2194 phi_list->at(i)->InitRealUses(i); |
2190 BitVector* connected_set = new(zone()) BitVector(phi_count, graph_->zone()); | 2195 BitVector* connected_set = new(zone()) BitVector(phi_count, graph_->zone()); |
2191 connected_set->Add(i); | 2196 connected_set->Add(i); |
2192 connected_phis.Add(connected_set); | 2197 connected_phis.Add(connected_set, zone()); |
2193 } | 2198 } |
2194 | 2199 |
2195 // (2) Do a fixed point iteration to find the set of connected phis. A | 2200 // (2) Do a fixed point iteration to find the set of connected phis. A |
2196 // phi is connected to another phi if its value is used either directly or | 2201 // phi is connected to another phi if its value is used either directly or |
2197 // indirectly through a transitive closure of the def-use relation. | 2202 // indirectly through a transitive closure of the def-use relation. |
2198 bool change = true; | 2203 bool change = true; |
2199 while (change) { | 2204 while (change) { |
2200 change = false; | 2205 change = false; |
2201 // We normally have far more "forward edges" than "backward edges", | 2206 // We normally have far more "forward edges" than "backward edges", |
2202 // so we terminate faster when we walk backwards. | 2207 // so we terminate faster when we walk backwards. |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2291 } | 2296 } |
2292 | 2297 |
2293 if (block->IsLoopHeader()) { | 2298 if (block->IsLoopHeader()) { |
2294 HBasicBlock* last_back_edge = | 2299 HBasicBlock* last_back_edge = |
2295 block->loop_information()->GetLastBackEdge(); | 2300 block->loop_information()->GetLastBackEdge(); |
2296 InitializeInferredTypes(i + 1, last_back_edge->block_id()); | 2301 InitializeInferredTypes(i + 1, last_back_edge->block_id()); |
2297 // Skip all blocks already processed by the recursive call. | 2302 // Skip all blocks already processed by the recursive call. |
2298 i = last_back_edge->block_id(); | 2303 i = last_back_edge->block_id(); |
2299 // Update phis of the loop header now after the whole loop body is | 2304 // Update phis of the loop header now after the whole loop body is |
2300 // guaranteed to be processed. | 2305 // guaranteed to be processed. |
2301 ZoneList<HValue*> worklist(block->phis()->length()); | 2306 ZoneList<HValue*> worklist(block->phis()->length(), zone()); |
2302 for (int j = 0; j < block->phis()->length(); ++j) { | 2307 for (int j = 0; j < block->phis()->length(); ++j) { |
2303 worklist.Add(block->phis()->at(j)); | 2308 worklist.Add(block->phis()->at(j), zone()); |
2304 } | 2309 } |
2305 InferTypes(&worklist); | 2310 InferTypes(&worklist); |
2306 } | 2311 } |
2307 } | 2312 } |
2308 } | 2313 } |
2309 | 2314 |
2310 | 2315 |
2311 void HGraph::PropagateMinusZeroChecks(HValue* value, BitVector* visited) { | 2316 void HGraph::PropagateMinusZeroChecks(HValue* value, BitVector* visited) { |
2312 HValue* current = value; | 2317 HValue* current = value; |
2313 while (current != NULL) { | 2318 while (current != NULL) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2360 // information we treat constants like normal instructions and insert the | 2365 // information we treat constants like normal instructions and insert the |
2361 // change instructions for them. | 2366 // change instructions for them. |
2362 HInstruction* new_value = NULL; | 2367 HInstruction* new_value = NULL; |
2363 bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32); | 2368 bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32); |
2364 bool deoptimize_on_undefined = | 2369 bool deoptimize_on_undefined = |
2365 use_value->CheckFlag(HValue::kDeoptimizeOnUndefined); | 2370 use_value->CheckFlag(HValue::kDeoptimizeOnUndefined); |
2366 if (value->IsConstant()) { | 2371 if (value->IsConstant()) { |
2367 HConstant* constant = HConstant::cast(value); | 2372 HConstant* constant = HConstant::cast(value); |
2368 // Try to create a new copy of the constant with the new representation. | 2373 // Try to create a new copy of the constant with the new representation. |
2369 new_value = is_truncating | 2374 new_value = is_truncating |
2370 ? constant->CopyToTruncatedInt32() | 2375 ? constant->CopyToTruncatedInt32(zone()) |
2371 : constant->CopyToRepresentation(to); | 2376 : constant->CopyToRepresentation(to, zone()); |
2372 } | 2377 } |
2373 | 2378 |
2374 if (new_value == NULL) { | 2379 if (new_value == NULL) { |
2375 new_value = new(zone()) HChange(value, to, | 2380 new_value = new(zone()) HChange(value, to, |
2376 is_truncating, deoptimize_on_undefined); | 2381 is_truncating, deoptimize_on_undefined); |
2377 } | 2382 } |
2378 | 2383 |
2379 new_value->InsertBefore(next); | 2384 new_value->InsertBefore(next); |
2380 use_value->SetOperandAt(use_index, new_value); | 2385 use_value->SetOperandAt(use_index, new_value); |
2381 } | 2386 } |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2780 | 2785 |
2781 | 2786 |
2782 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) { | 2787 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) { |
2783 for (int i = 0; i < exprs->length(); ++i) { | 2788 for (int i = 0; i < exprs->length(); ++i) { |
2784 CHECK_ALIVE(VisitForValue(exprs->at(i))); | 2789 CHECK_ALIVE(VisitForValue(exprs->at(i))); |
2785 } | 2790 } |
2786 } | 2791 } |
2787 | 2792 |
2788 | 2793 |
2789 HGraph* HGraphBuilder::CreateGraph() { | 2794 HGraph* HGraphBuilder::CreateGraph() { |
2790 graph_ = new(zone()) HGraph(info()); | 2795 graph_ = new(zone()) HGraph(info(), zone()); |
2791 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info()); | 2796 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info()); |
2792 | 2797 |
2793 { | 2798 { |
2794 HPhase phase("H_Block building"); | 2799 HPhase phase("H_Block building"); |
2795 current_block_ = graph()->entry_block(); | 2800 current_block_ = graph()->entry_block(); |
2796 | 2801 |
2797 Scope* scope = info()->scope(); | 2802 Scope* scope = info()->scope(); |
2798 if (scope->HasIllegalRedeclaration()) { | 2803 if (scope->HasIllegalRedeclaration()) { |
2799 Bailout("function with illegal redeclaration"); | 2804 Bailout("function with illegal redeclaration"); |
2800 return NULL; | 2805 return NULL; |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3131 | 3136 |
3132 static bool BoundsCheckKeyMatch(void* key1, void* key2) { | 3137 static bool BoundsCheckKeyMatch(void* key1, void* key2) { |
3133 BoundsCheckKey* k1 = static_cast<BoundsCheckKey*>(key1); | 3138 BoundsCheckKey* k1 = static_cast<BoundsCheckKey*>(key1); |
3134 BoundsCheckKey* k2 = static_cast<BoundsCheckKey*>(key2); | 3139 BoundsCheckKey* k2 = static_cast<BoundsCheckKey*>(key2); |
3135 return k1->IndexBase() == k2->IndexBase() && k1->Length() == k2->Length(); | 3140 return k1->IndexBase() == k2->IndexBase() && k1->Length() == k2->Length(); |
3136 } | 3141 } |
3137 | 3142 |
3138 | 3143 |
3139 class BoundsCheckTable : private ZoneHashMap { | 3144 class BoundsCheckTable : private ZoneHashMap { |
3140 public: | 3145 public: |
3141 BoundsCheckBbData** LookupOrInsert(BoundsCheckKey* key) { | 3146 BoundsCheckBbData** LookupOrInsert(BoundsCheckKey* key, Zone* zone) { |
3142 return reinterpret_cast<BoundsCheckBbData**>( | 3147 return reinterpret_cast<BoundsCheckBbData**>( |
3143 &(Lookup(key, key->Hash(), true)->value)); | 3148 &(Lookup(key, key->Hash(), true, ZoneAllocationPolicy(zone))->value)); |
3144 } | 3149 } |
3145 | 3150 |
3146 void Insert(BoundsCheckKey* key, BoundsCheckBbData* data) { | 3151 void Insert(BoundsCheckKey* key, BoundsCheckBbData* data, Zone* zone) { |
3147 Lookup(key, key->Hash(), true)->value = data; | 3152 Lookup(key, key->Hash(), true, ZoneAllocationPolicy(zone))->value = data; |
3148 } | 3153 } |
3149 | 3154 |
3150 void Delete(BoundsCheckKey* key) { | 3155 void Delete(BoundsCheckKey* key) { |
3151 Remove(key, key->Hash()); | 3156 Remove(key, key->Hash()); |
3152 } | 3157 } |
3153 | 3158 |
3154 BoundsCheckTable() : ZoneHashMap(BoundsCheckKeyMatch) { } | 3159 explicit BoundsCheckTable(Zone* zone) |
| 3160 : ZoneHashMap(BoundsCheckKeyMatch, ZoneHashMap::kDefaultHashMapCapacity, |
| 3161 ZoneAllocationPolicy(zone)) { } |
3155 }; | 3162 }; |
3156 | 3163 |
3157 | 3164 |
3158 // Eliminates checks in bb and recursively in the dominated blocks. | 3165 // Eliminates checks in bb and recursively in the dominated blocks. |
3159 // Also replace the results of check instructions with the original value, if | 3166 // Also replace the results of check instructions with the original value, if |
3160 // the result is used. This is safe now, since we don't do code motion after | 3167 // the result is used. This is safe now, since we don't do code motion after |
3161 // this point. It enables better register allocation since the value produced | 3168 // this point. It enables better register allocation since the value produced |
3162 // by check instructions is really a copy of the original value. | 3169 // by check instructions is really a copy of the original value. |
3163 void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, | 3170 void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, |
3164 BoundsCheckTable* table) { | 3171 BoundsCheckTable* table) { |
3165 BoundsCheckBbData* bb_data_list = NULL; | 3172 BoundsCheckBbData* bb_data_list = NULL; |
3166 | 3173 |
3167 for (HInstruction* i = bb->first(); i != NULL; i = i->next()) { | 3174 for (HInstruction* i = bb->first(); i != NULL; i = i->next()) { |
3168 if (!i->IsBoundsCheck()) continue; | 3175 if (!i->IsBoundsCheck()) continue; |
3169 | 3176 |
3170 HBoundsCheck* check = HBoundsCheck::cast(i); | 3177 HBoundsCheck* check = HBoundsCheck::cast(i); |
3171 check->ReplaceAllUsesWith(check->index()); | 3178 check->ReplaceAllUsesWith(check->index()); |
3172 | 3179 |
3173 if (!FLAG_array_bounds_checks_elimination) continue; | 3180 if (!FLAG_array_bounds_checks_elimination) continue; |
3174 | 3181 |
3175 int32_t offset; | 3182 int32_t offset; |
3176 BoundsCheckKey* key = | 3183 BoundsCheckKey* key = |
3177 BoundsCheckKey::Create(bb->zone(), check, &offset); | 3184 BoundsCheckKey::Create(zone(), check, &offset); |
3178 BoundsCheckBbData** data_p = table->LookupOrInsert(key); | 3185 BoundsCheckBbData** data_p = table->LookupOrInsert(key, zone()); |
3179 BoundsCheckBbData* data = *data_p; | 3186 BoundsCheckBbData* data = *data_p; |
3180 if (data == NULL) { | 3187 if (data == NULL) { |
3181 bb_data_list = new(zone()) BoundsCheckBbData(key, | 3188 bb_data_list = new(zone()) BoundsCheckBbData(key, |
3182 offset, | 3189 offset, |
3183 offset, | 3190 offset, |
3184 bb, | 3191 bb, |
3185 check, | 3192 check, |
3186 bb_data_list, | 3193 bb_data_list, |
3187 NULL); | 3194 NULL); |
3188 *data_p = bb_data_list; | 3195 *data_p = bb_data_list; |
3189 } else if (data->OffsetIsCovered(offset)) { | 3196 } else if (data->OffsetIsCovered(offset)) { |
3190 check->DeleteAndReplaceWith(NULL); | 3197 check->DeleteAndReplaceWith(NULL); |
3191 } else if (data->BasicBlock() == bb) { | 3198 } else if (data->BasicBlock() == bb) { |
3192 data->CoverCheck(check, offset); | 3199 data->CoverCheck(check, offset); |
3193 } else { | 3200 } else { |
3194 int32_t new_lower_offset = offset < data->LowerOffset() | 3201 int32_t new_lower_offset = offset < data->LowerOffset() |
3195 ? offset | 3202 ? offset |
3196 : data->LowerOffset(); | 3203 : data->LowerOffset(); |
3197 int32_t new_upper_offset = offset > data->UpperOffset() | 3204 int32_t new_upper_offset = offset > data->UpperOffset() |
3198 ? offset | 3205 ? offset |
3199 : data->UpperOffset(); | 3206 : data->UpperOffset(); |
3200 bb_data_list = new(bb->zone()) BoundsCheckBbData(key, | 3207 bb_data_list = new(zone()) BoundsCheckBbData(key, |
3201 new_lower_offset, | 3208 new_lower_offset, |
3202 new_upper_offset, | 3209 new_upper_offset, |
3203 bb, | 3210 bb, |
3204 check, | 3211 check, |
3205 bb_data_list, | 3212 bb_data_list, |
3206 data); | 3213 data); |
3207 table->Insert(key, bb_data_list); | 3214 table->Insert(key, bb_data_list, zone()); |
3208 } | 3215 } |
3209 } | 3216 } |
3210 | 3217 |
3211 for (int i = 0; i < bb->dominated_blocks()->length(); ++i) { | 3218 for (int i = 0; i < bb->dominated_blocks()->length(); ++i) { |
3212 EliminateRedundantBoundsChecks(bb->dominated_blocks()->at(i), table); | 3219 EliminateRedundantBoundsChecks(bb->dominated_blocks()->at(i), table); |
3213 } | 3220 } |
3214 | 3221 |
3215 for (BoundsCheckBbData* data = bb_data_list; | 3222 for (BoundsCheckBbData* data = bb_data_list; |
3216 data != NULL; | 3223 data != NULL; |
3217 data = data->NextInBasicBlock()) { | 3224 data = data->NextInBasicBlock()) { |
3218 data->RemoveZeroOperations(); | 3225 data->RemoveZeroOperations(); |
3219 if (data->FatherInDominatorTree()) { | 3226 if (data->FatherInDominatorTree()) { |
3220 table->Insert(data->Key(), data->FatherInDominatorTree()); | 3227 table->Insert(data->Key(), data->FatherInDominatorTree(), zone()); |
3221 } else { | 3228 } else { |
3222 table->Delete(data->Key()); | 3229 table->Delete(data->Key()); |
3223 } | 3230 } |
3224 } | 3231 } |
3225 } | 3232 } |
3226 | 3233 |
3227 | 3234 |
3228 void HGraph::EliminateRedundantBoundsChecks() { | 3235 void HGraph::EliminateRedundantBoundsChecks() { |
3229 HPhase phase("H_Eliminate bounds checks", this); | 3236 HPhase phase("H_Eliminate bounds checks", this); |
3230 AssertNoAllocation no_gc; | 3237 AssertNoAllocation no_gc; |
3231 BoundsCheckTable checks_table; | 3238 BoundsCheckTable checks_table(zone()); |
3232 EliminateRedundantBoundsChecks(entry_block(), &checks_table); | 3239 EliminateRedundantBoundsChecks(entry_block(), &checks_table); |
3233 } | 3240 } |
3234 | 3241 |
3235 | 3242 |
3236 static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) { | 3243 static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) { |
3237 HValue* index = array_operation->GetKey(); | 3244 HValue* index = array_operation->GetKey(); |
3238 | 3245 |
3239 HConstant* constant; | 3246 HConstant* constant; |
3240 HValue* subexpression; | 3247 HValue* subexpression; |
3241 int32_t sign; | 3248 int32_t sign; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3341 | 3348 |
3342 void HGraphBuilder::PushAndAdd(HInstruction* instr) { | 3349 void HGraphBuilder::PushAndAdd(HInstruction* instr) { |
3343 Push(instr); | 3350 Push(instr); |
3344 AddInstruction(instr); | 3351 AddInstruction(instr); |
3345 } | 3352 } |
3346 | 3353 |
3347 | 3354 |
3348 template <class Instruction> | 3355 template <class Instruction> |
3349 HInstruction* HGraphBuilder::PreProcessCall(Instruction* call) { | 3356 HInstruction* HGraphBuilder::PreProcessCall(Instruction* call) { |
3350 int count = call->argument_count(); | 3357 int count = call->argument_count(); |
3351 ZoneList<HValue*> arguments(count); | 3358 ZoneList<HValue*> arguments(count, zone()); |
3352 for (int i = 0; i < count; ++i) { | 3359 for (int i = 0; i < count; ++i) { |
3353 arguments.Add(Pop()); | 3360 arguments.Add(Pop(), zone()); |
3354 } | 3361 } |
3355 | 3362 |
3356 while (!arguments.is_empty()) { | 3363 while (!arguments.is_empty()) { |
3357 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); | 3364 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); |
3358 } | 3365 } |
3359 return call; | 3366 return call; |
3360 } | 3367 } |
3361 | 3368 |
3362 | 3369 |
3363 void HGraphBuilder::SetUpScope(Scope* scope) { | 3370 void HGraphBuilder::SetUpScope(Scope* scope) { |
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3843 current_block()->Finish(test); | 3850 current_block()->Finish(test); |
3844 | 3851 |
3845 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); | 3852 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); |
3846 non_osr_entry->Goto(loop_predecessor); | 3853 non_osr_entry->Goto(loop_predecessor); |
3847 | 3854 |
3848 set_current_block(osr_entry); | 3855 set_current_block(osr_entry); |
3849 int osr_entry_id = statement->OsrEntryId(); | 3856 int osr_entry_id = statement->OsrEntryId(); |
3850 int first_expression_index = environment()->first_expression_index(); | 3857 int first_expression_index = environment()->first_expression_index(); |
3851 int length = environment()->length(); | 3858 int length = environment()->length(); |
3852 ZoneList<HUnknownOSRValue*>* osr_values = | 3859 ZoneList<HUnknownOSRValue*>* osr_values = |
3853 new(zone()) ZoneList<HUnknownOSRValue*>(length); | 3860 new(zone()) ZoneList<HUnknownOSRValue*>(length, zone()); |
3854 | 3861 |
3855 for (int i = 0; i < first_expression_index; ++i) { | 3862 for (int i = 0; i < first_expression_index; ++i) { |
3856 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 3863 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; |
3857 AddInstruction(osr_value); | 3864 AddInstruction(osr_value); |
3858 environment()->Bind(i, osr_value); | 3865 environment()->Bind(i, osr_value); |
3859 osr_values->Add(osr_value); | 3866 osr_values->Add(osr_value, zone()); |
3860 } | 3867 } |
3861 | 3868 |
3862 if (first_expression_index != length) { | 3869 if (first_expression_index != length) { |
3863 environment()->Drop(length - first_expression_index); | 3870 environment()->Drop(length - first_expression_index); |
3864 for (int i = first_expression_index; i < length; ++i) { | 3871 for (int i = first_expression_index; i < length; ++i) { |
3865 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 3872 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; |
3866 AddInstruction(osr_value); | 3873 AddInstruction(osr_value); |
3867 environment()->Push(osr_value); | 3874 environment()->Push(osr_value); |
3868 osr_values->Add(osr_value); | 3875 osr_values->Add(osr_value, zone()); |
3869 } | 3876 } |
3870 } | 3877 } |
3871 | 3878 |
3872 graph()->set_osr_values(osr_values); | 3879 graph()->set_osr_values(osr_values); |
3873 | 3880 |
3874 AddSimulate(osr_entry_id); | 3881 AddSimulate(osr_entry_id); |
3875 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); | 3882 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); |
3876 HContext* context = new(zone()) HContext; | 3883 HContext* context = new(zone()) HContext; |
3877 AddInstruction(context); | 3884 AddInstruction(context); |
3878 environment()->BindContext(context); | 3885 environment()->BindContext(context); |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4486 expr->fast_elements(), | 4493 expr->fast_elements(), |
4487 expr->literal_index(), | 4494 expr->literal_index(), |
4488 expr->depth(), | 4495 expr->depth(), |
4489 expr->has_function()); | 4496 expr->has_function()); |
4490 } | 4497 } |
4491 | 4498 |
4492 // The object is expected in the bailout environment during computation | 4499 // The object is expected in the bailout environment during computation |
4493 // of the property values and is the value of the entire expression. | 4500 // of the property values and is the value of the entire expression. |
4494 PushAndAdd(literal); | 4501 PushAndAdd(literal); |
4495 | 4502 |
4496 expr->CalculateEmitStore(); | 4503 expr->CalculateEmitStore(zone()); |
4497 | 4504 |
4498 for (int i = 0; i < expr->properties()->length(); i++) { | 4505 for (int i = 0; i < expr->properties()->length(); i++) { |
4499 ObjectLiteral::Property* property = expr->properties()->at(i); | 4506 ObjectLiteral::Property* property = expr->properties()->at(i); |
4500 if (property->IsCompileTimeValue()) continue; | 4507 if (property->IsCompileTimeValue()) continue; |
4501 | 4508 |
4502 Literal* key = property->key(); | 4509 Literal* key = property->key(); |
4503 Expression* value = property->value(); | 4510 Expression* value = property->value(); |
4504 | 4511 |
4505 switch (property->kind()) { | 4512 switch (property->kind()) { |
4506 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 4513 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4676 | 4683 |
4677 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, | 4684 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, |
4678 Handle<String> name, | 4685 Handle<String> name, |
4679 HValue* value, | 4686 HValue* value, |
4680 Handle<Map> type, | 4687 Handle<Map> type, |
4681 LookupResult* lookup, | 4688 LookupResult* lookup, |
4682 bool smi_and_map_check) { | 4689 bool smi_and_map_check) { |
4683 ASSERT(lookup->IsFound()); | 4690 ASSERT(lookup->IsFound()); |
4684 if (smi_and_map_check) { | 4691 if (smi_and_map_check) { |
4685 AddInstruction(new(zone()) HCheckNonSmi(object)); | 4692 AddInstruction(new(zone()) HCheckNonSmi(object)); |
4686 AddInstruction(HCheckMaps::NewWithTransitions(object, type)); | 4693 AddInstruction(HCheckMaps::NewWithTransitions(object, type, zone())); |
4687 } | 4694 } |
4688 | 4695 |
4689 // If the property does not exist yet, we have to check that it wasn't made | 4696 // If the property does not exist yet, we have to check that it wasn't made |
4690 // readonly or turned into a setter by some meanwhile modifications on the | 4697 // readonly or turned into a setter by some meanwhile modifications on the |
4691 // prototype chain. | 4698 // prototype chain. |
4692 if (!lookup->IsProperty()) { | 4699 if (!lookup->IsProperty()) { |
4693 Object* proto = type->prototype(); | 4700 Object* proto = type->prototype(); |
4694 // First check that the prototype chain isn't affected already. | 4701 // First check that the prototype chain isn't affected already. |
4695 LookupResult proto_result(isolate()); | 4702 LookupResult proto_result(isolate()); |
4696 proto->Lookup(*name, &proto_result); | 4703 proto->Lookup(*name, &proto_result); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4821 (is_in_object == previous_field_is_in_object); | 4828 (is_in_object == previous_field_is_in_object); |
4822 } | 4829 } |
4823 ++count; | 4830 ++count; |
4824 } | 4831 } |
4825 } | 4832 } |
4826 | 4833 |
4827 // Use monomorphic load if property lookup results in the same field index | 4834 // Use monomorphic load if property lookup results in the same field index |
4828 // for all maps. Requires special map check on the set of all handled maps. | 4835 // for all maps. Requires special map check on the set of all handled maps. |
4829 HInstruction* instr; | 4836 HInstruction* instr; |
4830 if (count == types->length() && is_monomorphic_field) { | 4837 if (count == types->length() && is_monomorphic_field) { |
4831 AddInstruction(new(zone()) HCheckMaps(object, types)); | 4838 AddInstruction(new(zone()) HCheckMaps(object, types, zone())); |
4832 instr = BuildLoadNamedField(object, expr, map, &lookup, false); | 4839 instr = BuildLoadNamedField(object, expr, map, &lookup, false); |
4833 } else { | 4840 } else { |
4834 HValue* context = environment()->LookupContext(); | 4841 HValue* context = environment()->LookupContext(); |
4835 instr = new(zone()) HLoadNamedFieldPolymorphic(context, | 4842 instr = new(zone()) HLoadNamedFieldPolymorphic(context, |
4836 object, | 4843 object, |
4837 types, | 4844 types, |
4838 name); | 4845 name, |
| 4846 zone()); |
4839 } | 4847 } |
4840 | 4848 |
4841 instr->set_position(expr->position()); | 4849 instr->set_position(expr->position()); |
4842 return ast_context()->ReturnInstruction(instr, expr->id()); | 4850 return ast_context()->ReturnInstruction(instr, expr->id()); |
4843 } | 4851 } |
4844 | 4852 |
4845 | 4853 |
4846 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, | 4854 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, |
4847 HValue* object, | 4855 HValue* object, |
4848 HValue* value, | 4856 HValue* value, |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4915 ASSERT(join != NULL); | 4923 ASSERT(join != NULL); |
4916 join->SetJoinId(expr->id()); | 4924 join->SetJoinId(expr->id()); |
4917 set_current_block(join); | 4925 set_current_block(join); |
4918 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); | 4926 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); |
4919 } | 4927 } |
4920 | 4928 |
4921 | 4929 |
4922 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { | 4930 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { |
4923 Property* prop = expr->target()->AsProperty(); | 4931 Property* prop = expr->target()->AsProperty(); |
4924 ASSERT(prop != NULL); | 4932 ASSERT(prop != NULL); |
4925 expr->RecordTypeFeedback(oracle()); | 4933 expr->RecordTypeFeedback(oracle(), zone()); |
4926 CHECK_ALIVE(VisitForValue(prop->obj())); | 4934 CHECK_ALIVE(VisitForValue(prop->obj())); |
4927 | 4935 |
4928 HValue* value = NULL; | 4936 HValue* value = NULL; |
4929 HInstruction* instr = NULL; | 4937 HInstruction* instr = NULL; |
4930 | 4938 |
4931 if (prop->key()->IsPropertyName()) { | 4939 if (prop->key()->IsPropertyName()) { |
4932 // Named store. | 4940 // Named store. |
4933 CHECK_ALIVE(VisitForValue(expr->value())); | 4941 CHECK_ALIVE(VisitForValue(expr->value())); |
4934 value = Pop(); | 4942 value = Pop(); |
4935 HValue* object = Pop(); | 4943 HValue* object = Pop(); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5086 } | 5094 } |
5087 break; | 5095 break; |
5088 } | 5096 } |
5089 | 5097 |
5090 case Variable::LOOKUP: | 5098 case Variable::LOOKUP: |
5091 return Bailout("compound assignment to lookup slot"); | 5099 return Bailout("compound assignment to lookup slot"); |
5092 } | 5100 } |
5093 return ast_context()->ReturnValue(Pop()); | 5101 return ast_context()->ReturnValue(Pop()); |
5094 | 5102 |
5095 } else if (prop != NULL) { | 5103 } else if (prop != NULL) { |
5096 prop->RecordTypeFeedback(oracle()); | 5104 prop->RecordTypeFeedback(oracle(), zone()); |
5097 | 5105 |
5098 if (prop->key()->IsPropertyName()) { | 5106 if (prop->key()->IsPropertyName()) { |
5099 // Named property. | 5107 // Named property. |
5100 CHECK_ALIVE(VisitForValue(prop->obj())); | 5108 CHECK_ALIVE(VisitForValue(prop->obj())); |
5101 HValue* obj = Top(); | 5109 HValue* obj = Top(); |
5102 | 5110 |
5103 HInstruction* load = NULL; | 5111 HInstruction* load = NULL; |
5104 if (prop->IsMonomorphic()) { | 5112 if (prop->IsMonomorphic()) { |
5105 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 5113 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
5106 Handle<Map> map = prop->GetReceiverTypes()->first(); | 5114 Handle<Map> map = prop->GetReceiverTypes()->first(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5145 | 5153 |
5146 | 5154 |
5147 CHECK_ALIVE(VisitForValue(expr->value())); | 5155 CHECK_ALIVE(VisitForValue(expr->value())); |
5148 HValue* right = Pop(); | 5156 HValue* right = Pop(); |
5149 HValue* left = Pop(); | 5157 HValue* left = Pop(); |
5150 | 5158 |
5151 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 5159 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
5152 PushAndAdd(instr); | 5160 PushAndAdd(instr); |
5153 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); | 5161 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); |
5154 | 5162 |
5155 expr->RecordTypeFeedback(oracle()); | 5163 expr->RecordTypeFeedback(oracle(), zone()); |
5156 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), | 5164 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), |
5157 RelocInfo::kNoPosition, | 5165 RelocInfo::kNoPosition, |
5158 true, // is_store | 5166 true, // is_store |
5159 &has_side_effects); | 5167 &has_side_effects); |
5160 | 5168 |
5161 // Drop the simulated receiver, key, and value. Return the value. | 5169 // Drop the simulated receiver, key, and value. Return the value. |
5162 Drop(3); | 5170 Drop(3); |
5163 Push(instr); | 5171 Push(instr); |
5164 ASSERT(has_side_effects); // Stores always have side effects. | 5172 ASSERT(has_side_effects); // Stores always have side effects. |
5165 AddSimulate(expr->AssignmentId()); | 5173 AddSimulate(expr->AssignmentId()); |
(...skipping 27 matching lines...) Expand all Loading... |
5193 if (var->mode() == CONST) { | 5201 if (var->mode() == CONST) { |
5194 if (expr->op() != Token::INIT_CONST) { | 5202 if (expr->op() != Token::INIT_CONST) { |
5195 CHECK_ALIVE(VisitForValue(expr->value())); | 5203 CHECK_ALIVE(VisitForValue(expr->value())); |
5196 return ast_context()->ReturnValue(Pop()); | 5204 return ast_context()->ReturnValue(Pop()); |
5197 } | 5205 } |
5198 | 5206 |
5199 if (var->IsStackAllocated()) { | 5207 if (var->IsStackAllocated()) { |
5200 // We insert a use of the old value to detect unsupported uses of const | 5208 // We insert a use of the old value to detect unsupported uses of const |
5201 // variables (e.g. initialization inside a loop). | 5209 // variables (e.g. initialization inside a loop). |
5202 HValue* old_value = environment()->Lookup(var); | 5210 HValue* old_value = environment()->Lookup(var); |
5203 AddInstruction(new HUseConst(old_value)); | 5211 AddInstruction(new(zone()) HUseConst(old_value)); |
5204 } | 5212 } |
5205 } else if (var->mode() == CONST_HARMONY) { | 5213 } else if (var->mode() == CONST_HARMONY) { |
5206 if (expr->op() != Token::INIT_CONST_HARMONY) { | 5214 if (expr->op() != Token::INIT_CONST_HARMONY) { |
5207 return Bailout("non-initializer assignment to const"); | 5215 return Bailout("non-initializer assignment to const"); |
5208 } | 5216 } |
5209 } | 5217 } |
5210 | 5218 |
5211 if (proxy->IsArguments()) return Bailout("assignment to arguments"); | 5219 if (proxy->IsArguments()) return Bailout("assignment to arguments"); |
5212 | 5220 |
5213 // Handle the assignment. | 5221 // Handle the assignment. |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5320 } | 5328 } |
5321 | 5329 |
5322 | 5330 |
5323 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, | 5331 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, |
5324 Property* expr, | 5332 Property* expr, |
5325 Handle<Map> type, | 5333 Handle<Map> type, |
5326 LookupResult* lookup, | 5334 LookupResult* lookup, |
5327 bool smi_and_map_check) { | 5335 bool smi_and_map_check) { |
5328 if (smi_and_map_check) { | 5336 if (smi_and_map_check) { |
5329 AddInstruction(new(zone()) HCheckNonSmi(object)); | 5337 AddInstruction(new(zone()) HCheckNonSmi(object)); |
5330 AddInstruction(HCheckMaps::NewWithTransitions(object, type)); | 5338 AddInstruction(HCheckMaps::NewWithTransitions(object, type, zone())); |
5331 } | 5339 } |
5332 | 5340 |
5333 int index = lookup->GetLocalFieldIndexFromMap(*type); | 5341 int index = lookup->GetLocalFieldIndexFromMap(*type); |
5334 if (index < 0) { | 5342 if (index < 0) { |
5335 // Negative property indices are in-object properties, indexed | 5343 // Negative property indices are in-object properties, indexed |
5336 // from the end of the fixed part of the object. | 5344 // from the end of the fixed part of the object. |
5337 int offset = (index * kPointerSize) + type->instance_size(); | 5345 int offset = (index * kPointerSize) + type->instance_size(); |
5338 return new(zone()) HLoadNamedField(object, true, offset); | 5346 return new(zone()) HLoadNamedField(object, true, offset); |
5339 } else { | 5347 } else { |
5340 // Non-negative property indices are in the properties array. | 5348 // Non-negative property indices are in the properties array. |
(...skipping 23 matching lines...) Expand all Loading... |
5364 LookupResult lookup(isolate()); | 5372 LookupResult lookup(isolate()); |
5365 map->LookupInDescriptors(NULL, *name, &lookup); | 5373 map->LookupInDescriptors(NULL, *name, &lookup); |
5366 if (lookup.IsFound() && lookup.type() == FIELD) { | 5374 if (lookup.IsFound() && lookup.type() == FIELD) { |
5367 return BuildLoadNamedField(obj, | 5375 return BuildLoadNamedField(obj, |
5368 expr, | 5376 expr, |
5369 map, | 5377 map, |
5370 &lookup, | 5378 &lookup, |
5371 true); | 5379 true); |
5372 } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) { | 5380 } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) { |
5373 AddInstruction(new(zone()) HCheckNonSmi(obj)); | 5381 AddInstruction(new(zone()) HCheckNonSmi(obj)); |
5374 AddInstruction(HCheckMaps::NewWithTransitions(obj, map)); | 5382 AddInstruction(HCheckMaps::NewWithTransitions(obj, map, zone())); |
5375 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); | 5383 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); |
5376 return new(zone()) HConstant(function, Representation::Tagged()); | 5384 return new(zone()) HConstant(function, Representation::Tagged()); |
5377 } else { | 5385 } else { |
5378 return BuildLoadNamedGeneric(obj, expr); | 5386 return BuildLoadNamedGeneric(obj, expr); |
5379 } | 5387 } |
5380 } | 5388 } |
5381 | 5389 |
5382 | 5390 |
5383 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 5391 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
5384 HValue* key) { | 5392 HValue* key) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5477 } | 5485 } |
5478 | 5486 |
5479 | 5487 |
5480 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, | 5488 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, |
5481 HValue* key, | 5489 HValue* key, |
5482 HValue* val, | 5490 HValue* val, |
5483 HValue* dependency, | 5491 HValue* dependency, |
5484 Handle<Map> map, | 5492 Handle<Map> map, |
5485 bool is_store) { | 5493 bool is_store) { |
5486 HInstruction* mapcheck = | 5494 HInstruction* mapcheck = |
5487 AddInstruction(new(zone()) HCheckMaps(object, map, dependency)); | 5495 AddInstruction(new(zone()) HCheckMaps(object, map, zone(), dependency)); |
5488 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency | 5496 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency |
5489 // on a HElementsTransition instruction. The flag can also be removed if the | 5497 // on a HElementsTransition instruction. The flag can also be removed if the |
5490 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further | 5498 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further |
5491 // ElementsKind transitions. Finally, the dependency can be removed for stores | 5499 // ElementsKind transitions. Finally, the dependency can be removed for stores |
5492 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the | 5500 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the |
5493 // generated store code. | 5501 // generated store code. |
5494 if (dependency || | 5502 if (dependency || |
5495 (map->elements_kind() == FAST_HOLEY_ELEMENTS) || | 5503 (map->elements_kind() == FAST_HOLEY_ELEMENTS) || |
5496 (map->elements_kind() == FAST_ELEMENTS && is_store)) { | 5504 (map->elements_kind() == FAST_ELEMENTS && is_store)) { |
5497 mapcheck->ClearGVNFlag(kDependsOnElementsKind); | 5505 mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
5498 } | 5506 } |
5499 bool fast_smi_only_elements = map->has_fast_smi_elements(); | 5507 bool fast_smi_only_elements = map->has_fast_smi_elements(); |
5500 bool fast_elements = map->has_fast_object_elements(); | 5508 bool fast_elements = map->has_fast_object_elements(); |
5501 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); | 5509 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); |
5502 if (is_store && (fast_elements || fast_smi_only_elements)) { | 5510 if (is_store && (fast_elements || fast_smi_only_elements)) { |
5503 HCheckMaps* check_cow_map = new(zone()) HCheckMaps( | 5511 HCheckMaps* check_cow_map = new(zone()) HCheckMaps( |
5504 elements, isolate()->factory()->fixed_array_map()); | 5512 elements, isolate()->factory()->fixed_array_map(), zone()); |
5505 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 5513 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
5506 AddInstruction(check_cow_map); | 5514 AddInstruction(check_cow_map); |
5507 } | 5515 } |
5508 HInstruction* length = NULL; | 5516 HInstruction* length = NULL; |
5509 HInstruction* checked_key = NULL; | 5517 HInstruction* checked_key = NULL; |
5510 if (map->has_external_array_elements()) { | 5518 if (map->has_external_array_elements()) { |
5511 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 5519 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
5512 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 5520 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
5513 HLoadExternalArrayPointer* external_elements = | 5521 HLoadExternalArrayPointer* external_elements = |
5514 new(zone()) HLoadExternalArrayPointer(elements); | 5522 new(zone()) HLoadExternalArrayPointer(elements); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5601 : BuildLoadKeyedGeneric(object, key)); | 5609 : BuildLoadKeyedGeneric(object, key)); |
5602 } else { | 5610 } else { |
5603 instr = AddInstruction(BuildMonomorphicElementAccess( | 5611 instr = AddInstruction(BuildMonomorphicElementAccess( |
5604 object, key, val, transition, untransitionable_map, is_store)); | 5612 object, key, val, transition, untransitionable_map, is_store)); |
5605 } | 5613 } |
5606 *has_side_effects |= instr->HasObservableSideEffects(); | 5614 *has_side_effects |= instr->HasObservableSideEffects(); |
5607 instr->set_position(position); | 5615 instr->set_position(position); |
5608 return is_store ? NULL : instr; | 5616 return is_store ? NULL : instr; |
5609 } | 5617 } |
5610 | 5618 |
5611 AddInstruction(HCheckInstanceType::NewIsSpecObject(object)); | 5619 AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone())); |
5612 HBasicBlock* join = graph()->CreateBasicBlock(); | 5620 HBasicBlock* join = graph()->CreateBasicBlock(); |
5613 | 5621 |
5614 HInstruction* elements_kind_instr = | 5622 HInstruction* elements_kind_instr = |
5615 AddInstruction(new(zone()) HElementsKind(object)); | 5623 AddInstruction(new(zone()) HElementsKind(object)); |
5616 HCompareConstantEqAndBranch* elements_kind_branch = NULL; | 5624 HCompareConstantEqAndBranch* elements_kind_branch = NULL; |
5617 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); | 5625 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); |
5618 HLoadExternalArrayPointer* external_elements = NULL; | 5626 HLoadExternalArrayPointer* external_elements = NULL; |
5619 HInstruction* checked_key = NULL; | 5627 HInstruction* checked_key = NULL; |
5620 | 5628 |
5621 // Generated code assumes that FAST_* and DICTIONARY_ELEMENTS ElementsKinds | 5629 // Generated code assumes that FAST_* and DICTIONARY_ELEMENTS ElementsKinds |
(...skipping 26 matching lines...) Expand all Loading... |
5648 elements_kind_branch->SetSuccessorAt(0, if_true); | 5656 elements_kind_branch->SetSuccessorAt(0, if_true); |
5649 elements_kind_branch->SetSuccessorAt(1, if_false); | 5657 elements_kind_branch->SetSuccessorAt(1, if_false); |
5650 current_block()->Finish(elements_kind_branch); | 5658 current_block()->Finish(elements_kind_branch); |
5651 | 5659 |
5652 set_current_block(if_true); | 5660 set_current_block(if_true); |
5653 HInstruction* access; | 5661 HInstruction* access; |
5654 if (IsFastElementsKind(elements_kind)) { | 5662 if (IsFastElementsKind(elements_kind)) { |
5655 if (is_store && !IsFastDoubleElementsKind(elements_kind)) { | 5663 if (is_store && !IsFastDoubleElementsKind(elements_kind)) { |
5656 AddInstruction(new(zone()) HCheckMaps( | 5664 AddInstruction(new(zone()) HCheckMaps( |
5657 elements, isolate()->factory()->fixed_array_map(), | 5665 elements, isolate()->factory()->fixed_array_map(), |
5658 elements_kind_branch)); | 5666 zone(), elements_kind_branch)); |
5659 } | 5667 } |
5660 // TODO(jkummerow): The need for these two blocks could be avoided | 5668 // TODO(jkummerow): The need for these two blocks could be avoided |
5661 // in one of two ways: | 5669 // in one of two ways: |
5662 // (1) Introduce ElementsKinds for JSArrays that are distinct from | 5670 // (1) Introduce ElementsKinds for JSArrays that are distinct from |
5663 // those for fast objects. | 5671 // those for fast objects. |
5664 // (2) Put the common instructions into a third "join" block. This | 5672 // (2) Put the common instructions into a third "join" block. This |
5665 // requires additional AST IDs that we can deopt to from inside | 5673 // requires additional AST IDs that we can deopt to from inside |
5666 // that join block. They must be added to the Property class (when | 5674 // that join block. They must be added to the Property class (when |
5667 // it's a keyed property) and registered in the full codegen. | 5675 // it's a keyed property) and registered in the full codegen. |
5668 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); | 5676 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5855 } | 5863 } |
5856 ast_context()->ReturnInstruction(result, expr->id()); | 5864 ast_context()->ReturnInstruction(result, expr->id()); |
5857 return true; | 5865 return true; |
5858 } | 5866 } |
5859 | 5867 |
5860 | 5868 |
5861 void HGraphBuilder::VisitProperty(Property* expr) { | 5869 void HGraphBuilder::VisitProperty(Property* expr) { |
5862 ASSERT(!HasStackOverflow()); | 5870 ASSERT(!HasStackOverflow()); |
5863 ASSERT(current_block() != NULL); | 5871 ASSERT(current_block() != NULL); |
5864 ASSERT(current_block()->HasPredecessor()); | 5872 ASSERT(current_block()->HasPredecessor()); |
5865 expr->RecordTypeFeedback(oracle()); | 5873 expr->RecordTypeFeedback(oracle(), zone()); |
5866 | 5874 |
5867 if (TryArgumentsAccess(expr)) return; | 5875 if (TryArgumentsAccess(expr)) return; |
5868 | 5876 |
5869 CHECK_ALIVE(VisitForValue(expr->obj())); | 5877 CHECK_ALIVE(VisitForValue(expr->obj())); |
5870 | 5878 |
5871 HInstruction* instr = NULL; | 5879 HInstruction* instr = NULL; |
5872 if (expr->AsProperty()->IsArrayLength()) { | 5880 if (expr->AsProperty()->IsArrayLength()) { |
5873 HValue* array = Pop(); | 5881 HValue* array = Pop(); |
5874 AddInstruction(new(zone()) HCheckNonSmi(array)); | 5882 AddInstruction(new(zone()) HCheckNonSmi(array)); |
5875 HInstruction* mapcheck = | 5883 HInstruction* mapcheck = |
5876 AddInstruction(HCheckInstanceType::NewIsJSArray(array)); | 5884 AddInstruction(HCheckInstanceType::NewIsJSArray(array, zone())); |
5877 instr = new(zone()) HJSArrayLength(array, mapcheck); | 5885 instr = new(zone()) HJSArrayLength(array, mapcheck); |
5878 | 5886 |
5879 } else if (expr->IsStringLength()) { | 5887 } else if (expr->IsStringLength()) { |
5880 HValue* string = Pop(); | 5888 HValue* string = Pop(); |
5881 AddInstruction(new(zone()) HCheckNonSmi(string)); | 5889 AddInstruction(new(zone()) HCheckNonSmi(string)); |
5882 AddInstruction(HCheckInstanceType::NewIsString(string)); | 5890 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
5883 instr = new(zone()) HStringLength(string); | 5891 instr = new(zone()) HStringLength(string); |
5884 } else if (expr->IsStringAccess()) { | 5892 } else if (expr->IsStringAccess()) { |
5885 CHECK_ALIVE(VisitForValue(expr->key())); | 5893 CHECK_ALIVE(VisitForValue(expr->key())); |
5886 HValue* index = Pop(); | 5894 HValue* index = Pop(); |
5887 HValue* string = Pop(); | 5895 HValue* string = Pop(); |
5888 HValue* context = environment()->LookupContext(); | 5896 HValue* context = environment()->LookupContext(); |
5889 HStringCharCodeAt* char_code = | 5897 HStringCharCodeAt* char_code = |
5890 BuildStringCharCodeAt(context, string, index); | 5898 BuildStringCharCodeAt(context, string, index); |
5891 AddInstruction(char_code); | 5899 AddInstruction(char_code); |
5892 instr = new(zone()) HStringCharFromCode(context, char_code); | 5900 instr = new(zone()) HStringCharFromCode(context, char_code); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5940 | 5948 |
5941 void HGraphBuilder::AddCheckConstantFunction(Call* expr, | 5949 void HGraphBuilder::AddCheckConstantFunction(Call* expr, |
5942 HValue* receiver, | 5950 HValue* receiver, |
5943 Handle<Map> receiver_map, | 5951 Handle<Map> receiver_map, |
5944 bool smi_and_map_check) { | 5952 bool smi_and_map_check) { |
5945 // Constant functions have the nice property that the map will change if they | 5953 // Constant functions have the nice property that the map will change if they |
5946 // are overwritten. Therefore it is enough to check the map of the holder and | 5954 // are overwritten. Therefore it is enough to check the map of the holder and |
5947 // its prototypes. | 5955 // its prototypes. |
5948 if (smi_and_map_check) { | 5956 if (smi_and_map_check) { |
5949 AddInstruction(new(zone()) HCheckNonSmi(receiver)); | 5957 AddInstruction(new(zone()) HCheckNonSmi(receiver)); |
5950 AddInstruction(HCheckMaps::NewWithTransitions(receiver, receiver_map)); | 5958 AddInstruction(HCheckMaps::NewWithTransitions(receiver, receiver_map, |
| 5959 zone())); |
5951 } | 5960 } |
5952 if (!expr->holder().is_null()) { | 5961 if (!expr->holder().is_null()) { |
5953 AddInstruction(new(zone()) HCheckPrototypeMaps( | 5962 AddInstruction(new(zone()) HCheckPrototypeMaps( |
5954 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), | 5963 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), |
5955 expr->holder())); | 5964 expr->holder())); |
5956 } | 5965 } |
5957 } | 5966 } |
5958 | 5967 |
5959 | 5968 |
5960 class FunctionSorter { | 5969 class FunctionSorter { |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6275 // generating the optimized inline code. | 6284 // generating the optimized inline code. |
6276 target_info.EnableDeoptimizationSupport(); | 6285 target_info.EnableDeoptimizationSupport(); |
6277 if (!FullCodeGenerator::MakeCode(&target_info)) { | 6286 if (!FullCodeGenerator::MakeCode(&target_info)) { |
6278 TraceInline(target, caller, "could not generate deoptimization info"); | 6287 TraceInline(target, caller, "could not generate deoptimization info"); |
6279 return false; | 6288 return false; |
6280 } | 6289 } |
6281 if (target_shared->scope_info() == ScopeInfo::Empty()) { | 6290 if (target_shared->scope_info() == ScopeInfo::Empty()) { |
6282 // The scope info might not have been set if a lazily compiled | 6291 // The scope info might not have been set if a lazily compiled |
6283 // function is inlined before being called for the first time. | 6292 // function is inlined before being called for the first time. |
6284 Handle<ScopeInfo> target_scope_info = | 6293 Handle<ScopeInfo> target_scope_info = |
6285 ScopeInfo::Create(target_info.scope()); | 6294 ScopeInfo::Create(target_info.scope(), zone()); |
6286 target_shared->set_scope_info(*target_scope_info); | 6295 target_shared->set_scope_info(*target_scope_info); |
6287 } | 6296 } |
6288 target_shared->EnableDeoptimizationSupport(*target_info.code()); | 6297 target_shared->EnableDeoptimizationSupport(*target_info.code()); |
6289 Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG, | 6298 Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG, |
6290 &target_info, | 6299 &target_info, |
6291 target_shared); | 6300 target_shared); |
6292 } | 6301 } |
6293 | 6302 |
6294 // ---------------------------------------------------------------- | 6303 // ---------------------------------------------------------------- |
6295 // After this point, we've made a decision to inline this function (so | 6304 // After this point, we've made a decision to inline this function (so |
6296 // TryInline should always return true). | 6305 // TryInline should always return true). |
6297 | 6306 |
6298 // Save the pending call context and type feedback oracle. Set up new ones | 6307 // Save the pending call context and type feedback oracle. Set up new ones |
6299 // for the inlined function. | 6308 // for the inlined function. |
6300 ASSERT(target_shared->has_deoptimization_support()); | 6309 ASSERT(target_shared->has_deoptimization_support()); |
6301 TypeFeedbackOracle target_oracle( | 6310 TypeFeedbackOracle target_oracle( |
6302 Handle<Code>(target_shared->code()), | 6311 Handle<Code>(target_shared->code()), |
6303 Handle<Context>(target->context()->global_context()), | 6312 Handle<Context>(target->context()->global_context()), |
6304 isolate()); | 6313 isolate(), |
| 6314 zone()); |
6305 // The function state is new-allocated because we need to delete it | 6315 // The function state is new-allocated because we need to delete it |
6306 // in two different places. | 6316 // in two different places. |
6307 FunctionState* target_state = new FunctionState( | 6317 FunctionState* target_state = new FunctionState( |
6308 this, &target_info, &target_oracle, return_handling); | 6318 this, &target_info, &target_oracle, return_handling); |
6309 | 6319 |
6310 HConstant* undefined = graph()->GetConstantUndefined(); | 6320 HConstant* undefined = graph()->GetConstantUndefined(); |
6311 HEnvironment* inner_env = | 6321 HEnvironment* inner_env = |
6312 environment()->CopyForInlining(target, | 6322 environment()->CopyForInlining(target, |
6313 arguments->length(), | 6323 arguments->length(), |
6314 function, | 6324 function, |
6315 undefined, | 6325 undefined, |
6316 call_kind, | 6326 call_kind, |
6317 function_state()->is_construct()); | 6327 function_state()->is_construct()); |
6318 #ifdef V8_TARGET_ARCH_IA32 | 6328 #ifdef V8_TARGET_ARCH_IA32 |
6319 // IA32 only, overwrite the caller's context in the deoptimization | 6329 // IA32 only, overwrite the caller's context in the deoptimization |
6320 // environment with the correct one. | 6330 // environment with the correct one. |
6321 // | 6331 // |
6322 // TODO(kmillikin): implement the same inlining on other platforms so we | 6332 // TODO(kmillikin): implement the same inlining on other platforms so we |
6323 // can remove the unsightly ifdefs in this function. | 6333 // can remove the unsightly ifdefs in this function. |
6324 HConstant* context = new HConstant(Handle<Context>(target->context()), | 6334 HConstant* context = |
6325 Representation::Tagged()); | 6335 new(zone()) HConstant(Handle<Context>(target->context()), |
| 6336 Representation::Tagged()); |
6326 AddInstruction(context); | 6337 AddInstruction(context); |
6327 inner_env->BindContext(context); | 6338 inner_env->BindContext(context); |
6328 #endif | 6339 #endif |
6329 | 6340 |
6330 AddSimulate(return_id); | 6341 AddSimulate(return_id); |
6331 current_block()->UpdateEnvironment(inner_env); | 6342 current_block()->UpdateEnvironment(inner_env); |
6332 | 6343 |
6333 ZoneList<HValue*>* arguments_values = NULL; | 6344 ZoneList<HValue*>* arguments_values = NULL; |
6334 | 6345 |
6335 // If the function uses arguments copy current arguments values | 6346 // If the function uses arguments copy current arguments values |
6336 // to use them for materialization. | 6347 // to use them for materialization. |
6337 if (function->scope()->arguments() != NULL) { | 6348 if (function->scope()->arguments() != NULL) { |
6338 HEnvironment* arguments_env = inner_env->arguments_environment(); | 6349 HEnvironment* arguments_env = inner_env->arguments_environment(); |
6339 int arguments_count = arguments_env->parameter_count(); | 6350 int arguments_count = arguments_env->parameter_count(); |
6340 arguments_values = new(zone()) ZoneList<HValue*>(arguments_count); | 6351 arguments_values = new(zone()) ZoneList<HValue*>(arguments_count, zone()); |
6341 for (int i = 0; i < arguments_count; i++) { | 6352 for (int i = 0; i < arguments_count; i++) { |
6342 arguments_values->Add(arguments_env->Lookup(i)); | 6353 arguments_values->Add(arguments_env->Lookup(i), zone()); |
6343 } | 6354 } |
6344 } | 6355 } |
6345 | 6356 |
6346 HEnterInlined* enter_inlined = | 6357 HEnterInlined* enter_inlined = |
6347 new(zone()) HEnterInlined(target, | 6358 new(zone()) HEnterInlined(target, |
6348 arguments->length(), | 6359 arguments->length(), |
6349 function, | 6360 function, |
6350 call_kind, | 6361 call_kind, |
6351 function_state()->is_construct(), | 6362 function_state()->is_construct(), |
6352 function->scope()->arguments(), | 6363 function->scope()->arguments(), |
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6927 Drop(argument_count); | 6938 Drop(argument_count); |
6928 } | 6939 } |
6929 | 6940 |
6930 } else if (expr->IsMonomorphic()) { | 6941 } else if (expr->IsMonomorphic()) { |
6931 // The function is on the stack in the unoptimized code during | 6942 // The function is on the stack in the unoptimized code during |
6932 // evaluation of the arguments. | 6943 // evaluation of the arguments. |
6933 CHECK_ALIVE(VisitForValue(expr->expression())); | 6944 CHECK_ALIVE(VisitForValue(expr->expression())); |
6934 HValue* function = Top(); | 6945 HValue* function = Top(); |
6935 HValue* context = environment()->LookupContext(); | 6946 HValue* context = environment()->LookupContext(); |
6936 HGlobalObject* global = new(zone()) HGlobalObject(context); | 6947 HGlobalObject* global = new(zone()) HGlobalObject(context); |
| 6948 AddInstruction(global); |
6937 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global); | 6949 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global); |
6938 AddInstruction(global); | |
6939 PushAndAdd(receiver); | 6950 PushAndAdd(receiver); |
6940 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 6951 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
6941 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); | 6952 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); |
6942 | 6953 |
6943 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. | 6954 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. |
6944 if (FLAG_trace_inlining) { | 6955 if (FLAG_trace_inlining) { |
6945 PrintF("Inlining builtin "); | 6956 PrintF("Inlining builtin "); |
6946 expr->target()->ShortPrint(); | 6957 expr->target()->ShortPrint(); |
6947 PrintF("\n"); | 6958 PrintF("\n"); |
6948 } | 6959 } |
6949 return; | 6960 return; |
6950 } | 6961 } |
6951 | 6962 |
6952 if (TryInlineCall(expr, true)) { // Drop function from environment. | 6963 if (TryInlineCall(expr, true)) { // Drop function from environment. |
6953 return; | 6964 return; |
6954 } else { | 6965 } else { |
6955 call = PreProcessCall( | 6966 call = PreProcessCall( |
6956 new(zone()) HInvokeFunction(context, | 6967 new(zone()) HInvokeFunction(context, |
6957 function, | 6968 function, |
6958 expr->target(), | 6969 expr->target(), |
6959 argument_count)); | 6970 argument_count)); |
6960 Drop(1); // The function. | 6971 Drop(1); // The function. |
6961 } | 6972 } |
6962 | 6973 |
6963 } else { | 6974 } else { |
6964 CHECK_ALIVE(VisitForValue(expr->expression())); | 6975 CHECK_ALIVE(VisitForValue(expr->expression())); |
6965 HValue* function = Top(); | 6976 HValue* function = Top(); |
6966 HValue* context = environment()->LookupContext(); | 6977 HValue* context = environment()->LookupContext(); |
6967 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 6978 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| 6979 AddInstruction(global_object); |
6968 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global_object); | 6980 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global_object); |
6969 AddInstruction(global_object); | |
6970 AddInstruction(receiver); | 6981 AddInstruction(receiver); |
6971 PushAndAdd(new(zone()) HPushArgument(receiver)); | 6982 PushAndAdd(new(zone()) HPushArgument(receiver)); |
6972 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 6983 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
6973 | 6984 |
6974 call = new(zone()) HCallFunction(context, function, argument_count); | 6985 call = new(zone()) HCallFunction(context, function, argument_count); |
6975 Drop(argument_count + 1); | 6986 Drop(argument_count + 1); |
6976 } | 6987 } |
6977 } | 6988 } |
6978 | 6989 |
6979 call->set_position(expr->position()); | 6990 call->set_position(expr->position()); |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7365 break; | 7376 break; |
7366 } | 7377 } |
7367 | 7378 |
7368 case Variable::LOOKUP: | 7379 case Variable::LOOKUP: |
7369 return Bailout("lookup variable in count operation"); | 7380 return Bailout("lookup variable in count operation"); |
7370 } | 7381 } |
7371 | 7382 |
7372 } else { | 7383 } else { |
7373 // Argument of the count operation is a property. | 7384 // Argument of the count operation is a property. |
7374 ASSERT(prop != NULL); | 7385 ASSERT(prop != NULL); |
7375 prop->RecordTypeFeedback(oracle()); | 7386 prop->RecordTypeFeedback(oracle(), zone()); |
7376 | 7387 |
7377 if (prop->key()->IsPropertyName()) { | 7388 if (prop->key()->IsPropertyName()) { |
7378 // Named property. | 7389 // Named property. |
7379 if (returns_original_input) Push(graph_->GetConstantUndefined()); | 7390 if (returns_original_input) Push(graph_->GetConstantUndefined()); |
7380 | 7391 |
7381 CHECK_ALIVE(VisitForValue(prop->obj())); | 7392 CHECK_ALIVE(VisitForValue(prop->obj())); |
7382 HValue* obj = Top(); | 7393 HValue* obj = Top(); |
7383 | 7394 |
7384 HInstruction* load = NULL; | 7395 HInstruction* load = NULL; |
7385 if (prop->IsMonomorphic()) { | 7396 if (prop->IsMonomorphic()) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7419 HValue* load = HandleKeyedElementAccess( | 7430 HValue* load = HandleKeyedElementAccess( |
7420 obj, key, NULL, prop, expr->CountId(), RelocInfo::kNoPosition, | 7431 obj, key, NULL, prop, expr->CountId(), RelocInfo::kNoPosition, |
7421 false, // is_store | 7432 false, // is_store |
7422 &has_side_effects); | 7433 &has_side_effects); |
7423 Push(load); | 7434 Push(load); |
7424 if (has_side_effects) AddSimulate(expr->CountId()); | 7435 if (has_side_effects) AddSimulate(expr->CountId()); |
7425 | 7436 |
7426 after = BuildIncrement(returns_original_input, expr); | 7437 after = BuildIncrement(returns_original_input, expr); |
7427 input = Pop(); | 7438 input = Pop(); |
7428 | 7439 |
7429 expr->RecordTypeFeedback(oracle()); | 7440 expr->RecordTypeFeedback(oracle(), zone()); |
7430 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(), | 7441 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(), |
7431 RelocInfo::kNoPosition, | 7442 RelocInfo::kNoPosition, |
7432 true, // is_store | 7443 true, // is_store |
7433 &has_side_effects); | 7444 &has_side_effects); |
7434 | 7445 |
7435 // Drop the key from the bailout environment. Overwrite the receiver | 7446 // Drop the key from the bailout environment. Overwrite the receiver |
7436 // with the result of the operation, and the placeholder with the | 7447 // with the result of the operation, and the placeholder with the |
7437 // original value if necessary. | 7448 // original value if necessary. |
7438 Drop(1); | 7449 Drop(1); |
7439 environment()->SetExpressionStackAt(0, after); | 7450 environment()->SetExpressionStackAt(0, after); |
7440 if (returns_original_input) environment()->SetExpressionStackAt(1, input); | 7451 if (returns_original_input) environment()->SetExpressionStackAt(1, input); |
7441 ASSERT(has_side_effects); // Stores always have side effects. | 7452 ASSERT(has_side_effects); // Stores always have side effects. |
7442 AddSimulate(expr->AssignmentId()); | 7453 AddSimulate(expr->AssignmentId()); |
7443 } | 7454 } |
7444 } | 7455 } |
7445 | 7456 |
7446 Drop(returns_original_input ? 2 : 1); | 7457 Drop(returns_original_input ? 2 : 1); |
7447 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); | 7458 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); |
7448 } | 7459 } |
7449 | 7460 |
7450 | 7461 |
7451 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* context, | 7462 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* context, |
7452 HValue* string, | 7463 HValue* string, |
7453 HValue* index) { | 7464 HValue* index) { |
7454 AddInstruction(new(zone()) HCheckNonSmi(string)); | 7465 AddInstruction(new(zone()) HCheckNonSmi(string)); |
7455 AddInstruction(HCheckInstanceType::NewIsString(string)); | 7466 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
7456 HStringLength* length = new(zone()) HStringLength(string); | 7467 HStringLength* length = new(zone()) HStringLength(string); |
7457 AddInstruction(length); | 7468 AddInstruction(length); |
7458 HInstruction* checked_index = | 7469 HInstruction* checked_index = |
7459 AddInstruction(new(zone()) HBoundsCheck(index, length)); | 7470 AddInstruction(new(zone()) HBoundsCheck(index, length)); |
7460 return new(zone()) HStringCharCodeAt(context, string, checked_index); | 7471 return new(zone()) HStringCharCodeAt(context, string, checked_index); |
7461 } | 7472 } |
7462 | 7473 |
7463 | 7474 |
7464 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, | 7475 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, |
7465 HValue* left, | 7476 HValue* left, |
7466 HValue* right) { | 7477 HValue* right) { |
7467 HValue* context = environment()->LookupContext(); | 7478 HValue* context = environment()->LookupContext(); |
7468 TypeInfo info = oracle()->BinaryType(expr); | 7479 TypeInfo info = oracle()->BinaryType(expr); |
7469 if (info.IsUninitialized()) { | 7480 if (info.IsUninitialized()) { |
7470 AddInstruction(new(zone()) HSoftDeoptimize); | 7481 AddInstruction(new(zone()) HSoftDeoptimize); |
7471 current_block()->MarkAsDeoptimizing(); | 7482 current_block()->MarkAsDeoptimizing(); |
7472 info = TypeInfo::Unknown(); | 7483 info = TypeInfo::Unknown(); |
7473 } | 7484 } |
7474 HInstruction* instr = NULL; | 7485 HInstruction* instr = NULL; |
7475 switch (expr->op()) { | 7486 switch (expr->op()) { |
7476 case Token::ADD: | 7487 case Token::ADD: |
7477 if (info.IsString()) { | 7488 if (info.IsString()) { |
7478 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7489 AddInstruction(new(zone()) HCheckNonSmi(left)); |
7479 AddInstruction(HCheckInstanceType::NewIsString(left)); | 7490 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); |
7480 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7491 AddInstruction(new(zone()) HCheckNonSmi(right)); |
7481 AddInstruction(HCheckInstanceType::NewIsString(right)); | 7492 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); |
7482 instr = new(zone()) HStringAdd(context, left, right); | 7493 instr = new(zone()) HStringAdd(context, left, right); |
7483 } else { | 7494 } else { |
7484 instr = HAdd::NewHAdd(zone(), context, left, right); | 7495 instr = HAdd::NewHAdd(zone(), context, left, right); |
7485 } | 7496 } |
7486 break; | 7497 break; |
7487 case Token::SUB: | 7498 case Token::SUB: |
7488 instr = HSub::NewHSub(zone(), context, left, right); | 7499 instr = HSub::NewHSub(zone(), context, left, right); |
7489 break; | 7500 break; |
7490 case Token::MUL: | 7501 case Token::MUL: |
7491 instr = HMul::NewHMul(zone(), context, left, right); | 7502 instr = HMul::NewHMul(zone(), context, left, right); |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7873 result->set_position(expr->position()); | 7884 result->set_position(expr->position()); |
7874 return ast_context()->ReturnInstruction(result, expr->id()); | 7885 return ast_context()->ReturnInstruction(result, expr->id()); |
7875 } else if (type_info.IsNonPrimitive()) { | 7886 } else if (type_info.IsNonPrimitive()) { |
7876 switch (op) { | 7887 switch (op) { |
7877 case Token::EQ: | 7888 case Token::EQ: |
7878 case Token::EQ_STRICT: { | 7889 case Token::EQ_STRICT: { |
7879 // Can we get away with map check and not instance type check? | 7890 // Can we get away with map check and not instance type check? |
7880 Handle<Map> map = oracle()->GetCompareMap(expr); | 7891 Handle<Map> map = oracle()->GetCompareMap(expr); |
7881 if (!map.is_null()) { | 7892 if (!map.is_null()) { |
7882 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7893 AddInstruction(new(zone()) HCheckNonSmi(left)); |
7883 AddInstruction(HCheckMaps::NewWithTransitions(left, map)); | 7894 AddInstruction(HCheckMaps::NewWithTransitions(left, map, zone())); |
7884 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7895 AddInstruction(new(zone()) HCheckNonSmi(right)); |
7885 AddInstruction(HCheckMaps::NewWithTransitions(right, map)); | 7896 AddInstruction(HCheckMaps::NewWithTransitions(right, map, 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 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7902 AddInstruction(new(zone()) HCheckNonSmi(left)); |
7892 AddInstruction(HCheckInstanceType::NewIsSpecObject(left)); | 7903 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); |
7893 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7904 AddInstruction(new(zone()) HCheckNonSmi(right)); |
7894 AddInstruction(HCheckInstanceType::NewIsSpecObject(right)); | 7905 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); |
7895 HCompareObjectEqAndBranch* result = | 7906 HCompareObjectEqAndBranch* result = |
7896 new(zone()) HCompareObjectEqAndBranch(left, right); | 7907 new(zone()) HCompareObjectEqAndBranch(left, right); |
7897 result->set_position(expr->position()); | 7908 result->set_position(expr->position()); |
7898 return ast_context()->ReturnControl(result, expr->id()); | 7909 return ast_context()->ReturnControl(result, expr->id()); |
7899 } | 7910 } |
7900 } | 7911 } |
7901 default: | 7912 default: |
7902 return Bailout("Unsupported non-primitive compare"); | 7913 return Bailout("Unsupported non-primitive compare"); |
7903 } | 7914 } |
7904 } else if (type_info.IsString() && oracle()->IsSymbolCompare(expr) && | 7915 } else if (type_info.IsString() && oracle()->IsSymbolCompare(expr) && |
7905 (op == Token::EQ || op == Token::EQ_STRICT)) { | 7916 (op == Token::EQ || op == Token::EQ_STRICT)) { |
7906 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7917 AddInstruction(new(zone()) HCheckNonSmi(left)); |
7907 AddInstruction(HCheckInstanceType::NewIsSymbol(left)); | 7918 AddInstruction(HCheckInstanceType::NewIsSymbol(left, zone())); |
7908 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7919 AddInstruction(new(zone()) HCheckNonSmi(right)); |
7909 AddInstruction(HCheckInstanceType::NewIsSymbol(right)); | 7920 AddInstruction(HCheckInstanceType::NewIsSymbol(right, zone())); |
7910 HCompareObjectEqAndBranch* result = | 7921 HCompareObjectEqAndBranch* result = |
7911 new(zone()) HCompareObjectEqAndBranch(left, right); | 7922 new(zone()) HCompareObjectEqAndBranch(left, right); |
7912 result->set_position(expr->position()); | 7923 result->set_position(expr->position()); |
7913 return ast_context()->ReturnControl(result, expr->id()); | 7924 return ast_context()->ReturnControl(result, expr->id()); |
7914 } else { | 7925 } else { |
7915 Representation r = ToRepresentation(type_info); | 7926 Representation r = ToRepresentation(type_info); |
7916 if (r.IsTagged()) { | 7927 if (r.IsTagged()) { |
7917 HCompareGeneric* result = | 7928 HCompareGeneric* result = |
7918 new(zone()) HCompareGeneric(context, left, right, op); | 7929 new(zone()) HCompareGeneric(context, left, right, op); |
7919 result->set_position(expr->position()); | 7930 result->set_position(expr->position()); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7971 } | 7982 } |
7972 | 7983 |
7973 | 7984 |
7974 void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) { | 7985 void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) { |
7975 VariableProxy* proxy = declaration->proxy(); | 7986 VariableProxy* proxy = declaration->proxy(); |
7976 VariableMode mode = declaration->mode(); | 7987 VariableMode mode = declaration->mode(); |
7977 Variable* variable = proxy->var(); | 7988 Variable* variable = proxy->var(); |
7978 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; | 7989 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; |
7979 switch (variable->location()) { | 7990 switch (variable->location()) { |
7980 case Variable::UNALLOCATED: | 7991 case Variable::UNALLOCATED: |
7981 globals_.Add(variable->name()); | 7992 globals_.Add(variable->name(), zone()); |
7982 globals_.Add(variable->binding_needs_init() | 7993 globals_.Add(variable->binding_needs_init() |
7983 ? isolate()->factory()->the_hole_value() | 7994 ? isolate()->factory()->the_hole_value() |
7984 : isolate()->factory()->undefined_value()); | 7995 : isolate()->factory()->undefined_value(), zone()); |
7985 return; | 7996 return; |
7986 case Variable::PARAMETER: | 7997 case Variable::PARAMETER: |
7987 case Variable::LOCAL: | 7998 case Variable::LOCAL: |
7988 if (hole_init) { | 7999 if (hole_init) { |
7989 HValue* value = graph()->GetConstantHole(); | 8000 HValue* value = graph()->GetConstantHole(); |
7990 environment()->Bind(variable, value); | 8001 environment()->Bind(variable, value); |
7991 } | 8002 } |
7992 break; | 8003 break; |
7993 case Variable::CONTEXT: | 8004 case Variable::CONTEXT: |
7994 if (hole_init) { | 8005 if (hole_init) { |
7995 HValue* value = graph()->GetConstantHole(); | 8006 HValue* value = graph()->GetConstantHole(); |
7996 HValue* context = environment()->LookupContext(); | 8007 HValue* context = environment()->LookupContext(); |
7997 HStoreContextSlot* store = new HStoreContextSlot( | 8008 HStoreContextSlot* store = new(zone()) HStoreContextSlot( |
7998 context, variable->index(), HStoreContextSlot::kNoCheck, value); | 8009 context, variable->index(), HStoreContextSlot::kNoCheck, value); |
7999 AddInstruction(store); | 8010 AddInstruction(store); |
8000 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); | 8011 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); |
8001 } | 8012 } |
8002 break; | 8013 break; |
8003 case Variable::LOOKUP: | 8014 case Variable::LOOKUP: |
8004 return Bailout("unsupported lookup slot in declaration"); | 8015 return Bailout("unsupported lookup slot in declaration"); |
8005 } | 8016 } |
8006 } | 8017 } |
8007 | 8018 |
8008 | 8019 |
8009 void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) { | 8020 void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) { |
8010 VariableProxy* proxy = declaration->proxy(); | 8021 VariableProxy* proxy = declaration->proxy(); |
8011 Variable* variable = proxy->var(); | 8022 Variable* variable = proxy->var(); |
8012 switch (variable->location()) { | 8023 switch (variable->location()) { |
8013 case Variable::UNALLOCATED: { | 8024 case Variable::UNALLOCATED: { |
8014 globals_.Add(variable->name()); | 8025 globals_.Add(variable->name(), zone()); |
8015 Handle<SharedFunctionInfo> function = | 8026 Handle<SharedFunctionInfo> function = |
8016 Compiler::BuildFunctionInfo(declaration->fun(), info()->script()); | 8027 Compiler::BuildFunctionInfo(declaration->fun(), info()->script()); |
8017 // Check for stack-overflow exception. | 8028 // Check for stack-overflow exception. |
8018 if (function.is_null()) return SetStackOverflow(); | 8029 if (function.is_null()) return SetStackOverflow(); |
8019 globals_.Add(function); | 8030 globals_.Add(function, zone()); |
8020 return; | 8031 return; |
8021 } | 8032 } |
8022 case Variable::PARAMETER: | 8033 case Variable::PARAMETER: |
8023 case Variable::LOCAL: { | 8034 case Variable::LOCAL: { |
8024 CHECK_ALIVE(VisitForValue(declaration->fun())); | 8035 CHECK_ALIVE(VisitForValue(declaration->fun())); |
8025 HValue* value = Pop(); | 8036 HValue* value = Pop(); |
8026 environment()->Bind(variable, value); | 8037 environment()->Bind(variable, value); |
8027 break; | 8038 break; |
8028 } | 8039 } |
8029 case Variable::CONTEXT: { | 8040 case Variable::CONTEXT: { |
8030 CHECK_ALIVE(VisitForValue(declaration->fun())); | 8041 CHECK_ALIVE(VisitForValue(declaration->fun())); |
8031 HValue* value = Pop(); | 8042 HValue* value = Pop(); |
8032 HValue* context = environment()->LookupContext(); | 8043 HValue* context = environment()->LookupContext(); |
8033 HStoreContextSlot* store = new HStoreContextSlot( | 8044 HStoreContextSlot* store = new(zone()) HStoreContextSlot( |
8034 context, variable->index(), HStoreContextSlot::kNoCheck, value); | 8045 context, variable->index(), HStoreContextSlot::kNoCheck, value); |
8035 AddInstruction(store); | 8046 AddInstruction(store); |
8036 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); | 8047 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); |
8037 break; | 8048 break; |
8038 } | 8049 } |
8039 case Variable::LOOKUP: | 8050 case Variable::LOOKUP: |
8040 return Bailout("unsupported lookup slot in declaration"); | 8051 return Bailout("unsupported lookup slot in declaration"); |
8041 } | 8052 } |
8042 } | 8053 } |
8043 | 8054 |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8269 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); | 8280 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); |
8270 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); | 8281 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); |
8271 typecheck->SetSuccessorAt(0, if_js_value); | 8282 typecheck->SetSuccessorAt(0, if_js_value); |
8272 typecheck->SetSuccessorAt(1, not_js_value); | 8283 typecheck->SetSuccessorAt(1, not_js_value); |
8273 current_block()->Finish(typecheck); | 8284 current_block()->Finish(typecheck); |
8274 not_js_value->Goto(join); | 8285 not_js_value->Goto(join); |
8275 | 8286 |
8276 // Create in-object property store to kValueOffset. | 8287 // Create in-object property store to kValueOffset. |
8277 set_current_block(if_js_value); | 8288 set_current_block(if_js_value); |
8278 Handle<String> name = isolate()->factory()->undefined_symbol(); | 8289 Handle<String> name = isolate()->factory()->undefined_symbol(); |
8279 AddInstruction(new HStoreNamedField(object, | 8290 AddInstruction(new(zone()) HStoreNamedField(object, |
8280 name, | 8291 name, |
8281 value, | 8292 value, |
8282 true, // in-object store. | 8293 true, // in-object store. |
8283 JSValue::kValueOffset)); | 8294 JSValue::kValueOffset)); |
8284 if_js_value->Goto(join); | 8295 if_js_value->Goto(join); |
8285 join->SetJoinId(call->id()); | 8296 join->SetJoinId(call->id()); |
8286 set_current_block(join); | 8297 set_current_block(join); |
8287 return ast_context()->ReturnValue(value); | 8298 return ast_context()->ReturnValue(value); |
8288 } | 8299 } |
8289 | 8300 |
8290 | 8301 |
8291 // Fast support for charCodeAt(n). | 8302 // Fast support for charCodeAt(n). |
8292 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { | 8303 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { |
8293 ASSERT(call->arguments()->length() == 2); | 8304 ASSERT(call->arguments()->length() == 2); |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8561 return Bailout("inlined runtime function: FastAsciiArrayJoin"); | 8572 return Bailout("inlined runtime function: FastAsciiArrayJoin"); |
8562 } | 8573 } |
8563 | 8574 |
8564 | 8575 |
8565 #undef CHECK_BAILOUT | 8576 #undef CHECK_BAILOUT |
8566 #undef CHECK_ALIVE | 8577 #undef CHECK_ALIVE |
8567 | 8578 |
8568 | 8579 |
8569 HEnvironment::HEnvironment(HEnvironment* outer, | 8580 HEnvironment::HEnvironment(HEnvironment* outer, |
8570 Scope* scope, | 8581 Scope* scope, |
8571 Handle<JSFunction> closure) | 8582 Handle<JSFunction> closure, |
| 8583 Zone* zone) |
8572 : closure_(closure), | 8584 : closure_(closure), |
8573 values_(0), | 8585 values_(0, zone), |
8574 assigned_variables_(4), | 8586 assigned_variables_(4, zone), |
8575 frame_type_(JS_FUNCTION), | 8587 frame_type_(JS_FUNCTION), |
8576 parameter_count_(0), | 8588 parameter_count_(0), |
8577 specials_count_(1), | 8589 specials_count_(1), |
8578 local_count_(0), | 8590 local_count_(0), |
8579 outer_(outer), | 8591 outer_(outer), |
8580 pop_count_(0), | 8592 pop_count_(0), |
8581 push_count_(0), | 8593 push_count_(0), |
8582 ast_id_(AstNode::kNoNumber) { | 8594 ast_id_(AstNode::kNoNumber), |
| 8595 zone_(zone) { |
8583 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); | 8596 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); |
8584 } | 8597 } |
8585 | 8598 |
8586 | 8599 |
8587 HEnvironment::HEnvironment(const HEnvironment* other) | 8600 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) |
8588 : values_(0), | 8601 : values_(0, zone), |
8589 assigned_variables_(0), | 8602 assigned_variables_(0, zone), |
8590 frame_type_(JS_FUNCTION), | 8603 frame_type_(JS_FUNCTION), |
8591 parameter_count_(0), | 8604 parameter_count_(0), |
8592 specials_count_(1), | 8605 specials_count_(1), |
8593 local_count_(0), | 8606 local_count_(0), |
8594 outer_(NULL), | 8607 outer_(NULL), |
8595 pop_count_(0), | 8608 pop_count_(0), |
8596 push_count_(0), | 8609 push_count_(0), |
8597 ast_id_(other->ast_id()) { | 8610 ast_id_(other->ast_id()), |
| 8611 zone_(zone) { |
8598 Initialize(other); | 8612 Initialize(other); |
8599 } | 8613 } |
8600 | 8614 |
8601 | 8615 |
8602 HEnvironment::HEnvironment(HEnvironment* outer, | 8616 HEnvironment::HEnvironment(HEnvironment* outer, |
8603 Handle<JSFunction> closure, | 8617 Handle<JSFunction> closure, |
8604 FrameType frame_type, | 8618 FrameType frame_type, |
8605 int arguments) | 8619 int arguments, |
| 8620 Zone* zone) |
8606 : closure_(closure), | 8621 : closure_(closure), |
8607 values_(arguments), | 8622 values_(arguments, zone), |
8608 assigned_variables_(0), | 8623 assigned_variables_(0, zone), |
8609 frame_type_(frame_type), | 8624 frame_type_(frame_type), |
8610 parameter_count_(arguments), | 8625 parameter_count_(arguments), |
8611 local_count_(0), | 8626 local_count_(0), |
8612 outer_(outer), | 8627 outer_(outer), |
8613 pop_count_(0), | 8628 pop_count_(0), |
8614 push_count_(0), | 8629 push_count_(0), |
8615 ast_id_(AstNode::kNoNumber) { | 8630 ast_id_(AstNode::kNoNumber), |
| 8631 zone_(zone) { |
8616 } | 8632 } |
8617 | 8633 |
8618 | 8634 |
8619 void HEnvironment::Initialize(int parameter_count, | 8635 void HEnvironment::Initialize(int parameter_count, |
8620 int local_count, | 8636 int local_count, |
8621 int stack_height) { | 8637 int stack_height) { |
8622 parameter_count_ = parameter_count; | 8638 parameter_count_ = parameter_count; |
8623 local_count_ = local_count; | 8639 local_count_ = local_count; |
8624 | 8640 |
8625 // Avoid reallocating the temporaries' backing store on the first Push. | 8641 // Avoid reallocating the temporaries' backing store on the first Push. |
8626 int total = parameter_count + specials_count_ + local_count + stack_height; | 8642 int total = parameter_count + specials_count_ + local_count + stack_height; |
8627 values_.Initialize(total + 4); | 8643 values_.Initialize(total + 4, zone()); |
8628 for (int i = 0; i < total; ++i) values_.Add(NULL); | 8644 for (int i = 0; i < total; ++i) values_.Add(NULL, zone()); |
8629 } | 8645 } |
8630 | 8646 |
8631 | 8647 |
8632 void HEnvironment::Initialize(const HEnvironment* other) { | 8648 void HEnvironment::Initialize(const HEnvironment* other) { |
8633 closure_ = other->closure(); | 8649 closure_ = other->closure(); |
8634 values_.AddAll(other->values_); | 8650 values_.AddAll(other->values_, zone()); |
8635 assigned_variables_.AddAll(other->assigned_variables_); | 8651 assigned_variables_.AddAll(other->assigned_variables_, zone()); |
8636 frame_type_ = other->frame_type_; | 8652 frame_type_ = other->frame_type_; |
8637 parameter_count_ = other->parameter_count_; | 8653 parameter_count_ = other->parameter_count_; |
8638 local_count_ = other->local_count_; | 8654 local_count_ = other->local_count_; |
8639 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. | 8655 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. |
8640 pop_count_ = other->pop_count_; | 8656 pop_count_ = other->pop_count_; |
8641 push_count_ = other->push_count_; | 8657 push_count_ = other->push_count_; |
8642 ast_id_ = other->ast_id_; | 8658 ast_id_ = other->ast_id_; |
8643 } | 8659 } |
8644 | 8660 |
8645 | 8661 |
8646 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { | 8662 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { |
8647 ASSERT(!block->IsLoopHeader()); | 8663 ASSERT(!block->IsLoopHeader()); |
8648 ASSERT(values_.length() == other->values_.length()); | 8664 ASSERT(values_.length() == other->values_.length()); |
8649 | 8665 |
8650 int length = values_.length(); | 8666 int length = values_.length(); |
8651 for (int i = 0; i < length; ++i) { | 8667 for (int i = 0; i < length; ++i) { |
8652 HValue* value = values_[i]; | 8668 HValue* value = values_[i]; |
8653 if (value != NULL && value->IsPhi() && value->block() == block) { | 8669 if (value != NULL && value->IsPhi() && value->block() == block) { |
8654 // There is already a phi for the i'th value. | 8670 // There is already a phi for the i'th value. |
8655 HPhi* phi = HPhi::cast(value); | 8671 HPhi* phi = HPhi::cast(value); |
8656 // Assert index is correct and that we haven't missed an incoming edge. | 8672 // Assert index is correct and that we haven't missed an incoming edge. |
8657 ASSERT(phi->merged_index() == i); | 8673 ASSERT(phi->merged_index() == i); |
8658 ASSERT(phi->OperandCount() == block->predecessors()->length()); | 8674 ASSERT(phi->OperandCount() == block->predecessors()->length()); |
8659 phi->AddInput(other->values_[i]); | 8675 phi->AddInput(other->values_[i]); |
8660 } else if (values_[i] != other->values_[i]) { | 8676 } else if (values_[i] != other->values_[i]) { |
8661 // There is a fresh value on the incoming edge, a phi is needed. | 8677 // There is a fresh value on the incoming edge, a phi is needed. |
8662 ASSERT(values_[i] != NULL && other->values_[i] != NULL); | 8678 ASSERT(values_[i] != NULL && other->values_[i] != NULL); |
8663 HPhi* phi = new(block->zone()) HPhi(i); | 8679 HPhi* phi = new(zone()) HPhi(i, zone()); |
8664 HValue* old_value = values_[i]; | 8680 HValue* old_value = values_[i]; |
8665 for (int j = 0; j < block->predecessors()->length(); j++) { | 8681 for (int j = 0; j < block->predecessors()->length(); j++) { |
8666 phi->AddInput(old_value); | 8682 phi->AddInput(old_value); |
8667 } | 8683 } |
8668 phi->AddInput(other->values_[i]); | 8684 phi->AddInput(other->values_[i]); |
8669 this->values_[i] = phi; | 8685 this->values_[i] = phi; |
8670 block->AddPhi(phi); | 8686 block->AddPhi(phi); |
8671 } | 8687 } |
8672 } | 8688 } |
8673 } | 8689 } |
8674 | 8690 |
8675 | 8691 |
8676 void HEnvironment::Bind(int index, HValue* value) { | 8692 void HEnvironment::Bind(int index, HValue* value) { |
8677 ASSERT(value != NULL); | 8693 ASSERT(value != NULL); |
8678 if (!assigned_variables_.Contains(index)) { | 8694 if (!assigned_variables_.Contains(index)) { |
8679 assigned_variables_.Add(index); | 8695 assigned_variables_.Add(index, zone()); |
8680 } | 8696 } |
8681 values_[index] = value; | 8697 values_[index] = value; |
8682 } | 8698 } |
8683 | 8699 |
8684 | 8700 |
8685 bool HEnvironment::HasExpressionAt(int index) const { | 8701 bool HEnvironment::HasExpressionAt(int index) const { |
8686 return index >= parameter_count_ + specials_count_ + local_count_; | 8702 return index >= parameter_count_ + specials_count_ + local_count_; |
8687 } | 8703 } |
8688 | 8704 |
8689 | 8705 |
(...skipping 19 matching lines...) Expand all Loading... |
8709 | 8725 |
8710 | 8726 |
8711 void HEnvironment::Drop(int count) { | 8727 void HEnvironment::Drop(int count) { |
8712 for (int i = 0; i < count; ++i) { | 8728 for (int i = 0; i < count; ++i) { |
8713 Pop(); | 8729 Pop(); |
8714 } | 8730 } |
8715 } | 8731 } |
8716 | 8732 |
8717 | 8733 |
8718 HEnvironment* HEnvironment::Copy() const { | 8734 HEnvironment* HEnvironment::Copy() const { |
8719 return new(closure()->GetIsolate()->zone()) HEnvironment(this); | 8735 return new(zone()) HEnvironment(this, zone()); |
8720 } | 8736 } |
8721 | 8737 |
8722 | 8738 |
8723 HEnvironment* HEnvironment::CopyWithoutHistory() const { | 8739 HEnvironment* HEnvironment::CopyWithoutHistory() const { |
8724 HEnvironment* result = Copy(); | 8740 HEnvironment* result = Copy(); |
8725 result->ClearHistory(); | 8741 result->ClearHistory(); |
8726 return result; | 8742 return result; |
8727 } | 8743 } |
8728 | 8744 |
8729 | 8745 |
8730 HEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const { | 8746 HEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const { |
8731 HEnvironment* new_env = Copy(); | 8747 HEnvironment* new_env = Copy(); |
8732 for (int i = 0; i < values_.length(); ++i) { | 8748 for (int i = 0; i < values_.length(); ++i) { |
8733 HPhi* phi = new(loop_header->zone()) HPhi(i); | 8749 HPhi* phi = new(zone()) HPhi(i, zone()); |
8734 phi->AddInput(values_[i]); | 8750 phi->AddInput(values_[i]); |
8735 new_env->values_[i] = phi; | 8751 new_env->values_[i] = phi; |
8736 loop_header->AddPhi(phi); | 8752 loop_header->AddPhi(phi); |
8737 } | 8753 } |
8738 new_env->ClearHistory(); | 8754 new_env->ClearHistory(); |
8739 return new_env; | 8755 return new_env; |
8740 } | 8756 } |
8741 | 8757 |
8742 | 8758 |
8743 HEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer, | 8759 HEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer, |
8744 Handle<JSFunction> target, | 8760 Handle<JSFunction> target, |
8745 FrameType frame_type, | 8761 FrameType frame_type, |
8746 int arguments) const { | 8762 int arguments) const { |
8747 HEnvironment* new_env = new(closure()->GetIsolate()->zone()) | 8763 HEnvironment* new_env = |
8748 HEnvironment(outer, target, frame_type, arguments + 1); | 8764 new(zone()) HEnvironment(outer, target, frame_type, |
| 8765 arguments + 1, zone()); |
8749 for (int i = 0; i <= arguments; ++i) { // Include receiver. | 8766 for (int i = 0; i <= arguments; ++i) { // Include receiver. |
8750 new_env->Push(ExpressionStackAt(arguments - i)); | 8767 new_env->Push(ExpressionStackAt(arguments - i)); |
8751 } | 8768 } |
8752 new_env->ClearHistory(); | 8769 new_env->ClearHistory(); |
8753 return new_env; | 8770 return new_env; |
8754 } | 8771 } |
8755 | 8772 |
8756 | 8773 |
8757 HEnvironment* HEnvironment::CopyForInlining( | 8774 HEnvironment* HEnvironment::CopyForInlining( |
8758 Handle<JSFunction> target, | 8775 Handle<JSFunction> target, |
(...skipping 19 matching lines...) Expand all Loading... |
8778 // object instead, DoComputeConstructStubFrame() relies on that. | 8795 // object instead, DoComputeConstructStubFrame() relies on that. |
8779 outer = CreateStubEnvironment(outer, target, JS_CONSTRUCT, arguments); | 8796 outer = CreateStubEnvironment(outer, target, JS_CONSTRUCT, arguments); |
8780 } | 8797 } |
8781 | 8798 |
8782 if (arity != arguments) { | 8799 if (arity != arguments) { |
8783 // Create artificial arguments adaptation environment. | 8800 // Create artificial arguments adaptation environment. |
8784 outer = CreateStubEnvironment(outer, target, ARGUMENTS_ADAPTOR, arguments); | 8801 outer = CreateStubEnvironment(outer, target, ARGUMENTS_ADAPTOR, arguments); |
8785 } | 8802 } |
8786 | 8803 |
8787 HEnvironment* inner = | 8804 HEnvironment* inner = |
8788 new(zone) HEnvironment(outer, function->scope(), target); | 8805 new(zone) HEnvironment(outer, function->scope(), target, zone); |
8789 // Get the argument values from the original environment. | 8806 // Get the argument values from the original environment. |
8790 for (int i = 0; i <= arity; ++i) { // Include receiver. | 8807 for (int i = 0; i <= arity; ++i) { // Include receiver. |
8791 HValue* push = (i <= arguments) ? | 8808 HValue* push = (i <= arguments) ? |
8792 ExpressionStackAt(arguments - i) : undefined; | 8809 ExpressionStackAt(arguments - i) : undefined; |
8793 inner->SetValueAt(i, push); | 8810 inner->SetValueAt(i, push); |
8794 } | 8811 } |
8795 // If the function we are inlining is a strict mode function or a | 8812 // If the function we are inlining is a strict mode function or a |
8796 // builtin function, pass undefined as the receiver for function | 8813 // builtin function, pass undefined as the receiver for function |
8797 // calls (instead of the global receiver). | 8814 // calls (instead of the global receiver). |
8798 if ((target->shared()->native() || !function->is_classic_mode()) && | 8815 if ((target->shared()->native() || !function->is_classic_mode()) && |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8968 } | 8985 } |
8969 } | 8986 } |
8970 | 8987 |
8971 | 8988 |
8972 void HTracer::TraceLiveRanges(const char* name, LAllocator* allocator) { | 8989 void HTracer::TraceLiveRanges(const char* name, LAllocator* allocator) { |
8973 Tag tag(this, "intervals"); | 8990 Tag tag(this, "intervals"); |
8974 PrintStringProperty("name", name); | 8991 PrintStringProperty("name", name); |
8975 | 8992 |
8976 const Vector<LiveRange*>* fixed_d = allocator->fixed_double_live_ranges(); | 8993 const Vector<LiveRange*>* fixed_d = allocator->fixed_double_live_ranges(); |
8977 for (int i = 0; i < fixed_d->length(); ++i) { | 8994 for (int i = 0; i < fixed_d->length(); ++i) { |
8978 TraceLiveRange(fixed_d->at(i), "fixed"); | 8995 TraceLiveRange(fixed_d->at(i), "fixed", allocator->zone()); |
8979 } | 8996 } |
8980 | 8997 |
8981 const Vector<LiveRange*>* fixed = allocator->fixed_live_ranges(); | 8998 const Vector<LiveRange*>* fixed = allocator->fixed_live_ranges(); |
8982 for (int i = 0; i < fixed->length(); ++i) { | 8999 for (int i = 0; i < fixed->length(); ++i) { |
8983 TraceLiveRange(fixed->at(i), "fixed"); | 9000 TraceLiveRange(fixed->at(i), "fixed", allocator->zone()); |
8984 } | 9001 } |
8985 | 9002 |
8986 const ZoneList<LiveRange*>* live_ranges = allocator->live_ranges(); | 9003 const ZoneList<LiveRange*>* live_ranges = allocator->live_ranges(); |
8987 for (int i = 0; i < live_ranges->length(); ++i) { | 9004 for (int i = 0; i < live_ranges->length(); ++i) { |
8988 TraceLiveRange(live_ranges->at(i), "object"); | 9005 TraceLiveRange(live_ranges->at(i), "object", allocator->zone()); |
8989 } | 9006 } |
8990 } | 9007 } |
8991 | 9008 |
8992 | 9009 |
8993 void HTracer::TraceLiveRange(LiveRange* range, const char* type) { | 9010 void HTracer::TraceLiveRange(LiveRange* range, const char* type, |
| 9011 Zone* zone) { |
8994 if (range != NULL && !range->IsEmpty()) { | 9012 if (range != NULL && !range->IsEmpty()) { |
8995 PrintIndent(); | 9013 PrintIndent(); |
8996 trace_.Add("%d %s", range->id(), type); | 9014 trace_.Add("%d %s", range->id(), type); |
8997 if (range->HasRegisterAssigned()) { | 9015 if (range->HasRegisterAssigned()) { |
8998 LOperand* op = range->CreateAssignedOperand(ZONE); | 9016 LOperand* op = range->CreateAssignedOperand(zone); |
8999 int assigned_reg = op->index(); | 9017 int assigned_reg = op->index(); |
9000 if (op->IsDoubleRegister()) { | 9018 if (op->IsDoubleRegister()) { |
9001 trace_.Add(" \"%s\"", | 9019 trace_.Add(" \"%s\"", |
9002 DoubleRegister::AllocationIndexToString(assigned_reg)); | 9020 DoubleRegister::AllocationIndexToString(assigned_reg)); |
9003 } else { | 9021 } else { |
9004 ASSERT(op->IsRegister()); | 9022 ASSERT(op->IsRegister()); |
9005 trace_.Add(" \"%s\"", Register::AllocationIndexToString(assigned_reg)); | 9023 trace_.Add(" \"%s\"", Register::AllocationIndexToString(assigned_reg)); |
9006 } | 9024 } |
9007 } else if (range->IsSpilled()) { | 9025 } else if (range->IsSpilled()) { |
9008 LOperand* op = range->TopLevel()->GetSpillOperand(); | 9026 LOperand* op = range->TopLevel()->GetSpillOperand(); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9150 } | 9168 } |
9151 } | 9169 } |
9152 | 9170 |
9153 #ifdef DEBUG | 9171 #ifdef DEBUG |
9154 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 9172 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
9155 if (allocator_ != NULL) allocator_->Verify(); | 9173 if (allocator_ != NULL) allocator_->Verify(); |
9156 #endif | 9174 #endif |
9157 } | 9175 } |
9158 | 9176 |
9159 } } // namespace v8::internal | 9177 } } // namespace v8::internal |
OLD | NEW |