Skip to content

Commit

Permalink
[vm,kernel] New async/await implementation in the VM, part 1 - kernel
Browse files Browse the repository at this point in the history
This change includes kernel-related changes:

* --compact-async option is added to kernel compilers (front-end
  server and gen_kernel). This option disables desugaring of async
  and await on kernel AST. Note that 'await for' is still desugared.

* File offset of the 'await' is now written for AwaitExpression nodes
  in the kernel binaries (will be used for async stack traces).

* Async/async*/sync* functions and AwaitExpression nodes are supported
  in TFA.

Design doc: go/compact-async-await.

TEST=ci

Issue: #48378
Change-Id: I4233086b7434bc48347f4220645b0be5f9133456
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/241842
Reviewed-by: Slava Egorov <vegorov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
  • Loading branch information
alexmarkov authored and Commit Bot committed Apr 21, 2022
1 parent 707e201 commit 2afc341
Show file tree
Hide file tree
Showing 12 changed files with 225 additions and 167 deletions.
3 changes: 3 additions & 0 deletions pkg/frontend_server/lib/frontend_server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ ArgParser argParser = ArgParser(allowTrailingOptions: true)
help: 'Whether dart:mirrors is supported. By default dart:mirrors is '
'supported when --aot and --minimal-kernel are not used.',
defaultsTo: null)
..addFlag('compact-async',
help: 'Enable new compact async/await implementation.', defaultsTo: null)
..addFlag('tfa',
help:
'Enable global type flow analysis and related transformations in AOT mode.',
Expand Down Expand Up @@ -538,6 +540,7 @@ class FrontendCompiler implements CompilerInterface {
nullSafety: compilerOptions.nnbdMode == NnbdMode.Strong,
supportMirrors: options['support-mirrors'] ??
!(options['aot'] || options['minimal-kernel']),
compactAsync: options['compact-async'] ?? false /*options['aot']*/,
);
if (compilerOptions.target == null) {
print('Failed to create front-end target ${options['target']}.');
Expand Down
3 changes: 2 additions & 1 deletion pkg/kernel/binary.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ type CanonicalName {

type ComponentFile {
UInt32 magic = 0x90ABCDEF;
UInt32 formatVersion = 78;
UInt32 formatVersion = 79;
Byte[10] shortSdkHash;
List<String> problemsAsJson; // Described in problems.md.
Library[] libraries;
Expand Down Expand Up @@ -1070,6 +1070,7 @@ type MapEntry {

type AwaitExpression extends Expression {
Byte tag = 51;
FileOffset fileOffset;
Expression operand;
}

Expand Down
3 changes: 2 additions & 1 deletion pkg/kernel/lib/binary/ast_from_binary.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2602,7 +2602,8 @@ class BinaryBuilder {
}

Expression _readAwaitExpression() {
return new AwaitExpression(readExpression());
int offset = readOffset();
return new AwaitExpression(readExpression())..fileOffset = offset;
}

Expression _readFunctionExpression() {
Expand Down
1 change: 1 addition & 0 deletions pkg/kernel/lib/binary/ast_to_binary.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1986,6 +1986,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
@override
void visitAwaitExpression(AwaitExpression node) {
writeByte(Tag.AwaitExpression);
writeOffset(node.fileOffset);
writeNode(node.operand);
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/kernel/lib/binary/tag.dart
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ class Tag {
/// Internal version of kernel binary format.
/// Bump it when making incompatible changes in kernel binaries.
/// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
static const int BinaryFormatVersion = 78;
static const int BinaryFormatVersion = 79;
}

abstract class ConstantTag {
Expand Down
10 changes: 8 additions & 2 deletions pkg/kernel/lib/target/targets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,22 @@ class TargetFlags {
final bool trackWidgetCreation;
final bool enableNullSafety;
final bool supportMirrors;
final bool compactAsync;

const TargetFlags(
{this.trackWidgetCreation = false,
this.enableNullSafety = false,
this.supportMirrors = true});
this.supportMirrors = true,
this.compactAsync = false});

@override
bool operator ==(other) {
if (identical(this, other)) return true;
return other is TargetFlags &&
trackWidgetCreation == other.trackWidgetCreation &&
enableNullSafety == other.enableNullSafety &&
supportMirrors == other.supportMirrors;
supportMirrors == other.supportMirrors &&
compactAsync == other.compactAsync;
}

@override
Expand All @@ -37,6 +40,7 @@ class TargetFlags {
hash = 0x3fffffff & (hash * 31 + (hash ^ trackWidgetCreation.hashCode));
hash = 0x3fffffff & (hash * 31 + (hash ^ enableNullSafety.hashCode));
hash = 0x3fffffff & (hash * 31 + (hash ^ supportMirrors.hashCode));
hash = 0x3fffffff & (hash * 31 + (hash ^ compactAsync.hashCode));
return hash;
}
}
Expand Down Expand Up @@ -547,6 +551,8 @@ abstract class Target {
Class? concreteDoubleLiteralClass(CoreTypes coreTypes, double value) => null;
Class? concreteStringLiteralClass(CoreTypes coreTypes, String value) => null;

Class? concreteAsyncResultClass(CoreTypes coreTypes) => null;

ConstantsBackend get constantsBackend;

/// Returns an [DartLibrarySupport] the defines which, if any, of the
Expand Down
12 changes: 9 additions & 3 deletions pkg/vm/lib/kernel_front_end.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ void declareCompilerOptions(ArgParser args) {
help: 'Whether dart:mirrors is supported. By default dart:mirrors is '
'supported when --aot and --minimal-kernel are not used.',
defaultsTo: null);
args.addFlag('compact-async',
help: 'Enable new compact async/await implementation.', defaultsTo: null);
args.addOption('depfile', help: 'Path to output Ninja depfile');
args.addOption('from-dill',
help: 'Read existing dill file instead of compiling from sources',
Expand Down Expand Up @@ -200,6 +202,7 @@ Future<int> runCompiler(ArgResults options, String usage) async {
final String? manifestFilename = options['manifest'];
final String? dataDir = options['component-name'] ?? options['data-dir'];
final bool? supportMirrors = options['support-mirrors'];
final bool compactAsync = options['compact-async'] ?? false /*aot*/;

final bool minimalKernel = options['minimal-kernel'];
final bool treeShakeWriteOnlyFields = options['tree-shake-write-only-fields'];
Expand Down Expand Up @@ -283,7 +286,8 @@ Future<int> runCompiler(ArgResults options, String usage) async {
compilerOptions.target = createFrontEndTarget(targetName,
trackWidgetCreation: options['track-widget-creation'],
nullSafety: compilerOptions.nnbdMode == NnbdMode.Strong,
supportMirrors: supportMirrors ?? !(aot || minimalKernel));
supportMirrors: supportMirrors ?? !(aot || minimalKernel),
compactAsync: compactAsync);
if (compilerOptions.target == null) {
print('Failed to create front-end target $targetName.');
return badUsageExitCode;
Expand Down Expand Up @@ -612,14 +616,16 @@ Future<void> autoDetectNullSafetyMode(
Target? createFrontEndTarget(String targetName,
{bool trackWidgetCreation = false,
bool nullSafety = false,
bool supportMirrors = true}) {
bool supportMirrors = true,
bool compactAsync = false}) {
// Make sure VM-specific targets are available.
installAdditionalTargets();

final TargetFlags targetFlags = new TargetFlags(
trackWidgetCreation: trackWidgetCreation,
enableNullSafety: nullSafety,
supportMirrors: supportMirrors);
supportMirrors: supportMirrors,
compactAsync: compactAsync);
return getTarget(targetName, targetFlags);
}

Expand Down
8 changes: 6 additions & 2 deletions pkg/vm/lib/target/vm.dart
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ class VmTarget extends Target {
bool productMode = environmentDefines!["dart.vm.product"] == "true";
transformAsync.transformLibraries(
new TypeEnvironment(coreTypes, hierarchy), libraries,
productMode: productMode);
productMode: productMode, desugarAsync: !flags.compactAsync);
logger?.call("Transformed async methods");

lowering.transformLibraries(
Expand All @@ -208,7 +208,7 @@ class VmTarget extends Target {
bool productMode = environmentDefines!["dart.vm.product"] == "true";
transformAsync.transformProcedure(
new TypeEnvironment(coreTypes, hierarchy), procedure,
productMode: productMode);
productMode: productMode, desugarAsync: flags.supportMirrors);
logger?.call("Transformed async functions");

lowering.transformProcedure(
Expand Down Expand Up @@ -496,6 +496,10 @@ class VmTarget extends Target {
coreTypes.index.getClass('dart:core', '_OneByteString');
}

@override
Class? concreteAsyncResultClass(CoreTypes coreTypes) =>
coreTypes.futureImplClass;

@override
ConstantsBackend get constantsBackend => const ConstantsBackend();

Expand Down
4 changes: 3 additions & 1 deletion pkg/vm/lib/transformations/async.dart
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,9 @@ class ExpressionLifter extends Transformer {
@override
TreeNode visitFunctionNode(FunctionNode node) {
var nestedRewriter = new RecursiveContinuationRewriter(
continuationRewriter.helper, _staticTypeContext);
continuationRewriter.helper,
_staticTypeContext,
continuationRewriter.desugarAsync);
return nestedRewriter.transform(node);
}

Expand Down
Loading

0 comments on commit 2afc341

Please sign in to comment.