OLD | NEW |
---|---|
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/escape-analysis.h" | 5 #include "src/compiler/escape-analysis.h" |
6 | 6 |
7 #include "src/base/flags.h" | 7 #include "src/base/flags.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
10 #include "src/compiler/common-operator.h" | 10 #include "src/compiler/common-operator.h" |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
425 } | 425 } |
426 } | 426 } |
427 | 427 |
428 | 428 |
429 // -----------------------------EscapeObjectAnalysis--------------------------- | 429 // -----------------------------EscapeObjectAnalysis--------------------------- |
430 | 430 |
431 | 431 |
432 EscapeObjectAnalysis::EscapeObjectAnalysis(Graph* graph, | 432 EscapeObjectAnalysis::EscapeObjectAnalysis(Graph* graph, |
433 CommonOperatorBuilder* common, | 433 CommonOperatorBuilder* common, |
434 Zone* zone) | 434 Zone* zone) |
435 : graph_(graph), common_(common), zone_(zone), virtual_states_(zone) {} | 435 : graph_(graph), |
436 common_(common), | |
437 zone_(zone), | |
438 virtual_states_(zone), | |
439 effects_(zone) {} | |
436 | 440 |
437 | 441 |
438 EscapeObjectAnalysis::~EscapeObjectAnalysis() {} | 442 EscapeObjectAnalysis::~EscapeObjectAnalysis() {} |
439 | 443 |
440 | 444 |
441 void EscapeObjectAnalysis::Run() { | 445 void EscapeObjectAnalysis::Run() { |
446 effects_.resize(graph()->NodeCount()); | |
442 virtual_states_.resize(graph()->NodeCount()); | 447 virtual_states_.resize(graph()->NodeCount()); |
443 ZoneVector<Node*> queue(zone()); | 448 ZoneVector<Node*> queue(zone()); |
444 queue.push_back(graph()->start()); | 449 queue.push_back(graph()->start()); |
445 while (!queue.empty()) { | 450 while (!queue.empty()) { |
446 Node* node = queue.back(); | 451 Node* node = queue.back(); |
447 queue.pop_back(); | 452 queue.pop_back(); |
448 if (Process(node)) { | 453 if (Process(node)) { |
449 for (Edge edge : node->use_edges()) { | 454 for (Edge edge : node->use_edges()) { |
450 if (NodeProperties::IsEffectEdge(edge)) { | 455 if (NodeProperties::IsEffectEdge(edge)) { |
451 Node* use = edge.from(); | 456 Node* use = edge.from(); |
(...skipping 26 matching lines...) Expand all Loading... | |
478 if (node->op()->EffectOutputCount() == 0) return false; | 483 if (node->op()->EffectOutputCount() == 0) return false; |
479 for (Edge edge : node->use_edges()) { | 484 for (Edge edge : node->use_edges()) { |
480 if (NodeProperties::IsEffectEdge(edge)) { | 485 if (NodeProperties::IsEffectEdge(edge)) { |
481 return false; | 486 return false; |
482 } | 487 } |
483 } | 488 } |
484 return true; | 489 return true; |
485 } | 490 } |
486 | 491 |
487 | 492 |
493 void EscapeObjectAnalysis::RecordEffectForFrameStateUses(Node* node, | |
494 Node* effect) { | |
495 DCHECK(effect->op()->EffectInputCount() > 0); | |
496 ZoneVector<Node*> queue(zone()); | |
497 queue.push_back(node); | |
Jarin
2015/12/02 12:24:34
Nit: why is it called a queue when it is a stack?
sigurds
2015/12/02 16:35:12
Done.
| |
498 while (!queue.empty()) { | |
499 Node* cur = queue.back(); | |
500 queue.pop_back(); | |
501 for (Edge edge : cur->input_edges()) { | |
502 Node* input = edge.to(); | |
503 if (input->opcode() == IrOpcode::kFrameState || | |
504 input->opcode() == IrOpcode::kStateValues) { | |
505 if (effects_[input->id()] != effect) { | |
506 effects_[input->id()] = effect; | |
507 if (FLAG_trace_turbo_escape) { | |
508 PrintF("Recorded effect #%d (%s) for frame state %d\n", | |
509 effect->id(), effect->op()->mnemonic(), input->id()); | |
510 } | |
511 } | |
512 // climb up the chain. | |
513 queue.push_back(input); | |
514 } | |
515 } | |
516 } | |
517 } | |
518 | |
519 | |
488 bool EscapeObjectAnalysis::Process(Node* node) { | 520 bool EscapeObjectAnalysis::Process(Node* node) { |
489 switch (node->opcode()) { | 521 switch (node->opcode()) { |
490 case IrOpcode::kAllocate: | 522 case IrOpcode::kAllocate: |
491 ProcessAllocation(node); | 523 ProcessAllocation(node); |
492 break; | 524 break; |
493 case IrOpcode::kBeginRegion: | 525 case IrOpcode::kBeginRegion: |
494 ForwardVirtualState(node); | 526 ForwardVirtualState(node); |
495 break; | 527 break; |
496 case IrOpcode::kFinishRegion: | 528 case IrOpcode::kFinishRegion: |
497 ProcessFinishRegion(node); | 529 ProcessFinishRegion(node); |
498 break; | 530 break; |
499 case IrOpcode::kStoreField: | 531 case IrOpcode::kStoreField: |
500 ProcessStoreField(node); | 532 ProcessStoreField(node); |
501 break; | 533 break; |
502 case IrOpcode::kLoadField: | 534 case IrOpcode::kLoadField: |
503 ProcessLoadField(node); | 535 ProcessLoadField(node); |
504 break; | 536 break; |
505 case IrOpcode::kStart: | 537 case IrOpcode::kStart: |
506 ProcessStart(node); | 538 ProcessStart(node); |
507 break; | 539 break; |
508 case IrOpcode::kEffectPhi: | 540 case IrOpcode::kEffectPhi: |
509 return ProcessEffectPhi(node); | 541 return ProcessEffectPhi(node); |
510 break; | 542 break; |
511 default: | 543 default: |
512 if (node->op()->EffectInputCount() > 0) { | 544 if (node->op()->EffectInputCount() > 0) { |
513 ForwardVirtualState(node); | 545 ForwardVirtualState(node); |
546 RecordEffectForFrameStateUses(node, node); | |
514 } | 547 } |
515 break; | 548 break; |
516 } | 549 } |
517 return true; | 550 return true; |
518 } | 551 } |
519 | 552 |
520 | 553 |
521 bool EscapeObjectAnalysis::IsEffectBranchPoint(Node* node) { | 554 bool EscapeObjectAnalysis::IsEffectBranchPoint(Node* node) { |
522 int count = 0; | 555 int count = 0; |
523 for (Edge edge : node->use_edges()) { | 556 for (Edge edge : node->use_edges()) { |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
671 | 704 |
672 Node* EscapeObjectAnalysis::GetReplacement(Node* at, NodeId id) { | 705 Node* EscapeObjectAnalysis::GetReplacement(Node* at, NodeId id) { |
673 VirtualState* states = virtual_states_[at->id()]; | 706 VirtualState* states = virtual_states_[at->id()]; |
674 if (VirtualObject* obj = states->GetVirtualObject(id)) { | 707 if (VirtualObject* obj = states->GetVirtualObject(id)) { |
675 return obj->GetReplacement(); | 708 return obj->GetReplacement(); |
676 } | 709 } |
677 return nullptr; | 710 return nullptr; |
678 } | 711 } |
679 | 712 |
680 | 713 |
714 VirtualObject* EscapeObjectAnalysis::GetVirtualObject(Node* at, NodeId id) { | |
715 if (VirtualState* states = virtual_states_[at->id()]) { | |
716 return states->GetVirtualObject(id); | |
717 } | |
718 return nullptr; | |
719 } | |
720 | |
721 | |
722 Node* EscapeObjectAnalysis::GetEffect(Node* node) { | |
723 return effects_[node->id()]; | |
724 } | |
725 | |
726 | |
681 int EscapeObjectAnalysis::OffsetFromAccess(Node* node) { | 727 int EscapeObjectAnalysis::OffsetFromAccess(Node* node) { |
682 DCHECK(OpParameter<FieldAccess>(node).offset % kPointerSize == 0); | 728 DCHECK(OpParameter<FieldAccess>(node).offset % kPointerSize == 0); |
683 return OpParameter<FieldAccess>(node).offset / kPointerSize; | 729 return OpParameter<FieldAccess>(node).offset / kPointerSize; |
684 } | 730 } |
685 | 731 |
686 | 732 |
687 void EscapeObjectAnalysis::ProcessLoadField(Node* node) { | 733 void EscapeObjectAnalysis::ProcessLoadField(Node* node) { |
688 DCHECK_EQ(node->opcode(), IrOpcode::kLoadField); | 734 DCHECK_EQ(node->opcode(), IrOpcode::kLoadField); |
689 ForwardVirtualState(node); | 735 ForwardVirtualState(node); |
690 Node* from = NodeProperties::GetValueInput(node, 0); | 736 Node* from = NodeProperties::GetValueInput(node, 0); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
792 PrintF(" Object #%zu links to object #%d\n", id, obj->id()); | 838 PrintF(" Object #%zu links to object #%d\n", id, obj->id()); |
793 } | 839 } |
794 } | 840 } |
795 } | 841 } |
796 } | 842 } |
797 } | 843 } |
798 | 844 |
799 } // namespace compiler | 845 } // namespace compiler |
800 } // namespace internal | 846 } // namespace internal |
801 } // namespace v8 | 847 } // namespace v8 |
OLD | NEW |