Commit f431b597 authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

[turbofan] escape analysis: patch for wrong deopt info

Bug: chromium:713367
Change-Id: I3f5960f5b2da22c6468ca5a5ea9dc847b30c7fc7
Reviewed-on: https://chromium-review.googlesource.com/486360
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44862}
parent d049239c
...@@ -635,6 +635,11 @@ void EscapeStatusAnalysis::ResizeStatusVector() { ...@@ -635,6 +635,11 @@ void EscapeStatusAnalysis::ResizeStatusVector() {
size_t EscapeStatusAnalysis::GetStatusVectorSize() { return status_.size(); } size_t EscapeStatusAnalysis::GetStatusVectorSize() { return status_.size(); }
void EscapeStatusAnalysis::RunStatusAnalysis() { void EscapeStatusAnalysis::RunStatusAnalysis() {
// TODO(tebbi): This checks for faulty VirtualObject states, which can happen
// due to bug https://bugs.chromium.org/p/v8/issues/detail?id=6302. As a
// workaround, we set everything to escaped if such a faulty state was
// detected.
bool all_objects_complete = object_analysis_->AllObjectsComplete();
ResizeStatusVector(); ResizeStatusVector();
while (!status_stack_.empty()) { while (!status_stack_.empty()) {
Node* node = status_stack_.back(); Node* node = status_stack_.back();
...@@ -642,6 +647,7 @@ void EscapeStatusAnalysis::RunStatusAnalysis() { ...@@ -642,6 +647,7 @@ void EscapeStatusAnalysis::RunStatusAnalysis() {
status_[node->id()] &= ~kOnStack; status_[node->id()] &= ~kOnStack;
Process(node); Process(node);
status_[node->id()] |= kVisited; status_[node->id()] |= kVisited;
if (!all_objects_complete) SetEscaped(node);
} }
} }
...@@ -992,6 +998,25 @@ bool EscapeStatusAnalysis::IsNotReachable(Node* node) { ...@@ -992,6 +998,25 @@ bool EscapeStatusAnalysis::IsNotReachable(Node* node) {
return aliases_[node->id()] == kNotReachable; return aliases_[node->id()] == kNotReachable;
} }
bool EscapeAnalysis::AllObjectsComplete() {
for (VirtualState* state : virtual_states_) {
if (state) {
for (size_t i = 0; i < state->size(); ++i) {
if (VirtualObject* object = state->VirtualObjectFromAlias(i)) {
if (!object->AllFieldsClear()) {
for (size_t i = 0; i < object->field_count(); ++i) {
if (object->GetField(i) == nullptr) {
return false;
}
}
}
}
}
}
}
return true;
}
void EscapeAnalysis::RunObjectAnalysis() { void EscapeAnalysis::RunObjectAnalysis() {
virtual_states_.resize(graph()->NodeCount()); virtual_states_.resize(graph()->NodeCount());
ZoneDeque<Node*> queue(zone()); ZoneDeque<Node*> queue(zone());
...@@ -1035,6 +1060,7 @@ void EscapeAnalysis::RunObjectAnalysis() { ...@@ -1035,6 +1060,7 @@ void EscapeAnalysis::RunObjectAnalysis() {
danglers.clear(); danglers.clear();
} }
} }
#ifdef DEBUG #ifdef DEBUG
if (FLAG_trace_turbo_escape) { if (FLAG_trace_turbo_escape) {
DebugPrint(); DebugPrint();
...@@ -1700,6 +1726,8 @@ Node* EscapeAnalysis::GetOrCreateObjectState(Node* effect, Node* node) { ...@@ -1700,6 +1726,8 @@ Node* EscapeAnalysis::GetOrCreateObjectState(Node* effect, Node* node) {
for (size_t i = 0; i < vobj->field_count(); ++i) { for (size_t i = 0; i < vobj->field_count(); ++i) {
if (Node* field = vobj->GetField(i)) { if (Node* field = vobj->GetField(i)) {
cache_->fields().push_back(ResolveReplacement(field)); cache_->fields().push_back(ResolveReplacement(field));
} else {
return nullptr;
} }
} }
int input_count = static_cast<int>(cache_->fields().size()); int input_count = static_cast<int>(cache_->fields().size());
......
...@@ -37,6 +37,7 @@ class V8_EXPORT_PRIVATE EscapeAnalysis { ...@@ -37,6 +37,7 @@ class V8_EXPORT_PRIVATE EscapeAnalysis {
bool IsCyclicObjectState(Node* effect, Node* node); bool IsCyclicObjectState(Node* effect, Node* node);
bool ExistsVirtualAllocate(); bool ExistsVirtualAllocate();
bool SetReplacement(Node* node, Node* rep); bool SetReplacement(Node* node, Node* rep);
bool AllObjectsComplete();
private: private:
void RunObjectAnalysis(); void RunObjectAnalysis();
......
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --turbo --turbo-escape
var mp = Object.getPrototypeOf(0);
function getRandomProperty(v) {
var properties;
if (mp) { properties = Object.getOwnPropertyNames(mp); }
if (properties.includes("constructor") && v.constructor.hasOwnProperty()) {; }
if (properties.length == 0) { return "0"; }
return properties[NaN];
}
var c = 0;
function f() {
c++;
if (c === 3) %OptimizeFunctionOnNextCall(f);
if (c > 4) throw 42;
for (var x of ["x"]) {
getRandomProperty(0) ;
f();
%_DeoptimizeNow();
}
}
assertThrowsEquals(f, 42);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment