v8/test/mjsunit/regress/regress-crbug-902395.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

35 lines
749 B
JavaScript
Raw Normal View History

[ignition] More accurate dead statement elision The Ignition statement list visitor will skip the rest of the statements in the list if it hits a jump statement (like a return or break), as the rest of the code in the list can be considered dead. return; dead_call(); // skipped However, since this is at an AST node level, it does not take into account condition shortcutting: if(2.2) return; dead_call(); // not skipped There is also a second dead code elimination in Ignition compilation, at the bytecode array writer level, where a bytecodes are not emitted if an "exit" bytecode (Return, Jump, or a few others) has been written, until the next basic block starts (i.e. a Bind). This can cause an issue with statements that resurrect the bytecode array writer part-way through their visit. An example is try-catch statements, which save the context to a register, and then Bind to start the try region. For the case: if (2.2) return; try { // try statement not skipped ... } the bytecode writer is called with OutputReturn() // exit bytecode seen OutputMove(<context>, r1) // not emitted Bind(&try_begin) // starts new basic block // try body So, the try is emitted, but without saving the context to a register. This means that the liveness analysis sees the read of that register (as the output liveness of throwing bytecodes), but does not have a write to the register, which means that the liveness escapes. This patch fixes this by using the bytecode array writer dead-code elimination (i.e. "exit bytecode seen") to inform the statement list visitor, so that in this example the try statement is not visited at all. Bug: chromium:902395 Change-Id: Ieb8e46a4318df3edbac0ae17235e0ce8fba12ee3 Reviewed-on: https://chromium-review.googlesource.com/c/1322951 Reviewed-by: Mythri Alle <mythria@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/master@{#57350}
2018-11-07 12:41:41 +00:00
// Copyright 2018 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
function opt() {
try {
Object.seal({});
} finally {
try {
[ignition] More accurate dead statement elision The Ignition statement list visitor will skip the rest of the statements in the list if it hits a jump statement (like a return or break), as the rest of the code in the list can be considered dead. return; dead_call(); // skipped However, since this is at an AST node level, it does not take into account condition shortcutting: if(2.2) return; dead_call(); // not skipped There is also a second dead code elimination in Ignition compilation, at the bytecode array writer level, where a bytecodes are not emitted if an "exit" bytecode (Return, Jump, or a few others) has been written, until the next basic block starts (i.e. a Bind). This can cause an issue with statements that resurrect the bytecode array writer part-way through their visit. An example is try-catch statements, which save the context to a register, and then Bind to start the try region. For the case: if (2.2) return; try { // try statement not skipped ... } the bytecode writer is called with OutputReturn() // exit bytecode seen OutputMove(<context>, r1) // not emitted Bind(&try_begin) // starts new basic block // try body So, the try is emitted, but without saving the context to a register. This means that the liveness analysis sees the read of that register (as the output liveness of throwing bytecodes), but does not have a write to the register, which means that the liveness escapes. This patch fixes this by using the bytecode array writer dead-code elimination (i.e. "exit bytecode seen") to inform the statement list visitor, so that in this example the try statement is not visited at all. Bug: chromium:902395 Change-Id: Ieb8e46a4318df3edbac0ae17235e0ce8fba12ee3 Reviewed-on: https://chromium-review.googlesource.com/c/1322951 Reviewed-by: Mythri Alle <mythria@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/master@{#57350}
2018-11-07 12:41:41 +00:00
// Carefully crafted by clusterfuzz to alias the temporary object literal
// register with the below dead try block's context register.
({toString() {}})
.
apply(-1)
.x();
} finally {
if (2.2) {
return;
[ignition] More accurate dead statement elision The Ignition statement list visitor will skip the rest of the statements in the list if it hits a jump statement (like a return or break), as the rest of the code in the list can be considered dead. return; dead_call(); // skipped However, since this is at an AST node level, it does not take into account condition shortcutting: if(2.2) return; dead_call(); // not skipped There is also a second dead code elimination in Ignition compilation, at the bytecode array writer level, where a bytecodes are not emitted if an "exit" bytecode (Return, Jump, or a few others) has been written, until the next basic block starts (i.e. a Bind). This can cause an issue with statements that resurrect the bytecode array writer part-way through their visit. An example is try-catch statements, which save the context to a register, and then Bind to start the try region. For the case: if (2.2) return; try { // try statement not skipped ... } the bytecode writer is called with OutputReturn() // exit bytecode seen OutputMove(<context>, r1) // not emitted Bind(&try_begin) // starts new basic block // try body So, the try is emitted, but without saving the context to a register. This means that the liveness analysis sees the read of that register (as the output liveness of throwing bytecodes), but does not have a write to the register, which means that the liveness escapes. This patch fixes this by using the bytecode array writer dead-code elimination (i.e. "exit bytecode seen") to inform the statement list visitor, so that in this example the try statement is not visited at all. Bug: chromium:902395 Change-Id: Ieb8e46a4318df3edbac0ae17235e0ce8fba12ee3 Reviewed-on: https://chromium-review.googlesource.com/c/1322951 Reviewed-by: Mythri Alle <mythria@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/master@{#57350}
2018-11-07 12:41:41 +00:00
}
// This code should be dead.
try {
Reflect.construct;
} finally {
[ignition] More accurate dead statement elision The Ignition statement list visitor will skip the rest of the statements in the list if it hits a jump statement (like a return or break), as the rest of the code in the list can be considered dead. return; dead_call(); // skipped However, since this is at an AST node level, it does not take into account condition shortcutting: if(2.2) return; dead_call(); // not skipped There is also a second dead code elimination in Ignition compilation, at the bytecode array writer level, where a bytecodes are not emitted if an "exit" bytecode (Return, Jump, or a few others) has been written, until the next basic block starts (i.e. a Bind). This can cause an issue with statements that resurrect the bytecode array writer part-way through their visit. An example is try-catch statements, which save the context to a register, and then Bind to start the try region. For the case: if (2.2) return; try { // try statement not skipped ... } the bytecode writer is called with OutputReturn() // exit bytecode seen OutputMove(<context>, r1) // not emitted Bind(&try_begin) // starts new basic block // try body So, the try is emitted, but without saving the context to a register. This means that the liveness analysis sees the read of that register (as the output liveness of throwing bytecodes), but does not have a write to the register, which means that the liveness escapes. This patch fixes this by using the bytecode array writer dead-code elimination (i.e. "exit bytecode seen") to inform the statement list visitor, so that in this example the try statement is not visited at all. Bug: chromium:902395 Change-Id: Ieb8e46a4318df3edbac0ae17235e0ce8fba12ee3 Reviewed-on: https://chromium-review.googlesource.com/c/1322951 Reviewed-by: Mythri Alle <mythria@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/master@{#57350}
2018-11-07 12:41:41 +00:00
}
}
}
};
%PrepareFunctionForOptimization(opt);
[ignition] More accurate dead statement elision The Ignition statement list visitor will skip the rest of the statements in the list if it hits a jump statement (like a return or break), as the rest of the code in the list can be considered dead. return; dead_call(); // skipped However, since this is at an AST node level, it does not take into account condition shortcutting: if(2.2) return; dead_call(); // not skipped There is also a second dead code elimination in Ignition compilation, at the bytecode array writer level, where a bytecodes are not emitted if an "exit" bytecode (Return, Jump, or a few others) has been written, until the next basic block starts (i.e. a Bind). This can cause an issue with statements that resurrect the bytecode array writer part-way through their visit. An example is try-catch statements, which save the context to a register, and then Bind to start the try region. For the case: if (2.2) return; try { // try statement not skipped ... } the bytecode writer is called with OutputReturn() // exit bytecode seen OutputMove(<context>, r1) // not emitted Bind(&try_begin) // starts new basic block // try body So, the try is emitted, but without saving the context to a register. This means that the liveness analysis sees the read of that register (as the output liveness of throwing bytecodes), but does not have a write to the register, which means that the liveness escapes. This patch fixes this by using the bytecode array writer dead-code elimination (i.e. "exit bytecode seen") to inform the statement list visitor, so that in this example the try statement is not visited at all. Bug: chromium:902395 Change-Id: Ieb8e46a4318df3edbac0ae17235e0ce8fba12ee3 Reviewed-on: https://chromium-review.googlesource.com/c/1322951 Reviewed-by: Mythri Alle <mythria@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/master@{#57350}
2018-11-07 12:41:41 +00:00
opt();
%OptimizeFunctionOnNextCall(opt);
opt();