Skip to content

Commit badc772

Browse files
alexmarkovcommit-bot@chromium.org
authored andcommitted
[vm/aot] Avoid unbinding canonical names in AOT transformations
AOT transformations (mixin deduplication and TFA tree shaker) were using CanonicalName.unbind() in order to make sure that kernel writer will not be able to write dangling references to the deleted classes or members (to detect such dangling references earlier). This conflicts with lazy reading from a kernel file if --from-dill option is used: lazy reader may read a reference to such class after unbind() and it creates a new Reference object for such canonical name. This causes crash later when the fresh Reference is used as it doesn't have Class node filled in. The solution is to avoid calling CanonicalName.unbind(). Instead, it is enough to nullify node.reference.canonicalName, which won't break CanonicalName.reference used by lazy reader. This crash can be reproduced on tests/language_2/vm/regress_flutter_55345_test.dart if it is compiled in AOT mode using 2-step kernel generation. Bug: b/158853113 Change-Id: Ib2004dbbbda85d9f56adc56b48882f4ef08869a7 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151120 Commit-Queue: Alexander Markov <[email protected]> Reviewed-by: Martin Kustermann <[email protected]>
1 parent 66cd5d9 commit badc772

File tree

9 files changed

+113
-15
lines changed

9 files changed

+113
-15
lines changed

