Version 2.15.0-240.0.dev
Merge commit '33ac6e2c4d98aefbff90500281334a86a1aacc55' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index d8d2ac7..0c9499c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -335,6 +335,20 @@
/// not been processed yet, it might be missing.
Set<String> get knownFiles => _fsState.knownFilePaths;
+ /// Return the context in which libraries should be analyzed.
+ LibraryContext get libraryContext {
+ return _libraryContext ??= LibraryContext(
+ testView: _testView.libraryContextTestView,
+ session: currentSession,
+ logger: _logger,
+ byteStore: _byteStore,
+ analysisOptions: _analysisOptions,
+ declaredVariables: declaredVariables,
+ sourceFactory: _sourceFactory,
+ externalSummaries: _externalSummaries,
+ );
+ }
+
/// Return the path of the folder at the root of the context.
String get name => analysisContext?.contextRoot.root.path ?? '';
@@ -684,7 +698,6 @@
return UnspecifiedInvalidResult();
},
(externalLibrary) async {
- var libraryContext = _createLibraryContext(null);
var element = libraryContext.getLibraryElement(externalLibrary.uri);
return LibraryElementResultImpl(element);
},
@@ -1301,7 +1314,7 @@
return _newMissingDartLibraryResult(file, 'dart:async');
}
- var libraryContext = _createLibraryContext(library!);
+ libraryContext.load2(library!);
LibraryAnalyzer analyzer = LibraryAnalyzer(
analysisOptions as AnalysisOptionsImpl,
@@ -1373,7 +1386,7 @@
return _logger.run('Compute resolved library $path', () {
_testView.numOfAnalyzedLibraries++;
- var libraryContext = _createLibraryContext(library);
+ libraryContext.load2(library);
LibraryAnalyzer analyzer = LibraryAnalyzer(
analysisOptions as AnalysisOptionsImpl,
@@ -1431,7 +1444,7 @@
return _logger.run('Compute unit element for $path', () {
_logger.writeln('Work in $name');
- var libraryContext = _createLibraryContext(library!);
+ libraryContext.load2(library!);
var element = libraryContext.computeUnitElement(library, file);
return UnitElementResultImpl(
currentSession,
@@ -1478,36 +1491,6 @@
_fileTracker = FileTracker(_logger, _fsState);
}
- /// Return the context in which the [library] should be analyzed.
- LibraryContext _createLibraryContext(FileState? library) {
- {
- var libraryContext = _libraryContext;
- if (libraryContext != null) {
- if (libraryContext.pack()) {
- clearLibraryContext();
- }
- }
- }
-
- var libraryContext = _libraryContext;
- libraryContext ??= _libraryContext = LibraryContext(
- testView: _testView.libraryContextTestView,
- session: currentSession,
- logger: _logger,
- byteStore: _byteStore,
- analysisOptions: _analysisOptions,
- declaredVariables: declaredVariables,
- sourceFactory: _sourceFactory,
- externalSummaries: _externalSummaries,
- );
-
- if (library != null) {
- libraryContext.load2(library);
- }
-
- return libraryContext;
- }
-
/// If this has not been done yet, schedule discovery of all files that are
/// potentially available, so that they are included in [knownFiles].
void _discoverAvailableFiles() {
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index af4763e..dbdb140 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -36,8 +36,6 @@
///
/// Currently this is implemented as a wrapper around [AnalysisContext].
class LibraryContext {
- static const _maxLinkedDataInBytes = 64 * 1024 * 1024;
-
final LibraryContextTestView testView;
final PerformanceLog logger;
final ByteStore byteStore;
@@ -45,11 +43,6 @@
final SummaryDataStore? externalSummaries;
final SummaryDataStore store = SummaryDataStore([]);
- /// The size of the linked data that is loaded by this context.
- /// When it reaches [_maxLinkedDataInBytes] the whole context is thrown away.
- /// We use it as an approximation for the heap size of elements.
- final int _linkedDataInBytes = 0;
-
late final AnalysisContextImpl analysisContext;
late LinkedElementFactory elementFactory;
@@ -224,15 +217,6 @@
timerLoad2.stop();
}
- /// Return `true` if this context grew too large, and should be recreated.
- ///
- /// It might have been used to analyze libraries that we don't need anymore,
- /// and because loading libraries is not very expensive (but not free), the
- /// simplest way to get rid of the garbage is to throw away everything.
- bool pack() {
- return _linkedDataInBytes > _maxLinkedDataInBytes;
- }
-
void _createElementFactory() {
elementFactory = LinkedElementFactory(
analysisContext,
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 902f60b..63f5779 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -2314,6 +2314,14 @@
} else {
// TODO(ahe): Improve this error message.
addProblem(messageTypedefNotFunction, equals.charOffset, equals.length);
+ aliasedType = new NamedTypeBuilder.fromTypeDeclarationBuilder(
+ new InvalidTypeDeclarationBuilder(
+ "${name}",
+ messageTypedefNotType.withLocation(
+ uri, equals.charOffset, equals.length)),
+ const NullabilityBuilder.omitted(),
+ instanceTypeVariableAccess:
+ InstanceTypeVariableAccessState.Allowed);
}
}
List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?;
diff --git a/pkg/front_end/testcases/general/issue47495.dart b/pkg/front_end/testcases/general/issue47495.dart
new file mode 100644
index 0000000..53c19c1
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47495.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2021, 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.
+
+// @dart = 2.9
+
+class S {}
+class M {}
+
+typedef SAlias = S;
+typedef MAlias = M;
+
+class C = SAlias with MAlias;
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue47495.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue47495.dart.textual_outline.expect
new file mode 100644
index 0000000..c7f3471
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47495.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.9
+class S {}
+class M {}
+typedef SAlias = S;
+typedef MAlias = M;
+class C = SAlias with MAlias;
+main() {}
diff --git a/pkg/front_end/testcases/general/issue47495.dart.weak.expect b/pkg/front_end/testcases/general/issue47495.dart.weak.expect
new file mode 100644
index 0000000..1c6fab0
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47495.dart.weak.expect
@@ -0,0 +1,84 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue47495.dart:10:16: Error: Can't create typedef from non-function type.
+// typedef SAlias = S;
+// ^
+//
+// pkg/front_end/testcases/general/issue47495.dart:11:16: Error: Can't create typedef from non-function type.
+// typedef MAlias = M;
+// ^
+//
+// pkg/front_end/testcases/general/issue47495.dart:13:7: Error: The type 'MAlias' can't be mixed in.
+// class C = SAlias with MAlias;
+// ^
+// pkg/front_end/testcases/general/issue47495.dart:11:9: Context: The issue arises via this type alias.
+// typedef MAlias = M;
+// ^
+//
+// pkg/front_end/testcases/general/issue47495.dart:13:7: Error: The type 'SAlias' which is an alias of 'invalid-type' can't be used as supertype.
+// class C = SAlias with MAlias;
+// ^
+// pkg/front_end/testcases/general/issue47495.dart:10:9: Context: The issue arises via this type alias.
+// typedef SAlias = S;
+// ^
+//
+// pkg/front_end/testcases/general/issue47495.dart:13:7: Error: The type 'MAlias' which is an alias of 'invalid-type' can't be used as supertype.
+// class C = SAlias with MAlias;
+// ^
+// pkg/front_end/testcases/general/issue47495.dart:11:9: Context: The issue arises via this type alias.
+// typedef MAlias = M;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef SAlias = invalid-type;
+typedef MAlias = invalid-type;
+class S extends core::Object {
+ synthetic constructor •() → self::S*
+ : super core::Object::•()
+ ;
+ abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+ abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+ abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+ abstract member-signature method toString() → core::String*; -> core::Object::toString
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+ abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class M extends core::Object {
+ synthetic constructor •() → self::M*
+ : super core::Object::•()
+ ;
+ abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+ abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+ abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+ abstract member-signature method toString() → core::String*; -> core::Object::toString
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+ abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class C extends core::Object {
+ synthetic constructor •() → self::C*
+ : super core::Object::•()
+ ;
+ abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+ abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+ abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+ abstract member-signature method toString() → core::String*; -> core::Object::toString
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+ abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue47495.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue47495.dart.weak.outline.expect
new file mode 100644
index 0000000..f366ace
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47495.dart.weak.outline.expect
@@ -0,0 +1,82 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue47495.dart:10:16: Error: Can't create typedef from non-function type.
+// typedef SAlias = S;
+// ^
+//
+// pkg/front_end/testcases/general/issue47495.dart:11:16: Error: Can't create typedef from non-function type.
+// typedef MAlias = M;
+// ^
+//
+// pkg/front_end/testcases/general/issue47495.dart:13:7: Error: The type 'MAlias' can't be mixed in.
+// class C = SAlias with MAlias;
+// ^
+// pkg/front_end/testcases/general/issue47495.dart:11:9: Context: The issue arises via this type alias.
+// typedef MAlias = M;
+// ^
+//
+// pkg/front_end/testcases/general/issue47495.dart:13:7: Error: The type 'SAlias' which is an alias of 'invalid-type' can't be used as supertype.
+// class C = SAlias with MAlias;
+// ^
+// pkg/front_end/testcases/general/issue47495.dart:10:9: Context: The issue arises via this type alias.
+// typedef SAlias = S;
+// ^
+//
+// pkg/front_end/testcases/general/issue47495.dart:13:7: Error: The type 'MAlias' which is an alias of 'invalid-type' can't be used as supertype.
+// class C = SAlias with MAlias;
+// ^
+// pkg/front_end/testcases/general/issue47495.dart:11:9: Context: The issue arises via this type alias.
+// typedef MAlias = M;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef SAlias = invalid-type;
+typedef MAlias = invalid-type;
+class S extends core::Object {
+ synthetic constructor •() → self::S*
+ ;
+ abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+ abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+ abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+ abstract member-signature method toString() → core::String*; -> core::Object::toString
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+ abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class M extends core::Object {
+ synthetic constructor •() → self::M*
+ ;
+ abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+ abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+ abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+ abstract member-signature method toString() → core::String*; -> core::Object::toString
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+ abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class C extends core::Object {
+ synthetic constructor •() → self::C*
+ ;
+ abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+ abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+ abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+ abstract member-signature method toString() → core::String*; -> core::Object::toString
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+ abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/issue47495.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue47495.dart.weak.transformed.expect
new file mode 100644
index 0000000..1c6fab0
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47495.dart.weak.transformed.expect
@@ -0,0 +1,84 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue47495.dart:10:16: Error: Can't create typedef from non-function type.
+// typedef SAlias = S;
+// ^
+//
+// pkg/front_end/testcases/general/issue47495.dart:11:16: Error: Can't create typedef from non-function type.
+// typedef MAlias = M;
+// ^
+//
+// pkg/front_end/testcases/general/issue47495.dart:13:7: Error: The type 'MAlias' can't be mixed in.
+// class C = SAlias with MAlias;
+// ^
+// pkg/front_end/testcases/general/issue47495.dart:11:9: Context: The issue arises via this type alias.
+// typedef MAlias = M;
+// ^
+//
+// pkg/front_end/testcases/general/issue47495.dart:13:7: Error: The type 'SAlias' which is an alias of 'invalid-type' can't be used as supertype.
+// class C = SAlias with MAlias;
+// ^
+// pkg/front_end/testcases/general/issue47495.dart:10:9: Context: The issue arises via this type alias.
+// typedef SAlias = S;
+// ^
+//
+// pkg/front_end/testcases/general/issue47495.dart:13:7: Error: The type 'MAlias' which is an alias of 'invalid-type' can't be used as supertype.
+// class C = SAlias with MAlias;
+// ^
+// pkg/front_end/testcases/general/issue47495.dart:11:9: Context: The issue arises via this type alias.
+// typedef MAlias = M;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef SAlias = invalid-type;
+typedef MAlias = invalid-type;
+class S extends core::Object {
+ synthetic constructor •() → self::S*
+ : super core::Object::•()
+ ;
+ abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+ abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+ abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+ abstract member-signature method toString() → core::String*; -> core::Object::toString
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+ abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class M extends core::Object {
+ synthetic constructor •() → self::M*
+ : super core::Object::•()
+ ;
+ abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+ abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+ abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+ abstract member-signature method toString() → core::String*; -> core::Object::toString
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+ abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class C extends core::Object {
+ synthetic constructor •() → self::C*
+ : super core::Object::•()
+ ;
+ abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+ abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+ abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+ abstract member-signature method toString() → core::String*; -> core::Object::toString
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+ abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index 344af28..decb8b5 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -87,6 +87,7 @@
general/issue43363: FormatterCrash
general/issue45490: FormatterCrash
general/issue45700.crash: FormatterCrash
+general/issue47495: FormatterCrash
general/many_errors: FormatterCrash
general/missing_prefix_name: FormatterCrash
general/new_as_selector: FormatterCrash
diff --git a/runtime/tests/vm/dart/regress_47468_test.dart b/runtime/tests/vm/dart/regress_47468_test.dart
new file mode 100644
index 0000000..1ff1bbe
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_47468_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2021, 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 https://github.com/dart-lang/sdk/issues/47468.
+// Verifies that the sending empty non-const maps works
+
+// VMOptions=--no-enable-isolate-groups
+
+import 'dart:isolate';
+
+void main() async {
+ final nonConstMap = <int, Object>{};
+ final receivePort = ReceivePort();
+ final sendPort = receivePort.sendPort;
+ sendPort.send(nonConstMap);
+ await receivePort.first;
+}
diff --git a/runtime/tests/vm/dart_2/regress_47468_test.dart b/runtime/tests/vm/dart_2/regress_47468_test.dart
new file mode 100644
index 0000000..b1ccb10
--- /dev/null
+++ b/runtime/tests/vm/dart_2/regress_47468_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2021, 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 https://github.com/dart-lang/sdk/issues/47468.
+// Verifies that the sending empty non-const maps works
+
+// VMOptions=--no-enable-isolate-groups
+
+// @dart = 2.9
+
+import 'dart:isolate';
+
+void main() async {
+ final nonConstMap = <int, Object>{};
+ final receivePort = ReceivePort();
+ final sendPort = receivePort.sendPort;
+ sendPort.send(nonConstMap);
+ await receivePort.first;
+}
diff --git a/sdk/lib/_internal/vm/lib/compact_hash.dart b/sdk/lib/_internal/vm/lib/compact_hash.dart
index 096f7ef..14fbf46 100644
--- a/sdk/lib/_internal/vm/lib/compact_hash.dart
+++ b/sdk/lib/_internal/vm/lib/compact_hash.dart
@@ -24,15 +24,15 @@
// least one unoccupied entry.
// NOTE: When maps are deserialized, their _index and _hashMask is regenerated
// eagerly by _regenerateIndex.
- Uint32List _index = _initialIndex;
+ Uint32List _index = _uninitializedIndex;
// Cached in-place mask for the hash pattern component.
- int _hashMask = 0;
+ int _hashMask = _HashBase._UNINITIALIZED_HASH_MASK;
// Fixed-length list of keys (set) or key/value at even/odd indices (map).
//
// Can be either a mutable or immutable list.
- List _data = _initialData;
+ List _data = _uninitializedData;
// Length of _data that is used (i.e., keys + values for a map).
int _usedData = 0;
@@ -126,12 +126,15 @@
// TODO(koda): Consider moving field comments to _HashFieldBase.
abstract class _HashBase implements _HashVMBase {
// The number of bits used for each component is determined by table size.
- // The length of _index is twice the number of entries in _data, and both
- // are doubled when _data is full. Thus, _index will have a max load factor
- // of 1/2, which enables one more bit to be used for the hash.
+ // If initialized, the length of _index is (at least) twice the number of
+ // entries in _data, and both are doubled when _data is full. Thus, _index
+ // will have a max load factor of 1/2, which enables one more bit to be used
+ // for the hash.
// TODO(koda): Consider growing _data by factor sqrt(2), twice as often.
static const int _INITIAL_INDEX_BITS = 2;
static const int _INITIAL_INDEX_SIZE = 1 << (_INITIAL_INDEX_BITS + 1);
+ static const int _UNINITIALIZED_INDEX_SIZE = 1;
+ static const int _UNINITIALIZED_HASH_MASK = 0;
// Unused and deleted entries are marked by 0 and 1, respectively.
static const int _UNUSED_PAIR = 0;
@@ -142,6 +145,11 @@
// as unsigned words.
// Keep consistent with IndexSizeToHashMask in runtime/vm/object.h.
static int _indexSizeToHashMask(int indexSize) {
+ assert(indexSize >= _INITIAL_INDEX_SIZE ||
+ indexSize == _UNINITIALIZED_INDEX_SIZE);
+ if (indexSize == _UNINITIALIZED_INDEX_SIZE) {
+ return _UNINITIALIZED_HASH_MASK;
+ }
int indexBits = indexSize.bitLength - 2;
return internal.has63BitSmis
? (1 << (32 - indexBits)) - 1
@@ -203,11 +211,11 @@
bool _equals(e1, e2) => e1 == e2;
}
-final _initialIndex = new Uint32List(1);
+final _uninitializedIndex = new Uint32List(_HashBase._UNINITIALIZED_INDEX_SIZE);
// Note: not const. Const arrays are made immutable by having a different class
// than regular arrays that throws on element assignment. We want the data field
// in maps and sets to be monomorphic.
-final _initialData = new List.filled(0, null);
+final _uninitializedData = new List.filled(0, null);
// VM-internalized implementation of a default-constructed LinkedHashMap.
@pragma("vm:entry-point")
@@ -219,9 +227,9 @@
_OperatorEqualsAndHashCode
implements LinkedHashMap<K, V> {
_InternalLinkedHashMap() {
- _index = _initialIndex;
- _hashMask = 0;
- _data = _initialData;
+ _index = _uninitializedIndex;
+ _hashMask = _HashBase._UNINITIALIZED_HASH_MASK;
+ _data = _uninitializedData;
_usedData = 0;
_deletedKeys = 0;
}
@@ -324,7 +332,11 @@
void clear() {
if (!isEmpty) {
- _init(_HashBase._INITIAL_INDEX_SIZE, _hashMask, null, 0);
+ _index = _uninitializedIndex;
+ _hashMask = _HashBase._UNINITIALIZED_HASH_MASK;
+ _data = _uninitializedData;
+ _usedData = 0;
+ _deletedKeys = 0;
}
}
@@ -354,8 +366,9 @@
// This method is called by [_rehashObjects] (see above).
void _regenerateIndex() {
- _index = _data.length == 0 ? _initialIndex : new Uint32List(_data.length);
- assert(_hashMask == 0);
+ _index =
+ _data.length == 0 ? _uninitializedIndex : new Uint32List(_data.length);
+ assert(_hashMask == _HashBase._UNINITIALIZED_HASH_MASK);
_hashMask = _HashBase._indexSizeToHashMask(_index.length);
final int tmpUsed = _usedData;
_usedData = 0;
@@ -655,7 +668,11 @@
void clear() {
if (!isEmpty) {
- _init(_HashBase._INITIAL_INDEX_SIZE, _hashMask, null, 0);
+ _index = _uninitializedIndex;
+ _hashMask = _HashBase._UNINITIALIZED_HASH_MASK;
+ _data = _uninitializedData;
+ _usedData = 0;
+ _deletedKeys = 0;
}
}
@@ -773,8 +790,10 @@
// This method is called by [_rehashObjects] (see above).
void _regenerateIndex() {
- _index = _data.length == 0 ? _initialIndex : new Uint32List(_data.length);
- assert(_hashMask == 0);
+ final size =
+ _roundUpToPowerOfTwo(max(_data.length, _HashBase._INITIAL_INDEX_SIZE));
+ _index = _data.length == 0 ? _uninitializedIndex : new Uint32List(size);
+ assert(_hashMask == _HashBase._UNINITIALIZED_HASH_MASK);
_hashMask = _HashBase._indexSizeToHashMask(_index.length);
_rehash();
}
@@ -790,9 +809,9 @@
_OperatorEqualsAndHashCode
implements LinkedHashSet<E> {
_CompactLinkedHashSet() {
- _index = _initialIndex;
- _hashMask = 0;
- _data = _initialData;
+ _index = _uninitializedIndex;
+ _hashMask = _HashBase._UNINITIALIZED_HASH_MASK;
+ _data = _uninitializedData;
_usedData = 0;
_deletedKeys = 0;
}
diff --git a/tools/VERSION b/tools/VERSION
index bbfee5c..c11d373 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 239
+PRERELEASE 240
PRERELEASE_PATCH 0
\ No newline at end of file