mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 22:19:49 +00:00
[vm] Do not assign type to phi if it was loaded from a different local
During SSA construction in strong mode, types of local variables are propagated (assigned) to phis which are 'loaded' from slots corresponding to those local variables. It is incorrect if phi was stored in a different local variable with a more specific type and then reloaded. After this change, type is propagated from local variable to phis only if phi was created for this local. Fixes https://github.com/dart-lang/sdk/issues/32597 Change-Id: I7d86c2ef79d14895c9b4c3651d0234b3f9c66173 Reviewed-on: https://dart-review.googlesource.com/47200 Reviewed-by: Vyacheslav Egorov <vegorov@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
parent
d26c310a27
commit
b7c3c32f63
40
runtime/tests/vm/dart/regress32597_test.dart
Normal file
40
runtime/tests/vm/dart/regress32597_test.dart
Normal file
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Regression test for dartbug.com/32597: incorrect type was assigned to phi
|
||||
// in strong mode.
|
||||
|
||||
// VMOptions=--optimization_counter_threshold=10 --no-background-compilation
|
||||
|
||||
class Token {
|
||||
Token next;
|
||||
}
|
||||
|
||||
class StringToken extends Token {}
|
||||
|
||||
class ErrorToken extends Token {}
|
||||
|
||||
void foo(Token tokens) {
|
||||
Token current = tokens;
|
||||
for (int i = 0; i < 1; i++) {
|
||||
while (current is ErrorToken) {
|
||||
ErrorToken first = current;
|
||||
// Loading phi (created for local variable 'current') from another local
|
||||
// variable ('first') with more specific type should not change the type
|
||||
// assigned to phi.
|
||||
print(first);
|
||||
}
|
||||
current = current.next;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
Token token = new StringToken();
|
||||
token.next = token;
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
foo(token);
|
||||
}
|
||||
print('ok');
|
||||
}
|
|
@ -1191,8 +1191,12 @@ void FlowGraph::RenameRecursive(BlockEntryInstr* block_entry,
|
|||
|
||||
if ((phi != NULL) && isolate()->strong() &&
|
||||
FLAG_use_strong_mode_types) {
|
||||
phi->UpdateType(
|
||||
CompileType::FromAbstractType(load->local().type()));
|
||||
// Assign type to phi only if phi was not copied from another local.
|
||||
const auto* phis = phi->block()->phis();
|
||||
if ((index < phis->length()) && ((*phis)[index] == phi)) {
|
||||
phi->UpdateType(
|
||||
CompileType::FromAbstractType(load->local().type()));
|
||||
}
|
||||
}
|
||||
} else if (drop != NULL) {
|
||||
// Drop temps from the environment.
|
||||
|
|
Loading…
Reference in a new issue