pkg/vm/lib/transformations/mixin_deduplication.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,9 @@ class DeduplicateMixinsTransformer extends Transformer {
113113
assert(canonical != null);
114114

115115
if (canonical != c) {
116-
c.canonicalName?.unbind();
116+
// Ensure that kernel file writer will not be able to
117+
// write a dangling reference to the deleted class.
118+
c.reference.canonicalName = null;
117119
_duplicatedMixins[c] = canonical;
118120
return null; // Remove class.
119121
}

pkg/vm/lib/transformations/type_flow/transformer.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,7 +1464,9 @@ class _TreeShakerPass2 extends Transformer {
14641464
Class visitClass(Class node) {
14651465
if (!shaker.isClassUsed(node)) {
14661466
debugPrint('Dropped class ${node.name}');
1467-
node.canonicalName?.unbind();
1467+
// Ensure that kernel file writer will not be able to
1468+
// write a dangling reference to the deleted class.
1469+
node.reference.canonicalName = null;
14681470
Statistics.classesDropped++;
14691471
return null; // Remove the class.
14701472
}
@@ -1532,7 +1534,9 @@ class _TreeShakerPass2 extends Transformer {
15321534
@override
15331535
Member defaultMember(Member node) {
15341536
if (!shaker.isMemberUsed(node) && !_preserveSpecialMember(node)) {
1535-
node.canonicalName?.unbind();
1537+
// Ensure that kernel file writer will not be able to
1538+
// write a dangling reference to the deleted member.
1539+
node.reference.canonicalName = null;
15361540
Statistics.membersDropped++;
15371541
return null;
15381542
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// OtherResources=../../../../tests/language/vm/regress_flutter_55345_test.dart
6+
7+
// Runs regress_flutter_55345_test.dart using AOT kernel generation split into
8+
// 2 steps using '--from-dill' option.
9+
10+
import 'dart:io' show Platform;
11+
12+
import 'split_aot_kernel_generation_test.dart'
13+
show runSplitAOTKernelGenerationTest;
14+
15+
main() async {
16+
await runSplitAOTKernelGenerationTest(Platform.script.resolve(
17+
'../../../../tests/language/vm/regress_flutter_55345_test.dart'));
18+
}

runtime/tests/vm/dart/split_aot_compilation_test.dart renamed to runtime/tests/vm/dart/split_aot_kernel_generation_test.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,14 @@
44

55
// OtherResources=splay_test.dart
66

7-
// Tests AOT compilation split into 2 steps using '--from-dill' option.
7+
// Tests AOT kernel generation split into 2 steps using '--from-dill' option.
88

99
import 'dart:io' show Platform;
1010

1111
import 'package:path/path.dart' as path;
1212
import 'snapshot_test_helper.dart';
1313

14-
main() async {
15-
final testScriptUri = Platform.script.resolve('splay_test.dart');
16-
14+
Future<void> runSplitAOTKernelGenerationTest(Uri testScriptUri) async {
1715
await withTempDir((String temp) async {
1816
final intermediateDillPath = path.join(temp, 'intermediate.dill');
1917
final outputDillPath = path.join(temp, 'output.dill');
@@ -52,3 +50,8 @@ main() async {
5250
await runBinary('RUN SNAPSHOT', dartPrecompiledRuntime, [snapshotPath]);
5351
});
5452
}
53+
54+
main() async {
55+
await runSplitAOTKernelGenerationTest(
56+
Platform.script.resolve('splay_test.dart'));
57+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// OtherResources=../../../../tests/language_2/vm/regress_flutter_55345_test.dart
6+
7+
// Runs regress_flutter_55345_test.dart using AOT kernel generation split into
8+
// 2 steps using '--from-dill' option.
9+
10+
import 'dart:io' show Platform;
11+
12+
import 'split_aot_kernel_generation_test.dart'
13+
show runSplitAOTKernelGenerationTest;
14+
15+
main() async {
16+
await runSplitAOTKernelGenerationTest(Platform.script.resolve(
17+
'../../../../tests/language_2/vm/regress_flutter_55345_test.dart'));
18+
}

runtime/tests/vm/dart_2/split_aot_compilation_test.dart renamed to runtime/tests/vm/dart_2/split_aot_kernel_generation_test.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,14 @@
44

55
// OtherResources=splay_test.dart
66

7-
// Tests AOT compilation split into 2 steps using '--from-dill' option.
7+
// Tests AOT kernel generation split into 2 steps using '--from-dill' option.
88

99
import 'dart:io' show Platform;
1010

1111
import 'package:path/path.dart' as path;
1212
import 'snapshot_test_helper.dart';
1313

14-
main() async {
15-
final testScriptUri = Platform.script.resolve('splay_test.dart');
16-
14+
Future<void> runSplitAOTKernelGenerationTest(Uri testScriptUri) async {
1715
await withTempDir((String temp) async {
1816
final intermediateDillPath = path.join(temp, 'intermediate.dill');
1917
final outputDillPath = path.join(temp, 'output.dill');
@@ -52,3 +50,8 @@ main() async {
5250
await runBinary('RUN SNAPSHOT', dartPrecompiledRuntime, [snapshotPath]);
5351
});
5452
}
53+
54+
main() async {
55+
await runSplitAOTKernelGenerationTest(
56+
Platform.script.resolve('splay_test.dart'));
57+
}

runtime/tests/vm/vm.status

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,12 @@ dart_2/transferable_throws_oom_test: SkipByDesign # This test tries to allocate
8888
[ $builder_tag == crossword || $builder_tag == crossword_ast ]
8989
dart/emit_aot_size_info_flag_test: SkipByDesign # The test itself cannot determine the location of gen_snapshot (only tools/test.py knows where it is).
9090
dart/bytecode_with_ast_in_aot_test: SkipByDesign # The test doesn't know location of cross-platform gen_snapshot
91-
dart/split_aot_compilation_test: SkipByDesign # The test doesn't know location of cross-platform gen_snapshot
91+
dart/split_aot_kernel_generation_test: SkipByDesign # The test doesn't know location of cross-platform gen_snapshot
92+
dart/split_aot_kernel_generation2_test: SkipByDesign # The test doesn't know location of cross-platform gen_snapshot
9293
dart_2/emit_aot_size_info_flag_test: SkipByDesign # The test itself cannot determine the location of gen_snapshot (only tools/test.py knows where it is).
9394
dart_2/bytecode_with_ast_in_aot_test: SkipByDesign # The test doesn't know location of cross-platform gen_snapshot
94-
dart_2/split_aot_compilation_test: SkipByDesign # The test doesn't know location of cross-platform gen_snapshot
95+
dart_2/split_aot_kernel_generation_test: SkipByDesign # The test doesn't know location of cross-platform gen_snapshot
96+
dart_2/split_aot_kernel_generation2_test: SkipByDesign # The test doesn't know location of cross-platform gen_snapshot
9597

9698
[ $builder_tag == obfuscated ]
9799
dart/causal_stacks/async_throws_stack_lazy_test: SkipByDesign # Asserts exact stacktrace output.
@@ -410,11 +412,13 @@ dart_2/redirection_type_shuffling_test/none: RuntimeError
410412
dart/emit_aot_size_info_flag_test: SkipByDesign # This test is for VM AOT only and is quite slow (so we don't run it in debug mode).
411413
dart/use_bare_instructions_flag_test: SkipByDesign # This test is for VM AOT only and is quite slow (so we don't run it in debug mode).
412414
dart/bytecode_with_ast_in_aot_test: SkipByDesign # This test is for VM AOT only and is quite slow (so we don't run it in debug mode).
413-
dart/split_aot_compilation_test: SkipByDesign # This test is for VM AOT only and is quite slow (so we don't run it in debug mode).
415+
dart/split_aot_kernel_generation_test: SkipByDesign # This test is for VM AOT only and is quite slow (so we don't run it in debug mode).
416+
dart/split_aot_kernel_generation2_test: SkipByDesign # This test is for VM AOT only and is quite slow (so we don't run it in debug mode).
414417
dart_2/emit_aot_size_info_flag_test: SkipByDesign # This test is for VM AOT only and is quite slow (so we don't run it in debug mode).
415418
dart_2/use_bare_instructions_flag_test: SkipByDesign # This test is for VM AOT only and is quite slow (so we don't run it in debug mode).
416419
dart_2/bytecode_with_ast_in_aot_test: SkipByDesign # This test is for VM AOT only and is quite slow (so we don't run it in debug mode).
417-
dart_2/split_aot_compilation_test: SkipByDesign # This test is for VM AOT only and is quite slow (so we don't run it in debug mode).
420+
dart_2/split_aot_kernel_generation_test: SkipByDesign # This test is for VM AOT only and is quite slow (so we don't run it in debug mode).
421+
dart_2/split_aot_kernel_generation2_test: SkipByDesign # This test is for VM AOT only and is quite slow (so we don't run it in debug mode).
418422

419423
# It makes no sense to run any test that uses spawnURI under the simulator
420424
# as that would involve running CFE (the front end) in simulator mode
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// Verifies that references to deduplicated mixins are properly updated.
6+
// Regression test for https://github.com/flutter/flutter/issues/55345.
7+
8+
class Diagnosticable {}
9+
10+
class SomeClass with Diagnosticable {}
11+
12+
class State<T> with Diagnosticable {}
13+
14+
class StateA extends State {}
15+
16+
class StateB extends State<int> {}
17+
18+
StateA? a = StateA();
19+
StateB? b = StateB();
20+
21+
List<T> foo<T>(T x) {
22+
print(T);
23+
return <T>[x];
24+
}
25+
26+
T Function<S extends T>(T) bar<T>(T x) {
27+
print(T);
28+
29+
return <S extends T>(T y) {
30+
print(S);
31+
print(y);
32+
return y;
33+
};
34+
}
35+
36+
main() {
37+
var x2 = a ?? b;
38+
var x3 = foo(x2);
39+
var x4 = bar(x3);
40+
x4(x3);
41+
}

tools/bots/test_matrix.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"tests/corelib_2/",
4646
"tests/dart2js_2/",
4747
"tests/kernel/",
48+
"tests/language/",
4849
"tests/language_2/",
4950
"tests/lib_2/",
5051
"tests/light_unittest.dart",
@@ -85,6 +86,7 @@
8586
"tests/dart2js/",
8687
"tests/kernel/",
8788
"tests/language/",
89+
"tests/language_2/",
8890
"tests/lib/",
8991
"tests/light_unittest.dart",
9092
"tests/search/",
@@ -130,6 +132,7 @@
130132
"tests/corelib_2/",
131133
"tests/dart2js_2/",
132134
"tests/kernel/",
135+
"tests/language/",
133136
"tests/language_2/",
134137
"tests/lib_2/",
135138
"tests/light_unittest.dart",
@@ -177,6 +180,7 @@
177180
"tests/corelib_2/",
178181
"tests/dart2js_2/",
179182
"tests/kernel/",
183+
"tests/language/",
180184
"tests/language_2/",
181185
"tests/lib_2/",
182186
"tests/light_unittest.dart",
@@ -218,6 +222,7 @@
218222
"tests/dart2js/",
219223
"tests/kernel/",
220224
"tests/language/",
225+
"tests/language_2/",
221226
"tests/lib/",
222227
"tests/light_unittest.dart",
223228
"tests/search/",

0 commit comments

Comments
 (0)