Version 2.16.0-24.0.dev
Merge commit '3d1f6a48b79e2cc5a4ee9d2ea3a7a385a3b33eaa' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 98ff8fb..686137d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -1783,6 +1783,11 @@
void _removePotentiallyAffectedLibraries(String path) {
var affected = <FileState>{};
_fsState.collectAffected(path, affected);
+
+ for (var file in affected) {
+ file.invalidateLibraryCycle();
+ }
+
_libraryContext?.elementFactory.removeLibraries(
affected.map((e) => e.uriStr).toSet(),
);
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 433d6e3..a275ba2 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -352,6 +352,11 @@
_libraryCycle = cycle;
}
+ void invalidateLibraryCycle() {
+ _libraryCycle?.invalidate();
+ _libraryCycle = null;
+ }
+
/// Return a new parsed unresolved [CompilationUnit].
CompilationUnitImpl parse([AnalysisErrorListener? errorListener]) {
errorListener ??= AnalysisErrorListener.NULL_LISTENER;
@@ -765,6 +770,20 @@
/// Collected files that transitively reference a file with the [path].
/// These files are potentially affected by the change.
void collectAffected(String path, Set<FileState> affected) {
+ // TODO(scheglov) This should not be necessary.
+ // We use affected files to remove library elements, and we can only get
+ // these library elements when we link or load them, using library cycles.
+ // And we get library cycles by asking `directReferencedFiles`.
+ while (true) {
+ final knownFiles = this.knownFiles.toList();
+ for (var file in knownFiles.toList()) {
+ file.directReferencedFiles;
+ }
+ if (this.knownFiles.length == knownFiles.length) {
+ break;
+ }
+ }
+
collectAffected(FileState file) {
if (affected.add(file)) {
for (var other in file.referencingFiles) {
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index ae463a8..d8985b7 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -93,7 +93,7 @@
int get enabledConstructorTearOffLowerings => ConstructorTearOffLowering.all;
@override
- List<String> get extraRequiredLibraries => _requiredLibraries[name]!;
+ List<String> get extraRequiredLibraries => requiredLibraries[name]!;
@override
List<String> get extraIndexedLibraries => const [
@@ -222,49 +222,86 @@
// TODO(sigmund): this "extraRequiredLibraries" needs to be removed...
// compile-platform should just specify which libraries to compile instead.
-const _requiredLibraries = <String, List<String>>{
+const requiredLibraries = <String, List<String>>{
'dart2js': [
+ 'dart:_async_await_error_codes',
'dart:_dart2js_runtime_metrics',
'dart:_foreign_helper',
+ 'dart:_http',
'dart:_interceptors',
'dart:_internal',
+ 'dart:_js',
'dart:_js_annotations',
'dart:_js_embedded_names',
'dart:_js_helper',
'dart:_js_names',
+ 'dart:_js_primitives',
'dart:_late_helper',
+ 'dart:_metadata',
'dart:_native_typed_data',
+ 'dart:_recipe_syntax',
+ 'dart:_rti',
'dart:async',
'dart:collection',
+ 'dart:convert',
+ 'dart:developer',
'dart:html',
'dart:html_common',
'dart:indexed_db',
'dart:io',
+ 'dart:isolate',
'dart:js',
'dart:js_util',
+ 'dart:math',
'dart:svg',
+ 'dart:typed_data',
'dart:web_audio',
'dart:web_gl',
],
'dart2js_server': [
+ 'dart:_async_await_error_codes',
'dart:_dart2js_runtime_metrics',
'dart:_foreign_helper',
+ 'dart:_http',
'dart:_interceptors',
'dart:_internal',
+ 'dart:_js',
'dart:_js_annotations',
'dart:_js_embedded_names',
'dart:_js_helper',
'dart:_js_names',
+ 'dart:_js_primitives',
'dart:_late_helper',
'dart:_native_typed_data',
+ 'dart:_recipe_syntax',
+ 'dart:_rti',
'dart:async',
'dart:collection',
+ 'dart:convert',
+ 'dart:developer',
'dart:io',
+ 'dart:isolate',
'dart:js',
'dart:js_util',
+ 'dart:math',
+ 'dart:typed_data',
]
};
+/// Extends the Dart2jsTarget to transform outlines to meet the requirements
+/// of summaries in bazel and package-build.
+class Dart2jsSummaryTarget extends Dart2jsTarget with SummaryMixin {
+ @override
+ final List<Uri> sources;
+
+ @override
+ final bool excludeNonSources;
+
+ Dart2jsSummaryTarget(String name, this.sources, this.excludeNonSources,
+ TargetFlags targetFlags)
+ : super(name, targetFlags);
+}
+
class Dart2jsConstantsBackend extends ConstantsBackend {
@override
final bool supportsUnevaluatedConstants;
diff --git a/pkg/compiler/tool/modular_test_suite.dart b/pkg/compiler/tool/modular_test_suite.dart
index 6195548..1593208 100644
--- a/pkg/compiler/tool/modular_test_suite.dart
+++ b/pkg/compiler/tool/modular_test_suite.dart
@@ -9,6 +9,7 @@
import 'dart:async';
import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/kernel/dart2js_target.dart';
import 'package:front_end/src/compute_platform_binaries_location.dart'
show computePlatformBinariesLocation;
import 'package:modular_test/src/io_pipeline.dart';
@@ -32,36 +33,26 @@
_packageConfig = await loadPackageConfigUri(packageConfigUri);
await _resolveScripts();
await Future.wait([
+ // TODO(joshualitt): Factor modular steps into a library so we can test
+ // modular analysis alongside the existing pipeline.
runSuite(
sdkRoot.resolve('tests/modular/'),
'tests/modular',
_options,
IOPipeline([
- SourceToDillStep(),
- ModularAnalysisStep(),
- ComputeClosedWorldStep(useModularAnalysis: true),
+ OutlineDillCompilationStep(),
+ FullDillCompilationStep(),
+ ComputeClosedWorldStep(useModularAnalysis: false),
GlobalAnalysisStep(),
Dart2jsCodegenStep(codeId0),
Dart2jsCodegenStep(codeId1),
Dart2jsEmissionStep(),
RunD8(),
], cacheSharedModules: true)),
- runSuite(
- sdkRoot.resolve('tests/modular/'),
- 'tests/modular',
- _options,
- IOPipeline([
- SourceToDillStep(),
- ComputeClosedWorldStep(useModularAnalysis: false),
- LegacyGlobalAnalysisStep(),
- LegacyDart2jsCodegenStep(codeId0),
- LegacyDart2jsCodegenStep(codeId1),
- LegacyDart2jsEmissionStep(),
- RunD8(),
- ], cacheSharedModules: true))
]);
}
+const dillSummaryId = DataId("sdill");
const dillId = DataId("dill");
const modularUpdatedDillId = DataId("mdill");
const modularDataId = DataId("mdata");
@@ -86,27 +77,21 @@
return '{${fields.join(',')}}';
}
-// Step that compiles sources in a module to a .dill file.
-class SourceToDillStep implements IOModularStep {
- @override
- List<DataId> get resultData => const [dillId];
+abstract class CFEStep implements IOModularStep {
+ final String stepName;
+
+ CFEStep(this.stepName);
@override
bool get needsSources => true;
@override
- List<DataId> get dependencyDataNeeded => const [dillId];
-
- @override
- List<DataId> get moduleDataNeeded => const [];
-
- @override
bool get onlyOnMain => false;
@override
Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
List<String> flags) async {
- if (_options.verbose) print("\nstep: source-to-dill on $module");
+ if (_options.verbose) print("\nstep: $stepName on $module");
// We use non file-URI schemes for representeing source locations in a
// root-agnostic way. This allows us to refer to file across modules and
@@ -181,44 +166,45 @@
.writeAsString('$packagesContents');
List<String> sources;
- List<String> extraArgs;
+ List<String> extraArgs = ['--packages-file', '$rootScheme:/.packages'];
if (module.isSdk) {
// When no flags are passed, we can skip compilation and reuse the
// platform.dill created by build.py.
if (flags.isEmpty) {
var platform = computePlatformBinariesLocation()
.resolve("dart2js_platform_unsound.dill");
- var destination = root.resolveUri(toUri(module, dillId));
+ var destination = root.resolveUri(toUri(module, outputData));
if (_options.verbose) {
print('command:\ncp $platform $destination');
}
await File.fromUri(platform).copy(destination.toFilePath());
return;
}
- sources = ['dart:core'];
- extraArgs = ['--libraries-file', '$rootScheme:///sdk/lib/libraries.json'];
+ sources = requiredLibraries['dart2js'] + ['dart:core'];
+ extraArgs += [
+ '--libraries-file',
+ '$rootScheme:///sdk/lib/libraries.json'
+ ];
assert(transitiveDependencies.isEmpty);
} else {
sources = module.sources.map(sourceToImportUri).toList();
- extraArgs = ['--packages-file', '$rootScheme:/.packages'];
}
// TODO(joshualitt): Ensure the kernel worker has some way to specify
// --no-sound-null-safety
List<String> args = [
_kernelWorkerScript,
- '--no-summary-only',
- '--target',
- 'dart2js',
+ ...stepArguments,
+ '--exclude-non-sources',
'--multi-root',
'$root',
'--multi-root-scheme',
rootScheme,
...extraArgs,
'--output',
- '${toUri(module, dillId)}',
+ '${toUri(module, outputData)}',
...(transitiveDependencies
- .expand((m) => ['--input-linked', '${toUri(m, dillId)}'])),
+ .expand((m) => ['--input-summary', '${toUri(m, inputData)}'])),
...(sources.expand((String uri) => ['--source', uri])),
...(flags.expand((String flag) => ['--enable-experiment', flag])),
];
@@ -228,12 +214,73 @@
_checkExitCode(result, this, module);
}
+ List<String> get stepArguments;
+
+ DataId get inputData;
+
+ DataId get outputData;
+
@override
void notifyCached(Module module) {
- if (_options.verbose) print("\ncached step: source-to-dill on $module");
+ if (_options.verbose) print("\ncached step: $stepName on $module");
}
}
+// Step that compiles sources in a module to a summary .dill file.
+class OutlineDillCompilationStep extends CFEStep {
+ @override
+ List<DataId> get resultData => const [dillSummaryId];
+
+ @override
+ bool get needsSources => true;
+
+ @override
+ List<DataId> get dependencyDataNeeded => const [dillSummaryId];
+
+ @override
+ List<DataId> get moduleDataNeeded => const [];
+
+ @override
+ List<String> get stepArguments =>
+ ['--target', 'dart2js_summary', '--summary-only'];
+
+ @override
+ DataId get inputData => dillSummaryId;
+
+ @override
+ DataId get outputData => dillSummaryId;
+
+ OutlineDillCompilationStep() : super('outline-dill-compilation');
+}
+
+// Step that compiles sources in a module to a .dill file.
+class FullDillCompilationStep extends CFEStep {
+ @override
+ List<DataId> get resultData => const [dillId];
+
+ @override
+ bool get needsSources => true;
+
+ @override
+ List<DataId> get dependencyDataNeeded => const [dillSummaryId];
+
+ @override
+ List<DataId> get moduleDataNeeded => const [];
+
+ // TODO(joshualitt): we need a --no-summary argument to cfe.
+ @override
+ List<String> get stepArguments =>
+ ['--target', 'dart2js', '--no-summary-only'];
+
+ @override
+ DataId get inputData => dillSummaryId;
+
+ @override
+ DataId get outputData => dillId;
+
+ FullDillCompilationStep() : super('full-dill-compilation');
+}
+
class ModularAnalysisStep implements IOModularStep {
@override
List<DataId> get resultData => const [modularDataId, modularUpdatedDillId];
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 5746a68..99bfae9 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -329,6 +329,7 @@
destination
destinations
destroy
+destructive
deterministic
dev
device
@@ -620,6 +621,7 @@
int64
int8
integrate
+intends
intentionally
interested
interim
diff --git a/pkg/frontend_server/lib/compute_kernel.dart b/pkg/frontend_server/lib/compute_kernel.dart
index a75573e..9b60711 100644
--- a/pkg/frontend_server/lib/compute_kernel.dart
+++ b/pkg/frontend_server/lib/compute_kernel.dart
@@ -62,6 +62,7 @@
'flutter',
'flutter_runner',
'dart2js',
+ 'dart2js_summary',
'ddc',
],
help: 'Build kernel for the vm, flutter, flutter_runner, dart2js or ddc')
@@ -174,6 +175,14 @@
'error: --summary-only not supported for the dart2js target');
}
break;
+ case 'dart2js_summary':
+ target = new Dart2jsSummaryTarget(
+ 'dart2js', sources, excludeNonSources, targetFlags);
+ if (!summaryOnly) {
+ out.writeln(
+ 'error: --no-summary-only not supported for the dart2js summary target');
+ }
+ break;
case 'ddc':
// TODO(jakemac):If `generateKernel` changes to return a summary
// component, process the component instead.
@@ -358,47 +367,13 @@
}
}
-/// Extends the DevCompilerTarget to transform outlines to meet the requirements
-/// of summaries in bazel and package-build.
-///
-/// Build systems like package-build may provide the same input file twice to
-/// the summary worker, but only intends to have it in one output summary. The
-/// convention is that if it is listed as a source, it is intended to be part of
-/// the output, if the source file was loaded as a dependency, then it was
-/// already included in a different summary. The transformation below ensures
-/// that the output summary doesn't include those implicit inputs.
-///
-/// Note: this transformation is destructive and is only intended to be used
-/// when generating summaries.
-class DevCompilerSummaryTarget extends DevCompilerTarget {
+class DevCompilerSummaryTarget extends DevCompilerTarget with SummaryMixin {
final List<Uri> sources;
final bool excludeNonSources;
DevCompilerSummaryTarget(
this.sources, this.excludeNonSources, TargetFlags targetFlags)
: super(targetFlags);
-
- @override
- void performOutlineTransformations(Component component) {
- super.performOutlineTransformations(component);
- if (!excludeNonSources) return;
-
- List<Library> libraries = new List.from(component.libraries);
- component.libraries.clear();
- Set<Uri> include = sources.toSet();
- for (var lib in libraries) {
- if (include.contains(lib.importUri)) {
- component.libraries.add(lib);
- } else {
- // Excluding the library also means that their canonical names will not
- // be computed as part of serialization, so we need to do that
- // preemtively here to avoid errors when serializing references to
- // elements of these libraries.
- component.root.getChildFromUri(lib.importUri).bindTo(lib.reference);
- lib.computeCanonicalNames();
- }
- }
- }
}
Uri toUri(String uriString) {
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 1cb1b2c..14f30a3 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -918,3 +918,44 @@
TestTargetWrapper(Target target, this.flags) : super(target);
}
+
+/// Extends a Target to transform outlines to meet the requirements
+/// of summaries in bazel and package-build.
+///
+/// Build systems like package-build may provide the same input file twice to
+/// the summary worker, but only intends to have it in one output summary. The
+/// convention is that if it is listed as a source, it is intended to be part of
+/// the output, if the source file was loaded as a dependency, then it was
+/// already included in a different summary. The transformation below ensures
+/// that the output summary doesn't include those implicit inputs.
+///
+/// Note: this transformation is destructive and is only intended to be used
+/// when generating summaries.
+mixin SummaryMixin on Target {
+ List<Uri> get sources;
+ bool get excludeNonSources;
+
+ @override
+ void performOutlineTransformations(Component component) {
+ super.performOutlineTransformations(component);
+ if (!excludeNonSources) return;
+
+ List<Library> libraries = new List.from(component.libraries);
+ component.libraries.clear();
+ Set<Uri> include = sources.toSet();
+ for (Library library in libraries) {
+ if (include.contains(library.importUri)) {
+ component.libraries.add(library);
+ } else {
+ // Excluding the library also means that their canonical names will not
+ // be computed as part of serialization, so we need to do that
+ // preemptively here to avoid errors when serializing references to
+ // elements of these libraries.
+ component.root
+ .getChildFromUri(library.importUri)
+ .bindTo(library.reference);
+ library.computeCanonicalNames();
+ }
+ }
+ }
+}
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index ccd8144..d560dab 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -384,7 +384,8 @@
dart::bin::DartUtils::ReadFile, dart::bin::DartUtils::WriteFile,
dart::bin::DartUtils::CloseFile, /*entropy_source=*/nullptr,
/*get_service_assets=*/nullptr, start_kernel_isolate,
- /*code_observer=*/nullptr);
+ /*code_observer=*/nullptr, /*post_task=*/nullptr,
+ /*post_task_data*/ nullptr);
if (error != nullptr) {
Syslog::PrintErr("Failed to initialize VM: %s\n", error);
free(error);
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index b62c1a7..5d189df 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -831,7 +831,7 @@
* The current version of the Dart_InitializeFlags. Should be incremented every
* time Dart_InitializeFlags changes in a binary incompatible way.
*/
-#define DART_INITIALIZE_PARAMS_CURRENT_VERSION (0x00000004)
+#define DART_INITIALIZE_PARAMS_CURRENT_VERSION (0x00000005)
/** Forward declaration */
struct Dart_CodeObserver;
@@ -857,6 +857,50 @@
Dart_OnNewCodeCallback on_new_code;
} Dart_CodeObserver;
+typedef struct _Dart_Task* Dart_Task;
+typedef enum {
+ Dart_TaskPriority_Default,
+} Dart_TaskPriority;
+typedef struct {
+ /**
+ * Placeholder.
+ */
+ Dart_TaskPriority priority;
+ /**
+ * Time after which the task should run according to the clock of
+ * Dart_TimelineGetMicros.
+ */
+ int64_t time_point;
+} Dart_TaskData;
+/**
+ * Callback provided by the embedder that is used by the VM to eventually run
+ * various tasks. If no callback is provided, these tasks will run on a
+ * VM-internal thread pool. This callback allows the embedder to make its own
+ * choices around the scheduling of these tasks: when they run, how many threads
+ * are servicing these tasks, the priorities of said threads, etc.
+ * The callback can be invoked as early as during the Dart_Initialize call.
+ *
+ * \param post_task_data
+ * The data provided to Dart_InitializeParams.post_task_data.
+ * \param task
+ * A task that should eventually be passed to Dart_RunTask.
+ * \param task_data
+ * Hints about when the task should run.
+ */
+typedef void (*Dart_PostTaskCallback)(void* post_task_data,
+ Dart_Task task,
+ Dart_TaskData task_data);
+
+/**
+ * Runs a task given to the Dart_PostTaskCallback. Must not be called
+ * synchronously in response to any callback from the VM. In particular, must
+ * not be called synchronously by the implemention of a Dart native function
+ * or Dart_Post_TaskCallback.
+ *
+ * Requires there to be no current isolate or isolate group.
+ */
+DART_EXPORT void Dart_RunTask(Dart_Task task);
+
/**
* Describes how to initialize the VM. Used with Dart_Initialize.
*
@@ -884,6 +928,8 @@
* See Dart_GetVMServiceAssetsArchive.
* \param code_observer An external code observer callback function.
* The observer can be invoked as early as during the Dart_Initialize() call.
+ * \param post_task A task scheduling callback function.
+ * See Dart_PostTaskCallback.
*/
typedef struct {
int32_t version;
@@ -903,6 +949,8 @@
Dart_GetVMServiceAssetsArchive get_service_assets;
bool start_kernel_isolate;
Dart_CodeObserver* code_observer;
+ Dart_PostTaskCallback post_task;
+ void* post_task_data;
} Dart_InitializeParams;
/**
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 2dbd8d3..7425dd6 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -69,6 +69,8 @@
Dart_FileCloseCallback Dart::file_close_callback_ = NULL;
Dart_EntropySource Dart::entropy_source_callback_ = NULL;
Dart_GCEventCallback Dart::gc_event_callback_ = nullptr;
+Dart_PostTaskCallback Dart::post_task_callback_ = nullptr;
+void* Dart::post_task_data_ = nullptr;
// Structure for managing read-only global handles allocation used for
// creating global read-only handles that are pre created and initialized
@@ -259,7 +261,9 @@
Dart_EntropySource entropy_source,
Dart_GetVMServiceAssetsArchive get_service_assets,
bool start_kernel_isolate,
- Dart_CodeObserver* observer) {
+ Dart_CodeObserver* observer,
+ Dart_PostTaskCallback post_task,
+ void* post_task_data) {
CheckOffsets();
if (!Flags::Initialized()) {
@@ -294,6 +298,8 @@
set_thread_exit_callback(thread_exit);
SetFileCallbacks(file_open, file_read, file_write, file_close);
set_entropy_source_callback(entropy_source);
+ set_post_task_callback(post_task);
+ set_post_task_data(post_task_data);
OS::Init();
NOT_IN_PRODUCT(CodeObservers::Init());
if (observer != nullptr) {
@@ -531,18 +537,21 @@
Dart_EntropySource entropy_source,
Dart_GetVMServiceAssetsArchive get_service_assets,
bool start_kernel_isolate,
- Dart_CodeObserver* observer) {
+ Dart_CodeObserver* observer,
+ Dart_PostTaskCallback post_task,
+ void* post_task_data) {
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);
+ 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, post_task, post_task_data);
if (retval != NULL) {
init_state_.ResetInitializing();
return retval;
@@ -823,6 +832,8 @@
Service::SetEmbedderStreamCallbacks(NULL, NULL);
#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
VirtualMemory::Cleanup();
+ post_task_callback_ = nullptr;
+ post_task_data_ = nullptr;
return NULL;
}
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index 9d0cdf1..a8c4a56 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -44,7 +44,9 @@
Dart_EntropySource entropy_source,
Dart_GetVMServiceAssetsArchive get_service_assets,
bool start_kernel_isolate,
- Dart_CodeObserver* observer);
+ Dart_CodeObserver* observer,
+ Dart_PostTaskCallback post_task,
+ void* post_task_data);
// Returns null if cleanup succeeds, otherwise returns an error message
// (caller owns error message and has to free it).
@@ -123,6 +125,14 @@
static void set_thread_exit_callback(Dart_ThreadExitCallback cback) {
thread_exit_callback_ = cback;
}
+ static Dart_PostTaskCallback post_task_callback() {
+ return post_task_callback_;
+ }
+ static void set_post_task_callback(Dart_PostTaskCallback cback) {
+ post_task_callback_ = cback;
+ }
+ static void* post_task_data() { return post_task_data_; }
+ static void set_post_task_data(void* data) { post_task_data_ = data; }
static void SetFileCallbacks(Dart_FileOpenCallback file_open,
Dart_FileReadCallback file_read,
Dart_FileWriteCallback file_write,
@@ -174,7 +184,9 @@
Dart_EntropySource entropy_source,
Dart_GetVMServiceAssetsArchive get_service_assets,
bool start_kernel_isolate,
- Dart_CodeObserver* observer);
+ Dart_CodeObserver* observer,
+ Dart_PostTaskCallback post_task,
+ void* post_task_data);
static constexpr const char* kVmIsolateName = "vm-isolate";
@@ -194,6 +206,8 @@
static Dart_FileCloseCallback file_close_callback_;
static Dart_EntropySource entropy_source_callback_;
static Dart_GCEventCallback gc_event_callback_;
+ static Dart_PostTaskCallback post_task_callback_;
+ static void* post_task_data_;
};
} // namespace dart
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 082476f..fe7dcc4 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1211,14 +1211,14 @@
"Invalid Dart_InitializeParams version.");
}
- return Dart::Init(params->vm_snapshot_data, params->vm_snapshot_instructions,
- params->create_group, params->initialize_isolate,
- params->shutdown_isolate, params->cleanup_isolate,
- params->cleanup_group, params->thread_exit,
- params->file_open, params->file_read, params->file_write,
- params->file_close, params->entropy_source,
- params->get_service_assets, params->start_kernel_isolate,
- params->code_observer);
+ return Dart::Init(
+ params->vm_snapshot_data, params->vm_snapshot_instructions,
+ params->create_group, params->initialize_isolate,
+ params->shutdown_isolate, params->cleanup_isolate, params->cleanup_group,
+ params->thread_exit, params->file_open, params->file_read,
+ params->file_write, params->file_close, params->entropy_source,
+ params->get_service_assets, params->start_kernel_isolate,
+ params->code_observer, params->post_task, params->post_task_data);
}
DART_EXPORT char* Dart_Cleanup() {
@@ -2063,6 +2063,16 @@
return true;
}
+DART_EXPORT void Dart_RunTask(Dart_Task task) {
+ Thread* T = Thread::Current();
+ Isolate* I = T == nullptr ? nullptr : T->isolate();
+ CHECK_NO_ISOLATE(I);
+ API_TIMELINE_BEGIN_END(T);
+ ThreadPool::Task* task_impl = reinterpret_cast<ThreadPool::Task*>(task);
+ task_impl->Run();
+ delete task_impl;
+}
+
DART_EXPORT Dart_Handle Dart_HandleMessage() {
Thread* T = Thread::Current();
Isolate* I = T->isolate();
diff --git a/runtime/vm/thread_pool.cc b/runtime/vm/thread_pool.cc
index 93df2ff..f450555 100644
--- a/runtime/vm/thread_pool.cc
+++ b/runtime/vm/thread_pool.cc
@@ -82,6 +82,22 @@
}
bool ThreadPool::RunImpl(std::unique_ptr<Task> task) {
+ Dart_PostTaskCallback post_task = Dart::post_task_callback();
+ if (post_task != nullptr) {
+ {
+ MonitorLocker ml(&pool_monitor_);
+ if (shutting_down_) {
+ return false;
+ }
+ }
+ Dart_TaskData data;
+ data.priority = Dart_TaskPriority_Default;
+ data.time_point = 0;
+ post_task(Dart::post_task_data(),
+ reinterpret_cast<Dart_Task>(task.release()), data);
+ return true;
+ }
+
Worker* new_worker = nullptr;
{
MonitorLocker ml(&pool_monitor_);
diff --git a/tools/VERSION b/tools/VERSION
index cd8bf2f..f0a8718 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 16
PATCH 0
-PRERELEASE 23
+PRERELEASE 24
PRERELEASE_PATCH 0
\ No newline at end of file