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

Side by Side Diff: src/hydrogen.cc

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

Powered by Google App Engine
This is Rietveld 408576698