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

Side by Side Diff: src/compiler/escape-analysis.cc

Issue 1485183002: [turbofan] Deopt support for escape analysis (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@ea-local
Patch Set: Fix --always-opt triggered bug Created 5 years 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
« no previous file with comments | « src/compiler/escape-analysis.h ('k') | src/compiler/escape-analysis-reducer.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 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 11 matching lines...) Expand all
22 namespace compiler { 22 namespace compiler {
23 23
24 24
25 // ------------------------------VirtualObject---------------------------------- 25 // ------------------------------VirtualObject----------------------------------
26 26
27 27
28 class VirtualObject : public ZoneObject { 28 class VirtualObject : public ZoneObject {
29 public: 29 public:
30 enum Status { kUntracked = 0, kTracked = 1 }; 30 enum Status { kUntracked = 0, kTracked = 1 };
31 VirtualObject(NodeId id, Zone* zone) 31 VirtualObject(NodeId id, Zone* zone)
32 : id_(id), status_(kUntracked), fields_(zone), replacement_(nullptr) {} 32 : id_(id),
33 status_(kUntracked),
34 fields_(zone),
35 replacement_(nullptr),
36 object_state_(nullptr) {}
33 37
34 VirtualObject(const VirtualObject& other) 38 VirtualObject(const VirtualObject& other)
35 : id_(other.id_), 39 : id_(other.id_),
36 status_(other.status_), 40 status_(other.status_),
37 fields_(other.fields_), 41 fields_(other.fields_),
38 replacement_(other.replacement_) {} 42 replacement_(other.replacement_),
43 object_state_(other.object_state_) {}
39 44
40 VirtualObject(NodeId id, Zone* zone, size_t field_number) 45 VirtualObject(NodeId id, Zone* zone, size_t field_count)
41 : id_(id), status_(kTracked), fields_(zone), replacement_(nullptr) { 46 : id_(id),
42 fields_.resize(field_number); 47 status_(kTracked),
48 fields_(zone),
49 replacement_(nullptr),
50 object_state_(nullptr) {
51 fields_.resize(field_count);
43 } 52 }
44 53
45 Node* GetField(size_t offset) { 54 Node* GetField(size_t offset) {
46 if (offset < fields_.size()) { 55 if (offset < fields_.size()) {
47 return fields_[offset]; 56 return fields_[offset];
48 } 57 }
49 return nullptr; 58 return nullptr;
50 } 59 }
51 60
52 bool SetField(size_t offset, Node* node) { 61 bool SetField(size_t offset, Node* node) {
53 bool changed = fields_[offset] != node; 62 bool changed = fields_[offset] != node;
54 fields_[offset] = node; 63 fields_[offset] = node;
55 return changed; 64 return changed;
56 } 65 }
57 bool IsVirtual() const { return status_ == kTracked; } 66 bool IsVirtual() const { return status_ == kTracked; }
58 bool IsTracked() const { return status_ != kUntracked; } 67 bool IsTracked() const { return status_ != kUntracked; }
59 Node* GetReplacement() { return replacement_; } 68 Node* GetReplacement() { return replacement_; }
60 bool SetReplacement(Node* node) { 69 bool SetReplacement(Node* node) {
61 bool changed = replacement_ != node; 70 bool changed = replacement_ != node;
62 replacement_ = node; 71 replacement_ = node;
63 return changed; 72 return changed;
64 } 73 }
65 74
66 size_t fields() { return fields_.size(); } 75 Node** fields_array() { return &fields_.front(); }
67 bool ResizeFields(size_t field_number) { 76 size_t field_count() { return fields_.size(); }
68 if (field_number != fields_.size()) { 77 bool ResizeFields(size_t field_count) {
69 fields_.resize(field_number); 78 if (field_count != fields_.size()) {
79 fields_.resize(field_count);
70 return true; 80 return true;
71 } 81 }
72 return false; 82 return false;
73 } 83 }
74 84 void SetObjectState(Node* node) { object_state_ = node; }
85 Node* GetObjectState() { return object_state_; }
75 bool UpdateFrom(const VirtualObject& other); 86 bool UpdateFrom(const VirtualObject& other);
76 87
77 NodeId id() { return id_; } 88 NodeId id() { return id_; }
78 void id(NodeId id) { id_ = id; } 89 void id(NodeId id) { id_ = id; }
79 90
80 private: 91 private:
81 NodeId id_; 92 NodeId id_;
82 Status status_; 93 Status status_;
83 ZoneVector<Node*> fields_; 94 ZoneVector<Node*> fields_;
84 Node* replacement_; 95 Node* replacement_;
96 Node* object_state_;
85 }; 97 };
86 98
87 99
88 bool VirtualObject::UpdateFrom(const VirtualObject& other) { 100 bool VirtualObject::UpdateFrom(const VirtualObject& other) {
89 bool changed = status_ != other.status_; 101 bool changed = status_ != other.status_;
90 status_ = other.status_; 102 status_ = other.status_;
91 changed = replacement_ != other.replacement_ || changed; 103 changed = replacement_ != other.replacement_ || changed;
92 replacement_ = other.replacement_; 104 replacement_ = other.replacement_;
93 if (fields_.size() != other.fields_.size()) { 105 if (fields_.size() != other.fields_.size()) {
94 fields_ = other.fields_; 106 fields_ = other.fields_;
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 bool changed = false; 251 bool changed = false;
240 for (NodeId id = 0; id < std::min(left->size(), right->size()); ++id) { 252 for (NodeId id = 0; id < std::min(left->size(), right->size()); ++id) {
241 VirtualObject* ls = left->GetVirtualObject(id); 253 VirtualObject* ls = left->GetVirtualObject(id);
242 VirtualObject* rs = right->GetVirtualObject(id); 254 VirtualObject* rs = right->GetVirtualObject(id);
243 255
244 if (ls != nullptr && rs != nullptr) { 256 if (ls != nullptr && rs != nullptr) {
245 if (FLAG_trace_turbo_escape) { 257 if (FLAG_trace_turbo_escape) {
246 PrintF(" Merging fields of #%d\n", id); 258 PrintF(" Merging fields of #%d\n", id);
247 } 259 }
248 VirtualObject* mergeObject = GetOrCreateTrackedVirtualObject(id, zone); 260 VirtualObject* mergeObject = GetOrCreateTrackedVirtualObject(id, zone);
249 size_t fields = std::max(ls->fields(), rs->fields()); 261 size_t fields = std::max(ls->field_count(), rs->field_count());
250 changed = mergeObject->ResizeFields(fields) || changed; 262 changed = mergeObject->ResizeFields(fields) || changed;
251 for (size_t i = 0; i < fields; ++i) { 263 for (size_t i = 0; i < fields; ++i) {
252 if (ls->GetField(i) == rs->GetField(i)) { 264 if (ls->GetField(i) == rs->GetField(i)) {
253 changed = mergeObject->SetField(i, ls->GetField(i)) || changed; 265 changed = mergeObject->SetField(i, ls->GetField(i)) || changed;
254 if (FLAG_trace_turbo_escape && ls->GetField(i)) { 266 if (FLAG_trace_turbo_escape && ls->GetField(i)) {
255 PrintF(" Field %zu agree on rep #%d\n", i, 267 PrintF(" Field %zu agree on rep #%d\n", i,
256 ls->GetField(i)->id()); 268 ls->GetField(i)->id());
257 } 269 }
258 } else if (ls->GetField(i) != nullptr && rs->GetField(i) != nullptr) { 270 } else if (ls->GetField(i) != nullptr && rs->GetField(i) != nullptr) {
259 Node* phi = graph->NewNode(common->Phi(kMachAnyTagged, 2), 271 Node* phi = graph->NewNode(common->Phi(kMachAnyTagged, 2),
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 533
522 // -----------------------------EscapeAnalysis---------------------------------- 534 // -----------------------------EscapeAnalysis----------------------------------
523 535
524 536
525 EscapeAnalysis::EscapeAnalysis(Graph* graph, CommonOperatorBuilder* common, 537 EscapeAnalysis::EscapeAnalysis(Graph* graph, CommonOperatorBuilder* common,
526 Zone* zone) 538 Zone* zone)
527 : graph_(graph), 539 : graph_(graph),
528 common_(common), 540 common_(common),
529 zone_(zone), 541 zone_(zone),
530 virtual_states_(zone), 542 virtual_states_(zone),
531 escape_status_(this, graph, zone) {} 543 escape_status_(this, graph, zone),
544 effects_(zone) {}
532 545
533 546
534 EscapeAnalysis::~EscapeAnalysis() {} 547 EscapeAnalysis::~EscapeAnalysis() {}
535 548
536 549
537 void EscapeAnalysis::Run() { 550 void EscapeAnalysis::Run() {
538 RunObjectAnalysis(); 551 RunObjectAnalysis();
539 escape_status_.Run(); 552 escape_status_.Run();
540 } 553 }
541 554
542 555
543 void EscapeAnalysis::RunObjectAnalysis() { 556 void EscapeAnalysis::RunObjectAnalysis() {
557 effects_.resize(graph()->NodeCount());
544 virtual_states_.resize(graph()->NodeCount()); 558 virtual_states_.resize(graph()->NodeCount());
545 ZoneVector<Node*> queue(zone()); 559 ZoneVector<Node*> stack(zone());
Jarin 2015/12/04 13:41:11 Nit: you can actually even say ZoneStack<...> here
546 queue.push_back(graph()->start()); 560 stack.push_back(graph()->start());
547 while (!queue.empty()) { 561 while (!stack.empty()) {
548 Node* node = queue.back(); 562 Node* node = stack.back();
549 queue.pop_back(); 563 stack.pop_back();
550 if (Process(node)) { 564 if (Process(node)) {
551 for (Edge edge : node->use_edges()) { 565 for (Edge edge : node->use_edges()) {
552 if (NodeProperties::IsEffectEdge(edge)) { 566 if (NodeProperties::IsEffectEdge(edge)) {
553 Node* use = edge.from(); 567 Node* use = edge.from();
554 if (use->opcode() != IrOpcode::kLoadField || 568 if (use->opcode() != IrOpcode::kLoadField ||
555 !IsDanglingEffectNode(use)) { 569 !IsDanglingEffectNode(use)) {
556 queue.push_back(use); 570 stack.push_back(use);
557 } 571 }
558 } 572 }
559 } 573 }
560 // First process loads: dangling loads are a problem otherwise. 574 // First process loads: dangling loads are a problem otherwise.
561 for (Edge edge : node->use_edges()) { 575 for (Edge edge : node->use_edges()) {
562 if (NodeProperties::IsEffectEdge(edge)) { 576 if (NodeProperties::IsEffectEdge(edge)) {
563 Node* use = edge.from(); 577 Node* use = edge.from();
564 if (use->opcode() == IrOpcode::kLoadField && 578 if (use->opcode() == IrOpcode::kLoadField &&
565 IsDanglingEffectNode(use)) { 579 IsDanglingEffectNode(use)) {
566 queue.push_back(use); 580 stack.push_back(use);
567 } 581 }
568 } 582 }
569 } 583 }
570 } 584 }
571 } 585 }
572 if (FLAG_trace_turbo_escape) { 586 if (FLAG_trace_turbo_escape) {
573 DebugPrint(); 587 DebugPrint();
574 } 588 }
575 } 589 }
576 590
577 591
578 bool EscapeAnalysis::IsDanglingEffectNode(Node* node) { 592 bool EscapeAnalysis::IsDanglingEffectNode(Node* node) {
579 if (node->op()->EffectInputCount() == 0) return false; 593 if (node->op()->EffectInputCount() == 0) return false;
580 if (node->op()->EffectOutputCount() == 0) return false; 594 if (node->op()->EffectOutputCount() == 0) return false;
581 for (Edge edge : node->use_edges()) { 595 for (Edge edge : node->use_edges()) {
582 if (NodeProperties::IsEffectEdge(edge)) { 596 if (NodeProperties::IsEffectEdge(edge)) {
583 return false; 597 return false;
584 } 598 }
585 } 599 }
586 return true; 600 return true;
587 } 601 }
588 602
589 603
604 void EscapeAnalysis::RecordEffectForFrameStateUses(Node* node, Node* effect) {
605 DCHECK(effect->op()->EffectInputCount() > 0);
606 ZoneVector<Node*> stack(zone());
607 stack.push_back(node);
608 while (!stack.empty()) {
609 Node* cur = stack.back();
610 stack.pop_back();
611 for (Edge edge : cur->input_edges()) {
612 Node* input = edge.to();
613 if (input->opcode() == IrOpcode::kFrameState ||
614 input->opcode() == IrOpcode::kStateValues) {
615 if (effects_[input->id()] != effect) {
616 effects_[input->id()] = effect;
617 if (FLAG_trace_turbo_escape) {
618 PrintF("Recorded effect #%d (%s) for frame state %d\n",
619 effect->id(), effect->op()->mnemonic(), input->id());
620 }
621 }
622 // Climb up the chain.
623 stack.push_back(input);
624 }
625 }
626 }
627 }
628
629
590 bool EscapeAnalysis::Process(Node* node) { 630 bool EscapeAnalysis::Process(Node* node) {
591 switch (node->opcode()) { 631 switch (node->opcode()) {
592 case IrOpcode::kAllocate: 632 case IrOpcode::kAllocate:
593 ProcessAllocation(node); 633 ProcessAllocation(node);
594 break; 634 break;
595 case IrOpcode::kBeginRegion: 635 case IrOpcode::kBeginRegion:
596 ForwardVirtualState(node); 636 ForwardVirtualState(node);
597 break; 637 break;
598 case IrOpcode::kFinishRegion: 638 case IrOpcode::kFinishRegion:
599 ProcessFinishRegion(node); 639 ProcessFinishRegion(node);
600 break; 640 break;
601 case IrOpcode::kStoreField: 641 case IrOpcode::kStoreField:
602 ProcessStoreField(node); 642 ProcessStoreField(node);
603 break; 643 break;
604 case IrOpcode::kLoadField: 644 case IrOpcode::kLoadField:
605 ProcessLoadField(node); 645 ProcessLoadField(node);
606 break; 646 break;
607 case IrOpcode::kStart: 647 case IrOpcode::kStart:
608 ProcessStart(node); 648 ProcessStart(node);
609 break; 649 break;
610 case IrOpcode::kEffectPhi: 650 case IrOpcode::kEffectPhi:
611 return ProcessEffectPhi(node); 651 return ProcessEffectPhi(node);
612 break; 652 break;
613 default: 653 default:
614 if (node->op()->EffectInputCount() > 0) { 654 if (node->op()->EffectInputCount() > 0) {
615 ForwardVirtualState(node); 655 ForwardVirtualState(node);
656 RecordEffectForFrameStateUses(node, node);
616 } 657 }
617 break; 658 break;
618 } 659 }
619 return true; 660 return true;
620 } 661 }
621 662
622 663
623 bool EscapeAnalysis::IsEffectBranchPoint(Node* node) { 664 bool EscapeAnalysis::IsEffectBranchPoint(Node* node) {
624 int count = 0; 665 int count = 0;
625 for (Edge edge : node->use_edges()) { 666 for (Edge edge : node->use_edges()) {
626 Node* use = edge.from(); 667 Node* use = edge.from();
627 if (NodeProperties::IsEffectEdge(edge) && 668 if (NodeProperties::IsEffectEdge(edge) &&
628 use->opcode() != IrOpcode::kLoadField) { 669 use->opcode() != IrOpcode::kLoadField) {
629 if (++count > 1) { 670 if (++count > 1) {
630 return true; 671 return true;
631 } 672 }
632 } 673 }
633 } 674 }
634 return false; 675 return false;
635 } 676 }
636 677
637 678
638 void EscapeAnalysis::ForwardVirtualState(Node* node) { 679 void EscapeAnalysis::ForwardVirtualState(Node* node) {
639 DCHECK_EQ(node->op()->EffectInputCount(), 1); 680 DCHECK_EQ(node->op()->EffectInputCount(), 1);
640 if (node->opcode() != IrOpcode::kLoadField && IsDanglingEffectNode(node)) { 681 if (node->opcode() != IrOpcode::kLoadField &&
682 node->opcode() != IrOpcode::kLoad && IsDanglingEffectNode(node)) {
641 PrintF("Dangeling effect node: #%d (%s)\n", node->id(), 683 PrintF("Dangeling effect node: #%d (%s)\n", node->id(),
642 node->op()->mnemonic()); 684 node->op()->mnemonic());
643 DCHECK(false); 685 DCHECK(false);
644 } 686 }
645 Node* effect = NodeProperties::GetEffectInput(node); 687 Node* effect = NodeProperties::GetEffectInput(node);
646 // Break the cycle for effect phis. 688 // Break the cycle for effect phis.
647 if (effect->opcode() == IrOpcode::kEffectPhi) { 689 if (effect->opcode() == IrOpcode::kEffectPhi) {
648 if (virtual_states_[effect->id()] == nullptr) { 690 if (virtual_states_[effect->id()] == nullptr) {
649 virtual_states_[effect->id()] = 691 virtual_states_[effect->id()] =
650 new (zone()) VirtualState(zone(), graph()->NodeCount()); 692 new (zone()) VirtualState(zone(), graph()->NodeCount());
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 bool EscapeAnalysis::IsVirtual(Node* node) { 825 bool EscapeAnalysis::IsVirtual(Node* node) {
784 return escape_status_.IsVirtual(node); 826 return escape_status_.IsVirtual(node);
785 } 827 }
786 828
787 829
788 bool EscapeAnalysis::IsEscaped(Node* node) { 830 bool EscapeAnalysis::IsEscaped(Node* node) {
789 return escape_status_.IsEscaped(node); 831 return escape_status_.IsEscaped(node);
790 } 832 }
791 833
792 834
835 VirtualObject* EscapeAnalysis::GetVirtualObject(Node* at, NodeId id) {
836 if (VirtualState* states = virtual_states_[at->id()]) {
837 return states->GetVirtualObject(id);
838 }
839 return nullptr;
840 }
841
842
843 Node* EscapeAnalysis::GetEffect(Node* node) { return effects_[node->id()]; }
844
845
793 int EscapeAnalysis::OffsetFromAccess(Node* node) { 846 int EscapeAnalysis::OffsetFromAccess(Node* node) {
794 DCHECK(OpParameter<FieldAccess>(node).offset % kPointerSize == 0); 847 DCHECK(OpParameter<FieldAccess>(node).offset % kPointerSize == 0);
795 return OpParameter<FieldAccess>(node).offset / kPointerSize; 848 return OpParameter<FieldAccess>(node).offset / kPointerSize;
796 } 849 }
797 850
798 851
799 void EscapeAnalysis::ProcessLoadField(Node* node) { 852 void EscapeAnalysis::ProcessLoadField(Node* node) {
800 DCHECK_EQ(node->opcode(), IrOpcode::kLoadField); 853 DCHECK_EQ(node->opcode(), IrOpcode::kLoadField);
801 ForwardVirtualState(node); 854 ForwardVirtualState(node);
802 Node* from = NodeProperties::GetValueInput(node, 0); 855 Node* from = NodeProperties::GetValueInput(node, 0);
803 int offset = OffsetFromAccess(node);
804 VirtualState* states = virtual_states_[node->id()]; 856 VirtualState* states = virtual_states_[node->id()];
805 if (VirtualObject* state = states->GetVirtualObject(from)) { 857 if (VirtualObject* state = states->GetVirtualObject(from)) {
858 int offset = OffsetFromAccess(node);
806 if (!state->IsTracked()) return; 859 if (!state->IsTracked()) return;
807 Node* value = state->GetField(offset); 860 Node* value = state->GetField(offset);
808 if (value) { 861 if (value) {
809 // Record that the load has this alias. 862 // Record that the load has this alias.
810 states->UpdateReplacement(node, value, zone()); 863 states->UpdateReplacement(node, value, zone());
811 } else if (FLAG_trace_turbo_escape) { 864 } else if (FLAG_trace_turbo_escape) {
812 PrintF("No field %d on record for #%d\n", offset, from->id()); 865 PrintF("No field %d on record for #%d\n", offset, from->id());
813 } 866 }
814 } else { 867 } else {
815 if (from->opcode() == IrOpcode::kPhi) { 868 if (from->opcode() == IrOpcode::kPhi) {
869 int offset = OffsetFromAccess(node);
816 // Only binary phis are supported for now. 870 // Only binary phis are supported for now.
817 CHECK_EQ(from->op()->ValueInputCount(), 2); 871 CHECK_EQ(from->op()->ValueInputCount(), 2);
818 if (FLAG_trace_turbo_escape) { 872 if (FLAG_trace_turbo_escape) {
819 PrintF("Load #%d from phi #%d", node->id(), from->id()); 873 PrintF("Load #%d from phi #%d", node->id(), from->id());
820 } 874 }
821 Node* left = NodeProperties::GetValueInput(from, 0); 875 Node* left = NodeProperties::GetValueInput(from, 0);
822 Node* right = NodeProperties::GetValueInput(from, 1); 876 Node* right = NodeProperties::GetValueInput(from, 1);
823 VirtualObject* l = states->GetVirtualObject(left); 877 VirtualObject* l = states->GetVirtualObject(left);
824 VirtualObject* r = states->GetVirtualObject(right); 878 VirtualObject* r = states->GetVirtualObject(right);
825 if (l && r) { 879 if (l && r) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 VirtualState* states = virtual_states_[node->id()]; 921 VirtualState* states = virtual_states_[node->id()];
868 if (VirtualObject* obj = states->GetVirtualObject(to)) { 922 if (VirtualObject* obj = states->GetVirtualObject(to)) {
869 if (!obj->IsTracked()) return; 923 if (!obj->IsTracked()) return;
870 if (obj->SetField(offset, states->ResolveReplacement(val))) { 924 if (obj->SetField(offset, states->ResolveReplacement(val))) {
871 states->LastChangedAt(node); 925 states->LastChangedAt(node);
872 } 926 }
873 } 927 }
874 } 928 }
875 929
876 930
931 Node* EscapeAnalysis::GetOrCreateObjectState(Node* effect, Node* node) {
932 if ((node->opcode() == IrOpcode::kFinishRegion ||
933 node->opcode() == IrOpcode::kAllocate) &&
934 IsVirtual(node)) {
935 if (VirtualObject* vobj = GetVirtualObject(effect, node->id())) {
936 if (Node* object_state = vobj->GetObjectState()) {
937 return object_state;
938 } else {
939 Node* new_object_state = graph()->NewNode(
940 common()->ObjectState(static_cast<int>(vobj->field_count()),
941 vobj->id()),
942 static_cast<int>(vobj->field_count()), vobj->fields_array());
943 vobj->SetObjectState(new_object_state);
944 // Now fix uses of other objects.
945 for (size_t i = 0; i < vobj->field_count(); ++i) {
946 if (Node* field = vobj->GetField(i)) {
947 if (Node* field_object_state =
948 GetOrCreateObjectState(effect, field)) {
949 NodeProperties::ReplaceValueInput(
950 new_object_state, field_object_state, static_cast<int>(i));
951 }
952 }
953 }
954 return new_object_state;
955 }
956 }
957 }
958 return nullptr;
959 }
960
961
877 void EscapeAnalysis::DebugPrint() { 962 void EscapeAnalysis::DebugPrint() {
878 ZoneVector<VirtualState*> object_states(zone()); 963 ZoneVector<VirtualState*> object_states(zone());
879 for (NodeId id = 0; id < virtual_states_.size(); id++) { 964 for (NodeId id = 0; id < virtual_states_.size(); id++) {
880 if (VirtualState* states = virtual_states_[id]) { 965 if (VirtualState* states = virtual_states_[id]) {
881 if (std::find(object_states.begin(), object_states.end(), states) == 966 if (std::find(object_states.begin(), object_states.end(), states) ==
882 object_states.end()) { 967 object_states.end()) {
883 object_states.push_back(states); 968 object_states.push_back(states);
884 } 969 }
885 } 970 }
886 } 971 }
887 for (size_t n = 0; n < object_states.size(); n++) { 972 for (size_t n = 0; n < object_states.size(); n++) {
888 PrintF("Dumping object state %p\n", static_cast<void*>(object_states[n])); 973 PrintF("Dumping object state %p\n", static_cast<void*>(object_states[n]));
889 for (size_t id = 0; id < object_states[n]->size(); id++) { 974 for (size_t id = 0; id < object_states[n]->size(); id++) {
890 if (VirtualObject* obj = object_states[n]->GetVirtualObject(id)) { 975 if (VirtualObject* obj = object_states[n]->GetVirtualObject(id)) {
891 if (obj->id() == id) { 976 if (obj->id() == id) {
892 PrintF(" Object #%zu with %zu fields", id, obj->fields()); 977 PrintF(" Object #%zu with %zu fields", id, obj->field_count());
893 if (Node* rep = obj->GetReplacement()) { 978 if (Node* rep = obj->GetReplacement()) {
894 PrintF(", rep = #%d (%s)", rep->id(), rep->op()->mnemonic()); 979 PrintF(", rep = #%d (%s)", rep->id(), rep->op()->mnemonic());
895 } 980 }
896 PrintF("\n"); 981 PrintF("\n");
897 for (size_t i = 0; i < obj->fields(); ++i) { 982 for (size_t i = 0; i < obj->field_count(); ++i) {
898 if (Node* f = obj->GetField(i)) { 983 if (Node* f = obj->GetField(i)) {
899 PrintF(" Field %zu = #%d (%s)\n", i, f->id(), 984 PrintF(" Field %zu = #%d (%s)\n", i, f->id(),
900 f->op()->mnemonic()); 985 f->op()->mnemonic());
901 } 986 }
902 } 987 }
903 } else { 988 } else {
904 PrintF(" Object #%zu links to object #%d\n", id, obj->id()); 989 PrintF(" Object #%zu links to object #%d\n", id, obj->id());
905 } 990 }
906 } 991 }
907 } 992 }
908 } 993 }
909 } 994 }
910 995
911 } // namespace compiler 996 } // namespace compiler
912 } // namespace internal 997 } // namespace internal
913 } // namespace v8 998 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/escape-analysis.h ('k') | src/compiler/escape-analysis-reducer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698