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 <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/flags.h" | 9 #include "src/base/flags.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 } | 800 } |
801 // Fallthrough. | 801 // Fallthrough. |
802 case IrOpcode::kStoreField: | 802 case IrOpcode::kStoreField: |
803 case IrOpcode::kLoadField: | 803 case IrOpcode::kLoadField: |
804 case IrOpcode::kStoreElement: | 804 case IrOpcode::kStoreElement: |
805 case IrOpcode::kLoadElement: | 805 case IrOpcode::kLoadElement: |
806 case IrOpcode::kFrameState: | 806 case IrOpcode::kFrameState: |
807 case IrOpcode::kStateValues: | 807 case IrOpcode::kStateValues: |
808 case IrOpcode::kReferenceEqual: | 808 case IrOpcode::kReferenceEqual: |
809 case IrOpcode::kFinishRegion: | 809 case IrOpcode::kFinishRegion: |
| 810 case IrOpcode::kCheckMaps: |
810 if (IsEscaped(use) && SetEscaped(rep)) { | 811 if (IsEscaped(use) && SetEscaped(rep)) { |
811 TRACE( | 812 TRACE( |
812 "Setting #%d (%s) to escaped because of use by escaping node " | 813 "Setting #%d (%s) to escaped because of use by escaping node " |
813 "#%d (%s)\n", | 814 "#%d (%s)\n", |
814 rep->id(), rep->op()->mnemonic(), use->id(), | 815 rep->id(), rep->op()->mnemonic(), use->id(), |
815 use->op()->mnemonic()); | 816 use->op()->mnemonic()); |
816 return true; | 817 return true; |
817 } | 818 } |
818 break; | 819 break; |
819 case IrOpcode::kObjectIsSmi: | 820 case IrOpcode::kObjectIsSmi: |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1117 break; | 1118 break; |
1118 case IrOpcode::kLoadField: | 1119 case IrOpcode::kLoadField: |
1119 ProcessLoadField(node); | 1120 ProcessLoadField(node); |
1120 break; | 1121 break; |
1121 case IrOpcode::kStoreElement: | 1122 case IrOpcode::kStoreElement: |
1122 ProcessStoreElement(node); | 1123 ProcessStoreElement(node); |
1123 break; | 1124 break; |
1124 case IrOpcode::kLoadElement: | 1125 case IrOpcode::kLoadElement: |
1125 ProcessLoadElement(node); | 1126 ProcessLoadElement(node); |
1126 break; | 1127 break; |
| 1128 case IrOpcode::kCheckMaps: |
| 1129 ProcessCheckMaps(node); |
| 1130 break; |
1127 case IrOpcode::kStart: | 1131 case IrOpcode::kStart: |
1128 ProcessStart(node); | 1132 ProcessStart(node); |
1129 break; | 1133 break; |
1130 case IrOpcode::kEffectPhi: | 1134 case IrOpcode::kEffectPhi: |
1131 return ProcessEffectPhi(node); | 1135 return ProcessEffectPhi(node); |
1132 break; | 1136 break; |
1133 default: | 1137 default: |
1134 if (node->op()->EffectInputCount() > 0) { | 1138 if (node->op()->EffectInputCount() > 0) { |
1135 ForwardVirtualState(node); | 1139 ForwardVirtualState(node); |
1136 } | 1140 } |
(...skipping 17 matching lines...) Expand all Loading... |
1154 case IrOpcode::kStoreField: | 1158 case IrOpcode::kStoreField: |
1155 case IrOpcode::kLoadField: | 1159 case IrOpcode::kLoadField: |
1156 case IrOpcode::kStoreElement: | 1160 case IrOpcode::kStoreElement: |
1157 case IrOpcode::kLoadElement: | 1161 case IrOpcode::kLoadElement: |
1158 case IrOpcode::kFrameState: | 1162 case IrOpcode::kFrameState: |
1159 case IrOpcode::kStateValues: | 1163 case IrOpcode::kStateValues: |
1160 case IrOpcode::kReferenceEqual: | 1164 case IrOpcode::kReferenceEqual: |
1161 case IrOpcode::kFinishRegion: | 1165 case IrOpcode::kFinishRegion: |
1162 case IrOpcode::kObjectIsSmi: | 1166 case IrOpcode::kObjectIsSmi: |
1163 break; | 1167 break; |
| 1168 case IrOpcode::kCheckMaps: { |
| 1169 CheckMapsParameters params = CheckMapsParametersOf(node->op()); |
| 1170 if (params.flags() == CheckMapsFlag::kNone) break; |
| 1171 } // Fallthrough. |
1164 default: | 1172 default: |
1165 VirtualState* state = virtual_states_[node->id()]; | 1173 VirtualState* state = virtual_states_[node->id()]; |
1166 if (VirtualObject* obj = | 1174 if (VirtualObject* obj = |
1167 GetVirtualObject(state, ResolveReplacement(input))) { | 1175 GetVirtualObject(state, ResolveReplacement(input))) { |
1168 if (!obj->AllFieldsClear()) { | 1176 if (!obj->AllFieldsClear()) { |
1169 obj = CopyForModificationAt(obj, state, node); | 1177 obj = CopyForModificationAt(obj, state, node); |
1170 obj->ClearAllFields(); | 1178 obj->ClearAllFields(); |
1171 TRACE("Cleared all fields of @%d:#%d\n", | 1179 TRACE("Cleared all fields of @%d:#%d\n", |
1172 status_analysis_->GetAlias(obj->id()), obj->id()); | 1180 status_analysis_->GetAlias(obj->id()), obj->id()); |
1173 } | 1181 } |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1507 } else if (from->opcode() == IrOpcode::kPhi && | 1515 } else if (from->opcode() == IrOpcode::kPhi && |
1508 IsOffsetForFieldAccessCorrect(FieldAccessOf(node->op()))) { | 1516 IsOffsetForFieldAccessCorrect(FieldAccessOf(node->op()))) { |
1509 int offset = OffsetForFieldAccess(node); | 1517 int offset = OffsetForFieldAccess(node); |
1510 // Only binary phis are supported for now. | 1518 // Only binary phis are supported for now. |
1511 ProcessLoadFromPhi(offset, from, node, state); | 1519 ProcessLoadFromPhi(offset, from, node, state); |
1512 } else { | 1520 } else { |
1513 UpdateReplacement(state, node, nullptr); | 1521 UpdateReplacement(state, node, nullptr); |
1514 } | 1522 } |
1515 } | 1523 } |
1516 | 1524 |
| 1525 void EscapeAnalysis::ProcessCheckMaps(Node* node) { |
| 1526 DCHECK_EQ(node->opcode(), IrOpcode::kCheckMaps); |
| 1527 ForwardVirtualState(node); |
| 1528 Node* checked = ResolveReplacement(NodeProperties::GetValueInput(node, 0)); |
| 1529 if (FLAG_turbo_experimental) { |
| 1530 VirtualState* state = virtual_states_[node->id()]; |
| 1531 if (VirtualObject* object = GetVirtualObject(state, checked)) { |
| 1532 if (!object->IsTracked()) { |
| 1533 if (status_analysis_->SetEscaped(node)) { |
| 1534 TRACE( |
| 1535 "Setting #%d (%s) to escaped because checked object #%i is not " |
| 1536 "tracked\n", |
| 1537 node->id(), node->op()->mnemonic(), object->id()); |
| 1538 } |
| 1539 return; |
| 1540 } |
| 1541 CheckMapsParameters params = CheckMapsParametersOf(node->op()); |
| 1542 |
| 1543 Node* value = object->GetField(HeapObject::kMapOffset / kPointerSize); |
| 1544 if (value) { |
| 1545 value = ResolveReplacement(value); |
| 1546 // TODO(tebbi): We want to extend this beyond constant folding with a |
| 1547 // CheckMapsValue operator that takes the load-eliminated map value as |
| 1548 // input. |
| 1549 if (value->opcode() == IrOpcode::kHeapConstant && |
| 1550 params.maps().contains(ZoneHandleSet<Map>( |
| 1551 Handle<Map>::cast(OpParameter<Handle<HeapObject>>(value))))) { |
| 1552 TRACE("CheckMaps #%i seems to be redundant (until now).\n", |
| 1553 node->id()); |
| 1554 return; |
| 1555 } |
| 1556 } |
| 1557 } |
| 1558 } |
| 1559 if (status_analysis_->SetEscaped(node)) { |
| 1560 TRACE("Setting #%d (%s) to escaped (checking #%i)\n", node->id(), |
| 1561 node->op()->mnemonic(), checked->id()); |
| 1562 } |
| 1563 } |
| 1564 |
1517 void EscapeAnalysis::ProcessLoadElement(Node* node) { | 1565 void EscapeAnalysis::ProcessLoadElement(Node* node) { |
1518 DCHECK_EQ(node->opcode(), IrOpcode::kLoadElement); | 1566 DCHECK_EQ(node->opcode(), IrOpcode::kLoadElement); |
1519 ForwardVirtualState(node); | 1567 ForwardVirtualState(node); |
1520 Node* from = ResolveReplacement(NodeProperties::GetValueInput(node, 0)); | 1568 Node* from = ResolveReplacement(NodeProperties::GetValueInput(node, 0)); |
1521 VirtualState* state = virtual_states_[node->id()]; | 1569 VirtualState* state = virtual_states_[node->id()]; |
1522 Node* index_node = node->InputAt(1); | 1570 Node* index_node = node->InputAt(1); |
1523 NumberMatcher index(index_node); | 1571 NumberMatcher index(index_node); |
1524 DCHECK(index_node->opcode() != IrOpcode::kInt32Constant && | 1572 DCHECK(index_node->opcode() != IrOpcode::kInt32Constant && |
1525 index_node->opcode() != IrOpcode::kInt64Constant && | 1573 index_node->opcode() != IrOpcode::kInt64Constant && |
1526 index_node->opcode() != IrOpcode::kFloat32Constant && | 1574 index_node->opcode() != IrOpcode::kFloat32Constant && |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1748 } | 1796 } |
1749 } | 1797 } |
1750 return false; | 1798 return false; |
1751 } | 1799 } |
1752 | 1800 |
1753 Graph* EscapeAnalysis::graph() const { return status_analysis_->graph(); } | 1801 Graph* EscapeAnalysis::graph() const { return status_analysis_->graph(); } |
1754 | 1802 |
1755 } // namespace compiler | 1803 } // namespace compiler |
1756 } // namespace internal | 1804 } // namespace internal |
1757 } // namespace v8 | 1805 } // namespace v8 |
OLD | NEW |