Chromium Code Reviews| 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 |