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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2169 } | 2174 } |
2170 | 2175 |
2171 | 2176 |
2172 void HInferRepresentation::Analyze() { | 2177 void HInferRepresentation::Analyze() { |
2173 HPhase phase("H_Infer representations", graph_); | 2178 HPhase phase("H_Infer representations", graph_); |
2174 | 2179 |
2175 // (1) Initialize bit vectors and count real uses. Each phi gets a | 2180 // (1) Initialize bit vectors and count real uses. Each phi gets a |
2176 // bit-vector of length <number of phis>. | 2181 // bit-vector of length <number of phis>. |
2177 const ZoneList<HPhi*>* phi_list = graph_->phi_list(); | 2182 const ZoneList<HPhi*>* phi_list = graph_->phi_list(); |
2178 int phi_count = phi_list->length(); | 2183 int phi_count = phi_list->length(); |
2179 ZoneList<BitVector*> connected_phis(phi_count); | 2184 ZoneList<BitVector*> connected_phis(phi_count, graph_->zone()); |
2180 for (int i = 0; i < phi_count; ++i) { | 2185 for (int i = 0; i < phi_count; ++i) { |
2181 phi_list->at(i)->InitRealUses(i); | 2186 phi_list->at(i)->InitRealUses(i); |
2182 BitVector* connected_set = new(zone()) BitVector(phi_count, graph_->zone()); | 2187 BitVector* connected_set = new(zone()) BitVector(phi_count, graph_->zone()); |
2183 connected_set->Add(i); | 2188 connected_set->Add(i); |
2184 connected_phis.Add(connected_set); | 2189 connected_phis.Add(connected_set, zone()); |
2185 } | 2190 } |
2186 | 2191 |
2187 // (2) Do a fixed point iteration to find the set of connected phis. A | 2192 // (2) Do a fixed point iteration to find the set of connected phis. A |
2188 // phi is connected to another phi if its value is used either directly or | 2193 // phi is connected to another phi if its value is used either directly or |
2189 // indirectly through a transitive closure of the def-use relation. | 2194 // indirectly through a transitive closure of the def-use relation. |
2190 bool change = true; | 2195 bool change = true; |
2191 while (change) { | 2196 while (change) { |
2192 change = false; | 2197 change = false; |
2193 // We normally have far more "forward edges" than "backward edges", | 2198 // We normally have far more "forward edges" than "backward edges", |
2194 // so we terminate faster when we walk backwards. | 2199 // so we terminate faster when we walk backwards. |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2270 } | 2275 } |
2271 | 2276 |
2272 if (block->IsLoopHeader()) { | 2277 if (block->IsLoopHeader()) { |
2273 HBasicBlock* last_back_edge = | 2278 HBasicBlock* last_back_edge = |
2274 block->loop_information()->GetLastBackEdge(); | 2279 block->loop_information()->GetLastBackEdge(); |
2275 InitializeInferredTypes(i + 1, last_back_edge->block_id()); | 2280 InitializeInferredTypes(i + 1, last_back_edge->block_id()); |
2276 // Skip all blocks already processed by the recursive call. | 2281 // Skip all blocks already processed by the recursive call. |
2277 i = last_back_edge->block_id(); | 2282 i = last_back_edge->block_id(); |
2278 // Update phis of the loop header now after the whole loop body is | 2283 // Update phis of the loop header now after the whole loop body is |
2279 // guaranteed to be processed. | 2284 // guaranteed to be processed. |
2280 ZoneList<HValue*> worklist(block->phis()->length()); | 2285 ZoneList<HValue*> worklist(block->phis()->length(), zone()); |
2281 for (int j = 0; j < block->phis()->length(); ++j) { | 2286 for (int j = 0; j < block->phis()->length(); ++j) { |
2282 worklist.Add(block->phis()->at(j)); | 2287 worklist.Add(block->phis()->at(j), zone()); |
2283 } | 2288 } |
2284 InferTypes(&worklist); | 2289 InferTypes(&worklist); |
2285 } | 2290 } |
2286 } | 2291 } |
2287 } | 2292 } |
2288 | 2293 |
2289 | 2294 |
2290 void HGraph::PropagateMinusZeroChecks(HValue* value, BitVector* visited) { | 2295 void HGraph::PropagateMinusZeroChecks(HValue* value, BitVector* visited) { |
2291 HValue* current = value; | 2296 HValue* current = value; |
2292 while (current != NULL) { | 2297 while (current != NULL) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2339 // information we treat constants like normal instructions and insert the | 2344 // information we treat constants like normal instructions and insert the |
2340 // change instructions for them. | 2345 // change instructions for them. |
2341 HInstruction* new_value = NULL; | 2346 HInstruction* new_value = NULL; |
2342 bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32); | 2347 bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32); |
2343 bool deoptimize_on_undefined = | 2348 bool deoptimize_on_undefined = |
2344 use_value->CheckFlag(HValue::kDeoptimizeOnUndefined); | 2349 use_value->CheckFlag(HValue::kDeoptimizeOnUndefined); |
2345 if (value->IsConstant()) { | 2350 if (value->IsConstant()) { |
2346 HConstant* constant = HConstant::cast(value); | 2351 HConstant* constant = HConstant::cast(value); |
2347 // Try to create a new copy of the constant with the new representation. | 2352 // Try to create a new copy of the constant with the new representation. |
2348 new_value = is_truncating | 2353 new_value = is_truncating |
2349 ? constant->CopyToTruncatedInt32() | 2354 ? constant->CopyToTruncatedInt32(zone()) |
2350 : constant->CopyToRepresentation(to); | 2355 : constant->CopyToRepresentation(to, zone()); |
2351 } | 2356 } |
2352 | 2357 |
2353 if (new_value == NULL) { | 2358 if (new_value == NULL) { |
2354 new_value = new(zone()) HChange(value, to, | 2359 new_value = new(zone()) HChange(value, to, |
2355 is_truncating, deoptimize_on_undefined); | 2360 is_truncating, deoptimize_on_undefined); |
2356 } | 2361 } |
2357 | 2362 |
2358 new_value->InsertBefore(next); | 2363 new_value->InsertBefore(next); |
2359 use_value->SetOperandAt(use_index, new_value); | 2364 use_value->SetOperandAt(use_index, new_value); |
2360 } | 2365 } |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2759 | 2764 |
2760 | 2765 |
2761 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) { | 2766 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) { |
2762 for (int i = 0; i < exprs->length(); ++i) { | 2767 for (int i = 0; i < exprs->length(); ++i) { |
2763 CHECK_ALIVE(VisitForValue(exprs->at(i))); | 2768 CHECK_ALIVE(VisitForValue(exprs->at(i))); |
2764 } | 2769 } |
2765 } | 2770 } |
2766 | 2771 |
2767 | 2772 |
2768 HGraph* HGraphBuilder::CreateGraph() { | 2773 HGraph* HGraphBuilder::CreateGraph() { |
2769 graph_ = new(zone()) HGraph(info()); | 2774 graph_ = new(zone()) HGraph(info(), zone()); |
2770 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info()); | 2775 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info()); |
2771 | 2776 |
2772 { | 2777 { |
2773 HPhase phase("H_Block building"); | 2778 HPhase phase("H_Block building"); |
2774 current_block_ = graph()->entry_block(); | 2779 current_block_ = graph()->entry_block(); |
2775 | 2780 |
2776 Scope* scope = info()->scope(); | 2781 Scope* scope = info()->scope(); |
2777 if (scope->HasIllegalRedeclaration()) { | 2782 if (scope->HasIllegalRedeclaration()) { |
2778 Bailout("function with illegal redeclaration"); | 2783 Bailout("function with illegal redeclaration"); |
2779 return NULL; | 2784 return NULL; |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3110 | 3115 |
3111 static bool BoundsCheckKeyMatch(void* key1, void* key2) { | 3116 static bool BoundsCheckKeyMatch(void* key1, void* key2) { |
3112 BoundsCheckKey* k1 = static_cast<BoundsCheckKey*>(key1); | 3117 BoundsCheckKey* k1 = static_cast<BoundsCheckKey*>(key1); |
3113 BoundsCheckKey* k2 = static_cast<BoundsCheckKey*>(key2); | 3118 BoundsCheckKey* k2 = static_cast<BoundsCheckKey*>(key2); |
3114 return k1->IndexBase() == k2->IndexBase() && k1->Length() == k2->Length(); | 3119 return k1->IndexBase() == k2->IndexBase() && k1->Length() == k2->Length(); |
3115 } | 3120 } |
3116 | 3121 |
3117 | 3122 |
3118 class BoundsCheckTable : private ZoneHashMap { | 3123 class BoundsCheckTable : private ZoneHashMap { |
3119 public: | 3124 public: |
3120 BoundsCheckBbData** LookupOrInsert(BoundsCheckKey* key) { | 3125 BoundsCheckBbData** LookupOrInsert(BoundsCheckKey* key, Zone* zone) { |
3121 return reinterpret_cast<BoundsCheckBbData**>( | 3126 return reinterpret_cast<BoundsCheckBbData**>( |
3122 &(Lookup(key, key->Hash(), true)->value)); | 3127 &(Lookup(key, key->Hash(), true, ZoneAllocationPolicy(zone))->value)); |
3123 } | 3128 } |
3124 | 3129 |
3125 void Insert(BoundsCheckKey* key, BoundsCheckBbData* data) { | 3130 void Insert(BoundsCheckKey* key, BoundsCheckBbData* data, Zone* zone) { |
3126 Lookup(key, key->Hash(), true)->value = data; | 3131 Lookup(key, key->Hash(), true, ZoneAllocationPolicy(zone))->value = data; |
3127 } | 3132 } |
3128 | 3133 |
3129 void Delete(BoundsCheckKey* key) { | 3134 void Delete(BoundsCheckKey* key) { |
3130 Remove(key, key->Hash()); | 3135 Remove(key, key->Hash()); |
3131 } | 3136 } |
3132 | 3137 |
3133 BoundsCheckTable() : ZoneHashMap(BoundsCheckKeyMatch) { } | 3138 explicit BoundsCheckTable(Zone* zone) |
3139 : ZoneHashMap(BoundsCheckKeyMatch, ZoneHashMap::kDefaultHashMapCapacity, | |
3140 ZoneAllocationPolicy(zone)) { } | |
3134 }; | 3141 }; |
3135 | 3142 |
3136 | 3143 |
3137 // Eliminates checks in bb and recursively in the dominated blocks. | 3144 // Eliminates checks in bb and recursively in the dominated blocks. |
3138 // Also replace the results of check instructions with the original value, if | 3145 // Also replace the results of check instructions with the original value, if |
3139 // the result is used. This is safe now, since we don't do code motion after | 3146 // the result is used. This is safe now, since we don't do code motion after |
3140 // this point. It enables better register allocation since the value produced | 3147 // this point. It enables better register allocation since the value produced |
3141 // by check instructions is really a copy of the original value. | 3148 // by check instructions is really a copy of the original value. |
3142 void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, | 3149 void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, |
3143 BoundsCheckTable* table) { | 3150 BoundsCheckTable* table) { |
3144 BoundsCheckBbData* bb_data_list = NULL; | 3151 BoundsCheckBbData* bb_data_list = NULL; |
3145 | 3152 |
3146 for (HInstruction* i = bb->first(); i != NULL; i = i->next()) { | 3153 for (HInstruction* i = bb->first(); i != NULL; i = i->next()) { |
3147 if (!i->IsBoundsCheck()) continue; | 3154 if (!i->IsBoundsCheck()) continue; |
3148 | 3155 |
3149 HBoundsCheck* check = HBoundsCheck::cast(i); | 3156 HBoundsCheck* check = HBoundsCheck::cast(i); |
3150 check->ReplaceAllUsesWith(check->index()); | 3157 check->ReplaceAllUsesWith(check->index()); |
3151 | 3158 |
3152 if (!FLAG_array_bounds_checks_elimination) continue; | 3159 if (!FLAG_array_bounds_checks_elimination) continue; |
3153 | 3160 |
3154 int32_t offset; | 3161 int32_t offset; |
3155 BoundsCheckKey* key = | 3162 BoundsCheckKey* key = |
3156 BoundsCheckKey::Create(bb->zone(), check, &offset); | 3163 BoundsCheckKey::Create(zone(), check, &offset); |
3157 BoundsCheckBbData** data_p = table->LookupOrInsert(key); | 3164 BoundsCheckBbData** data_p = table->LookupOrInsert(key, zone()); |
3158 BoundsCheckBbData* data = *data_p; | 3165 BoundsCheckBbData* data = *data_p; |
3159 if (data == NULL) { | 3166 if (data == NULL) { |
3160 bb_data_list = new(zone()) BoundsCheckBbData(key, | 3167 bb_data_list = new(zone()) BoundsCheckBbData(key, |
3161 offset, | 3168 offset, |
3162 offset, | 3169 offset, |
3163 bb, | 3170 bb, |
3164 check, | 3171 check, |
3165 bb_data_list, | 3172 bb_data_list, |
3166 NULL); | 3173 NULL); |
3167 *data_p = bb_data_list; | 3174 *data_p = bb_data_list; |
3168 } else if (data->OffsetIsCovered(offset)) { | 3175 } else if (data->OffsetIsCovered(offset)) { |
3169 check->DeleteAndReplaceWith(NULL); | 3176 check->DeleteAndReplaceWith(NULL); |
3170 } else if (data->BasicBlock() == bb) { | 3177 } else if (data->BasicBlock() == bb) { |
3171 data->CoverCheck(check, offset); | 3178 data->CoverCheck(check, offset); |
3172 } else { | 3179 } else { |
3173 int32_t new_lower_offset = offset < data->LowerOffset() | 3180 int32_t new_lower_offset = offset < data->LowerOffset() |
3174 ? offset | 3181 ? offset |
3175 : data->LowerOffset(); | 3182 : data->LowerOffset(); |
3176 int32_t new_upper_offset = offset > data->UpperOffset() | 3183 int32_t new_upper_offset = offset > data->UpperOffset() |
3177 ? offset | 3184 ? offset |
3178 : data->UpperOffset(); | 3185 : data->UpperOffset(); |
3179 bb_data_list = new(bb->zone()) BoundsCheckBbData(key, | 3186 bb_data_list = new(zone()) BoundsCheckBbData(key, |
3180 new_lower_offset, | 3187 new_lower_offset, |
3181 new_upper_offset, | 3188 new_upper_offset, |
3182 bb, | 3189 bb, |
3183 check, | 3190 check, |
3184 bb_data_list, | 3191 bb_data_list, |
3185 data); | 3192 data); |
3186 table->Insert(key, bb_data_list); | 3193 table->Insert(key, bb_data_list, zone()); |
3187 } | 3194 } |
3188 } | 3195 } |
3189 | 3196 |
3190 for (int i = 0; i < bb->dominated_blocks()->length(); ++i) { | 3197 for (int i = 0; i < bb->dominated_blocks()->length(); ++i) { |
3191 EliminateRedundantBoundsChecks(bb->dominated_blocks()->at(i), table); | 3198 EliminateRedundantBoundsChecks(bb->dominated_blocks()->at(i), table); |
3192 } | 3199 } |
3193 | 3200 |
3194 for (BoundsCheckBbData* data = bb_data_list; | 3201 for (BoundsCheckBbData* data = bb_data_list; |
3195 data != NULL; | 3202 data != NULL; |
3196 data = data->NextInBasicBlock()) { | 3203 data = data->NextInBasicBlock()) { |
3197 data->RemoveZeroOperations(); | 3204 data->RemoveZeroOperations(); |
3198 if (data->FatherInDominatorTree()) { | 3205 if (data->FatherInDominatorTree()) { |
3199 table->Insert(data->Key(), data->FatherInDominatorTree()); | 3206 table->Insert(data->Key(), data->FatherInDominatorTree(), zone()); |
3200 } else { | 3207 } else { |
3201 table->Delete(data->Key()); | 3208 table->Delete(data->Key()); |
3202 } | 3209 } |
3203 } | 3210 } |
3204 } | 3211 } |
3205 | 3212 |
3206 | 3213 |
3207 void HGraph::EliminateRedundantBoundsChecks() { | 3214 void HGraph::EliminateRedundantBoundsChecks() { |
3208 HPhase phase("H_Eliminate bounds checks", this); | 3215 HPhase phase("H_Eliminate bounds checks", this); |
3209 AssertNoAllocation no_gc; | 3216 AssertNoAllocation no_gc; |
3210 BoundsCheckTable checks_table; | 3217 BoundsCheckTable checks_table(zone()); |
3211 EliminateRedundantBoundsChecks(entry_block(), &checks_table); | 3218 EliminateRedundantBoundsChecks(entry_block(), &checks_table); |
3212 } | 3219 } |
3213 | 3220 |
3214 | 3221 |
3215 static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) { | 3222 static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) { |
3216 HValue* index = array_operation->GetKey(); | 3223 HValue* index = array_operation->GetKey(); |
3217 | 3224 |
3218 HConstant* constant; | 3225 HConstant* constant; |
3219 HValue* subexpression; | 3226 HValue* subexpression; |
3220 int32_t sign; | 3227 int32_t sign; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3320 | 3327 |
3321 void HGraphBuilder::PushAndAdd(HInstruction* instr) { | 3328 void HGraphBuilder::PushAndAdd(HInstruction* instr) { |
3322 Push(instr); | 3329 Push(instr); |
3323 AddInstruction(instr); | 3330 AddInstruction(instr); |
3324 } | 3331 } |
3325 | 3332 |
3326 | 3333 |
3327 template <class Instruction> | 3334 template <class Instruction> |
3328 HInstruction* HGraphBuilder::PreProcessCall(Instruction* call) { | 3335 HInstruction* HGraphBuilder::PreProcessCall(Instruction* call) { |
3329 int count = call->argument_count(); | 3336 int count = call->argument_count(); |
3330 ZoneList<HValue*> arguments(count); | 3337 ZoneList<HValue*> arguments(count, zone()); |
3331 for (int i = 0; i < count; ++i) { | 3338 for (int i = 0; i < count; ++i) { |
3332 arguments.Add(Pop()); | 3339 arguments.Add(Pop(), zone()); |
3333 } | 3340 } |
3334 | 3341 |
3335 while (!arguments.is_empty()) { | 3342 while (!arguments.is_empty()) { |
3336 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); | 3343 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); |
3337 } | 3344 } |
3338 return call; | 3345 return call; |
3339 } | 3346 } |
3340 | 3347 |
3341 | 3348 |
3342 void HGraphBuilder::SetUpScope(Scope* scope) { | 3349 void HGraphBuilder::SetUpScope(Scope* scope) { |
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3822 current_block()->Finish(test); | 3829 current_block()->Finish(test); |
3823 | 3830 |
3824 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); | 3831 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); |
3825 non_osr_entry->Goto(loop_predecessor); | 3832 non_osr_entry->Goto(loop_predecessor); |
3826 | 3833 |
3827 set_current_block(osr_entry); | 3834 set_current_block(osr_entry); |
3828 int osr_entry_id = statement->OsrEntryId(); | 3835 int osr_entry_id = statement->OsrEntryId(); |
3829 int first_expression_index = environment()->first_expression_index(); | 3836 int first_expression_index = environment()->first_expression_index(); |
3830 int length = environment()->length(); | 3837 int length = environment()->length(); |
3831 ZoneList<HUnknownOSRValue*>* osr_values = | 3838 ZoneList<HUnknownOSRValue*>* osr_values = |
3832 new(zone()) ZoneList<HUnknownOSRValue*>(length); | 3839 new(zone()) ZoneList<HUnknownOSRValue*>(length, zone()); |
3833 | 3840 |
3834 for (int i = 0; i < first_expression_index; ++i) { | 3841 for (int i = 0; i < first_expression_index; ++i) { |
3835 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 3842 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; |
3836 AddInstruction(osr_value); | 3843 AddInstruction(osr_value); |
3837 environment()->Bind(i, osr_value); | 3844 environment()->Bind(i, osr_value); |
3838 osr_values->Add(osr_value); | 3845 osr_values->Add(osr_value, zone()); |
3839 } | 3846 } |
3840 | 3847 |
3841 if (first_expression_index != length) { | 3848 if (first_expression_index != length) { |
3842 environment()->Drop(length - first_expression_index); | 3849 environment()->Drop(length - first_expression_index); |
3843 for (int i = first_expression_index; i < length; ++i) { | 3850 for (int i = first_expression_index; i < length; ++i) { |
3844 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 3851 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; |
3845 AddInstruction(osr_value); | 3852 AddInstruction(osr_value); |
3846 environment()->Push(osr_value); | 3853 environment()->Push(osr_value); |
3847 osr_values->Add(osr_value); | 3854 osr_values->Add(osr_value, zone()); |
3848 } | 3855 } |
3849 } | 3856 } |
3850 | 3857 |
3851 graph()->set_osr_values(osr_values); | 3858 graph()->set_osr_values(osr_values); |
3852 | 3859 |
3853 AddSimulate(osr_entry_id); | 3860 AddSimulate(osr_entry_id); |
3854 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); | 3861 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); |
3855 HContext* context = new(zone()) HContext; | 3862 HContext* context = new(zone()) HContext; |
3856 AddInstruction(context); | 3863 AddInstruction(context); |
3857 environment()->BindContext(context); | 3864 environment()->BindContext(context); |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4465 expr->fast_elements(), | 4472 expr->fast_elements(), |
4466 expr->literal_index(), | 4473 expr->literal_index(), |
4467 expr->depth(), | 4474 expr->depth(), |
4468 expr->has_function()); | 4475 expr->has_function()); |
4469 } | 4476 } |
4470 | 4477 |
4471 // The object is expected in the bailout environment during computation | 4478 // The object is expected in the bailout environment during computation |
4472 // of the property values and is the value of the entire expression. | 4479 // of the property values and is the value of the entire expression. |
4473 PushAndAdd(literal); | 4480 PushAndAdd(literal); |
4474 | 4481 |
4475 expr->CalculateEmitStore(); | 4482 expr->CalculateEmitStore(zone()); |
4476 | 4483 |
4477 for (int i = 0; i < expr->properties()->length(); i++) { | 4484 for (int i = 0; i < expr->properties()->length(); i++) { |
4478 ObjectLiteral::Property* property = expr->properties()->at(i); | 4485 ObjectLiteral::Property* property = expr->properties()->at(i); |
4479 if (property->IsCompileTimeValue()) continue; | 4486 if (property->IsCompileTimeValue()) continue; |
4480 | 4487 |
4481 Literal* key = property->key(); | 4488 Literal* key = property->key(); |
4482 Expression* value = property->value(); | 4489 Expression* value = property->value(); |
4483 | 4490 |
4484 switch (property->kind()) { | 4491 switch (property->kind()) { |
4485 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 4492 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4655 | 4662 |
4656 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, | 4663 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, |
4657 Handle<String> name, | 4664 Handle<String> name, |
4658 HValue* value, | 4665 HValue* value, |
4659 Handle<Map> type, | 4666 Handle<Map> type, |
4660 LookupResult* lookup, | 4667 LookupResult* lookup, |
4661 bool smi_and_map_check) { | 4668 bool smi_and_map_check) { |
4662 ASSERT(lookup->IsFound()); | 4669 ASSERT(lookup->IsFound()); |
4663 if (smi_and_map_check) { | 4670 if (smi_and_map_check) { |
4664 AddInstruction(new(zone()) HCheckNonSmi(object)); | 4671 AddInstruction(new(zone()) HCheckNonSmi(object)); |
4665 AddInstruction(HCheckMaps::NewWithTransitions(object, type)); | 4672 AddInstruction(HCheckMaps::NewWithTransitions(object, type, zone())); |
4666 } | 4673 } |
4667 | 4674 |
4668 // If the property does not exist yet, we have to check that it wasn't made | 4675 // If the property does not exist yet, we have to check that it wasn't made |
4669 // readonly or turned into a setter by some meanwhile modifications on the | 4676 // readonly or turned into a setter by some meanwhile modifications on the |
4670 // prototype chain. | 4677 // prototype chain. |
4671 if (!lookup->IsProperty()) { | 4678 if (!lookup->IsProperty()) { |
4672 Object* proto = type->prototype(); | 4679 Object* proto = type->prototype(); |
4673 // First check that the prototype chain isn't affected already. | 4680 // First check that the prototype chain isn't affected already. |
4674 LookupResult proto_result(isolate()); | 4681 LookupResult proto_result(isolate()); |
4675 proto->Lookup(*name, &proto_result); | 4682 proto->Lookup(*name, &proto_result); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4800 (is_in_object == previous_field_is_in_object); | 4807 (is_in_object == previous_field_is_in_object); |
4801 } | 4808 } |
4802 ++count; | 4809 ++count; |
4803 } | 4810 } |
4804 } | 4811 } |
4805 | 4812 |
4806 // Use monomorphic load if property lookup results in the same field index | 4813 // Use monomorphic load if property lookup results in the same field index |
4807 // for all maps. Requires special map check on the set of all handled maps. | 4814 // for all maps. Requires special map check on the set of all handled maps. |
4808 HInstruction* instr; | 4815 HInstruction* instr; |
4809 if (count == types->length() && is_monomorphic_field) { | 4816 if (count == types->length() && is_monomorphic_field) { |
4810 AddInstruction(new(zone()) HCheckMaps(object, types)); | 4817 AddInstruction(new(zone()) HCheckMaps(object, types, zone())); |
4811 instr = BuildLoadNamedField(object, expr, map, &lookup, false); | 4818 instr = BuildLoadNamedField(object, expr, map, &lookup, false); |
4812 } else { | 4819 } else { |
4813 HValue* context = environment()->LookupContext(); | 4820 HValue* context = environment()->LookupContext(); |
4814 instr = new(zone()) HLoadNamedFieldPolymorphic(context, | 4821 instr = new(zone()) HLoadNamedFieldPolymorphic(context, |
4815 object, | 4822 object, |
4816 types, | 4823 types, |
4817 name); | 4824 name, |
4825 zone()); | |
4818 } | 4826 } |
4819 | 4827 |
4820 instr->set_position(expr->position()); | 4828 instr->set_position(expr->position()); |
4821 return ast_context()->ReturnInstruction(instr, expr->id()); | 4829 return ast_context()->ReturnInstruction(instr, expr->id()); |
4822 } | 4830 } |
4823 | 4831 |
4824 | 4832 |
4825 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, | 4833 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, |
4826 HValue* object, | 4834 HValue* object, |
4827 HValue* value, | 4835 HValue* value, |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4894 ASSERT(join != NULL); | 4902 ASSERT(join != NULL); |
4895 join->SetJoinId(expr->id()); | 4903 join->SetJoinId(expr->id()); |
4896 set_current_block(join); | 4904 set_current_block(join); |
4897 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); | 4905 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); |
4898 } | 4906 } |
4899 | 4907 |
4900 | 4908 |
4901 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { | 4909 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { |
4902 Property* prop = expr->target()->AsProperty(); | 4910 Property* prop = expr->target()->AsProperty(); |
4903 ASSERT(prop != NULL); | 4911 ASSERT(prop != NULL); |
4904 expr->RecordTypeFeedback(oracle()); | 4912 expr->RecordTypeFeedback(oracle(), zone()); |
4905 CHECK_ALIVE(VisitForValue(prop->obj())); | 4913 CHECK_ALIVE(VisitForValue(prop->obj())); |
4906 | 4914 |
4907 HValue* value = NULL; | 4915 HValue* value = NULL; |
4908 HInstruction* instr = NULL; | 4916 HInstruction* instr = NULL; |
4909 | 4917 |
4910 if (prop->key()->IsPropertyName()) { | 4918 if (prop->key()->IsPropertyName()) { |
4911 // Named store. | 4919 // Named store. |
4912 CHECK_ALIVE(VisitForValue(expr->value())); | 4920 CHECK_ALIVE(VisitForValue(expr->value())); |
4913 value = Pop(); | 4921 value = Pop(); |
4914 HValue* object = Pop(); | 4922 HValue* object = Pop(); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5065 } | 5073 } |
5066 break; | 5074 break; |
5067 } | 5075 } |
5068 | 5076 |
5069 case Variable::LOOKUP: | 5077 case Variable::LOOKUP: |
5070 return Bailout("compound assignment to lookup slot"); | 5078 return Bailout("compound assignment to lookup slot"); |
5071 } | 5079 } |
5072 return ast_context()->ReturnValue(Pop()); | 5080 return ast_context()->ReturnValue(Pop()); |
5073 | 5081 |
5074 } else if (prop != NULL) { | 5082 } else if (prop != NULL) { |
5075 prop->RecordTypeFeedback(oracle()); | 5083 prop->RecordTypeFeedback(oracle(), zone()); |
5076 | 5084 |
5077 if (prop->key()->IsPropertyName()) { | 5085 if (prop->key()->IsPropertyName()) { |
5078 // Named property. | 5086 // Named property. |
5079 CHECK_ALIVE(VisitForValue(prop->obj())); | 5087 CHECK_ALIVE(VisitForValue(prop->obj())); |
5080 HValue* obj = Top(); | 5088 HValue* obj = Top(); |
5081 | 5089 |
5082 HInstruction* load = NULL; | 5090 HInstruction* load = NULL; |
5083 if (prop->IsMonomorphic()) { | 5091 if (prop->IsMonomorphic()) { |
5084 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 5092 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
5085 Handle<Map> map = prop->GetReceiverTypes()->first(); | 5093 Handle<Map> map = prop->GetReceiverTypes()->first(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5124 | 5132 |
5125 | 5133 |
5126 CHECK_ALIVE(VisitForValue(expr->value())); | 5134 CHECK_ALIVE(VisitForValue(expr->value())); |
5127 HValue* right = Pop(); | 5135 HValue* right = Pop(); |
5128 HValue* left = Pop(); | 5136 HValue* left = Pop(); |
5129 | 5137 |
5130 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 5138 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
5131 PushAndAdd(instr); | 5139 PushAndAdd(instr); |
5132 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); | 5140 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); |
5133 | 5141 |
5134 expr->RecordTypeFeedback(oracle()); | 5142 expr->RecordTypeFeedback(oracle(), zone()); |
5135 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), | 5143 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), |
5136 RelocInfo::kNoPosition, | 5144 RelocInfo::kNoPosition, |
5137 true, // is_store | 5145 true, // is_store |
5138 &has_side_effects); | 5146 &has_side_effects); |
5139 | 5147 |
5140 // Drop the simulated receiver, key, and value. Return the value. | 5148 // Drop the simulated receiver, key, and value. Return the value. |
5141 Drop(3); | 5149 Drop(3); |
5142 Push(instr); | 5150 Push(instr); |
5143 ASSERT(has_side_effects); // Stores always have side effects. | 5151 ASSERT(has_side_effects); // Stores always have side effects. |
5144 AddSimulate(expr->AssignmentId()); | 5152 AddSimulate(expr->AssignmentId()); |
(...skipping 27 matching lines...) Expand all Loading... | |
5172 if (var->mode() == CONST) { | 5180 if (var->mode() == CONST) { |
5173 if (expr->op() != Token::INIT_CONST) { | 5181 if (expr->op() != Token::INIT_CONST) { |
5174 CHECK_ALIVE(VisitForValue(expr->value())); | 5182 CHECK_ALIVE(VisitForValue(expr->value())); |
5175 return ast_context()->ReturnValue(Pop()); | 5183 return ast_context()->ReturnValue(Pop()); |
5176 } | 5184 } |
5177 | 5185 |
5178 if (var->IsStackAllocated()) { | 5186 if (var->IsStackAllocated()) { |
5179 // We insert a use of the old value to detect unsupported uses of const | 5187 // We insert a use of the old value to detect unsupported uses of const |
5180 // variables (e.g. initialization inside a loop). | 5188 // variables (e.g. initialization inside a loop). |
5181 HValue* old_value = environment()->Lookup(var); | 5189 HValue* old_value = environment()->Lookup(var); |
5182 AddInstruction(new HUseConst(old_value)); | 5190 AddInstruction(new(zone()) HUseConst(old_value)); |
5183 } | 5191 } |
5184 } else if (var->mode() == CONST_HARMONY) { | 5192 } else if (var->mode() == CONST_HARMONY) { |
5185 if (expr->op() != Token::INIT_CONST_HARMONY) { | 5193 if (expr->op() != Token::INIT_CONST_HARMONY) { |
5186 return Bailout("non-initializer assignment to const"); | 5194 return Bailout("non-initializer assignment to const"); |
5187 } | 5195 } |
5188 } | 5196 } |
5189 | 5197 |
5190 if (proxy->IsArguments()) return Bailout("assignment to arguments"); | 5198 if (proxy->IsArguments()) return Bailout("assignment to arguments"); |
5191 | 5199 |
5192 // Handle the assignment. | 5200 // Handle the assignment. |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5299 } | 5307 } |
5300 | 5308 |
5301 | 5309 |
5302 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, | 5310 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, |
5303 Property* expr, | 5311 Property* expr, |
5304 Handle<Map> type, | 5312 Handle<Map> type, |
5305 LookupResult* lookup, | 5313 LookupResult* lookup, |
5306 bool smi_and_map_check) { | 5314 bool smi_and_map_check) { |
5307 if (smi_and_map_check) { | 5315 if (smi_and_map_check) { |
5308 AddInstruction(new(zone()) HCheckNonSmi(object)); | 5316 AddInstruction(new(zone()) HCheckNonSmi(object)); |
5309 AddInstruction(HCheckMaps::NewWithTransitions(object, type)); | 5317 AddInstruction(HCheckMaps::NewWithTransitions(object, type, zone())); |
5310 } | 5318 } |
5311 | 5319 |
5312 int index = lookup->GetLocalFieldIndexFromMap(*type); | 5320 int index = lookup->GetLocalFieldIndexFromMap(*type); |
5313 if (index < 0) { | 5321 if (index < 0) { |
5314 // Negative property indices are in-object properties, indexed | 5322 // Negative property indices are in-object properties, indexed |
5315 // from the end of the fixed part of the object. | 5323 // from the end of the fixed part of the object. |
5316 int offset = (index * kPointerSize) + type->instance_size(); | 5324 int offset = (index * kPointerSize) + type->instance_size(); |
5317 return new(zone()) HLoadNamedField(object, true, offset); | 5325 return new(zone()) HLoadNamedField(object, true, offset); |
5318 } else { | 5326 } else { |
5319 // Non-negative property indices are in the properties array. | 5327 // Non-negative property indices are in the properties array. |
(...skipping 23 matching lines...) Expand all Loading... | |
5343 LookupResult lookup(isolate()); | 5351 LookupResult lookup(isolate()); |
5344 map->LookupInDescriptors(NULL, *name, &lookup); | 5352 map->LookupInDescriptors(NULL, *name, &lookup); |
5345 if (lookup.IsFound() && lookup.type() == FIELD) { | 5353 if (lookup.IsFound() && lookup.type() == FIELD) { |
5346 return BuildLoadNamedField(obj, | 5354 return BuildLoadNamedField(obj, |
5347 expr, | 5355 expr, |
5348 map, | 5356 map, |
5349 &lookup, | 5357 &lookup, |
5350 true); | 5358 true); |
5351 } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) { | 5359 } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) { |
5352 AddInstruction(new(zone()) HCheckNonSmi(obj)); | 5360 AddInstruction(new(zone()) HCheckNonSmi(obj)); |
5353 AddInstruction(HCheckMaps::NewWithTransitions(obj, map)); | 5361 AddInstruction(HCheckMaps::NewWithTransitions(obj, map, zone())); |
5354 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); | 5362 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); |
5355 return new(zone()) HConstant(function, Representation::Tagged()); | 5363 return new(zone()) HConstant(function, Representation::Tagged()); |
5356 } else { | 5364 } else { |
5357 return BuildLoadNamedGeneric(obj, expr); | 5365 return BuildLoadNamedGeneric(obj, expr); |
5358 } | 5366 } |
5359 } | 5367 } |
5360 | 5368 |
5361 | 5369 |
5362 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 5370 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
5363 HValue* key) { | 5371 HValue* key) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5456 } | 5464 } |
5457 | 5465 |
5458 | 5466 |
5459 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, | 5467 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, |
5460 HValue* key, | 5468 HValue* key, |
5461 HValue* val, | 5469 HValue* val, |
5462 HValue* dependency, | 5470 HValue* dependency, |
5463 Handle<Map> map, | 5471 Handle<Map> map, |
5464 bool is_store) { | 5472 bool is_store) { |
5465 HInstruction* mapcheck = | 5473 HInstruction* mapcheck = |
5466 AddInstruction(new(zone()) HCheckMaps(object, map, dependency)); | 5474 AddInstruction(new(zone()) HCheckMaps(object, map, zone(), dependency)); |
5467 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency | 5475 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency |
5468 // on a HElementsTransition instruction. The flag can also be removed if the | 5476 // on a HElementsTransition instruction. The flag can also be removed if the |
5469 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further | 5477 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further |
5470 // ElementsKind transitions. Finally, the dependency can be removed for stores | 5478 // ElementsKind transitions. Finally, the dependency can be removed for stores |
5471 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the | 5479 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the |
5472 // generated store code. | 5480 // generated store code. |
5473 if (dependency || | 5481 if (dependency || |
5474 (map->elements_kind() == FAST_HOLEY_ELEMENTS) || | 5482 (map->elements_kind() == FAST_HOLEY_ELEMENTS) || |
5475 (map->elements_kind() == FAST_ELEMENTS && is_store)) { | 5483 (map->elements_kind() == FAST_ELEMENTS && is_store)) { |
5476 mapcheck->ClearGVNFlag(kDependsOnElementsKind); | 5484 mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
5477 } | 5485 } |
5478 bool fast_smi_only_elements = map->has_fast_smi_elements(); | 5486 bool fast_smi_only_elements = map->has_fast_smi_elements(); |
5479 bool fast_elements = map->has_fast_object_elements(); | 5487 bool fast_elements = map->has_fast_object_elements(); |
5480 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); | 5488 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); |
5481 if (is_store && (fast_elements || fast_smi_only_elements)) { | 5489 if (is_store && (fast_elements || fast_smi_only_elements)) { |
5482 HCheckMaps* check_cow_map = new(zone()) HCheckMaps( | 5490 HCheckMaps* check_cow_map = new(zone()) HCheckMaps( |
5483 elements, isolate()->factory()->fixed_array_map()); | 5491 elements, isolate()->factory()->fixed_array_map(), zone()); |
5484 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 5492 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
5485 AddInstruction(check_cow_map); | 5493 AddInstruction(check_cow_map); |
5486 } | 5494 } |
5487 HInstruction* length = NULL; | 5495 HInstruction* length = NULL; |
5488 HInstruction* checked_key = NULL; | 5496 HInstruction* checked_key = NULL; |
5489 if (map->has_external_array_elements()) { | 5497 if (map->has_external_array_elements()) { |
5490 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 5498 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
5491 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 5499 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
5492 HLoadExternalArrayPointer* external_elements = | 5500 HLoadExternalArrayPointer* external_elements = |
5493 new(zone()) HLoadExternalArrayPointer(elements); | 5501 new(zone()) HLoadExternalArrayPointer(elements); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5580 : BuildLoadKeyedGeneric(object, key)); | 5588 : BuildLoadKeyedGeneric(object, key)); |
5581 } else { | 5589 } else { |
5582 instr = AddInstruction(BuildMonomorphicElementAccess( | 5590 instr = AddInstruction(BuildMonomorphicElementAccess( |
5583 object, key, val, transition, untransitionable_map, is_store)); | 5591 object, key, val, transition, untransitionable_map, is_store)); |
5584 } | 5592 } |
5585 *has_side_effects |= instr->HasObservableSideEffects(); | 5593 *has_side_effects |= instr->HasObservableSideEffects(); |
5586 instr->set_position(position); | 5594 instr->set_position(position); |
5587 return is_store ? NULL : instr; | 5595 return is_store ? NULL : instr; |
5588 } | 5596 } |
5589 | 5597 |
5590 AddInstruction(HCheckInstanceType::NewIsSpecObject(object)); | 5598 AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone())); |
5591 HBasicBlock* join = graph()->CreateBasicBlock(); | 5599 HBasicBlock* join = graph()->CreateBasicBlock(); |
5592 | 5600 |
5593 HInstruction* elements_kind_instr = | 5601 HInstruction* elements_kind_instr = |
5594 AddInstruction(new(zone()) HElementsKind(object)); | 5602 AddInstruction(new(zone()) HElementsKind(object)); |
5595 HCompareConstantEqAndBranch* elements_kind_branch = NULL; | 5603 HCompareConstantEqAndBranch* elements_kind_branch = NULL; |
5596 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); | 5604 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); |
5597 HLoadExternalArrayPointer* external_elements = NULL; | 5605 HLoadExternalArrayPointer* external_elements = NULL; |
5598 HInstruction* checked_key = NULL; | 5606 HInstruction* checked_key = NULL; |
5599 | 5607 |
5600 // Generated code assumes that FAST_* and DICTIONARY_ELEMENTS ElementsKinds | 5608 // Generated code assumes that FAST_* and DICTIONARY_ELEMENTS ElementsKinds |
(...skipping 26 matching lines...) Expand all Loading... | |
5627 elements_kind_branch->SetSuccessorAt(0, if_true); | 5635 elements_kind_branch->SetSuccessorAt(0, if_true); |
5628 elements_kind_branch->SetSuccessorAt(1, if_false); | 5636 elements_kind_branch->SetSuccessorAt(1, if_false); |
5629 current_block()->Finish(elements_kind_branch); | 5637 current_block()->Finish(elements_kind_branch); |
5630 | 5638 |
5631 set_current_block(if_true); | 5639 set_current_block(if_true); |
5632 HInstruction* access; | 5640 HInstruction* access; |
5633 if (IsFastElementsKind(elements_kind)) { | 5641 if (IsFastElementsKind(elements_kind)) { |
5634 if (is_store && !IsFastDoubleElementsKind(elements_kind)) { | 5642 if (is_store && !IsFastDoubleElementsKind(elements_kind)) { |
5635 AddInstruction(new(zone()) HCheckMaps( | 5643 AddInstruction(new(zone()) HCheckMaps( |
5636 elements, isolate()->factory()->fixed_array_map(), | 5644 elements, isolate()->factory()->fixed_array_map(), |
5637 elements_kind_branch)); | 5645 zone(), elements_kind_branch)); |
5638 } | 5646 } |
5639 // TODO(jkummerow): The need for these two blocks could be avoided | 5647 // TODO(jkummerow): The need for these two blocks could be avoided |
5640 // in one of two ways: | 5648 // in one of two ways: |
5641 // (1) Introduce ElementsKinds for JSArrays that are distinct from | 5649 // (1) Introduce ElementsKinds for JSArrays that are distinct from |
5642 // those for fast objects. | 5650 // those for fast objects. |
5643 // (2) Put the common instructions into a third "join" block. This | 5651 // (2) Put the common instructions into a third "join" block. This |
5644 // requires additional AST IDs that we can deopt to from inside | 5652 // requires additional AST IDs that we can deopt to from inside |
5645 // that join block. They must be added to the Property class (when | 5653 // that join block. They must be added to the Property class (when |
5646 // it's a keyed property) and registered in the full codegen. | 5654 // it's a keyed property) and registered in the full codegen. |
5647 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); | 5655 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5834 } | 5842 } |
5835 ast_context()->ReturnInstruction(result, expr->id()); | 5843 ast_context()->ReturnInstruction(result, expr->id()); |
5836 return true; | 5844 return true; |
5837 } | 5845 } |
5838 | 5846 |
5839 | 5847 |
5840 void HGraphBuilder::VisitProperty(Property* expr) { | 5848 void HGraphBuilder::VisitProperty(Property* expr) { |
5841 ASSERT(!HasStackOverflow()); | 5849 ASSERT(!HasStackOverflow()); |
5842 ASSERT(current_block() != NULL); | 5850 ASSERT(current_block() != NULL); |
5843 ASSERT(current_block()->HasPredecessor()); | 5851 ASSERT(current_block()->HasPredecessor()); |
5844 expr->RecordTypeFeedback(oracle()); | 5852 expr->RecordTypeFeedback(oracle(), zone()); |
5845 | 5853 |
5846 if (TryArgumentsAccess(expr)) return; | 5854 if (TryArgumentsAccess(expr)) return; |
5847 | 5855 |
5848 CHECK_ALIVE(VisitForValue(expr->obj())); | 5856 CHECK_ALIVE(VisitForValue(expr->obj())); |
5849 | 5857 |
5850 HInstruction* instr = NULL; | 5858 HInstruction* instr = NULL; |
5851 if (expr->AsProperty()->IsArrayLength()) { | 5859 if (expr->AsProperty()->IsArrayLength()) { |
5852 HValue* array = Pop(); | 5860 HValue* array = Pop(); |
5853 AddInstruction(new(zone()) HCheckNonSmi(array)); | 5861 AddInstruction(new(zone()) HCheckNonSmi(array)); |
5854 HInstruction* mapcheck = | 5862 HInstruction* mapcheck = |
5855 AddInstruction(HCheckInstanceType::NewIsJSArray(array)); | 5863 AddInstruction(HCheckInstanceType::NewIsJSArray(array, zone())); |
5856 instr = new(zone()) HJSArrayLength(array, mapcheck); | 5864 instr = new(zone()) HJSArrayLength(array, mapcheck); |
5857 | 5865 |
5858 } else if (expr->IsStringLength()) { | 5866 } else if (expr->IsStringLength()) { |
5859 HValue* string = Pop(); | 5867 HValue* string = Pop(); |
5860 AddInstruction(new(zone()) HCheckNonSmi(string)); | 5868 AddInstruction(new(zone()) HCheckNonSmi(string)); |
5861 AddInstruction(HCheckInstanceType::NewIsString(string)); | 5869 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
5862 instr = new(zone()) HStringLength(string); | 5870 instr = new(zone()) HStringLength(string); |
5863 } else if (expr->IsStringAccess()) { | 5871 } else if (expr->IsStringAccess()) { |
5864 CHECK_ALIVE(VisitForValue(expr->key())); | 5872 CHECK_ALIVE(VisitForValue(expr->key())); |
5865 HValue* index = Pop(); | 5873 HValue* index = Pop(); |
5866 HValue* string = Pop(); | 5874 HValue* string = Pop(); |
5867 HValue* context = environment()->LookupContext(); | 5875 HValue* context = environment()->LookupContext(); |
5868 HStringCharCodeAt* char_code = | 5876 HStringCharCodeAt* char_code = |
5869 BuildStringCharCodeAt(context, string, index); | 5877 BuildStringCharCodeAt(context, string, index); |
5870 AddInstruction(char_code); | 5878 AddInstruction(char_code); |
5871 instr = new(zone()) HStringCharFromCode(context, char_code); | 5879 instr = new(zone()) HStringCharFromCode(context, char_code); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5919 | 5927 |
5920 void HGraphBuilder::AddCheckConstantFunction(Call* expr, | 5928 void HGraphBuilder::AddCheckConstantFunction(Call* expr, |
5921 HValue* receiver, | 5929 HValue* receiver, |
5922 Handle<Map> receiver_map, | 5930 Handle<Map> receiver_map, |
5923 bool smi_and_map_check) { | 5931 bool smi_and_map_check) { |
5924 // Constant functions have the nice property that the map will change if they | 5932 // Constant functions have the nice property that the map will change if they |
5925 // are overwritten. Therefore it is enough to check the map of the holder and | 5933 // are overwritten. Therefore it is enough to check the map of the holder and |
5926 // its prototypes. | 5934 // its prototypes. |
5927 if (smi_and_map_check) { | 5935 if (smi_and_map_check) { |
5928 AddInstruction(new(zone()) HCheckNonSmi(receiver)); | 5936 AddInstruction(new(zone()) HCheckNonSmi(receiver)); |
5929 AddInstruction(HCheckMaps::NewWithTransitions(receiver, receiver_map)); | 5937 AddInstruction(HCheckMaps::NewWithTransitions(receiver, receiver_map, |
5938 zone())); | |
5930 } | 5939 } |
5931 if (!expr->holder().is_null()) { | 5940 if (!expr->holder().is_null()) { |
5932 AddInstruction(new(zone()) HCheckPrototypeMaps( | 5941 AddInstruction(new(zone()) HCheckPrototypeMaps( |
5933 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), | 5942 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), |
5934 expr->holder())); | 5943 expr->holder())); |
5935 } | 5944 } |
5936 } | 5945 } |
5937 | 5946 |
5938 | 5947 |
5939 class FunctionSorter { | 5948 class FunctionSorter { |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6254 // generating the optimized inline code. | 6263 // generating the optimized inline code. |
6255 target_info.EnableDeoptimizationSupport(); | 6264 target_info.EnableDeoptimizationSupport(); |
6256 if (!FullCodeGenerator::MakeCode(&target_info)) { | 6265 if (!FullCodeGenerator::MakeCode(&target_info)) { |
6257 TraceInline(target, caller, "could not generate deoptimization info"); | 6266 TraceInline(target, caller, "could not generate deoptimization info"); |
6258 return false; | 6267 return false; |
6259 } | 6268 } |
6260 if (target_shared->scope_info() == ScopeInfo::Empty()) { | 6269 if (target_shared->scope_info() == ScopeInfo::Empty()) { |
6261 // The scope info might not have been set if a lazily compiled | 6270 // The scope info might not have been set if a lazily compiled |
6262 // function is inlined before being called for the first time. | 6271 // function is inlined before being called for the first time. |
6263 Handle<ScopeInfo> target_scope_info = | 6272 Handle<ScopeInfo> target_scope_info = |
6264 ScopeInfo::Create(target_info.scope()); | 6273 ScopeInfo::Create(target_info.scope(), zone()); |
6265 target_shared->set_scope_info(*target_scope_info); | 6274 target_shared->set_scope_info(*target_scope_info); |
6266 } | 6275 } |
6267 target_shared->EnableDeoptimizationSupport(*target_info.code()); | 6276 target_shared->EnableDeoptimizationSupport(*target_info.code()); |
6268 Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG, | 6277 Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG, |
6269 &target_info, | 6278 &target_info, |
6270 target_shared); | 6279 target_shared); |
6271 } | 6280 } |
6272 | 6281 |
6273 // ---------------------------------------------------------------- | 6282 // ---------------------------------------------------------------- |
6274 // After this point, we've made a decision to inline this function (so | 6283 // After this point, we've made a decision to inline this function (so |
6275 // TryInline should always return true). | 6284 // TryInline should always return true). |
6276 | 6285 |
6277 // Save the pending call context and type feedback oracle. Set up new ones | 6286 // Save the pending call context and type feedback oracle. Set up new ones |
6278 // for the inlined function. | 6287 // for the inlined function. |
6279 ASSERT(target_shared->has_deoptimization_support()); | 6288 ASSERT(target_shared->has_deoptimization_support()); |
6280 TypeFeedbackOracle target_oracle( | 6289 TypeFeedbackOracle target_oracle( |
6281 Handle<Code>(target_shared->code()), | 6290 Handle<Code>(target_shared->code()), |
6282 Handle<Context>(target->context()->global_context()), | 6291 Handle<Context>(target->context()->global_context()), |
6283 isolate()); | 6292 isolate(), |
6293 zone()); | |
6284 // The function state is new-allocated because we need to delete it | 6294 // The function state is new-allocated because we need to delete it |
6285 // in two different places. | 6295 // in two different places. |
6286 FunctionState* target_state = new FunctionState( | 6296 FunctionState* target_state = new FunctionState( |
6287 this, &target_info, &target_oracle, return_handling); | 6297 this, &target_info, &target_oracle, return_handling); |
6288 | 6298 |
6289 HConstant* undefined = graph()->GetConstantUndefined(); | 6299 HConstant* undefined = graph()->GetConstantUndefined(); |
6290 HEnvironment* inner_env = | 6300 HEnvironment* inner_env = |
6291 environment()->CopyForInlining(target, | 6301 environment()->CopyForInlining(target, |
6292 arguments->length(), | 6302 arguments->length(), |
6293 function, | 6303 function, |
6294 undefined, | 6304 undefined, |
6295 call_kind, | 6305 call_kind, |
6296 function_state()->is_construct()); | 6306 function_state()->is_construct()); |
6297 #ifdef V8_TARGET_ARCH_IA32 | 6307 #ifdef V8_TARGET_ARCH_IA32 |
6298 // IA32 only, overwrite the caller's context in the deoptimization | 6308 // IA32 only, overwrite the caller's context in the deoptimization |
6299 // environment with the correct one. | 6309 // environment with the correct one. |
6300 // | 6310 // |
6301 // TODO(kmillikin): implement the same inlining on other platforms so we | 6311 // TODO(kmillikin): implement the same inlining on other platforms so we |
6302 // can remove the unsightly ifdefs in this function. | 6312 // can remove the unsightly ifdefs in this function. |
6303 HConstant* context = new HConstant(Handle<Context>(target->context()), | 6313 HConstant* context = |
6304 Representation::Tagged()); | 6314 new(zone()) HConstant(Handle<Context>(target->context()), |
6315 Representation::Tagged()); | |
6305 AddInstruction(context); | 6316 AddInstruction(context); |
6306 inner_env->BindContext(context); | 6317 inner_env->BindContext(context); |
6307 #endif | 6318 #endif |
6308 | 6319 |
6309 AddSimulate(return_id); | 6320 AddSimulate(return_id); |
6310 current_block()->UpdateEnvironment(inner_env); | 6321 current_block()->UpdateEnvironment(inner_env); |
6311 | 6322 |
6312 ZoneList<HValue*>* arguments_values = NULL; | 6323 ZoneList<HValue*>* arguments_values = NULL; |
6313 | 6324 |
6314 // If the function uses arguments copy current arguments values | 6325 // If the function uses arguments copy current arguments values |
6315 // to use them for materialization. | 6326 // to use them for materialization. |
6316 if (function->scope()->arguments() != NULL) { | 6327 if (function->scope()->arguments() != NULL) { |
6317 HEnvironment* arguments_env = inner_env->arguments_environment(); | 6328 HEnvironment* arguments_env = inner_env->arguments_environment(); |
6318 int arguments_count = arguments_env->parameter_count(); | 6329 int arguments_count = arguments_env->parameter_count(); |
6319 arguments_values = new(zone()) ZoneList<HValue*>(arguments_count); | 6330 arguments_values = new(zone()) ZoneList<HValue*>(arguments_count, zone()); |
6320 for (int i = 0; i < arguments_count; i++) { | 6331 for (int i = 0; i < arguments_count; i++) { |
6321 arguments_values->Add(arguments_env->Lookup(i)); | 6332 arguments_values->Add(arguments_env->Lookup(i), zone()); |
6322 } | 6333 } |
6323 } | 6334 } |
6324 | 6335 |
6325 HEnterInlined* enter_inlined = | 6336 HEnterInlined* enter_inlined = |
6326 new(zone()) HEnterInlined(target, | 6337 new(zone()) HEnterInlined(target, |
6327 arguments->length(), | 6338 arguments->length(), |
6328 function, | 6339 function, |
6329 call_kind, | 6340 call_kind, |
6330 function_state()->is_construct(), | 6341 function_state()->is_construct(), |
6331 function->scope()->arguments(), | 6342 function->scope()->arguments(), |
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6906 Drop(argument_count); | 6917 Drop(argument_count); |
6907 } | 6918 } |
6908 | 6919 |
6909 } else if (expr->IsMonomorphic()) { | 6920 } else if (expr->IsMonomorphic()) { |
6910 // The function is on the stack in the unoptimized code during | 6921 // The function is on the stack in the unoptimized code during |
6911 // evaluation of the arguments. | 6922 // evaluation of the arguments. |
6912 CHECK_ALIVE(VisitForValue(expr->expression())); | 6923 CHECK_ALIVE(VisitForValue(expr->expression())); |
6913 HValue* function = Top(); | 6924 HValue* function = Top(); |
6914 HValue* context = environment()->LookupContext(); | 6925 HValue* context = environment()->LookupContext(); |
6915 HGlobalObject* global = new(zone()) HGlobalObject(context); | 6926 HGlobalObject* global = new(zone()) HGlobalObject(context); |
6927 AddInstruction(global); | |
6916 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global); | 6928 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global); |
6917 AddInstruction(global); | |
6918 PushAndAdd(receiver); | 6929 PushAndAdd(receiver); |
6919 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 6930 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
6920 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); | 6931 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); |
6921 | 6932 |
6922 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. | 6933 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. |
6923 if (FLAG_trace_inlining) { | 6934 if (FLAG_trace_inlining) { |
6924 PrintF("Inlining builtin "); | 6935 PrintF("Inlining builtin "); |
6925 expr->target()->ShortPrint(); | 6936 expr->target()->ShortPrint(); |
6926 PrintF("\n"); | 6937 PrintF("\n"); |
6927 } | 6938 } |
6928 return; | 6939 return; |
6929 } | 6940 } |
6930 | 6941 |
6931 if (TryInlineCall(expr, true)) { // Drop function from environment. | 6942 if (TryInlineCall(expr, true)) { // Drop function from environment. |
6932 return; | 6943 return; |
6933 } else { | 6944 } else { |
6934 call = PreProcessCall( | 6945 call = PreProcessCall( |
6935 new(zone()) HInvokeFunction(context, | 6946 new(zone()) HInvokeFunction(context, |
6936 function, | 6947 function, |
6937 expr->target(), | 6948 expr->target(), |
6938 argument_count)); | 6949 argument_count)); |
6939 Drop(1); // The function. | 6950 Drop(1); // The function. |
6940 } | 6951 } |
6941 | 6952 |
6942 } else { | 6953 } else { |
6943 CHECK_ALIVE(VisitForValue(expr->expression())); | 6954 CHECK_ALIVE(VisitForValue(expr->expression())); |
6944 HValue* function = Top(); | 6955 HValue* function = Top(); |
6945 HValue* context = environment()->LookupContext(); | 6956 HValue* context = environment()->LookupContext(); |
6946 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 6957 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
6958 AddInstruction(global_object); | |
danno
2012/06/11 12:11:45
This is an unrelated change, can you please remove
sanjoy
2012/06/11 12:37:56
This change is required since the HGlobalReceiver
| |
6947 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global_object); | 6959 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global_object); |
6948 AddInstruction(global_object); | |
6949 AddInstruction(receiver); | 6960 AddInstruction(receiver); |
6950 PushAndAdd(new(zone()) HPushArgument(receiver)); | 6961 PushAndAdd(new(zone()) HPushArgument(receiver)); |
6951 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 6962 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
6952 | 6963 |
6953 call = new(zone()) HCallFunction(context, function, argument_count); | 6964 call = new(zone()) HCallFunction(context, function, argument_count); |
6954 Drop(argument_count + 1); | 6965 Drop(argument_count + 1); |
6955 } | 6966 } |
6956 } | 6967 } |
6957 | 6968 |
6958 call->set_position(expr->position()); | 6969 call->set_position(expr->position()); |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7344 break; | 7355 break; |
7345 } | 7356 } |
7346 | 7357 |
7347 case Variable::LOOKUP: | 7358 case Variable::LOOKUP: |
7348 return Bailout("lookup variable in count operation"); | 7359 return Bailout("lookup variable in count operation"); |
7349 } | 7360 } |
7350 | 7361 |
7351 } else { | 7362 } else { |
7352 // Argument of the count operation is a property. | 7363 // Argument of the count operation is a property. |
7353 ASSERT(prop != NULL); | 7364 ASSERT(prop != NULL); |
7354 prop->RecordTypeFeedback(oracle()); | 7365 prop->RecordTypeFeedback(oracle(), zone()); |
7355 | 7366 |
7356 if (prop->key()->IsPropertyName()) { | 7367 if (prop->key()->IsPropertyName()) { |
7357 // Named property. | 7368 // Named property. |
7358 if (returns_original_input) Push(graph_->GetConstantUndefined()); | 7369 if (returns_original_input) Push(graph_->GetConstantUndefined()); |
7359 | 7370 |
7360 CHECK_ALIVE(VisitForValue(prop->obj())); | 7371 CHECK_ALIVE(VisitForValue(prop->obj())); |
7361 HValue* obj = Top(); | 7372 HValue* obj = Top(); |
7362 | 7373 |
7363 HInstruction* load = NULL; | 7374 HInstruction* load = NULL; |
7364 if (prop->IsMonomorphic()) { | 7375 if (prop->IsMonomorphic()) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7398 HValue* load = HandleKeyedElementAccess( | 7409 HValue* load = HandleKeyedElementAccess( |
7399 obj, key, NULL, prop, expr->CountId(), RelocInfo::kNoPosition, | 7410 obj, key, NULL, prop, expr->CountId(), RelocInfo::kNoPosition, |
7400 false, // is_store | 7411 false, // is_store |
7401 &has_side_effects); | 7412 &has_side_effects); |
7402 Push(load); | 7413 Push(load); |
7403 if (has_side_effects) AddSimulate(expr->CountId()); | 7414 if (has_side_effects) AddSimulate(expr->CountId()); |
7404 | 7415 |
7405 after = BuildIncrement(returns_original_input, expr); | 7416 after = BuildIncrement(returns_original_input, expr); |
7406 input = Pop(); | 7417 input = Pop(); |
7407 | 7418 |
7408 expr->RecordTypeFeedback(oracle()); | 7419 expr->RecordTypeFeedback(oracle(), zone()); |
7409 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(), | 7420 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(), |
7410 RelocInfo::kNoPosition, | 7421 RelocInfo::kNoPosition, |
7411 true, // is_store | 7422 true, // is_store |
7412 &has_side_effects); | 7423 &has_side_effects); |
7413 | 7424 |
7414 // Drop the key from the bailout environment. Overwrite the receiver | 7425 // Drop the key from the bailout environment. Overwrite the receiver |
7415 // with the result of the operation, and the placeholder with the | 7426 // with the result of the operation, and the placeholder with the |
7416 // original value if necessary. | 7427 // original value if necessary. |
7417 Drop(1); | 7428 Drop(1); |
7418 environment()->SetExpressionStackAt(0, after); | 7429 environment()->SetExpressionStackAt(0, after); |
7419 if (returns_original_input) environment()->SetExpressionStackAt(1, input); | 7430 if (returns_original_input) environment()->SetExpressionStackAt(1, input); |
7420 ASSERT(has_side_effects); // Stores always have side effects. | 7431 ASSERT(has_side_effects); // Stores always have side effects. |
7421 AddSimulate(expr->AssignmentId()); | 7432 AddSimulate(expr->AssignmentId()); |
7422 } | 7433 } |
7423 } | 7434 } |
7424 | 7435 |
7425 Drop(returns_original_input ? 2 : 1); | 7436 Drop(returns_original_input ? 2 : 1); |
7426 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); | 7437 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); |
7427 } | 7438 } |
7428 | 7439 |
7429 | 7440 |
7430 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* context, | 7441 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* context, |
7431 HValue* string, | 7442 HValue* string, |
7432 HValue* index) { | 7443 HValue* index) { |
7433 AddInstruction(new(zone()) HCheckNonSmi(string)); | 7444 AddInstruction(new(zone()) HCheckNonSmi(string)); |
7434 AddInstruction(HCheckInstanceType::NewIsString(string)); | 7445 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
7435 HStringLength* length = new(zone()) HStringLength(string); | 7446 HStringLength* length = new(zone()) HStringLength(string); |
7436 AddInstruction(length); | 7447 AddInstruction(length); |
7437 HInstruction* checked_index = | 7448 HInstruction* checked_index = |
7438 AddInstruction(new(zone()) HBoundsCheck(index, length)); | 7449 AddInstruction(new(zone()) HBoundsCheck(index, length)); |
7439 return new(zone()) HStringCharCodeAt(context, string, checked_index); | 7450 return new(zone()) HStringCharCodeAt(context, string, checked_index); |
7440 } | 7451 } |
7441 | 7452 |
7442 | 7453 |
7443 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, | 7454 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, |
7444 HValue* left, | 7455 HValue* left, |
7445 HValue* right) { | 7456 HValue* right) { |
7446 HValue* context = environment()->LookupContext(); | 7457 HValue* context = environment()->LookupContext(); |
7447 TypeInfo info = oracle()->BinaryType(expr); | 7458 TypeInfo info = oracle()->BinaryType(expr); |
7448 if (info.IsUninitialized()) { | 7459 if (info.IsUninitialized()) { |
7449 AddInstruction(new(zone()) HSoftDeoptimize); | 7460 AddInstruction(new(zone()) HSoftDeoptimize); |
7450 current_block()->MarkAsDeoptimizing(); | 7461 current_block()->MarkAsDeoptimizing(); |
7451 info = TypeInfo::Unknown(); | 7462 info = TypeInfo::Unknown(); |
7452 } | 7463 } |
7453 HInstruction* instr = NULL; | 7464 HInstruction* instr = NULL; |
7454 switch (expr->op()) { | 7465 switch (expr->op()) { |
7455 case Token::ADD: | 7466 case Token::ADD: |
7456 if (info.IsString()) { | 7467 if (info.IsString()) { |
7457 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7468 AddInstruction(new(zone()) HCheckNonSmi(left)); |
7458 AddInstruction(HCheckInstanceType::NewIsString(left)); | 7469 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); |
7459 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7470 AddInstruction(new(zone()) HCheckNonSmi(right)); |
7460 AddInstruction(HCheckInstanceType::NewIsString(right)); | 7471 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); |
7461 instr = new(zone()) HStringAdd(context, left, right); | 7472 instr = new(zone()) HStringAdd(context, left, right); |
7462 } else { | 7473 } else { |
7463 instr = HAdd::NewHAdd(zone(), context, left, right); | 7474 instr = HAdd::NewHAdd(zone(), context, left, right); |
7464 } | 7475 } |
7465 break; | 7476 break; |
7466 case Token::SUB: | 7477 case Token::SUB: |
7467 instr = HSub::NewHSub(zone(), context, left, right); | 7478 instr = HSub::NewHSub(zone(), context, left, right); |
7468 break; | 7479 break; |
7469 case Token::MUL: | 7480 case Token::MUL: |
7470 instr = HMul::NewHMul(zone(), context, left, right); | 7481 instr = HMul::NewHMul(zone(), context, left, right); |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7850 result->set_position(expr->position()); | 7861 result->set_position(expr->position()); |
7851 return ast_context()->ReturnInstruction(result, expr->id()); | 7862 return ast_context()->ReturnInstruction(result, expr->id()); |
7852 } else if (type_info.IsNonPrimitive()) { | 7863 } else if (type_info.IsNonPrimitive()) { |
7853 switch (op) { | 7864 switch (op) { |
7854 case Token::EQ: | 7865 case Token::EQ: |
7855 case Token::EQ_STRICT: { | 7866 case Token::EQ_STRICT: { |
7856 // Can we get away with map check and not instance type check? | 7867 // Can we get away with map check and not instance type check? |
7857 Handle<Map> map = oracle()->GetCompareMap(expr); | 7868 Handle<Map> map = oracle()->GetCompareMap(expr); |
7858 if (!map.is_null()) { | 7869 if (!map.is_null()) { |
7859 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7870 AddInstruction(new(zone()) HCheckNonSmi(left)); |
7860 AddInstruction(HCheckMaps::NewWithTransitions(left, map)); | 7871 AddInstruction(HCheckMaps::NewWithTransitions(left, map, zone())); |
7861 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7872 AddInstruction(new(zone()) HCheckNonSmi(right)); |
7862 AddInstruction(HCheckMaps::NewWithTransitions(right, map)); | 7873 AddInstruction(HCheckMaps::NewWithTransitions(right, map, zone())); |
7863 HCompareObjectEqAndBranch* result = | 7874 HCompareObjectEqAndBranch* result = |
7864 new(zone()) HCompareObjectEqAndBranch(left, right); | 7875 new(zone()) HCompareObjectEqAndBranch(left, right); |
7865 result->set_position(expr->position()); | 7876 result->set_position(expr->position()); |
7866 return ast_context()->ReturnControl(result, expr->id()); | 7877 return ast_context()->ReturnControl(result, expr->id()); |
7867 } else { | 7878 } else { |
7868 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7879 AddInstruction(new(zone()) HCheckNonSmi(left)); |
7869 AddInstruction(HCheckInstanceType::NewIsSpecObject(left)); | 7880 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); |
7870 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7881 AddInstruction(new(zone()) HCheckNonSmi(right)); |
7871 AddInstruction(HCheckInstanceType::NewIsSpecObject(right)); | 7882 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); |
7872 HCompareObjectEqAndBranch* result = | 7883 HCompareObjectEqAndBranch* result = |
7873 new(zone()) HCompareObjectEqAndBranch(left, right); | 7884 new(zone()) HCompareObjectEqAndBranch(left, right); |
7874 result->set_position(expr->position()); | 7885 result->set_position(expr->position()); |
7875 return ast_context()->ReturnControl(result, expr->id()); | 7886 return ast_context()->ReturnControl(result, expr->id()); |
7876 } | 7887 } |
7877 } | 7888 } |
7878 default: | 7889 default: |
7879 return Bailout("Unsupported non-primitive compare"); | 7890 return Bailout("Unsupported non-primitive compare"); |
7880 } | 7891 } |
7881 } else if (type_info.IsString() && oracle()->IsSymbolCompare(expr) && | 7892 } else if (type_info.IsString() && oracle()->IsSymbolCompare(expr) && |
7882 (op == Token::EQ || op == Token::EQ_STRICT)) { | 7893 (op == Token::EQ || op == Token::EQ_STRICT)) { |
7883 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7894 AddInstruction(new(zone()) HCheckNonSmi(left)); |
7884 AddInstruction(HCheckInstanceType::NewIsSymbol(left)); | 7895 AddInstruction(HCheckInstanceType::NewIsSymbol(left, zone())); |
7885 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7896 AddInstruction(new(zone()) HCheckNonSmi(right)); |
7886 AddInstruction(HCheckInstanceType::NewIsSymbol(right)); | 7897 AddInstruction(HCheckInstanceType::NewIsSymbol(right, zone())); |
7887 HCompareObjectEqAndBranch* result = | 7898 HCompareObjectEqAndBranch* result = |
7888 new(zone()) HCompareObjectEqAndBranch(left, right); | 7899 new(zone()) HCompareObjectEqAndBranch(left, right); |
7889 result->set_position(expr->position()); | 7900 result->set_position(expr->position()); |
7890 return ast_context()->ReturnControl(result, expr->id()); | 7901 return ast_context()->ReturnControl(result, expr->id()); |
7891 } else { | 7902 } else { |
7892 Representation r = ToRepresentation(type_info); | 7903 Representation r = ToRepresentation(type_info); |
7893 if (r.IsTagged()) { | 7904 if (r.IsTagged()) { |
7894 HCompareGeneric* result = | 7905 HCompareGeneric* result = |
7895 new(zone()) HCompareGeneric(context, left, right, op); | 7906 new(zone()) HCompareGeneric(context, left, right, op); |
7896 result->set_position(expr->position()); | 7907 result->set_position(expr->position()); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7948 } | 7959 } |
7949 | 7960 |
7950 | 7961 |
7951 void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) { | 7962 void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) { |
7952 VariableProxy* proxy = declaration->proxy(); | 7963 VariableProxy* proxy = declaration->proxy(); |
7953 VariableMode mode = declaration->mode(); | 7964 VariableMode mode = declaration->mode(); |
7954 Variable* variable = proxy->var(); | 7965 Variable* variable = proxy->var(); |
7955 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; | 7966 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; |
7956 switch (variable->location()) { | 7967 switch (variable->location()) { |
7957 case Variable::UNALLOCATED: | 7968 case Variable::UNALLOCATED: |
7958 globals_.Add(variable->name()); | 7969 globals_.Add(variable->name(), zone()); |
7959 globals_.Add(variable->binding_needs_init() | 7970 globals_.Add(variable->binding_needs_init() |
7960 ? isolate()->factory()->the_hole_value() | 7971 ? isolate()->factory()->the_hole_value() |
7961 : isolate()->factory()->undefined_value()); | 7972 : isolate()->factory()->undefined_value(), zone()); |
7962 return; | 7973 return; |
7963 case Variable::PARAMETER: | 7974 case Variable::PARAMETER: |
7964 case Variable::LOCAL: | 7975 case Variable::LOCAL: |
7965 if (hole_init) { | 7976 if (hole_init) { |
7966 HValue* value = graph()->GetConstantHole(); | 7977 HValue* value = graph()->GetConstantHole(); |
7967 environment()->Bind(variable, value); | 7978 environment()->Bind(variable, value); |
7968 } | 7979 } |
7969 break; | 7980 break; |
7970 case Variable::CONTEXT: | 7981 case Variable::CONTEXT: |
7971 if (hole_init) { | 7982 if (hole_init) { |
7972 HValue* value = graph()->GetConstantHole(); | 7983 HValue* value = graph()->GetConstantHole(); |
7973 HValue* context = environment()->LookupContext(); | 7984 HValue* context = environment()->LookupContext(); |
7974 HStoreContextSlot* store = new HStoreContextSlot( | 7985 HStoreContextSlot* store = new(zone()) HStoreContextSlot( |
7975 context, variable->index(), HStoreContextSlot::kNoCheck, value); | 7986 context, variable->index(), HStoreContextSlot::kNoCheck, value); |
7976 AddInstruction(store); | 7987 AddInstruction(store); |
7977 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); | 7988 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); |
7978 } | 7989 } |
7979 break; | 7990 break; |
7980 case Variable::LOOKUP: | 7991 case Variable::LOOKUP: |
7981 return Bailout("unsupported lookup slot in declaration"); | 7992 return Bailout("unsupported lookup slot in declaration"); |
7982 } | 7993 } |
7983 } | 7994 } |
7984 | 7995 |
7985 | 7996 |
7986 void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) { | 7997 void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) { |
7987 VariableProxy* proxy = declaration->proxy(); | 7998 VariableProxy* proxy = declaration->proxy(); |
7988 Variable* variable = proxy->var(); | 7999 Variable* variable = proxy->var(); |
7989 switch (variable->location()) { | 8000 switch (variable->location()) { |
7990 case Variable::UNALLOCATED: { | 8001 case Variable::UNALLOCATED: { |
7991 globals_.Add(variable->name()); | 8002 globals_.Add(variable->name(), zone()); |
7992 Handle<SharedFunctionInfo> function = | 8003 Handle<SharedFunctionInfo> function = |
7993 Compiler::BuildFunctionInfo(declaration->fun(), info()->script()); | 8004 Compiler::BuildFunctionInfo(declaration->fun(), info()->script()); |
7994 // Check for stack-overflow exception. | 8005 // Check for stack-overflow exception. |
7995 if (function.is_null()) return SetStackOverflow(); | 8006 if (function.is_null()) return SetStackOverflow(); |
7996 globals_.Add(function); | 8007 globals_.Add(function, zone()); |
7997 return; | 8008 return; |
7998 } | 8009 } |
7999 case Variable::PARAMETER: | 8010 case Variable::PARAMETER: |
8000 case Variable::LOCAL: { | 8011 case Variable::LOCAL: { |
8001 CHECK_ALIVE(VisitForValue(declaration->fun())); | 8012 CHECK_ALIVE(VisitForValue(declaration->fun())); |
8002 HValue* value = Pop(); | 8013 HValue* value = Pop(); |
8003 environment()->Bind(variable, value); | 8014 environment()->Bind(variable, value); |
8004 break; | 8015 break; |
8005 } | 8016 } |
8006 case Variable::CONTEXT: { | 8017 case Variable::CONTEXT: { |
8007 CHECK_ALIVE(VisitForValue(declaration->fun())); | 8018 CHECK_ALIVE(VisitForValue(declaration->fun())); |
8008 HValue* value = Pop(); | 8019 HValue* value = Pop(); |
8009 HValue* context = environment()->LookupContext(); | 8020 HValue* context = environment()->LookupContext(); |
8010 HStoreContextSlot* store = new HStoreContextSlot( | 8021 HStoreContextSlot* store = new(zone()) HStoreContextSlot( |
8011 context, variable->index(), HStoreContextSlot::kNoCheck, value); | 8022 context, variable->index(), HStoreContextSlot::kNoCheck, value); |
8012 AddInstruction(store); | 8023 AddInstruction(store); |
8013 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); | 8024 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); |
8014 break; | 8025 break; |
8015 } | 8026 } |
8016 case Variable::LOOKUP: | 8027 case Variable::LOOKUP: |
8017 return Bailout("unsupported lookup slot in declaration"); | 8028 return Bailout("unsupported lookup slot in declaration"); |
8018 } | 8029 } |
8019 } | 8030 } |
8020 | 8031 |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8246 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); | 8257 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); |
8247 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); | 8258 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); |
8248 typecheck->SetSuccessorAt(0, if_js_value); | 8259 typecheck->SetSuccessorAt(0, if_js_value); |
8249 typecheck->SetSuccessorAt(1, not_js_value); | 8260 typecheck->SetSuccessorAt(1, not_js_value); |
8250 current_block()->Finish(typecheck); | 8261 current_block()->Finish(typecheck); |
8251 not_js_value->Goto(join); | 8262 not_js_value->Goto(join); |
8252 | 8263 |
8253 // Create in-object property store to kValueOffset. | 8264 // Create in-object property store to kValueOffset. |
8254 set_current_block(if_js_value); | 8265 set_current_block(if_js_value); |
8255 Handle<String> name = isolate()->factory()->undefined_symbol(); | 8266 Handle<String> name = isolate()->factory()->undefined_symbol(); |
8256 AddInstruction(new HStoreNamedField(object, | 8267 AddInstruction(new(zone()) HStoreNamedField(object, |
8257 name, | 8268 name, |
8258 value, | 8269 value, |
8259 true, // in-object store. | 8270 true, // in-object store. |
8260 JSValue::kValueOffset)); | 8271 JSValue::kValueOffset)); |
8261 if_js_value->Goto(join); | 8272 if_js_value->Goto(join); |
8262 join->SetJoinId(call->id()); | 8273 join->SetJoinId(call->id()); |
8263 set_current_block(join); | 8274 set_current_block(join); |
8264 return ast_context()->ReturnValue(value); | 8275 return ast_context()->ReturnValue(value); |
8265 } | 8276 } |
8266 | 8277 |
8267 | 8278 |
8268 // Fast support for charCodeAt(n). | 8279 // Fast support for charCodeAt(n). |
8269 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { | 8280 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { |
8270 ASSERT(call->arguments()->length() == 2); | 8281 ASSERT(call->arguments()->length() == 2); |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8538 return Bailout("inlined runtime function: FastAsciiArrayJoin"); | 8549 return Bailout("inlined runtime function: FastAsciiArrayJoin"); |
8539 } | 8550 } |
8540 | 8551 |
8541 | 8552 |
8542 #undef CHECK_BAILOUT | 8553 #undef CHECK_BAILOUT |
8543 #undef CHECK_ALIVE | 8554 #undef CHECK_ALIVE |
8544 | 8555 |
8545 | 8556 |
8546 HEnvironment::HEnvironment(HEnvironment* outer, | 8557 HEnvironment::HEnvironment(HEnvironment* outer, |
8547 Scope* scope, | 8558 Scope* scope, |
8548 Handle<JSFunction> closure) | 8559 Handle<JSFunction> closure, |
8560 Zone* zone) | |
8549 : closure_(closure), | 8561 : closure_(closure), |
8550 values_(0), | 8562 values_(0, zone), |
8551 assigned_variables_(4), | 8563 assigned_variables_(4, zone), |
8552 frame_type_(JS_FUNCTION), | 8564 frame_type_(JS_FUNCTION), |
8553 parameter_count_(0), | 8565 parameter_count_(0), |
8554 specials_count_(1), | 8566 specials_count_(1), |
8555 local_count_(0), | 8567 local_count_(0), |
8556 outer_(outer), | 8568 outer_(outer), |
8557 pop_count_(0), | 8569 pop_count_(0), |
8558 push_count_(0), | 8570 push_count_(0), |
8559 ast_id_(AstNode::kNoNumber) { | 8571 ast_id_(AstNode::kNoNumber), |
8572 zone_(zone) { | |
8560 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); | 8573 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); |
8561 } | 8574 } |
8562 | 8575 |
8563 | 8576 |
8564 HEnvironment::HEnvironment(const HEnvironment* other) | 8577 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) |
8565 : values_(0), | 8578 : values_(0, zone), |
8566 assigned_variables_(0), | 8579 assigned_variables_(0, zone), |
8567 frame_type_(JS_FUNCTION), | 8580 frame_type_(JS_FUNCTION), |
8568 parameter_count_(0), | 8581 parameter_count_(0), |
8569 specials_count_(1), | 8582 specials_count_(1), |
8570 local_count_(0), | 8583 local_count_(0), |
8571 outer_(NULL), | 8584 outer_(NULL), |
8572 pop_count_(0), | 8585 pop_count_(0), |
8573 push_count_(0), | 8586 push_count_(0), |
8574 ast_id_(other->ast_id()) { | 8587 ast_id_(other->ast_id()), |
8588 zone_(zone) { | |
8575 Initialize(other); | 8589 Initialize(other); |
8576 } | 8590 } |
8577 | 8591 |
8578 | 8592 |
8579 HEnvironment::HEnvironment(HEnvironment* outer, | 8593 HEnvironment::HEnvironment(HEnvironment* outer, |
8580 Handle<JSFunction> closure, | 8594 Handle<JSFunction> closure, |
8581 FrameType frame_type, | 8595 FrameType frame_type, |
8582 int arguments) | 8596 int arguments, |
8597 Zone* zone) | |
8583 : closure_(closure), | 8598 : closure_(closure), |
8584 values_(arguments), | 8599 values_(arguments, zone), |
8585 assigned_variables_(0), | 8600 assigned_variables_(0, zone), |
8586 frame_type_(frame_type), | 8601 frame_type_(frame_type), |
8587 parameter_count_(arguments), | 8602 parameter_count_(arguments), |
8588 local_count_(0), | 8603 local_count_(0), |
8589 outer_(outer), | 8604 outer_(outer), |
8590 pop_count_(0), | 8605 pop_count_(0), |
8591 push_count_(0), | 8606 push_count_(0), |
8592 ast_id_(AstNode::kNoNumber) { | 8607 ast_id_(AstNode::kNoNumber), |
8608 zone_(zone) { | |
8593 } | 8609 } |
8594 | 8610 |
8595 | 8611 |
8596 void HEnvironment::Initialize(int parameter_count, | 8612 void HEnvironment::Initialize(int parameter_count, |
8597 int local_count, | 8613 int local_count, |
8598 int stack_height) { | 8614 int stack_height) { |
8599 parameter_count_ = parameter_count; | 8615 parameter_count_ = parameter_count; |
8600 local_count_ = local_count; | 8616 local_count_ = local_count; |
8601 | 8617 |
8602 // Avoid reallocating the temporaries' backing store on the first Push. | 8618 // Avoid reallocating the temporaries' backing store on the first Push. |
8603 int total = parameter_count + specials_count_ + local_count + stack_height; | 8619 int total = parameter_count + specials_count_ + local_count + stack_height; |
8604 values_.Initialize(total + 4); | 8620 values_.Initialize(total + 4, zone()); |
8605 for (int i = 0; i < total; ++i) values_.Add(NULL); | 8621 for (int i = 0; i < total; ++i) values_.Add(NULL, zone()); |
8606 } | 8622 } |
8607 | 8623 |
8608 | 8624 |
8609 void HEnvironment::Initialize(const HEnvironment* other) { | 8625 void HEnvironment::Initialize(const HEnvironment* other) { |
8610 closure_ = other->closure(); | 8626 closure_ = other->closure(); |
8611 values_.AddAll(other->values_); | 8627 values_.AddAll(other->values_, zone()); |
8612 assigned_variables_.AddAll(other->assigned_variables_); | 8628 assigned_variables_.AddAll(other->assigned_variables_, zone()); |
8613 frame_type_ = other->frame_type_; | 8629 frame_type_ = other->frame_type_; |
8614 parameter_count_ = other->parameter_count_; | 8630 parameter_count_ = other->parameter_count_; |
8615 local_count_ = other->local_count_; | 8631 local_count_ = other->local_count_; |
8616 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. | 8632 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. |
8617 pop_count_ = other->pop_count_; | 8633 pop_count_ = other->pop_count_; |
8618 push_count_ = other->push_count_; | 8634 push_count_ = other->push_count_; |
8619 ast_id_ = other->ast_id_; | 8635 ast_id_ = other->ast_id_; |
8620 } | 8636 } |
8621 | 8637 |
8622 | 8638 |
8623 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { | 8639 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { |
8624 ASSERT(!block->IsLoopHeader()); | 8640 ASSERT(!block->IsLoopHeader()); |
8625 ASSERT(values_.length() == other->values_.length()); | 8641 ASSERT(values_.length() == other->values_.length()); |
8626 | 8642 |
8627 int length = values_.length(); | 8643 int length = values_.length(); |
8628 for (int i = 0; i < length; ++i) { | 8644 for (int i = 0; i < length; ++i) { |
8629 HValue* value = values_[i]; | 8645 HValue* value = values_[i]; |
8630 if (value != NULL && value->IsPhi() && value->block() == block) { | 8646 if (value != NULL && value->IsPhi() && value->block() == block) { |
8631 // There is already a phi for the i'th value. | 8647 // There is already a phi for the i'th value. |
8632 HPhi* phi = HPhi::cast(value); | 8648 HPhi* phi = HPhi::cast(value); |
8633 // Assert index is correct and that we haven't missed an incoming edge. | 8649 // Assert index is correct and that we haven't missed an incoming edge. |
8634 ASSERT(phi->merged_index() == i); | 8650 ASSERT(phi->merged_index() == i); |
8635 ASSERT(phi->OperandCount() == block->predecessors()->length()); | 8651 ASSERT(phi->OperandCount() == block->predecessors()->length()); |
8636 phi->AddInput(other->values_[i]); | 8652 phi->AddInput(other->values_[i]); |
8637 } else if (values_[i] != other->values_[i]) { | 8653 } else if (values_[i] != other->values_[i]) { |
8638 // There is a fresh value on the incoming edge, a phi is needed. | 8654 // There is a fresh value on the incoming edge, a phi is needed. |
8639 ASSERT(values_[i] != NULL && other->values_[i] != NULL); | 8655 ASSERT(values_[i] != NULL && other->values_[i] != NULL); |
8640 HPhi* phi = new(block->zone()) HPhi(i); | 8656 HPhi* phi = new(zone()) HPhi(i, zone()); |
8641 HValue* old_value = values_[i]; | 8657 HValue* old_value = values_[i]; |
8642 for (int j = 0; j < block->predecessors()->length(); j++) { | 8658 for (int j = 0; j < block->predecessors()->length(); j++) { |
8643 phi->AddInput(old_value); | 8659 phi->AddInput(old_value); |
8644 } | 8660 } |
8645 phi->AddInput(other->values_[i]); | 8661 phi->AddInput(other->values_[i]); |
8646 this->values_[i] = phi; | 8662 this->values_[i] = phi; |
8647 block->AddPhi(phi); | 8663 block->AddPhi(phi); |
8648 } | 8664 } |
8649 } | 8665 } |
8650 } | 8666 } |
8651 | 8667 |
8652 | 8668 |
8653 void HEnvironment::Bind(int index, HValue* value) { | 8669 void HEnvironment::Bind(int index, HValue* value) { |
8654 ASSERT(value != NULL); | 8670 ASSERT(value != NULL); |
8655 if (!assigned_variables_.Contains(index)) { | 8671 if (!assigned_variables_.Contains(index)) { |
8656 assigned_variables_.Add(index); | 8672 assigned_variables_.Add(index, zone()); |
8657 } | 8673 } |
8658 values_[index] = value; | 8674 values_[index] = value; |
8659 } | 8675 } |
8660 | 8676 |
8661 | 8677 |
8662 bool HEnvironment::HasExpressionAt(int index) const { | 8678 bool HEnvironment::HasExpressionAt(int index) const { |
8663 return index >= parameter_count_ + specials_count_ + local_count_; | 8679 return index >= parameter_count_ + specials_count_ + local_count_; |
8664 } | 8680 } |
8665 | 8681 |
8666 | 8682 |
(...skipping 19 matching lines...) Expand all Loading... | |
8686 | 8702 |
8687 | 8703 |
8688 void HEnvironment::Drop(int count) { | 8704 void HEnvironment::Drop(int count) { |
8689 for (int i = 0; i < count; ++i) { | 8705 for (int i = 0; i < count; ++i) { |
8690 Pop(); | 8706 Pop(); |
8691 } | 8707 } |
8692 } | 8708 } |
8693 | 8709 |
8694 | 8710 |
8695 HEnvironment* HEnvironment::Copy() const { | 8711 HEnvironment* HEnvironment::Copy() const { |
8696 return new(closure()->GetIsolate()->zone()) HEnvironment(this); | 8712 return new(zone()) HEnvironment(this, zone()); |
8697 } | 8713 } |
8698 | 8714 |
8699 | 8715 |
8700 HEnvironment* HEnvironment::CopyWithoutHistory() const { | 8716 HEnvironment* HEnvironment::CopyWithoutHistory() const { |
8701 HEnvironment* result = Copy(); | 8717 HEnvironment* result = Copy(); |
8702 result->ClearHistory(); | 8718 result->ClearHistory(); |
8703 return result; | 8719 return result; |
8704 } | 8720 } |
8705 | 8721 |
8706 | 8722 |
8707 HEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const { | 8723 HEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const { |
8708 HEnvironment* new_env = Copy(); | 8724 HEnvironment* new_env = Copy(); |
8709 for (int i = 0; i < values_.length(); ++i) { | 8725 for (int i = 0; i < values_.length(); ++i) { |
8710 HPhi* phi = new(loop_header->zone()) HPhi(i); | 8726 HPhi* phi = new(zone()) HPhi(i, zone()); |
8711 phi->AddInput(values_[i]); | 8727 phi->AddInput(values_[i]); |
8712 new_env->values_[i] = phi; | 8728 new_env->values_[i] = phi; |
8713 loop_header->AddPhi(phi); | 8729 loop_header->AddPhi(phi); |
8714 } | 8730 } |
8715 new_env->ClearHistory(); | 8731 new_env->ClearHistory(); |
8716 return new_env; | 8732 return new_env; |
8717 } | 8733 } |
8718 | 8734 |
8719 | 8735 |
8720 HEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer, | 8736 HEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer, |
8721 Handle<JSFunction> target, | 8737 Handle<JSFunction> target, |
8722 FrameType frame_type, | 8738 FrameType frame_type, |
8723 int arguments) const { | 8739 int arguments) const { |
8724 HEnvironment* new_env = new(closure()->GetIsolate()->zone()) | 8740 HEnvironment* new_env = |
8725 HEnvironment(outer, target, frame_type, arguments + 1); | 8741 new(zone()) HEnvironment(outer, target, frame_type, |
8742 arguments + 1, zone()); | |
8726 for (int i = 0; i <= arguments; ++i) { // Include receiver. | 8743 for (int i = 0; i <= arguments; ++i) { // Include receiver. |
8727 new_env->Push(ExpressionStackAt(arguments - i)); | 8744 new_env->Push(ExpressionStackAt(arguments - i)); |
8728 } | 8745 } |
8729 new_env->ClearHistory(); | 8746 new_env->ClearHistory(); |
8730 return new_env; | 8747 return new_env; |
8731 } | 8748 } |
8732 | 8749 |
8733 | 8750 |
8734 HEnvironment* HEnvironment::CopyForInlining( | 8751 HEnvironment* HEnvironment::CopyForInlining( |
8735 Handle<JSFunction> target, | 8752 Handle<JSFunction> target, |
(...skipping 19 matching lines...) Expand all Loading... | |
8755 // object instead, DoComputeConstructStubFrame() relies on that. | 8772 // object instead, DoComputeConstructStubFrame() relies on that. |
8756 outer = CreateStubEnvironment(outer, target, JS_CONSTRUCT, arguments); | 8773 outer = CreateStubEnvironment(outer, target, JS_CONSTRUCT, arguments); |
8757 } | 8774 } |
8758 | 8775 |
8759 if (arity != arguments) { | 8776 if (arity != arguments) { |
8760 // Create artificial arguments adaptation environment. | 8777 // Create artificial arguments adaptation environment. |
8761 outer = CreateStubEnvironment(outer, target, ARGUMENTS_ADAPTOR, arguments); | 8778 outer = CreateStubEnvironment(outer, target, ARGUMENTS_ADAPTOR, arguments); |
8762 } | 8779 } |
8763 | 8780 |
8764 HEnvironment* inner = | 8781 HEnvironment* inner = |
8765 new(zone) HEnvironment(outer, function->scope(), target); | 8782 new(zone) HEnvironment(outer, function->scope(), target, zone); |
8766 // Get the argument values from the original environment. | 8783 // Get the argument values from the original environment. |
8767 for (int i = 0; i <= arity; ++i) { // Include receiver. | 8784 for (int i = 0; i <= arity; ++i) { // Include receiver. |
8768 HValue* push = (i <= arguments) ? | 8785 HValue* push = (i <= arguments) ? |
8769 ExpressionStackAt(arguments - i) : undefined; | 8786 ExpressionStackAt(arguments - i) : undefined; |
8770 inner->SetValueAt(i, push); | 8787 inner->SetValueAt(i, push); |
8771 } | 8788 } |
8772 // If the function we are inlining is a strict mode function or a | 8789 // If the function we are inlining is a strict mode function or a |
8773 // builtin function, pass undefined as the receiver for function | 8790 // builtin function, pass undefined as the receiver for function |
8774 // calls (instead of the global receiver). | 8791 // calls (instead of the global receiver). |
8775 if ((target->shared()->native() || !function->is_classic_mode()) && | 8792 if ((target->shared()->native() || !function->is_classic_mode()) && |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8945 } | 8962 } |
8946 } | 8963 } |
8947 | 8964 |
8948 | 8965 |
8949 void HTracer::TraceLiveRanges(const char* name, LAllocator* allocator) { | 8966 void HTracer::TraceLiveRanges(const char* name, LAllocator* allocator) { |
8950 Tag tag(this, "intervals"); | 8967 Tag tag(this, "intervals"); |
8951 PrintStringProperty("name", name); | 8968 PrintStringProperty("name", name); |
8952 | 8969 |
8953 const Vector<LiveRange*>* fixed_d = allocator->fixed_double_live_ranges(); | 8970 const Vector<LiveRange*>* fixed_d = allocator->fixed_double_live_ranges(); |
8954 for (int i = 0; i < fixed_d->length(); ++i) { | 8971 for (int i = 0; i < fixed_d->length(); ++i) { |
8955 TraceLiveRange(fixed_d->at(i), "fixed"); | 8972 TraceLiveRange(fixed_d->at(i), "fixed", allocator->zone()); |
8956 } | 8973 } |
8957 | 8974 |
8958 const Vector<LiveRange*>* fixed = allocator->fixed_live_ranges(); | 8975 const Vector<LiveRange*>* fixed = allocator->fixed_live_ranges(); |
8959 for (int i = 0; i < fixed->length(); ++i) { | 8976 for (int i = 0; i < fixed->length(); ++i) { |
8960 TraceLiveRange(fixed->at(i), "fixed"); | 8977 TraceLiveRange(fixed->at(i), "fixed", allocator->zone()); |
8961 } | 8978 } |
8962 | 8979 |
8963 const ZoneList<LiveRange*>* live_ranges = allocator->live_ranges(); | 8980 const ZoneList<LiveRange*>* live_ranges = allocator->live_ranges(); |
8964 for (int i = 0; i < live_ranges->length(); ++i) { | 8981 for (int i = 0; i < live_ranges->length(); ++i) { |
8965 TraceLiveRange(live_ranges->at(i), "object"); | 8982 TraceLiveRange(live_ranges->at(i), "object", allocator->zone()); |
8966 } | 8983 } |
8967 } | 8984 } |
8968 | 8985 |
8969 | 8986 |
8970 void HTracer::TraceLiveRange(LiveRange* range, const char* type) { | 8987 void HTracer::TraceLiveRange(LiveRange* range, const char* type, |
8988 Zone* zone) { | |
8971 if (range != NULL && !range->IsEmpty()) { | 8989 if (range != NULL && !range->IsEmpty()) { |
8972 PrintIndent(); | 8990 PrintIndent(); |
8973 trace_.Add("%d %s", range->id(), type); | 8991 trace_.Add("%d %s", range->id(), type); |
8974 if (range->HasRegisterAssigned()) { | 8992 if (range->HasRegisterAssigned()) { |
8975 LOperand* op = range->CreateAssignedOperand(ZONE); | 8993 LOperand* op = range->CreateAssignedOperand(zone); |
8976 int assigned_reg = op->index(); | 8994 int assigned_reg = op->index(); |
8977 if (op->IsDoubleRegister()) { | 8995 if (op->IsDoubleRegister()) { |
8978 trace_.Add(" \"%s\"", | 8996 trace_.Add(" \"%s\"", |
8979 DoubleRegister::AllocationIndexToString(assigned_reg)); | 8997 DoubleRegister::AllocationIndexToString(assigned_reg)); |
8980 } else { | 8998 } else { |
8981 ASSERT(op->IsRegister()); | 8999 ASSERT(op->IsRegister()); |
8982 trace_.Add(" \"%s\"", Register::AllocationIndexToString(assigned_reg)); | 9000 trace_.Add(" \"%s\"", Register::AllocationIndexToString(assigned_reg)); |
8983 } | 9001 } |
8984 } else if (range->IsSpilled()) { | 9002 } else if (range->IsSpilled()) { |
8985 LOperand* op = range->TopLevel()->GetSpillOperand(); | 9003 LOperand* op = range->TopLevel()->GetSpillOperand(); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9127 } | 9145 } |
9128 } | 9146 } |
9129 | 9147 |
9130 #ifdef DEBUG | 9148 #ifdef DEBUG |
9131 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 9149 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
9132 if (allocator_ != NULL) allocator_->Verify(); | 9150 if (allocator_ != NULL) allocator_->Verify(); |
9133 #endif | 9151 #endif |
9134 } | 9152 } |
9135 | 9153 |
9136 } } // namespace v8::internal | 9154 } } // namespace v8::internal |
OLD | NEW |