Skip to content

Commit efd7536

Browse files
committed
Version 2.10.1
* Cherry-pick 62354c1 to stable * Cherry-pick 68fd2a9 to stable * Cherry-pick 350481a to stable * Cherry-pick 88aa0544f78010d358d0abac76f23975422412a7 to stable
2 parents 41eab9b + 4c59341 commit efd7536

18 files changed

+414
-85
lines changed

CHANGELOG.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
1-
## 2.10.0
1+
## 2.10.1 - 2020-10-06
2+
3+
This is a patch release that fixes the following issues:
4+
* crashes when developing Flutter applications (issue [#43464][]).
5+
* non-deterministicall weird program behaviour and/or crashes (issue
6+
[flutter/flutter#66672][]).
7+
* uncaught TypeErrors in DDC (issue [#43661][]).
8+
9+
[#43464]: https://github.com/dart-lang/sdk/issues/43464
10+
[flutter/flutter#66672]: https://github.com/flutter/flutter/issues/66672
11+
[#43661]: https://github.com/dart-lang/sdk/issues/43661
12+
13+
## 2.10.0 - 2020-09-28
214

315
### Core libraries
416

@@ -36,7 +48,7 @@
3648
deferred loading of types, pass `--no-defer-class-types`. See the original
3749
post on the [unsoundness in the deferred loading algorithm][].
3850
* Enables a new sound deferred splitting algorithm. To explicitly disable
39-
the new deferred splitting algorithm, pass `--no-new-deferred-split'.
51+
the new deferred splitting algorithm, pass `--no-new-deferred-split`.
4052
See the original post on the
4153
[unsoundness in the deferred loading algorithm][].
4254

pkg/dev_compiler/lib/src/kernel/compiler.dart

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -867,21 +867,16 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
867867
var savedTopLevelClass = _classEmittingExtends;
868868
_classEmittingExtends = c;
869869

870-
// Refers to 'S' in `class C extends S`. Set this to null to avoid
871-
// referencing deferred supertypes in _emitClassConstructor's JS output.
872-
js_ast.Expression baseClass;
873-
870+
// Unroll mixins.
874871
if (shouldDefer(supertype)) {
875872
deferredSupertypes.add(runtimeStatement('setBaseClass(#, #)', [
876873
getBaseClass(isMixinAliasClass(c) ? 0 : mixins.length),
877874
emitDeferredType(supertype),
878875
]));
879-
// Refers to 'supertype' without any type arguments.
880876
supertype =
881877
_coreTypes.rawType(supertype.classNode, _currentLibrary.nonNullable);
882-
} else {
883-
baseClass = emitClassRef(supertype);
884878
}
879+
var baseClass = emitClassRef(supertype);
885880

886881
if (isMixinAliasClass(c)) {
887882
// Given `class C = Object with M [implements I1, I2 ...];`
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
import 'package:expect/expect.dart';
6+
7+
class A {}
8+
9+
abstract class B<T> {
10+
dynamic foo(T a);
11+
}
12+
13+
class C extends B<A> {
14+
dynamic foo(A a) {
15+
return () => a;
16+
}
17+
}
18+
19+
main() {
20+
Expect.throws(() => (C().foo as dynamic)(1));
21+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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+
// This test attempts to verify that write barrier slow path does not
6+
// clobber any live values.
7+
8+
import 'dart:_internal' show VMInternalsForTesting;
9+
10+
import 'package:expect/expect.dart';
11+
12+
class Old {
13+
var f;
14+
Old(this.f);
15+
}
16+
17+
@pragma('vm:never-inline')
18+
int crashy(int v, List<Old> oldies) {
19+
// This test attempts to create a lot of live values which would live across
20+
// write barrier invocation so that when write-barrier calls runtime and
21+
// clobbers a register this is detected.
22+
var young = Object();
23+
var len = oldies.length;
24+
var i = 0;
25+
var v00 = v + 0;
26+
var v01 = v + 1;
27+
var v02 = v + 2;
28+
var v03 = v + 3;
29+
var v04 = v + 4;
30+
var v05 = v + 5;
31+
var v06 = v + 6;
32+
var v07 = v + 7;
33+
var v08 = v + 8;
34+
var v09 = v + 9;
35+
var v10 = v + 10;
36+
var v11 = v + 11;
37+
var v12 = v + 12;
38+
var v13 = v + 13;
39+
var v14 = v + 14;
40+
var v15 = v + 15;
41+
var v16 = v + 16;
42+
var v17 = v + 17;
43+
var v18 = v + 18;
44+
var v19 = v + 19;
45+
while (i < len) {
46+
// Eventually this will overflow store buffer and call runtime to acquire
47+
// a new block.
48+
oldies[i++].f = young;
49+
}
50+
return v00 +
51+
v01 +
52+
v02 +
53+
v03 +
54+
v04 +
55+
v05 +
56+
v06 +
57+
v07 +
58+
v08 +
59+
v09 +
60+
v10 +
61+
v11 +
62+
v12 +
63+
v13 +
64+
v14 +
65+
v15 +
66+
v16 +
67+
v17 +
68+
v18 +
69+
v19;
70+
}
71+
72+
void main(List<String> args) {
73+
final init = args.contains('impossible') ? 1 : 0;
74+
final oldies = List<Old>.generate(100000, (i) => Old(""));
75+
VMInternalsForTesting.collectAllGarbage();
76+
VMInternalsForTesting.collectAllGarbage();
77+
Expect.equals(crashy(init, oldies), 190);
78+
for (var o in oldies) {
79+
Expect.isTrue(o.f is! String);
80+
}
81+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
import 'package:expect/expect.dart';
6+
7+
class A {}
8+
9+
abstract class B<T> {
10+
dynamic foo(T a);
11+
}
12+
13+
class C extends B<A> {
14+
dynamic foo(A a) {
15+
return () => a;
16+
}
17+
}
18+
19+
main() {
20+
Expect.throws(() => (C().foo as dynamic)(1));
21+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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+
// This test attempts to verify that write barrier slow path does not
6+
// clobber any live values.
7+
8+
import 'dart:_internal' show VMInternalsForTesting;
9+
10+
import 'package:expect/expect.dart';
11+
12+
class Old {
13+
var f;
14+
Old(this.f);
15+
}
16+
17+
@pragma('vm:never-inline')
18+
int crashy(int v, List<Old> oldies) {
19+
// This test attempts to create a lot of live values which would live across
20+
// write barrier invocation so that when write-barrier calls runtime and
21+
// clobbers a register this is detected.
22+
var young = Object();
23+
var len = oldies.length;
24+
var i = 0;
25+
var v00 = v + 0;
26+
var v01 = v + 1;
27+
var v02 = v + 2;
28+
var v03 = v + 3;
29+
var v04 = v + 4;
30+
var v05 = v + 5;
31+
var v06 = v + 6;
32+
var v07 = v + 7;
33+
var v08 = v + 8;
34+
var v09 = v + 9;
35+
var v10 = v + 10;
36+
var v11 = v + 11;
37+
var v12 = v + 12;
38+
var v13 = v + 13;
39+
var v14 = v + 14;
40+
var v15 = v + 15;
41+
var v16 = v + 16;
42+
var v17 = v + 17;
43+
var v18 = v + 18;
44+
var v19 = v + 19;
45+
while (i < len) {
46+
// Eventually this will overflow store buffer and call runtime to acquire
47+
// a new block.
48+
oldies[i++].f = young;
49+
}
50+
return v00 +
51+
v01 +
52+
v02 +
53+
v03 +
54+
v04 +
55+
v05 +
56+
v06 +
57+
v07 +
58+
v08 +
59+
v09 +
60+
v10 +
61+
v11 +
62+
v12 +
63+
v13 +
64+
v14 +
65+
v15 +
66+
v16 +
67+
v17 +
68+
v18 +
69+
v19;
70+
}
71+
72+
void main(List<String> args) {
73+
final init = args.contains('impossible') ? 1 : 0;
74+
final oldies = List<Old>.generate(100000, (i) => Old(""));
75+
VMInternalsForTesting.collectAllGarbage();
76+
VMInternalsForTesting.collectAllGarbage();
77+
Expect.equals(crashy(init, oldies), 190);
78+
for (var o in oldies) {
79+
Expect.isTrue(o.f is! String);
80+
}
81+
}

runtime/vm/compiler/assembler/assembler_arm64.cc

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,7 +1485,7 @@ void Assembler::TransitionNativeToGenerated(Register state,
14851485
StoreToOffset(state, THR, target::Thread::exit_through_ffi_offset());
14861486
}
14871487

1488-
void Assembler::EnterCallRuntimeFrame(intptr_t frame_size) {
1488+
void Assembler::EnterCallRuntimeFrame(intptr_t frame_size, bool is_leaf) {
14891489
Comment("EnterCallRuntimeFrame");
14901490
EnterFrame(0);
14911491
if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
@@ -1510,19 +1510,30 @@ void Assembler::EnterCallRuntimeFrame(intptr_t frame_size) {
15101510
Push(reg);
15111511
}
15121512

1513-
ReserveAlignedFrameSpace(frame_size);
1513+
if (!is_leaf) { // Leaf calling sequence aligns the stack itself.
1514+
ReserveAlignedFrameSpace(frame_size);
1515+
} else {
1516+
PushPair(kCallLeafRuntimeCalleeSaveScratch1,
1517+
kCallLeafRuntimeCalleeSaveScratch2);
1518+
}
15141519
}
15151520

1516-
void Assembler::LeaveCallRuntimeFrame() {
1521+
void Assembler::LeaveCallRuntimeFrame(bool is_leaf) {
15171522
// SP might have been modified to reserve space for arguments
15181523
// and ensure proper alignment of the stack frame.
15191524
// We need to restore it before restoring registers.
1525+
const intptr_t fixed_frame_words_without_pc_and_fp =
1526+
target::frame_layout.dart_fixed_frame_size - 2;
15201527
const intptr_t kPushedRegistersSize =
1521-
kDartVolatileCpuRegCount * target::kWordSize +
1522-
kDartVolatileFpuRegCount * target::kWordSize +
1523-
(target::frame_layout.dart_fixed_frame_size - 2) *
1524-
target::kWordSize; // From EnterStubFrame (excluding PC / FP)
1528+
kDartVolatileFpuRegCount * sizeof(double) +
1529+
(kDartVolatileCpuRegCount + (is_leaf ? 2 : 0) +
1530+
fixed_frame_words_without_pc_and_fp) *
1531+
target::kWordSize;
15251532
AddImmediate(SP, FP, -kPushedRegistersSize);
1533+
if (is_leaf) {
1534+
PopPair(kCallLeafRuntimeCalleeSaveScratch1,
1535+
kCallLeafRuntimeCalleeSaveScratch2);
1536+
}
15261537
for (int i = kDartLastVolatileCpuReg; i >= kDartFirstVolatileCpuReg; i--) {
15271538
const Register reg = static_cast<Register>(i);
15281539
Pop(reg);
@@ -1547,6 +1558,37 @@ void Assembler::CallRuntime(const RuntimeEntry& entry,
15471558
entry.Call(this, argument_count);
15481559
}
15491560

1561+
void Assembler::CallRuntimeScope::Call(intptr_t argument_count) {
1562+
assembler_->CallRuntime(entry_, argument_count);
1563+
}
1564+
1565+
Assembler::CallRuntimeScope::~CallRuntimeScope() {
1566+
if (preserve_registers_) {
1567+
assembler_->LeaveCallRuntimeFrame(entry_.is_leaf());
1568+
if (restore_code_reg_) {
1569+
assembler_->Pop(CODE_REG);
1570+
}
1571+
}
1572+
}
1573+
1574+
Assembler::CallRuntimeScope::CallRuntimeScope(Assembler* assembler,
1575+
const RuntimeEntry& entry,
1576+
intptr_t frame_size,
1577+
bool preserve_registers,
1578+
const Address* caller)
1579+
: assembler_(assembler),
1580+
entry_(entry),
1581+
preserve_registers_(preserve_registers),
1582+
restore_code_reg_(caller != nullptr) {
1583+
if (preserve_registers_) {
1584+
if (caller != nullptr) {
1585+
assembler_->Push(CODE_REG);
1586+
assembler_->ldr(CODE_REG, *caller);
1587+
}
1588+
assembler_->EnterCallRuntimeFrame(frame_size, entry.is_leaf());
1589+
}
1590+
}
1591+
15501592
void Assembler::EnterStubFrame() {
15511593
EnterDartFrame(0);
15521594
}

0 commit comments

Comments
 (0)