Version 2.15.0-16.0.dev
Merge commit 'fc4d4144fb0503cc4bebb46cc478ef7a9538fced' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index b41bf1d..e70c308 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -206,7 +206,7 @@
},
{
"name": "dart2js_info",
- "rootUri": "../third_party/pkg/dart2js_info",
+ "rootUri": "../pkg/dart2js_info",
"packageUri": "lib/",
"languageVersion": "2.3"
},
diff --git a/.packages b/.packages
index 3b46619..b22e6a2 100644
--- a/.packages
+++ b/.packages
@@ -29,7 +29,7 @@
convert:third_party/pkg/convert/lib
crypto:third_party/pkg/crypto/lib
csslib:third_party/pkg/csslib/lib
-dart2js_info:third_party/pkg/dart2js_info/lib
+dart2js_info:pkg/dart2js_info/lib
dart2js_runtime_metrics:pkg/dart2js_runtime_metrics/lib
dart2js_tools:pkg/dart2js_tools/lib
dart2native:pkg/dart2native/lib
diff --git a/DEPS b/DEPS
index 4134666..0656dad 100644
--- a/DEPS
+++ b/DEPS
@@ -90,7 +90,6 @@
"convert_rev": "e063fdca4bebffecbb5e6aa5525995120982d9ce",
"crypto_rev": "b5024e4de2b1c474dd558bef593ddbf0bfade152",
"csslib_rev": "e411d862fd8cc50415c1badf2632e017373b3f47",
- "dart2js_info_rev" : "e0acfeb5affdf94c53067e68bd836adf589628fd",
# Note: Updates to dart_style have to be coordinated with the infrastructure
# team so that the internal formatter in `tools/sdks/dart-sdk/bin/dartfmt`
@@ -348,8 +347,6 @@
Var("dart_git") + "csslib.git" + "@" + Var("csslib_rev"),
Var("dart_root") + "/third_party/pkg_tested/dart_style":
Var("dart_git") + "dart_style.git" + "@" + Var("dart_style_rev"),
- Var("dart_root") + "/third_party/pkg/dart2js_info":
- Var("dart_git") + "dart2js_info.git" + "@" + Var("dart2js_info_rev"),
Var("dart_root") + "/third_party/pkg/dartdoc":
Var("dart_git") + "dartdoc.git" + "@" + Var("dartdoc_rev"),
Var("dart_root") + "/third_party/pkg/ffi":
diff --git a/pkg/compiler/pubspec.yaml b/pkg/compiler/pubspec.yaml
index ada6b1e..dbdaec6 100644
--- a/pkg/compiler/pubspec.yaml
+++ b/pkg/compiler/pubspec.yaml
@@ -62,6 +62,8 @@
path: ../kernel
meta:
path: ../meta
+ dart2js_info:
+ path: ../dart2js_info
# Packages brought in via DEPS
args:
@@ -76,8 +78,6 @@
path: ../../third_party/pkg/convert
crypto:
path: ../../third_party/pkg/crypto
- dart2js_info:
- path: ../../third_party/pkg/dart2js_info
fixnum:
path: ../../third_party/pkg/fixnum
http_parser:
diff --git a/pkg/compiler/test/analyses/dart2js_allowed.json b/pkg/compiler/test/analyses/dart2js_allowed.json
index 9048e82..242faa0 100644
--- a/pkg/compiler/test/analyses/dart2js_allowed.json
+++ b/pkg/compiler/test/analyses/dart2js_allowed.json
@@ -170,13 +170,13 @@
"Dynamic invocation of '>='.": 1,
"Dynamic invocation of 'codeUnitAt'.": 1
},
- "third_party/pkg/dart2js_info/lib/json_info_codec.dart": {
+ "pkg/dart2js_info/lib/json_info_codec.dart": {
"Dynamic invocation of '[]'.": 11,
"Dynamic invocation of 'forEach'.": 2,
"Dynamic invocation of 'map'.": 2,
"Dynamic invocation of 'compareTo'.": 1
},
- "third_party/pkg/dart2js_info/lib/binary_serialization.dart": {
+ "pkg/dart2js_info/lib/binary_serialization.dart": {
"Dynamic invocation of 'cast'.": 1
},
"pkg/compiler/lib/src/universe/side_effects.dart": {
@@ -209,11 +209,11 @@
"Dynamic invocation of '[]'.": 9,
"Dynamic invocation of 'toStatement'.": 3
},
- "third_party/pkg/dart2js_info/lib/src/util.dart": {
+ "pkg/dart2js_info/lib/src/util.dart": {
"Dynamic access of 'name'.": 1,
"Dynamic invocation of '-'.": 1
},
- "third_party/pkg/dart2js_info/lib/src/binary/sink.dart": {
+ "pkg/dart2js_info/lib/src/binary/sink.dart": {
"Dynamic access of 'index'.": 1
},
"pkg/compiler/lib/src/inferrer/type_graph_nodes.dart": {
diff --git a/pkg/dart2js_info/test/binary_serialization_test.dart b/pkg/dart2js_info/test/binary_serialization_test.dart
index e38f3cb..116003e 100644
--- a/pkg/dart2js_info/test/binary_serialization_test.dart
+++ b/pkg/dart2js_info/test/binary_serialization_test.dart
@@ -10,7 +10,7 @@
import 'package:test/test.dart';
class ByteSink implements Sink<List<int>> {
- BytesBuilder builder = new BytesBuilder();
+ BytesBuilder builder = BytesBuilder();
add(List<int> data) => builder.add(data);
close() {}
@@ -19,19 +19,20 @@
main() {
group('json to proto conversion with deferred files', () {
test('hello_world_deferred', () {
- var helloWorld = new File(
- 'test/hello_world_deferred/hello_world_deferred.js.info.json');
+ var uri = Platform.script.resolve(
+ 'hello_world_deferred/hello_world_deferred.js.info.json');
+ var helloWorld = File.fromUri(uri);
var contents = helloWorld.readAsStringSync();
var json = jsonDecode(contents);
- var info = new AllInfoJsonCodec().decode(json);
+ var info = AllInfoJsonCodec().decode(json);
- var sink = new ByteSink();
+ var sink = ByteSink();
binary.encode(info, sink);
var info2 = binary.decode(sink.builder.toBytes());
- var json2 = new AllInfoJsonCodec().encode(info2);
+ var json2 = AllInfoJsonCodec().encode(info2);
- info.program.toJsonDuration = new Duration(milliseconds: 0);
- var json1 = new AllInfoJsonCodec().encode(info);
+ info.program.toJsonDuration = Duration(milliseconds: 0);
+ var json1 = AllInfoJsonCodec().encode(info);
var contents1 = const JsonEncoder.withIndent(" ").convert(json1);
var contents2 = const JsonEncoder.withIndent(" ").convert(json2);
expect(contents1 == contents2, isTrue);
diff --git a/pkg/dart2js_info/test/json_to_proto_deferred_test.dart b/pkg/dart2js_info/test/json_to_proto_deferred_test.dart
index 0f1eaf2..70d7681 100644
--- a/pkg/dart2js_info/test/json_to_proto_deferred_test.dart
+++ b/pkg/dart2js_info/test/json_to_proto_deferred_test.dart
@@ -12,11 +12,12 @@
main() {
group('json to proto conversion with deferred files', () {
test('hello_world_deferred', () {
- final helloWorld = new File(
- 'test/hello_world_deferred/hello_world_deferred.js.info.json');
+ var uri = Platform.script.resolve(
+ 'hello_world_deferred/hello_world_deferred.js.info.json');
+ final helloWorld = File.fromUri(uri);
final json = jsonDecode(helloWorld.readAsStringSync());
- final decoded = new AllInfoJsonCodec().decode(json);
- final proto = new AllInfoProtoCodec().encode(decoded);
+ final decoded = AllInfoJsonCodec().decode(json);
+ final proto = AllInfoProtoCodec().encode(decoded);
expect(proto.deferredImports, hasLength(1));
final libraryImports = proto.deferredImports.first;
diff --git a/pkg/dart2js_info/test/json_to_proto_test.dart b/pkg/dart2js_info/test/json_to_proto_test.dart
index 609532b..735b2d7 100644
--- a/pkg/dart2js_info/test/json_to_proto_test.dart
+++ b/pkg/dart2js_info/test/json_to_proto_test.dart
@@ -13,28 +13,32 @@
main() {
group('json to proto conversion', () {
test('hello_world', () {
- final helloWorld = new File('test/hello_world/hello_world.js.info.json');
+ var uri = Platform.script.resolve(
+ 'hello_world/hello_world.js.info.json');
+ final helloWorld = File.fromUri(uri);
final json = jsonDecode(helloWorld.readAsStringSync());
- final decoded = new AllInfoJsonCodec().decode(json);
- final proto = new AllInfoProtoCodec().encode(decoded);
+ final decoded = AllInfoJsonCodec().decode(json);
+ final proto = AllInfoProtoCodec().encode(decoded);
expect(proto.program.entrypointId, isNotNull);
expect(proto.program.size, 10324);
expect(proto.program.compilationMoment.toInt(),
DateTime.parse("2017-04-17 09:46:41.661617").microsecondsSinceEpoch);
expect(proto.program.toProtoDuration.toInt(),
- new Duration(milliseconds: 4).inMicroseconds);
+ Duration(milliseconds: 4).inMicroseconds);
expect(proto.program.dumpInfoDuration.toInt(),
- new Duration(milliseconds: 0).inMicroseconds);
+ Duration(milliseconds: 0).inMicroseconds);
expect(proto.program.noSuchMethodEnabled, isFalse);
expect(proto.program.minified, isFalse);
});
test('has proper id format', () {
- final helloWorld = new File('test/hello_world/hello_world.js.info.json');
+ var uri = Platform.script.resolve(
+ 'hello_world/hello_world.js.info.json');
+ final helloWorld = File.fromUri(uri);
final json = jsonDecode(helloWorld.readAsStringSync());
- final decoded = new AllInfoJsonCodec().decode(json);
- final proto = new AllInfoProtoCodec().encode(decoded);
+ final decoded = AllInfoJsonCodec().decode(json);
+ final proto = AllInfoProtoCodec().encode(decoded);
final expectedPrefixes = <InfoKind, String>{};
for (final kind in InfoKind.values) {
diff --git a/pkg/dart2js_info/test/parse_test.dart b/pkg/dart2js_info/test/parse_test.dart
index 1e6b382..ae71615 100644
--- a/pkg/dart2js_info/test/parse_test.dart
+++ b/pkg/dart2js_info/test/parse_test.dart
@@ -11,9 +11,11 @@
main() {
group('parse', () {
test('hello_world', () {
- var helloWorld = new File('test/hello_world/hello_world.js.info.json');
+ var uri =
+ Platform.script.resolve('hello_world/hello_world.js.info.json');
+ var helloWorld = File.fromUri(uri);
var json = jsonDecode(helloWorld.readAsStringSync());
- var decoded = new AllInfoJsonCodec().decode(json);
+ var decoded = AllInfoJsonCodec().decode(json);
var program = decoded.program;
expect(program, isNotNull);
diff --git a/pkg/dartdev/test/commands/flag_test.dart b/pkg/dartdev/test/commands/flag_test.dart
index 5d9d0ab..da055db 100644
--- a/pkg/dartdev/test/commands/flag_test.dart
+++ b/pkg/dartdev/test/commands/flag_test.dart
@@ -37,8 +37,8 @@
if (command.argParser != null) {
if (command.name != 'help' &&
command.name != 'format' &&
- command.name != 'migrate' &&
- command.name != 'pub') {
+ command.name != 'pub' &&
+ command.name != 'test') {
expect(command.argParser.usageLineLength,
stdout.hasTerminal ? stdout.terminalColumns : null);
} else if (command.name == 'pub') {
@@ -97,6 +97,22 @@
contains('The following options are only used for VM development'));
});
+ test('print Dart CLI help on usage error', () {
+ p = project();
+ var result = p.runSync(['---help']);
+ expect(result.exitCode, 255);
+ expect(result.stdout, contains(DartdevRunner.dartdevDescription));
+ expect(result.stderr, isEmpty);
+ });
+
+ test('print VM help on usage error when --disable-dart-dev is provided', () {
+ p = project();
+ var result = p.runSync(['---help', '--disable-dart-dev']);
+ expect(result.exitCode, 255);
+ expect(result.stdout, isNot(contains(DartdevRunner.dartdevDescription)));
+ expect(result.stderr, isEmpty);
+ });
+
test('help', () {
p = project();
var result = p.runSync(['help']);
diff --git a/pkg/dds/lib/src/devtools/devtools_client.dart b/pkg/dds/lib/src/devtools/devtools_client.dart
index 8bc3564..e5ec54e 100644
--- a/pkg/dds/lib/src/devtools/devtools_client.dart
+++ b/pkg/dds/lib/src/devtools/devtools_client.dart
@@ -4,12 +4,11 @@
import 'dart:async';
+import 'package:devtools_shared/devtools_server.dart';
import 'package:json_rpc_2/src/server.dart' as json_rpc;
import 'package:sse/src/server/sse_handler.dart';
import 'package:stream_channel/stream_channel.dart';
-import 'server_api.dart';
-
class LoggingMiddlewareSink<S> implements StreamSink<S> {
LoggingMiddlewareSink(this.sink);
diff --git a/pkg/dds/lib/src/devtools/devtools_handler.dart b/pkg/dds/lib/src/devtools/devtools_handler.dart
index 87c4fa6..3b55bfb 100644
--- a/pkg/dds/lib/src/devtools/devtools_handler.dart
+++ b/pkg/dds/lib/src/devtools/devtools_handler.dart
@@ -5,13 +5,13 @@
import 'dart:async';
import 'package:dds/src/constants.dart';
+import 'package:devtools_shared/devtools_server.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf_static/shelf_static.dart';
import 'package:sse/server/sse_handler.dart';
import '../dds_impl.dart';
import 'devtools_client.dart';
-import 'server_api.dart';
/// Returns a [Handler] which handles serving DevTools and the DevTools server
/// API under $DDS_URI/devtools/.
diff --git a/pkg/dds/lib/src/devtools/file_system.dart b/pkg/dds/lib/src/devtools/file_system.dart
deleted file mode 100644
index d5d6c6a..0000000
--- a/pkg/dds/lib/src/devtools/file_system.dart
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// TODO(bkonyi): remove once package:devtools_server_api is available
-// See https://github.com/flutter/devtools/issues/2958.
-
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:path/path.dart' as path;
-
-import 'usage.dart';
-
-class LocalFileSystem {
- static String _userHomeDir() {
- final String envKey =
- Platform.operatingSystem == 'windows' ? 'APPDATA' : 'HOME';
- final String? value = Platform.environment[envKey];
- return value == null ? '.' : value;
- }
-
- /// Returns the path to the DevTools storage directory.
- static String devToolsDir() {
- return path.join(_userHomeDir(), '.flutter-devtools');
- }
-
- /// Moves the .devtools file to ~/.flutter-devtools/.devtools if the .devtools file
- /// exists in the user's home directory.
- static void maybeMoveLegacyDevToolsStore() {
- final file = File(path.join(_userHomeDir(), DevToolsUsage.storeName));
- if (file.existsSync()) {
- ensureDevToolsDirectory();
- file.copySync(path.join(devToolsDir(), DevToolsUsage.storeName));
- file.deleteSync();
- }
- }
-
- /// Creates the ~/.flutter-devtools directory if it does not already exist.
- static void ensureDevToolsDirectory() {
- Directory('${LocalFileSystem.devToolsDir()}').createSync();
- }
-
- /// Returns a DevTools file from the given path.
- ///
- /// Only files within ~/.flutter-devtools/ can be accessed.
- static File? devToolsFileFromPath(String pathFromDevToolsDir) {
- if (pathFromDevToolsDir.contains('..')) {
- // The passed in path should not be able to walk up the directory tree
- // outside of the ~/.flutter-devtools/ directory.
- return null;
- }
- ensureDevToolsDirectory();
- final file = File(path.join(devToolsDir(), pathFromDevToolsDir));
- if (!file.existsSync()) {
- return null;
- }
- return file;
- }
-
- /// Returns a DevTools file from the given path as encoded json.
- ///
- /// Only files within ~/.flutter-devtools/ can be accessed.
- static String? devToolsFileAsJson(String pathFromDevToolsDir) {
- final file = devToolsFileFromPath(pathFromDevToolsDir);
- if (file == null) return null;
-
- final fileName = path.basename(file.path);
- if (!fileName.endsWith('.json')) return null;
-
- final content = file.readAsStringSync();
- final json = jsonDecode(content);
- json['lastModifiedTime'] = file.lastModifiedSync().toString();
- return jsonEncode(json);
- }
-
- /// Whether the flutter store file exists.
- static bool flutterStoreExists() {
- final flutterStore = File('${_userHomeDir()}/.flutter');
- return flutterStore.existsSync();
- }
-}
diff --git a/pkg/dds/lib/src/devtools/server_api.dart b/pkg/dds/lib/src/devtools/server_api.dart
deleted file mode 100644
index 5f21a03..0000000
--- a/pkg/dds/lib/src/devtools/server_api.dart
+++ /dev/null
@@ -1,228 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// TODO(bkonyi): remove once package:devtools_server_api is available
-// See https://github.com/flutter/devtools/issues/2958.
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:devtools_shared/devtools_shared.dart';
-import 'package:shelf/shelf.dart' as shelf;
-
-import 'file_system.dart';
-import 'usage.dart';
-
-/// The DevTools server API.
-///
-/// This defines endpoints that serve all requests that come in over api/.
-class ServerApi {
- static const errorNoActiveSurvey = 'ERROR: setActiveSurvey not called.';
-
- /// Determines whether or not [request] is an API call.
- static bool canHandle(shelf.Request request) {
- return request.url.path.startsWith(apiPrefix);
- }
-
- /// Handles all requests.
- ///
- /// To override an API call, pass in a subclass of [ServerApi].
- static FutureOr<shelf.Response> handle(
- shelf.Request request, [
- ServerApi? api,
- ]) {
- api ??= ServerApi();
- switch (request.url.path) {
- // ----- Flutter Tool GA store. -----
- case apiGetFlutterGAEnabled:
- // Is Analytics collection enabled?
- return api.getCompleted(
- request,
- json.encode(FlutterUsage.doesStoreExist ? _usage!.enabled : null),
- );
- case apiGetFlutterGAClientId:
- // Flutter Tool GA clientId - ONLY get Flutter's clientId if enabled is
- // true.
- return (FlutterUsage.doesStoreExist)
- ? api.getCompleted(
- request,
- json.encode(_usage!.enabled ? _usage!.clientId : null),
- )
- : api.getCompleted(
- request,
- json.encode(null),
- );
-
- // ----- DevTools GA store. -----
-
- case apiResetDevTools:
- _devToolsUsage.reset();
- return api.getCompleted(request, json.encode(true));
- case apiGetDevToolsFirstRun:
- // Has DevTools been run first time? To bring up welcome screen.
- return api.getCompleted(
- request,
- json.encode(_devToolsUsage.isFirstRun),
- );
- case apiGetDevToolsEnabled:
- // Is DevTools Analytics collection enabled?
- return api.getCompleted(request, json.encode(_devToolsUsage.enabled));
- case apiSetDevToolsEnabled:
- // Enable or disable DevTools analytics collection.
- final queryParams = request.requestedUri.queryParameters;
- if (queryParams.containsKey(devToolsEnabledPropertyName)) {
- _devToolsUsage.enabled =
- json.decode(queryParams[devToolsEnabledPropertyName]!);
- }
- return api.setCompleted(request, json.encode(_devToolsUsage.enabled));
-
- // ----- DevTools survey store. -----
-
- case apiSetActiveSurvey:
- // Assume failure.
- bool result = false;
-
- // Set the active survey used to store subsequent apiGetSurveyActionTaken,
- // apiSetSurveyActionTaken, apiGetSurveyShownCount, and
- // apiIncrementSurveyShownCount calls.
- final queryParams = request.requestedUri.queryParameters;
- if (queryParams.keys.length == 1 &&
- queryParams.containsKey(activeSurveyName)) {
- final String theSurveyName = queryParams[activeSurveyName]!;
-
- // Set the current activeSurvey.
- _devToolsUsage.activeSurvey = theSurveyName;
- result = true;
- }
-
- return api.getCompleted(request, json.encode(result));
- case apiGetSurveyActionTaken:
- // Request setActiveSurvey has not been requested.
- if (_devToolsUsage.activeSurvey == null) {
- return api.badRequest('$errorNoActiveSurvey '
- '- $apiGetSurveyActionTaken');
- }
- // SurveyActionTaken has the survey been acted upon (taken or dismissed)
- return api.getCompleted(
- request,
- json.encode(_devToolsUsage.surveyActionTaken),
- );
- // TODO(terry): remove the query param logic for this request.
- // setSurveyActionTaken should only be called with the value of true, so
- // we can remove the extra complexity.
- case apiSetSurveyActionTaken:
- // Request setActiveSurvey has not been requested.
- if (_devToolsUsage.activeSurvey == null) {
- return api.badRequest('$errorNoActiveSurvey '
- '- $apiSetSurveyActionTaken');
- }
- // Set the SurveyActionTaken.
- // Has the survey been taken or dismissed..
- final queryParams = request.requestedUri.queryParameters;
- if (queryParams.containsKey(surveyActionTakenPropertyName)) {
- _devToolsUsage.surveyActionTaken =
- json.decode(queryParams[surveyActionTakenPropertyName]!);
- }
- return api.setCompleted(
- request,
- json.encode(_devToolsUsage.surveyActionTaken),
- );
- case apiGetSurveyShownCount:
- // Request setActiveSurvey has not been requested.
- if (_devToolsUsage.activeSurvey == null) {
- return api.badRequest('$errorNoActiveSurvey '
- '- $apiGetSurveyShownCount');
- }
- // SurveyShownCount how many times have we asked to take survey.
- return api.getCompleted(
- request,
- json.encode(_devToolsUsage.surveyShownCount),
- );
- case apiIncrementSurveyShownCount:
- // Request setActiveSurvey has not been requested.
- if (_devToolsUsage.activeSurvey == null) {
- return api.badRequest('$errorNoActiveSurvey '
- '- $apiIncrementSurveyShownCount');
- }
- // Increment the SurveyShownCount, we've asked about the survey.
- _devToolsUsage.incrementSurveyShownCount();
- return api.getCompleted(
- request,
- json.encode(_devToolsUsage.surveyShownCount),
- );
- case apiGetBaseAppSizeFile:
- final queryParams = request.requestedUri.queryParameters;
- if (queryParams.containsKey(baseAppSizeFilePropertyName)) {
- final filePath = queryParams[baseAppSizeFilePropertyName]!;
- final fileJson = LocalFileSystem.devToolsFileAsJson(filePath);
- if (fileJson == null) {
- return api.badRequest('No JSON file available at $filePath.');
- }
- return api.getCompleted(request, fileJson);
- }
- return api.badRequest('Request for base app size file does not '
- 'contain a query parameter with the expected key: '
- '$baseAppSizeFilePropertyName');
- case apiGetTestAppSizeFile:
- final queryParams = request.requestedUri.queryParameters;
- if (queryParams.containsKey(testAppSizeFilePropertyName)) {
- final filePath = queryParams[testAppSizeFilePropertyName]!;
- final fileJson = LocalFileSystem.devToolsFileAsJson(filePath);
- if (fileJson == null) {
- return api.badRequest('No JSON file available at $filePath.');
- }
- return api.getCompleted(request, fileJson);
- }
- return api.badRequest('Request for test app size file does not '
- 'contain a query parameter with the expected key: '
- '$testAppSizeFilePropertyName');
- default:
- return api.notImplemented(request);
- }
- }
-
- // Accessing Flutter usage file e.g., ~/.flutter.
- // NOTE: Only access the file if it exists otherwise Flutter Tool hasn't yet
- // been run.
- static final FlutterUsage? _usage =
- FlutterUsage.doesStoreExist ? FlutterUsage() : null;
-
- // Accessing DevTools usage file e.g., ~/.devtools
- static final DevToolsUsage _devToolsUsage = DevToolsUsage();
-
- static DevToolsUsage get devToolsPreferences => _devToolsUsage;
-
- /// Logs a page view in the DevTools server.
- ///
- /// In the open-source version of DevTools, Google Analytics handles this
- /// without any need to involve the server.
- FutureOr<shelf.Response> logScreenView(shelf.Request request) =>
- notImplemented(request);
-
- /// Return the value of the property.
- FutureOr<shelf.Response> getCompleted(shelf.Request request, String value) =>
- shelf.Response.ok('$value');
-
- /// Return the value of the property after the property value has been set.
- FutureOr<shelf.Response> setCompleted(shelf.Request request, String value) =>
- shelf.Response.ok('$value');
-
- /// A [shelf.Response] for API calls that encountered a request problem e.g.,
- /// setActiveSurvey not called.
- ///
- /// This is a 400 Bad Request response.
- FutureOr<shelf.Response> badRequest([String? logError]) {
- if (logError != null) print(logError);
- return shelf.Response(HttpStatus.badRequest);
- }
-
- /// A [shelf.Response] for API calls that have not been implemented in this
- /// server.
- ///
- /// This is a no-op 204 No Content response because returning 404 Not Found
- /// creates unnecessary noise in the console.
- FutureOr<shelf.Response> notImplemented(shelf.Request request) =>
- shelf.Response(HttpStatus.noContent);
-}
diff --git a/pkg/dds/lib/src/devtools/usage.dart b/pkg/dds/lib/src/devtools/usage.dart
deleted file mode 100644
index 8e61b90..0000000
--- a/pkg/dds/lib/src/devtools/usage.dart
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// TODO(bkonyi): remove once package:devtools_server_api is available
-// See https://github.com/flutter/devtools/issues/2958.
-
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:path/path.dart' as path;
-import 'package:usage/usage_io.dart';
-
-import 'file_system.dart';
-
-/// Access the file '~/.flutter'.
-class FlutterUsage {
- /// Create a new Usage instance; [versionOverride] and [configDirOverride] are
- /// used for testing.
- FlutterUsage({
- String settingsName = 'flutter',
- String? versionOverride,
- String? configDirOverride,
- }) {
- _analytics = AnalyticsIO('', settingsName, '');
- }
-
- late Analytics _analytics;
-
- /// Does the .flutter store exist?
- static bool get doesStoreExist {
- return LocalFileSystem.flutterStoreExists();
- }
-
- bool get isFirstRun => _analytics.firstRun;
-
- bool get enabled => _analytics.enabled;
-
- set enabled(bool value) => _analytics.enabled = value;
-
- String get clientId => _analytics.clientId;
-}
-
-// Access the DevTools on disk store (~/.devtools/.devtools).
-class DevToolsUsage {
- /// Create a new Usage instance; [versionOverride] and [configDirOverride] are
- /// used for testing.
- DevToolsUsage({
- String? versionOverride,
- String? configDirOverride,
- }) {
- LocalFileSystem.maybeMoveLegacyDevToolsStore();
- properties = IOPersistentProperties(
- storeName,
- documentDirPath: LocalFileSystem.devToolsDir(),
- );
- }
-
- static const storeName = '.devtools';
-
- /// The activeSurvey is the property name of a top-level property
- /// existing or created in the file ~/.devtools
- /// If the property doesn't exist it is created with default survey values:
- ///
- /// properties[activeSurvey]['surveyActionTaken'] = false;
- /// properties[activeSurvey]['surveyShownCount'] = 0;
- ///
- /// It is a requirement that the API apiSetActiveSurvey must be called before
- /// calling any survey method on DevToolsUsage (addSurvey, rewriteActiveSurvey,
- /// surveyShownCount, incrementSurveyShownCount, or surveyActionTaken).
- String? _activeSurvey;
-
- late IOPersistentProperties properties;
-
- static const _surveyActionTaken = 'surveyActionTaken';
- static const _surveyShownCount = 'surveyShownCount';
-
- void reset() {
- properties.remove('firstRun');
- properties['enabled'] = false;
- }
-
- bool get isFirstRun {
- properties['firstRun'] = properties['firstRun'] == null;
- return properties['firstRun'];
- }
-
- bool get enabled {
- if (properties['enabled'] == null) {
- properties['enabled'] = false;
- }
-
- return properties['enabled'];
- }
-
- set enabled(bool? value) {
- properties['enabled'] = value;
- return properties['enabled'];
- }
-
- bool surveyNameExists(String? surveyName) => properties[surveyName] != null;
-
- void _addSurvey(String? surveyName) {
- assert(activeSurvey == surveyName);
- rewriteActiveSurvey(false, 0);
- }
-
- String? get activeSurvey => _activeSurvey;
-
- set activeSurvey(String? surveyName) {
- _activeSurvey = surveyName;
-
- if (!surveyNameExists(activeSurvey)) {
- // Create the survey if property is non-existent in ~/.devtools
- _addSurvey(activeSurvey);
- }
- }
-
- /// Need to rewrite the entire survey structure for property to be persisted.
- void rewriteActiveSurvey(bool? actionTaken, int? shownCount) {
- properties[activeSurvey] = {
- _surveyActionTaken: actionTaken,
- _surveyShownCount: shownCount,
- };
- }
-
- int? get surveyShownCount {
- final prop = properties[activeSurvey];
- if (prop[_surveyShownCount] == null) {
- rewriteActiveSurvey(prop[_surveyActionTaken], 0);
- }
- return properties[activeSurvey][_surveyShownCount];
- }
-
- void incrementSurveyShownCount() {
- surveyShownCount; // Ensure surveyShownCount has been initialized.
- final prop = properties[activeSurvey];
- rewriteActiveSurvey(prop[_surveyActionTaken], prop[_surveyShownCount] + 1);
- }
-
- bool get surveyActionTaken {
- return properties[activeSurvey][_surveyActionTaken] == true;
- }
-
- set surveyActionTaken(bool? value) {
- final prop = properties[activeSurvey];
- rewriteActiveSurvey(value, prop[_surveyShownCount]);
- }
-}
-
-abstract class PersistentProperties {
- PersistentProperties(this.name);
-
- final String name;
-
- dynamic operator [](String key);
-
- void operator []=(String key, dynamic value);
-
- /// Re-read settings from the backing store.
- ///
- /// May be a no-op on some platforms.
- void syncSettings();
-}
-
-const JsonEncoder _jsonEncoder = JsonEncoder.withIndent(' ');
-
-class IOPersistentProperties extends PersistentProperties {
- IOPersistentProperties(
- String name, {
- String? documentDirPath,
- }) : super(name) {
- final String fileName = name.replaceAll(' ', '_');
- documentDirPath ??= LocalFileSystem.devToolsDir();
- _file = File(path.join(documentDirPath, fileName));
- if (!_file.existsSync()) {
- _file.createSync(recursive: true);
- }
- syncSettings();
- }
-
- IOPersistentProperties.fromFile(File file) : super(path.basename(file.path)) {
- _file = file;
- if (!_file.existsSync()) {
- _file.createSync(recursive: true);
- }
- syncSettings();
- }
-
- late File _file;
-
- Map? _map;
-
- @override
- dynamic operator [](String? key) => _map![key];
-
- @override
- void operator []=(String? key, dynamic value) {
- if (value == null && !_map!.containsKey(key)) return;
- if (_map![key] == value) return;
-
- if (value == null) {
- _map!.remove(key);
- } else {
- _map![key] = value;
- }
-
- try {
- _file.writeAsStringSync(_jsonEncoder.convert(_map) + '\n');
- } catch (_) {}
- }
-
- @override
- void syncSettings() {
- try {
- String contents = _file.readAsStringSync();
- if (contents.isEmpty) contents = '{}';
- _map = jsonDecode(contents);
- } catch (_) {
- _map = {};
- }
- }
-
- void remove(String propertyName) {
- _map!.remove(propertyName);
- }
-}
diff --git a/pkg/dds/pubspec.yaml b/pkg/dds/pubspec.yaml
index 9bdb587..d9b8b92 100644
--- a/pkg/dds/pubspec.yaml
+++ b/pkg/dds/pubspec.yaml
@@ -25,7 +25,6 @@
shelf_web_socket: ^1.0.0
sse: ^4.0.0
stream_channel: ^2.0.0
- usage: ^4.0.0
vm_service: ^7.0.0
web_socket_channel: ^2.0.0
diff --git a/pkg/nnbd_migration/lib/src/edge_origin.dart b/pkg/nnbd_migration/lib/src/edge_origin.dart
index ea9e4b1..91bb299 100644
--- a/pkg/nnbd_migration/lib/src/edge_origin.dart
+++ b/pkg/nnbd_migration/lib/src/edge_origin.dart
@@ -71,7 +71,7 @@
@override
String get description =>
- "annotated with an Angular annotation indicating nullability";
+ 'annotated with an Angular annotation indicating nullability';
@override
EdgeOriginKind get kind => EdgeOriginKind.angularAnnotation;
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 8386f5a..a196360 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -134,6 +134,7 @@
dds/test/dap/integration/*: Slow, Pass
[ $runtime != vm ]
+dart2js_info/test/*: SkipByDesign # Only meant to run on vm
dds/test/*: SkipByDesign # Only meant to run on vm
dev_compiler/test/options/*: SkipByDesign
front_end/test/hot_reload_e2e_test: Skip
diff --git a/runtime/bin/dartdev_isolate.cc b/runtime/bin/dartdev_isolate.cc
index 468ef64..62701b7 100644
--- a/runtime/bin/dartdev_isolate.cc
+++ b/runtime/bin/dartdev_isolate.cc
@@ -36,6 +36,7 @@
DartDevIsolate::DartDevRunner DartDevIsolate::runner_ =
DartDevIsolate::DartDevRunner();
bool DartDevIsolate::should_run_dart_dev_ = false;
+bool DartDevIsolate::print_usage_error_ = false;
Monitor* DartDevIsolate::DartDevRunner::monitor_ = new Monitor();
DartDevIsolate::DartDev_Result DartDevIsolate::DartDevRunner::result_ =
DartDevIsolate::DartDev_Result_Unknown;
@@ -98,6 +99,13 @@
package_config_override_ = packages_file;
script_ = script;
+ // We've encountered an error during preliminary argument parsing so we'll
+ // output the standard help message and exit with an error code.
+ if (print_usage_error_) {
+ dart_options_->Reset();
+ dart_options_->AddArgument("--help");
+ }
+
MonitorLocker locker(monitor_);
int result = Thread::Start("DartDev Runner", RunCallback,
reinterpret_cast<uword>(this));
@@ -170,7 +178,9 @@
// If we're given a non-zero exit code, DartDev is signaling for us to
// shutdown.
- Process::SetGlobalExitCode(dartdev_exit_code);
+ int32_t exit_code =
+ print_usage_error_ ? kErrorExitCode : dartdev_exit_code;
+ Process::SetGlobalExitCode(exit_code);
// If DartDev hasn't signaled for us to do anything else, we can assume
// there's nothing else for the VM to run and that we can exit.
diff --git a/runtime/bin/dartdev_isolate.h b/runtime/bin/dartdev_isolate.h
index a25664c..a6382f6 100644
--- a/runtime/bin/dartdev_isolate.h
+++ b/runtime/bin/dartdev_isolate.h
@@ -39,6 +39,11 @@
should_run_dart_dev_ = enable;
}
+ static void PrintUsageErrorOnRun() {
+ set_should_run_dart_dev(true);
+ print_usage_error_ = true;
+ }
+
static bool should_run_dart_dev() { return should_run_dart_dev_; }
// Attempts to find the path of the DartDev kernel file.
@@ -95,6 +100,7 @@
static DartDevRunner runner_;
static bool should_run_dart_dev_;
+ static bool print_usage_error_;
DISALLOW_ALLOCATION();
DISALLOW_IMPLICIT_CONSTRUCTORS(DartDevIsolate);
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index a288a79..234fa62 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -1157,6 +1157,8 @@
}
Platform::Exit(0);
} else {
+ // This usage error case will only be invoked when
+ // Options::disable_dart_dev() is false.
Options::PrintUsage();
Platform::Exit(kErrorExitCode);
}
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index a3fb4e1..44386ec 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -526,24 +526,40 @@
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
#if !defined(DART_PRECOMPILED_RUNTIME)
- else if (!Options::disable_dart_dev() && // NOLINT
- ((Options::help_option() && !Options::verbose_option()) ||
- (argc == 1))) {
- DartDevIsolate::set_should_run_dart_dev(true);
- // Let DartDev handle the default help message.
- dart_options->AddArgument("help");
- return true;
- } else if (!Options::disable_dart_dev() &&
- (enable_dartdev_analytics || disable_dartdev_analytics)) {
- // The analytics flags are a special case as we don't have a target script
- // or DartDev command but we still want to launch DartDev.
- DartDevIsolate::set_should_run_dart_dev(true);
- dart_options->AddArgument(enable_dartdev_analytics ? "--enable-analytics"
- : "--disable-analytics");
- return true;
+ else if (!Options::disable_dart_dev()) { // NOLINT
+ // Handles following invocation arguments:
+ // - dart help
+ // - dart --help
+ // - dart
+ if (((Options::help_option() && !Options::verbose_option()) ||
+ (argc == 1))) {
+ DartDevIsolate::set_should_run_dart_dev(true);
+ // Let DartDev handle the default help message.
+ dart_options->AddArgument("help");
+ return true;
+ }
+ // Handles cases where only analytics flags are provided. We need to start
+ // the DartDev isolate to set this state.
+ else if (enable_dartdev_analytics || disable_dartdev_analytics) { // NOLINT
+ // The analytics flags are a special case as we don't have a target script
+ // or DartDev command but we still want to launch DartDev.
+ DartDevIsolate::set_should_run_dart_dev(true);
+ dart_options->AddArgument(enable_dartdev_analytics
+ ? "--enable-analytics"
+ : "--disable-analytics");
+ return true;
+ }
+ // Let the VM handle '--version' and '--help --disable-dart-dev'.
+ // Otherwise, we'll launch the DartDev isolate to print its help message
+ // and set an error exit code.
+ else if (!Options::help_option() && !Options::version_option()) { // NOLINT
+ DartDevIsolate::PrintUsageErrorOnRun();
+ return true;
+ }
+ return false;
}
-
-#endif // !defined(DART_PRECOMPILED_RUNTIME)
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ // Handle argument parsing errors.
else { // NOLINT
return false;
}
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index 9513513..ccd8144 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -109,7 +109,8 @@
// vm/cc tests to randomly time out due to inability to shut service-isolate
// down.
// Issue(https://dartbug.com/37741):
- if (strcmp(run_filter, "DartAPI_InvokeVMServiceMethod") != 0) {
+ if ((strcmp(run_filter, "DartAPI_InvokeVMServiceMethod") != 0) &&
+ (strcmp(run_filter, "DartAPI_InvokeVMServiceMethod_Loop") != 0)) {
return nullptr;
}
diff --git a/runtime/tests/vm/dart/regress_46798_test.dart b/runtime/tests/vm/dart/regress_46798_test.dart
new file mode 100644
index 0000000..1e82ffc
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_46798_test.dart
@@ -0,0 +1,26 @@
+// 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/46798.
+// Verifies that compiler can handle LoadIndexed from AllocateObject.
+
+// VMOptions=--deterministic --optimization_counter_threshold=100
+
+import 'package:expect/expect.dart';
+
+bool foo(Object other) => other is String && other.codeUnitAt(0) == 5;
+
+int x = 0;
+
+void bar(bool cond) {
+ if (cond || foo(MapEntry<int, int>(1, 1))) {
+ ++x;
+ }
+}
+
+void main() {
+ for (int i = 0; i < 1000; ++i) foo('abc');
+ for (int i = 0; i < 1000; ++i) bar(false);
+ Expect.equals(0, x);
+}
diff --git a/runtime/tests/vm/dart_2/regress_46798_test.dart b/runtime/tests/vm/dart_2/regress_46798_test.dart
new file mode 100644
index 0000000..1c226d8
--- /dev/null
+++ b/runtime/tests/vm/dart_2/regress_46798_test.dart
@@ -0,0 +1,28 @@
+// 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
+
+// Regression test for https://github.com/dart-lang/sdk/issues/46798.
+// Verifies that compiler can handle LoadIndexed from AllocateObject.
+
+// VMOptions=--deterministic --optimization_counter_threshold=100
+
+import 'package:expect/expect.dart';
+
+bool foo(Object other) => other is String && other.codeUnitAt(0) == 5;
+
+int x = 0;
+
+void bar(bool cond) {
+ if (cond || foo(MapEntry<int, int>(1, 1))) {
+ ++x;
+ }
+}
+
+void main() {
+ for (int i = 0; i < 1000; ++i) foo('abc');
+ for (int i = 0; i < 1000; ++i) bar(false);
+ Expect.equals(0, x);
+}
diff --git a/runtime/vm/class_id.h b/runtime/vm/class_id.h
index eeb6d41..ac06355 100644
--- a/runtime/vm/class_id.h
+++ b/runtime/vm/class_id.h
@@ -244,7 +244,7 @@
// Class Id predicates.
-bool IsInternalOnlyId(intptr_t index);
+bool IsInternalOnlyClassId(intptr_t index);
bool IsErrorClassId(intptr_t index);
bool IsNumberClassId(intptr_t index);
bool IsIntegerClassId(intptr_t index);
@@ -272,18 +272,15 @@
COMPILE_ASSERT(kFirstInternalOnlyCid == kObjectCid + 1);
COMPILE_ASSERT(kInstanceCid == kLastInternalOnlyCid + 1);
-// Checks that the cids in CLASS_LIST_INTERNAL_ONLY come after kObjectCid.
-// Use with COMPILE_ASSERT where code assumes that Object immediately precedes
-// the other internal-only cids, so it can be adjusted if this changes.
-constexpr bool ObjectComesBeforeOtherInternalOnlyClasses() {
- return kFirstInternalOnlyCid == kObjectCid + 1;
-}
-
// Returns true for any class id that either does not correspond to a real
// class, like kIllegalCid or kForwardingCorpse, or that is internal to the VM
// and should not be exposed directly to user code.
-inline bool IsInternalOnlyId(intptr_t index) {
- COMPILE_ASSERT(ObjectComesBeforeOtherInternalOnlyClasses());
+inline bool IsInternalOnlyClassId(intptr_t index) {
+ // Fix the condition below if these become non-contiguous.
+ COMPILE_ASSERT(kIllegalCid + 1 == kFreeListElement &&
+ kIllegalCid + 2 == kForwardingCorpse &&
+ kIllegalCid + 3 == kObjectCid &&
+ kIllegalCid + 4 == kFirstInternalOnlyCid);
return index <= kLastInternalOnlyCid;
}
@@ -293,8 +290,9 @@
kLanguageErrorCid == kErrorCid + 2 &&
kUnhandledExceptionCid == kErrorCid + 3 &&
kUnwindErrorCid == kErrorCid + 4 &&
+ // Change if needed for detecting a new error added at the end.
kLastInternalOnlyCid == kUnwindErrorCid);
- return (index >= kErrorCid && index <= kLastInternalOnlyCid);
+ return (index >= kErrorCid && index <= kUnwindErrorCid);
}
inline bool IsNumberClassId(intptr_t index) {
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index d1f3df1..a1c58c0 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -39,7 +39,7 @@
calloc(capacity_, sizeof(RelaxedAtomic<intptr_t>)));
// The following cids don't have a corresponding class object in Dart code.
// We therefore need to initialize them eagerly.
- COMPILE_ASSERT(ObjectComesBeforeOtherInternalOnlyClasses());
+ COMPILE_ASSERT(kFirstInternalOnlyCid == kObjectCid + 1);
for (intptr_t i = kObjectCid; i <= kLastInternalOnlyCid; i++) {
table[i] = vm_shared_class_table->SizeAt(i);
}
@@ -106,7 +106,7 @@
static_cast<ClassPtr*>(calloc(capacity_, sizeof(ClassPtr)));
// The following cids don't have a corresponding class object in Dart code.
// We therefore need to initialize them eagerly.
- COMPILE_ASSERT(ObjectComesBeforeOtherInternalOnlyClasses());
+ COMPILE_ASSERT(kFirstInternalOnlyCid == kObjectCid + 1);
for (intptr_t i = kObjectCid; i <= kLastInternalOnlyCid; i++) {
table[i] = vm_class_table->At(i);
}
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index ad6fa8a..d85727d 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -2074,7 +2074,11 @@
slot = &store->slot();
} else if (use->instruction()->IsLoadIndexed() ||
use->instruction()->IsStoreIndexed()) {
- ASSERT(alloc->IsArrayAllocation());
+ if (!alloc->IsArrayAllocation()) {
+ // Non-array allocations can be accessed with LoadIndexed
+ // and StoreIndex in the unreachable code.
+ continue;
+ }
if (alloc->IsAllocateTypedData()) {
// Typed data payload elements are unboxed and initialized to
// zero, so don't forward a tagged null value.
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index f6650b2..42a9839 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -821,7 +821,7 @@
// VM-internal objects don't have a compile-type. Return dynamic-type
// in this case.
- if (IsInternalOnlyId(cid_) || cid_ == kTypeArgumentsCid) {
+ if (IsInternalOnlyClassId(cid_) || cid_ == kTypeArgumentsCid) {
type_ = &Object::dynamic_type();
return type_;
}
diff --git a/runtime/vm/compiler/cha.cc b/runtime/vm/compiler/cha.cc
index 2668918..06888b6 100644
--- a/runtime/vm/compiler/cha.cc
+++ b/runtime/vm/compiler/cha.cc
@@ -32,7 +32,7 @@
bool CHA::HasSubclasses(const Class& cls) {
ASSERT(!cls.IsNull());
- ASSERT(!IsInternalOnlyId(cls.id()));
+ ASSERT(!IsInternalOnlyClassId(cls.id()));
// Can't track dependencies for classes on the VM heap since those are
// read-only.
// TODO(fschneider): Enable tracking of CHA dependent code for VM heap
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index a3e59b2..6a4d13e 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -90,6 +90,91 @@
DISALLOW_COPY_AND_ASSIGN(ReadOnlyHandles);
};
+class DartInitializationState {
+ public:
+ enum class InitializationState {
+ kUnInitialized = 0,
+ kInitializing = 1,
+ kInitialized = 2,
+ kCleaningup = 3,
+ };
+
+ DartInitializationState()
+ : state_(InitializationState::kUnInitialized),
+ in_use_(false),
+ lock_(nullptr) {
+ lock_ = new Monitor();
+ }
+ ~DartInitializationState() {}
+
+ bool SetInitializing() {
+ MonitorLocker ml(lock_);
+ if (state_ != InitializationState::kUnInitialized || in_use_) {
+ return false;
+ }
+ state_ = InitializationState::kInitializing;
+ return true;
+ }
+
+ void ResetInitializing() {
+ MonitorLocker ml(lock_);
+ ASSERT((state_ == InitializationState::kInitializing) && !in_use_);
+ state_ = InitializationState::kUnInitialized;
+ }
+
+ void SetInitialized() {
+ MonitorLocker ml(lock_);
+ ASSERT((state_ == InitializationState::kInitializing) && !in_use_);
+ state_ = InitializationState::kInitialized;
+ }
+
+ bool IsInitialized() const {
+ MonitorLocker ml(lock_);
+ return (state_ == InitializationState::kInitialized);
+ }
+
+ bool SetCleaningup() {
+ MonitorLocker ml(lock_);
+ if (state_ != InitializationState::kInitialized) {
+ return false;
+ }
+ state_ = InitializationState::kCleaningup;
+ return true;
+ }
+
+ void SetUnInitialized() {
+ MonitorLocker ml(lock_);
+ ASSERT(state_ == InitializationState::kCleaningup);
+ while (in_use_) {
+ ml.Wait();
+ }
+ state_ = InitializationState::kUnInitialized;
+ }
+
+ bool SetInUse() {
+ MonitorLocker ml(lock_);
+ if (state_ != InitializationState::kInitialized) {
+ return false;
+ }
+ in_use_ = true;
+ return true;
+ }
+
+ void ResetInUse() {
+ MonitorLocker ml(lock_);
+ ASSERT((state_ == InitializationState::kInitialized) ||
+ (state_ == InitializationState::kCleaningup));
+ in_use_ = false;
+ ml.NotifyAll();
+ }
+
+ private:
+ InitializationState state_;
+ bool in_use_;
+ Monitor* lock_;
+};
+static DartInitializationState init_state_;
+
static void CheckOffsets() {
#if !defined(IS_SIMARM_X64)
// These offsets are embedded in precompiled instructions. We need the
@@ -180,26 +265,29 @@
#endif // !defined(IS_SIMARM_X64)
}
-char* Dart::Init(const uint8_t* vm_isolate_snapshot,
- const uint8_t* instructions_snapshot,
- Dart_IsolateGroupCreateCallback create_group,
- Dart_InitializeIsolateCallback initialize_isolate,
- Dart_IsolateShutdownCallback shutdown,
- Dart_IsolateCleanupCallback cleanup,
- Dart_IsolateGroupCleanupCallback cleanup_group,
- Dart_ThreadExitCallback thread_exit,
- Dart_FileOpenCallback file_open,
- Dart_FileReadCallback file_read,
- Dart_FileWriteCallback file_write,
- Dart_FileCloseCallback file_close,
- Dart_EntropySource entropy_source,
- Dart_GetVMServiceAssetsArchive get_service_assets,
- bool start_kernel_isolate,
- Dart_CodeObserver* observer) {
+char* Dart::DartInit(const uint8_t* vm_isolate_snapshot,
+ const uint8_t* instructions_snapshot,
+ Dart_IsolateGroupCreateCallback create_group,
+ Dart_InitializeIsolateCallback initialize_isolate,
+ Dart_IsolateShutdownCallback shutdown,
+ Dart_IsolateCleanupCallback cleanup,
+ Dart_IsolateGroupCleanupCallback cleanup_group,
+ Dart_ThreadExitCallback thread_exit,
+ Dart_FileOpenCallback file_open,
+ Dart_FileReadCallback file_read,
+ Dart_FileWriteCallback file_write,
+ Dart_FileCloseCallback file_close,
+ Dart_EntropySource entropy_source,
+ Dart_GetVMServiceAssetsArchive get_service_assets,
+ bool start_kernel_isolate,
+ Dart_CodeObserver* observer) {
CheckOffsets();
- // TODO(iposva): Fix race condition here.
- if (vm_isolate_ != NULL || !Flags::Initialized()) {
- return Utils::StrDup("VM already initialized or flags not initialized.");
+
+ if (!Flags::Initialized()) {
+ return Utils::StrDup("VM initialization failed-VM Flags not initialized.");
+ }
+ if (vm_isolate_ != NULL) {
+ return Utils::StrDup("VM initialization is in an inconsistent state.");
}
const Snapshot* snapshot = nullptr;
@@ -439,6 +527,41 @@
return NULL;
}
+char* Dart::Init(const uint8_t* vm_isolate_snapshot,
+ const uint8_t* instructions_snapshot,
+ Dart_IsolateGroupCreateCallback create_group,
+ Dart_InitializeIsolateCallback initialize_isolate,
+ Dart_IsolateShutdownCallback shutdown,
+ Dart_IsolateCleanupCallback cleanup,
+ Dart_IsolateGroupCleanupCallback cleanup_group,
+ Dart_ThreadExitCallback thread_exit,
+ Dart_FileOpenCallback file_open,
+ Dart_FileReadCallback file_read,
+ Dart_FileWriteCallback file_write,
+ Dart_FileCloseCallback file_close,
+ Dart_EntropySource entropy_source,
+ Dart_GetVMServiceAssetsArchive get_service_assets,
+ bool start_kernel_isolate,
+ Dart_CodeObserver* observer) {
+ if (!init_state_.SetInitializing()) {
+ return Utils::StrDup(
+ "Bad VM initialization state, "
+ "already initialized or "
+ "multiple threads initializing the VM.");
+ }
+ char* retval = DartInit(vm_isolate_snapshot, instructions_snapshot,
+ create_group, initialize_isolate, shutdown, cleanup,
+ cleanup_group, thread_exit, file_open, file_read,
+ file_write, file_close, entropy_source,
+ get_service_assets, start_kernel_isolate, observer);
+ if (retval != NULL) {
+ init_state_.ResetInitializing();
+ return retval;
+ }
+ init_state_.SetInitialized();
+ return NULL;
+}
+
static void DumpAliveIsolates(intptr_t num_attempts,
bool only_aplication_isolates) {
IsolateGroup::ForEach([&](IsolateGroup* group) {
@@ -501,9 +624,10 @@
char* Dart::Cleanup() {
ASSERT(Isolate::Current() == NULL);
- if (vm_isolate_ == NULL) {
+ if (!init_state_.SetCleaningup()) {
return Utils::StrDup("VM already terminated.");
}
+ ASSERT(vm_isolate_ != NULL);
if (FLAG_trace_shutdown) {
OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Starting shutdown\n",
@@ -592,6 +716,7 @@
OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleting thread pool\n",
UptimeMillis());
}
+ init_state_.SetUnInitialized();
thread_pool_->Shutdown();
delete thread_pool_;
thread_pool_ = NULL;
@@ -681,6 +806,18 @@
return NULL;
}
+bool Dart::IsInitialized() {
+ return init_state_.IsInitialized();
+}
+
+bool Dart::SetActiveApiCall() {
+ return init_state_.SetInUse();
+}
+
+void Dart::ResetActiveApiCall() {
+ init_state_.ResetInUse();
+}
+
Isolate* Dart::CreateIsolate(const char* name_prefix,
const Dart_IsolateFlags& api_flags,
IsolateGroup* isolate_group) {
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index b0776be..c22f1f0 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -9,6 +9,8 @@
#include "include/dart_tools_api.h"
#include "vm/allocation.h"
#include "vm/isolate.h"
+#include "vm/lockers.h"
+#include "vm/os_thread.h"
#include "vm/snapshot.h"
namespace dart {
@@ -48,6 +50,13 @@
// (caller owns error message and has to free it).
static char* Cleanup();
+ // Returns true if the VM is initialized.
+ static bool IsInitialized();
+
+ // Used to Indicate that a Dart API call is active.
+ static bool SetActiveApiCall();
+ static void ResetActiveApiCall();
+
static Isolate* CreateIsolate(const char* name_prefix,
const Dart_IsolateFlags& api_flags,
IsolateGroup* isolate_group);
@@ -149,6 +158,23 @@
static Dart_GCEventCallback gc_event_callback() { return gc_event_callback_; }
private:
+ static char* DartInit(const uint8_t* vm_snapshot_data,
+ const uint8_t* vm_snapshot_instructions,
+ Dart_IsolateGroupCreateCallback create_group,
+ Dart_InitializeIsolateCallback initialize_isolate,
+ Dart_IsolateShutdownCallback shutdown,
+ Dart_IsolateCleanupCallback cleanup,
+ Dart_IsolateGroupCleanupCallback cleanup_group,
+ Dart_ThreadExitCallback thread_exit,
+ Dart_FileOpenCallback file_open,
+ Dart_FileReadCallback file_read,
+ Dart_FileWriteCallback file_write,
+ Dart_FileCloseCallback file_close,
+ Dart_EntropySource entropy_source,
+ Dart_GetVMServiceAssetsArchive get_service_assets,
+ bool start_kernel_isolate,
+ Dart_CodeObserver* observer);
+
static constexpr const char* kVmIsolateName = "vm-isolate";
static void WaitForIsolateShutdown();
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 8acd172..00061db 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -6324,54 +6324,57 @@
if (type > Dart_Timeline_Event_Flow_End) {
return;
}
+ if (!Dart::SetActiveApiCall()) {
+ return;
+ }
TimelineStream* stream = Timeline::GetEmbedderStream();
ASSERT(stream != NULL);
TimelineEvent* event = stream->StartEvent();
- if (event == NULL) {
- return;
+ if (event != NULL) {
+ switch (type) {
+ case Dart_Timeline_Event_Begin:
+ event->Begin(label, timestamp0);
+ break;
+ case Dart_Timeline_Event_End:
+ event->End(label, timestamp0);
+ break;
+ case Dart_Timeline_Event_Instant:
+ event->Instant(label, timestamp0);
+ break;
+ case Dart_Timeline_Event_Duration:
+ event->Duration(label, timestamp0, timestamp1_or_async_id);
+ break;
+ case Dart_Timeline_Event_Async_Begin:
+ event->AsyncBegin(label, timestamp1_or_async_id, timestamp0);
+ break;
+ case Dart_Timeline_Event_Async_End:
+ event->AsyncEnd(label, timestamp1_or_async_id, timestamp0);
+ break;
+ case Dart_Timeline_Event_Async_Instant:
+ event->AsyncInstant(label, timestamp1_or_async_id, timestamp0);
+ break;
+ case Dart_Timeline_Event_Counter:
+ event->Counter(label, timestamp0);
+ break;
+ case Dart_Timeline_Event_Flow_Begin:
+ event->FlowBegin(label, timestamp1_or_async_id, timestamp0);
+ break;
+ case Dart_Timeline_Event_Flow_Step:
+ event->FlowStep(label, timestamp1_or_async_id, timestamp0);
+ break;
+ case Dart_Timeline_Event_Flow_End:
+ event->FlowEnd(label, timestamp1_or_async_id, timestamp0);
+ break;
+ default:
+ FATAL("Unknown Dart_Timeline_Event_Type");
+ }
+ event->SetNumArguments(argument_count);
+ for (intptr_t i = 0; i < argument_count; i++) {
+ event->CopyArgument(i, argument_names[i], argument_values[i]);
+ }
+ event->Complete();
}
- switch (type) {
- case Dart_Timeline_Event_Begin:
- event->Begin(label, timestamp0);
- break;
- case Dart_Timeline_Event_End:
- event->End(label, timestamp0);
- break;
- case Dart_Timeline_Event_Instant:
- event->Instant(label, timestamp0);
- break;
- case Dart_Timeline_Event_Duration:
- event->Duration(label, timestamp0, timestamp1_or_async_id);
- break;
- case Dart_Timeline_Event_Async_Begin:
- event->AsyncBegin(label, timestamp1_or_async_id, timestamp0);
- break;
- case Dart_Timeline_Event_Async_End:
- event->AsyncEnd(label, timestamp1_or_async_id, timestamp0);
- break;
- case Dart_Timeline_Event_Async_Instant:
- event->AsyncInstant(label, timestamp1_or_async_id, timestamp0);
- break;
- case Dart_Timeline_Event_Counter:
- event->Counter(label, timestamp0);
- break;
- case Dart_Timeline_Event_Flow_Begin:
- event->FlowBegin(label, timestamp1_or_async_id, timestamp0);
- break;
- case Dart_Timeline_Event_Flow_Step:
- event->FlowStep(label, timestamp1_or_async_id, timestamp0);
- break;
- case Dart_Timeline_Event_Flow_End:
- event->FlowEnd(label, timestamp1_or_async_id, timestamp0);
- break;
- default:
- FATAL("Unknown Dart_Timeline_Event_Type");
- }
- event->SetNumArguments(argument_count);
- for (intptr_t i = 0; i < argument_count; i++) {
- event->CopyArgument(i, argument_names[i], argument_values[i]);
- }
- event->Complete();
+ Dart::ResetActiveApiCall();
#endif
}
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index 59ce2aa..bd5d3e9 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -212,7 +212,7 @@
// Returns true if the handle holds a Dart Instance.
static bool IsInstance(Dart_Handle handle) {
- return !IsInternalOnlyId(ClassId(handle));
+ return !IsInternalOnlyClassId(ClassId(handle));
}
// Returns true if the handle is non-dangling.
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index b61e6c2..5b0bc2b 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -24,6 +24,7 @@
namespace dart {
DECLARE_FLAG(bool, verify_acquired_data);
+DECLARE_FLAG(bool, complete_timeline);
#ifndef PRODUCT
@@ -9305,13 +9306,13 @@
TEST_CASE(DartAPI_InvokeVMServiceMethod) {
char buffer[1024];
- snprintf(buffer, sizeof(buffer),
- R"({
- "jsonrpc": 2.0,
- "id": "foo",
- "method": "getVM",
- "params": { }
- })");
+ Utils::SNPrint(buffer, sizeof(buffer),
+ R"({
+ "jsonrpc": 2.0,
+ "id": "foo",
+ "method": "getVM",
+ "params": { }
+ })");
uint8_t* response_json = nullptr;
intptr_t response_json_length = 0;
char* error = nullptr;
@@ -9361,6 +9362,151 @@
EXPECT(result == Dart_True());
}
+static Monitor* loop_test_lock = new Monitor();
+static bool loop_test_exit = false;
+static bool loop_reset_count = false;
+
+#if !defined(PRODUCT)
+static void InvokeServiceMessages(uword param) {
+ char buffer[1024];
+ Utils::SNPrint(buffer, sizeof(buffer),
+ R"({
+ "jsonrpc": 2.0,
+ "id": "foo",
+ "method": "getVM",
+ "params": { }
+ })");
+ uint8_t* response_json = nullptr;
+ intptr_t response_json_length = 0;
+ char* error = nullptr;
+ uint32_t count = 0;
+ do {
+ error = nullptr;
+ response_json = nullptr;
+ response_json_length = 0;
+ const bool success = Dart_InvokeVMServiceMethod(
+ reinterpret_cast<uint8_t*>(buffer), strlen(buffer), &response_json,
+ &response_json_length, &error);
+ if (success) {
+ MonitorLocker ml(loop_test_lock);
+ EXPECT(error == nullptr);
+ free(response_json);
+ if (count == 10) {
+ loop_test_exit = true;
+ ml.Notify();
+ }
+ count++;
+ }
+ } while (count < 100);
+ free(error);
+}
+
+TEST_CASE(DartAPI_InvokeVMServiceMethod_Loop) {
+ MonitorLocker ml(loop_test_lock);
+ loop_test_exit = false;
+ loop_reset_count = false;
+ OSThread::Start("InvokeServiceMessages", InvokeServiceMessages, 0);
+ while (!loop_test_exit) {
+ ml.Wait();
+ }
+}
+#endif // !defined(PRODUCT)
+
+static void HandleResponse(Dart_Port dest_port_id, Dart_CObject* message) {
+ printf("Response received\n");
+}
+
+static void CreateNativePorts(uword param) {
+ uint32_t count = 0;
+ do {
+ const Dart_Port port_id = Dart_NewNativePort("tst", &HandleResponse, false);
+ if (port_id != ILLEGAL_PORT) {
+ Dart_CloseNativePort(port_id);
+ MonitorLocker ml(loop_test_lock);
+ if (count == 10) {
+ loop_test_exit = true;
+ ml.Notify();
+ }
+ count++;
+ }
+ } while (count < 100);
+}
+
+TEST_CASE(DartAPI_NativePort_Loop) {
+ MonitorLocker ml(loop_test_lock);
+ loop_test_exit = false;
+ loop_reset_count = false;
+ OSThread::Start("NativePort", CreateNativePorts, 0);
+ while (!loop_test_exit) {
+ ml.Wait();
+ }
+}
+
+#if !defined(PRODUCT)
+static void CreateTimelineEvents(uword param) {
+ {
+ MonitorLocker ml(loop_test_lock);
+ loop_test_exit = true;
+ ml.Notify();
+ }
+ do {
+ Dart_TimelineEvent("T1", 0, 1, Dart_Timeline_Event_Begin, 0, NULL, NULL);
+ Dart_TimelineEvent("T1", 0, 9, Dart_Timeline_Event_End, 0, NULL, NULL);
+ Dart_TimelineEvent("T2", 0, 1, Dart_Timeline_Event_Instant, 0, NULL, NULL);
+ Dart_TimelineEvent("T3", 0, 2, Dart_Timeline_Event_Duration, 0, NULL, NULL);
+ Dart_TimelineEvent("T4", 0, 3, Dart_Timeline_Event_Async_Begin, 0, NULL,
+ NULL);
+ Dart_TimelineEvent("T4", 9, 3, Dart_Timeline_Event_Async_End, 0, NULL,
+ NULL);
+ Dart_TimelineEvent("T5", 1, 4, Dart_Timeline_Event_Async_Instant, 0, NULL,
+ NULL);
+ Dart_TimelineEvent("T7", 1, 4, Dart_Timeline_Event_Counter, 0, NULL, NULL);
+ Dart_TimelineEvent("T8", 1, 4, Dart_Timeline_Event_Flow_Begin, 0, NULL,
+ NULL);
+ Dart_TimelineEvent("T8", 1, 4, Dart_Timeline_Event_Flow_Step, 0, NULL,
+ NULL);
+ Dart_TimelineEvent("T8", 1, 4, Dart_Timeline_Event_Flow_End, 0, NULL, NULL);
+ } while (true);
+}
+
+UNIT_TEST_CASE(DartAPI_TimelineEvents_Loop) {
+ EXPECT(Dart_SetVMFlags(TesterState::argc, TesterState::argv) == nullptr);
+ FLAG_complete_timeline = true;
+ Dart_InitializeParams params;
+ memset(¶ms, 0, sizeof(Dart_InitializeParams));
+ params.version = DART_INITIALIZE_PARAMS_CURRENT_VERSION;
+ params.vm_snapshot_data = TesterState::vm_snapshot_data;
+ params.create_group = TesterState::create_callback;
+ params.shutdown_isolate = TesterState::shutdown_callback;
+ params.cleanup_group = TesterState::group_cleanup_callback;
+ params.start_kernel_isolate = true;
+ char* result = nullptr;
+
+ result = Dart_Initialize(¶ms);
+ EXPECT(result == nullptr);
+ {
+ MonitorLocker ml(loop_test_lock);
+ loop_test_exit = false;
+ loop_reset_count = false;
+ OSThread::Start("TimelineEvents", CreateTimelineEvents, 0);
+ while (!loop_test_exit) {
+ printf("VM waiting for notification\n");
+ ml.Wait();
+ }
+ loop_test_exit = false;
+ }
+ result = Dart_Cleanup();
+ EXPECT(result == nullptr);
+ for (intptr_t i = 0; i < 50; i++) {
+ EXPECT(Dart_SetVMFlags(TesterState::argc, TesterState::argv) == nullptr);
+ result = Dart_Initialize(¶ms);
+ EXPECT(result == nullptr);
+ result = Dart_Cleanup();
+ EXPECT(result == nullptr);
+ }
+}
+#endif // !defined(PRODUCT)
+
static intptr_t EchoInt(double x) {
return x;
}
diff --git a/runtime/vm/heap/verifier.cc b/runtime/vm/heap/verifier.cc
index 095fc6f..71ea299 100644
--- a/runtime/vm/heap/verifier.cc
+++ b/runtime/vm/heap/verifier.cc
@@ -117,7 +117,7 @@
// Therefore we disable the handle verification here.
const bool old_verify_flag = FLAG_verify_handles;
FLAG_verify_handles = false;
- if (!IsInternalOnlyId(obj->GetClassId()) &&
+ if (!IsInternalOnlyClassId(obj->GetClassId()) &&
(obj->GetClassId() != kTypeArgumentsCid)) {
if (obj->untag()->IsCanonical()) {
instanceHandle_ ^= obj;
diff --git a/runtime/vm/native_api_impl.cc b/runtime/vm/native_api_impl.cc
index 132ac95..07a2fec 100644
--- a/runtime/vm/native_api_impl.cc
+++ b/runtime/vm/native_api_impl.cc
@@ -82,6 +82,9 @@
CURRENT_FUNC);
return ILLEGAL_PORT;
}
+ if (!Dart::SetActiveApiCall()) {
+ return ILLEGAL_PORT;
+ }
// Start the native port without a current isolate.
IsolateLeaveScope saver(Isolate::Current());
@@ -89,6 +92,7 @@
Dart_Port port_id = PortMap::CreatePort(nmh);
PortMap::SetPortState(port_id, PortMap::kLivePort);
nmh->Run(Dart::thread_pool(), NULL, NULL, 0);
+ Dart::ResetActiveApiCall();
return port_id;
}
@@ -112,6 +116,11 @@
ASSERT(isolate == nullptr || !isolate->is_service_isolate());
IsolateLeaveScope saver(isolate);
+ if (!Dart::IsInitialized()) {
+ *error = ::dart::Utils::StrDup("VM Service is not active.");
+ return false;
+ }
+
// We only allow one isolate reload at a time. If this turns out to be on the
// critical path, we can change it to have a global datastructure which is
// mapping the reply ports to receive buffers.
@@ -155,9 +164,21 @@
if (ServiceIsolate::SendServiceRpc(request_json, request_json_length, port,
error)) {
// We posted successfully and expect the vm-service to send the reply, so
- // we will wait for it now.
- auto wait_result = monitor.Wait();
- ASSERT(wait_result == Monitor::kNotified);
+ // we will wait for it now. Since the service isolate could have shutdown
+ // after we sent the message we make sure to wake up periodically and
+ // check to see if the service isolate has shutdown.
+ do {
+ auto wait_result = monitor.Wait(1000); /* milliseconds */
+ if (wait_result == Monitor::kNotified) {
+ break;
+ }
+ if (!ServiceIsolate::IsRunning()) {
+ // Service Isolate has shutdown while we were waiting for a reply,
+ // We will not get a reply anymore, cleanup and return an error.
+ Dart_CloseNativePort(port);
+ return false;
+ }
+ } while (true);
// The caller takes ownership of the data.
*response_json = result_bytes;
@@ -235,7 +256,10 @@
DART_EXPORT void* Dart_ExecuteInternalCommand(const char* command, void* arg) {
if (strcmp(command, "gc-on-nth-allocation") == 0) {
- TransitionNativeToVM _(Thread::Current());
+ Thread* const thread = Thread::Current();
+ Isolate* isolate = (thread == NULL) ? NULL : thread->isolate();
+ CHECK_ISOLATE(isolate);
+ TransitionNativeToVM _(thread);
intptr_t argument = reinterpret_cast<intptr_t>(arg);
ASSERT(argument > 0);
IsolateGroup::Current()->heap()->CollectOnNthAllocation(argument);
@@ -243,7 +267,10 @@
} else if (strcmp(command, "gc-now") == 0) {
ASSERT(arg == nullptr); // Don't pass an argument to this command.
- TransitionNativeToVM _(Thread::Current());
+ Thread* const thread = Thread::Current();
+ Isolate* isolate = (thread == NULL) ? NULL : thread->isolate();
+ CHECK_ISOLATE(isolate);
+ TransitionNativeToVM _(thread);
IsolateGroup::Current()->heap()->CollectAllGarbage();
return nullptr;
@@ -255,6 +282,7 @@
} else if (strcmp(command, "is-mutator-in-native") == 0) {
Isolate* const isolate = reinterpret_cast<Isolate*>(arg);
+ CHECK_ISOLATE(isolate);
if (isolate->mutator_thread()->execution_state_cross_thread_for_testing() ==
Thread::kThreadInNative) {
return arg;
@@ -265,7 +293,9 @@
} else if (strcmp(command, "run-in-safepoint-and-rw-code") == 0) {
const RunInSafepointAndRWCodeArgs* const args =
reinterpret_cast<RunInSafepointAndRWCodeArgs*>(arg);
- Thread::EnterIsolateAsHelper(args->isolate, Thread::TaskKind::kUnknownTask);
+ Isolate* const isolate = args->isolate;
+ CHECK_ISOLATE(isolate);
+ Thread::EnterIsolateAsHelper(isolate, Thread::TaskKind::kUnknownTask);
Thread* const thread = Thread::Current();
{
GcSafepointOperationScope scope(thread);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 50cd146..a716109 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -2952,7 +2952,7 @@
result.set_num_type_arguments_unsafe(0);
result.set_num_native_fields(0);
result.set_state_bits(0);
- if (IsInternalOnlyId(FakeObject::kClassId) ||
+ if (IsInternalOnlyClassId(FakeObject::kClassId) ||
(FakeObject::kClassId == kTypeArgumentsCid)) {
// VM internal classes are done. There is no finalization needed or
// possible in this case.
@@ -4465,7 +4465,7 @@
const Array& arguments,
const TypeArguments& type_arguments) const {
ASSERT(Thread::Current()->IsMutatorThread());
- if (IsInternalOnlyId(id()) || (id() == kTypeArgumentsCid)) {
+ if (IsInternalOnlyClassId(id()) || (id() == kTypeArgumentsCid)) {
const Instance& exception = Instance::Handle(String::New(
"Expressions can be evaluated only with regular Dart instances"));
const Instance& stacktrace = Instance::Handle();
diff --git a/runtime/vm/object_graph.cc b/runtime/vm/object_graph.cc
index f169091..40e55a83 100644
--- a/runtime/vm/object_graph.cc
+++ b/runtime/vm/object_graph.cc
@@ -24,7 +24,7 @@
static bool IsUserClass(intptr_t cid) {
if (cid == kContextCid) return true;
if (cid == kTypeArgumentsCid) return false;
- return !IsInternalOnlyId(cid);
+ return !IsInternalOnlyClassId(cid);
}
// The state of a pre-order, depth-first traversal of an object graph.
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 71e0b48..6112fa7 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -2786,7 +2786,7 @@
isStatic = false;
}
if (!cls.IsTopLevel() &&
- (IsInternalOnlyId(cls.id()) || cls.id() == kTypeArgumentsCid)) {
+ (IsInternalOnlyClassId(cls.id()) || cls.id() == kTypeArgumentsCid)) {
js->PrintError(
kInvalidParams,
"Expressions can be evaluated only with regular Dart instances");
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index acc453f..418aa3a 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -188,11 +188,14 @@
request.value.as_array.length = ARRAY_SIZE(request_array);
ServiceIsolate::WaitForServiceIsolateStartup();
Dart_Port service_port = ServiceIsolate::Port();
-
- const bool success = Dart_PostCObject(service_port, &request);
-
- if (!success && error != nullptr) {
- if (service_port == ILLEGAL_PORT) {
+ bool success = false;
+ if (service_port != ILLEGAL_PORT) {
+ success = Dart_PostCObject(service_port, &request);
+ if (!success && error != nullptr) {
+ *error = Utils::StrDup("Was unable to post message to service isolate.");
+ }
+ } else {
+ if (error != nullptr) {
if (startup_failure_reason_ != nullptr) {
*error = OS::SCreate(/*zone=*/nullptr,
"Service isolate failed to start up: %s.",
@@ -200,11 +203,8 @@
} else {
*error = Utils::StrDup("No service isolate port was found.");
}
- } else {
- *error = Utils::StrDup("Was unable to post message to service isolate.");
}
}
-
return success;
}
@@ -318,6 +318,8 @@
MonitorLocker ml(monitor_);
ASSERT(state_ == kStarted || state_ == kStopping);
state_ = kStopped;
+ port_ = ILLEGAL_PORT;
+ isolate_ = nullptr;
ml.NotifyAll();
}
@@ -332,6 +334,7 @@
MonitorLocker ml(monitor_);
ASSERT(state_ == kStarting);
state_ = kStopped;
+ port_ = ILLEGAL_PORT;
startup_failure_reason_ = error;
ml.NotifyAll();
}
diff --git a/runtime/vm/tagged_pointer.h b/runtime/vm/tagged_pointer.h
index 4265b03..19444ff 100644
--- a/runtime/vm/tagged_pointer.h
+++ b/runtime/vm/tagged_pointer.h
@@ -109,7 +109,7 @@
bool IsStringInstance() const { return IsStringClassId(GetClassId()); }
bool IsRawNull() const { return GetClassId() == kNullCid; }
bool IsDartInstance() const {
- return (!IsHeapObject() || !IsInternalOnlyId(GetClassId()));
+ return (!IsHeapObject() || !IsInternalOnlyClassId(GetClassId()));
}
bool IsFreeListElement() const {
return ((GetClassId() == kFreeListElement));
diff --git a/tools/VERSION b/tools/VERSION
index 61d8e8a..f6002f4 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 15
+PRERELEASE 16
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index a3a6e36..9e2fefe 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -3341,6 +3341,15 @@
]
},
{
+ "name": "analyze pkg/nnbd_migration",
+ "script": "out/ReleaseX64/dart-sdk/bin/dart",
+ "arguments": [
+ "analyze",
+ "--fatal-infos",
+ "pkg/nnbd_migration"
+ ]
+ },
+ {
"name": "analyze pkg/smith",
"script": "out/ReleaseX64/dart-sdk/bin/dart",
"arguments": [
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index c8ff6b3..20a25ed 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -2002,7 +2002,7 @@
' $RENAME$METADATA$MODIFIERS$TYPE $NAME($PARAMS) => '\
'js_util.callMethod(this, \'$JSNAME\', [$ARGS]);\n'
if CanUseStaticExtensions(self._interface_name, self._generate_static_extensions) else
- ' $RENAME$METADATA$MODIFIERS$TYPE $NAME($PARAMS) native;\n',
+ '\n $RENAME$METADATA$MODIFIERS$TYPE $NAME($PARAMS) native;\n',
RENAME=self._RenamingAnnotation(info.declared_name, html_name),
METADATA=self._Metadata(
info.type_name, info.declared_name,
diff --git a/tools/dom/templates/dart2js_static_extension_impl.darttemplate b/tools/dom/templates/dart2js_static_extension_impl.darttemplate
index e2b3c61..5501eee 100644
--- a/tools/dom/templates/dart2js_static_extension_impl.darttemplate
+++ b/tools/dom/templates/dart2js_static_extension_impl.darttemplate
@@ -1,10 +1,11 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// 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.
part of $LIBRARYNAME;
-$(ANNOTATIONS)@sealed$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$MIXINS$IMPLEMENTS { $!CLASSMEMBERS }
+//todo: add @sealed annotation
+$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$MIXINS$IMPLEMENTS { $!CLASSMEMBERS }
extension $(CLASSNAME)Extension on $CLASSNAME {
$!EXTENSIONMEMBERS
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index 1559461..d1e9e6b 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -52,6 +52,7 @@
getNativeInterceptor,
setDispatchProperty;
import 'dart:_foreign_helper' show JS, JS_INTERCEPTOR_CONSTANT;
+import 'dart:js_util' as js_util;
export 'dart:_internal' show HttpStatus;
export 'dart:html_common' show promiseToFuture;
diff --git a/tools/generate_package_config.dart b/tools/generate_package_config.dart
index 1664201..882c827 100644
--- a/tools/generate_package_config.dart
+++ b/tools/generate_package_config.dart
@@ -62,8 +62,6 @@
packageDirectory('third_party/pkg/webdev/frontend_server_client'),
packageDirectory('tools/package_deps'),
];
- // TODO(sigmund): remove this when dart2js_info's new location is used.
- packageDirs.remove(packageDirectory(p.join('pkg', 'dart2js_info')));
var cfePackageDirs = [
packageDirectory('pkg/front_end/testcases/'),