[turbofan] fixed escape analysis crash because of incomplete replacements
R=epertoso@chromium.org,mstarzinger@chromium.org BUG=671324 Review-Url: https://codereview.chromium.org/2571793002 Cr-Commit-Position: refs/heads/master@{#41679}
This commit is contained in:
parent
6106a483de
commit
c22c70b605
@ -31,7 +31,7 @@ EscapeAnalysisReducer::EscapeAnalysisReducer(Editor* editor, JSGraph* jsgraph,
|
||||
fully_reduced_(static_cast<int>(jsgraph->graph()->NodeCount() * 2), zone),
|
||||
exists_virtual_allocate_(escape_analysis->ExistsVirtualAllocate()) {}
|
||||
|
||||
Reduction EscapeAnalysisReducer::Reduce(Node* node) {
|
||||
Reduction EscapeAnalysisReducer::ReduceNode(Node* node) {
|
||||
if (node->id() < static_cast<NodeId>(fully_reduced_.length()) &&
|
||||
fully_reduced_.Contains(node->id())) {
|
||||
return NoChange();
|
||||
@ -97,6 +97,14 @@ Reduction EscapeAnalysisReducer::Reduce(Node* node) {
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
Reduction EscapeAnalysisReducer::Reduce(Node* node) {
|
||||
Reduction reduction = ReduceNode(node);
|
||||
if (reduction.Changed() && node != reduction.replacement()) {
|
||||
escape_analysis()->SetReplacement(node, reduction.replacement());
|
||||
}
|
||||
return reduction;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
Node* MaybeGuard(JSGraph* jsgraph, Node* original, Node* replacement) {
|
||||
@ -202,7 +210,7 @@ Reduction EscapeAnalysisReducer::ReduceReferenceEqual(Node* node) {
|
||||
escape_analysis()->CompareVirtualObjects(left, right)) {
|
||||
ReplaceWithValue(node, jsgraph()->TrueConstant());
|
||||
TRACE("Replaced ref eq #%d with true\n", node->id());
|
||||
Replace(jsgraph()->TrueConstant());
|
||||
return Replace(jsgraph()->TrueConstant());
|
||||
}
|
||||
// Right-hand side is not a virtual object, or a different one.
|
||||
ReplaceWithValue(node, jsgraph()->FalseConstant());
|
||||
|
@ -33,6 +33,7 @@ class V8_EXPORT_PRIVATE EscapeAnalysisReducer final
|
||||
bool compilation_failed() const { return compilation_failed_; }
|
||||
|
||||
private:
|
||||
Reduction ReduceNode(Node* node);
|
||||
Reduction ReduceLoad(Node* node);
|
||||
Reduction ReduceStore(Node* node);
|
||||
Reduction ReduceAllocate(Node* node);
|
||||
|
@ -1586,7 +1586,7 @@ Node* EscapeAnalysis::GetOrCreateObjectState(Node* effect, Node* node) {
|
||||
cache_->fields().clear();
|
||||
for (size_t i = 0; i < vobj->field_count(); ++i) {
|
||||
if (Node* field = vobj->GetField(i)) {
|
||||
cache_->fields().push_back(field);
|
||||
cache_->fields().push_back(ResolveReplacement(field));
|
||||
}
|
||||
}
|
||||
int input_count = static_cast<int>(cache_->fields().size());
|
||||
|
@ -35,6 +35,7 @@ class V8_EXPORT_PRIVATE EscapeAnalysis {
|
||||
Node* GetOrCreateObjectState(Node* effect, Node* node);
|
||||
bool IsCyclicObjectState(Node* effect, Node* node);
|
||||
bool ExistsVirtualAllocate();
|
||||
bool SetReplacement(Node* node, Node* rep);
|
||||
|
||||
private:
|
||||
void RunObjectAnalysis();
|
||||
@ -59,7 +60,6 @@ class V8_EXPORT_PRIVATE EscapeAnalysis {
|
||||
|
||||
Node* replacement(Node* node);
|
||||
Node* ResolveReplacement(Node* node);
|
||||
bool SetReplacement(Node* node, Node* rep);
|
||||
bool UpdateReplacement(VirtualState* state, Node* node, Node* rep);
|
||||
|
||||
VirtualObject* GetVirtualObject(VirtualState* state, Node* node);
|
||||
|
42
test/mjsunit/compiler/escape-analysis-replacement.js
Normal file
42
test/mjsunit/compiler/escape-analysis-replacement.js
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2016 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Flags: --allow-natives-syntax --turbo-escape
|
||||
|
||||
function foo(x){
|
||||
var c = {c: {} === {}};
|
||||
if(x) c.c = true;
|
||||
return c.c;
|
||||
}
|
||||
|
||||
foo(true);
|
||||
foo(false);
|
||||
foo(true);
|
||||
foo(false);
|
||||
%OptimizeFunctionOnNextCall(foo);
|
||||
assertTrue(foo(true));
|
||||
assertFalse(foo(false));
|
Loading…
Reference in New Issue
Block a user