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

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

Issue 2459273002: [turbofan] Properly deal with out-of-bounds fields in EscapeAnalysis. (Closed)
Patch Set: Created 4 years, 1 month 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 | « no previous file | test/mjsunit/regress/regress-crbug-658185.js » ('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 <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 1381 matching lines...) Expand 10 before | Expand all | Expand 10 after
1392 } 1392 }
1393 1393
1394 void EscapeAnalysis::ProcessLoadField(Node* node) { 1394 void EscapeAnalysis::ProcessLoadField(Node* node) {
1395 DCHECK_EQ(node->opcode(), IrOpcode::kLoadField); 1395 DCHECK_EQ(node->opcode(), IrOpcode::kLoadField);
1396 ForwardVirtualState(node); 1396 ForwardVirtualState(node);
1397 Node* from = ResolveReplacement(NodeProperties::GetValueInput(node, 0)); 1397 Node* from = ResolveReplacement(NodeProperties::GetValueInput(node, 0));
1398 VirtualState* state = virtual_states_[node->id()]; 1398 VirtualState* state = virtual_states_[node->id()];
1399 if (VirtualObject* object = GetVirtualObject(state, from)) { 1399 if (VirtualObject* object = GetVirtualObject(state, from)) {
1400 if (!object->IsTracked()) return; 1400 if (!object->IsTracked()) return;
1401 int offset = OffsetForFieldAccess(node); 1401 int offset = OffsetForFieldAccess(node);
1402 if (static_cast<size_t>(offset) >= object->field_count()) return; 1402 if (static_cast<size_t>(offset) >= object->field_count()) {
1403 // We have a load from a field that is not inside the {object}. This
1404 // can only happen with conflicting type feedback and for dead {node}s.
1405 // For now, we just mark the {object} as escaping.
1406 // TODO(turbofan): Consider introducing an Undefined or None operator
1407 // that we can replace this load with, since we know it's dead code.
1408 if (status_analysis_->SetEscaped(from)) {
1409 TRACE(
1410 "Setting #%d (%s) to escaped because load field #%d from "
1411 "offset %d outside of object\n",
1412 from->id(), from->op()->mnemonic(), node->id(), offset);
1413 }
1414 return;
1415 }
1403 Node* value = object->GetField(offset); 1416 Node* value = object->GetField(offset);
1404 if (value) { 1417 if (value) {
1405 value = ResolveReplacement(value); 1418 value = ResolveReplacement(value);
1406 } 1419 }
1407 // Record that the load has this alias. 1420 // Record that the load has this alias.
1408 UpdateReplacement(state, node, value); 1421 UpdateReplacement(state, node, value);
1409 } else if (from->opcode() == IrOpcode::kPhi && 1422 } else if (from->opcode() == IrOpcode::kPhi &&
1410 FieldAccessOf(node->op()).offset % kPointerSize == 0) { 1423 FieldAccessOf(node->op()).offset % kPointerSize == 0) {
1411 int offset = OffsetForFieldAccess(node); 1424 int offset = OffsetForFieldAccess(node);
1412 // Only binary phis are supported for now. 1425 // Only binary phis are supported for now.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1457 } 1470 }
1458 1471
1459 void EscapeAnalysis::ProcessStoreField(Node* node) { 1472 void EscapeAnalysis::ProcessStoreField(Node* node) {
1460 DCHECK_EQ(node->opcode(), IrOpcode::kStoreField); 1473 DCHECK_EQ(node->opcode(), IrOpcode::kStoreField);
1461 ForwardVirtualState(node); 1474 ForwardVirtualState(node);
1462 Node* to = ResolveReplacement(NodeProperties::GetValueInput(node, 0)); 1475 Node* to = ResolveReplacement(NodeProperties::GetValueInput(node, 0));
1463 VirtualState* state = virtual_states_[node->id()]; 1476 VirtualState* state = virtual_states_[node->id()];
1464 if (VirtualObject* object = GetVirtualObject(state, to)) { 1477 if (VirtualObject* object = GetVirtualObject(state, to)) {
1465 if (!object->IsTracked()) return; 1478 if (!object->IsTracked()) return;
1466 int offset = OffsetForFieldAccess(node); 1479 int offset = OffsetForFieldAccess(node);
1467 if (static_cast<size_t>(offset) >= object->field_count()) return; 1480 if (static_cast<size_t>(offset) >= object->field_count()) {
1481 // We have a store to a field that is not inside the {object}. This
1482 // can only happen with conflicting type feedback and for dead {node}s.
1483 // For now, we just mark the {object} as escaping.
1484 // TODO(turbofan): Consider just eliminating the store in the reducer
1485 // pass, as it's dead code anyways.
1486 if (status_analysis_->SetEscaped(to)) {
1487 TRACE(
1488 "Setting #%d (%s) to escaped because store field #%d to "
1489 "offset %d outside of object\n",
1490 to->id(), to->op()->mnemonic(), node->id(), offset);
1491 }
1492 return;
1493 }
1468 Node* val = ResolveReplacement(NodeProperties::GetValueInput(node, 1)); 1494 Node* val = ResolveReplacement(NodeProperties::GetValueInput(node, 1));
1469 // TODO(mstarzinger): The following is a workaround to not track some well 1495 // TODO(mstarzinger): The following is a workaround to not track some well
1470 // known raw fields. We only ever store default initial values into these 1496 // known raw fields. We only ever store default initial values into these
1471 // fields which are hard-coded in {TranslatedState::MaterializeAt} as well. 1497 // fields which are hard-coded in {TranslatedState::MaterializeAt} as well.
1472 if (val->opcode() == IrOpcode::kInt32Constant || 1498 if (val->opcode() == IrOpcode::kInt32Constant ||
1473 val->opcode() == IrOpcode::kInt64Constant) { 1499 val->opcode() == IrOpcode::kInt64Constant) {
1474 DCHECK(FieldAccessOf(node->op()).offset == JSFunction::kCodeEntryOffset || 1500 DCHECK(FieldAccessOf(node->op()).offset == JSFunction::kCodeEntryOffset ||
1475 FieldAccessOf(node->op()).offset == Name::kHashFieldOffset); 1501 FieldAccessOf(node->op()).offset == Name::kHashFieldOffset);
1476 val = slot_not_analyzed_; 1502 val = slot_not_analyzed_;
1477 } 1503 }
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1636 } 1662 }
1637 } 1663 }
1638 return false; 1664 return false;
1639 } 1665 }
1640 1666
1641 Graph* EscapeAnalysis::graph() const { return status_analysis_->graph(); } 1667 Graph* EscapeAnalysis::graph() const { return status_analysis_->graph(); }
1642 1668
1643 } // namespace compiler 1669 } // namespace compiler
1644 } // namespace internal 1670 } // namespace internal
1645 } // namespace v8 1671 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-crbug-658185.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698