Skip to content

Commit dd89732

Browse files
committed
[dart2wasm] Make implicit arguments check use optimized is/as helpers
The implicit covariance type checks are currently performed by always calling out to RTT. Those can use our existing optimized implementation for is/as checks. This reduces code size of -O2 mode as well as makes certain benchmarks significantly faster (e.g. UIMatrix* 2x faster) Change-Id: Ib5224a310b2188b9edb2de1e800d2e60010d11f1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/370280 Reviewed-by: Srujan Gaddam <[email protected]> Commit-Queue: Martin Kustermann <[email protected]>
1 parent 07d2288 commit dd89732

File tree

1 file changed

+41
-58
lines changed

1 file changed

+41
-58
lines changed

pkg/dart2wasm/lib/code_generator.dart

Lines changed: 41 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,6 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
325325
}
326326
}
327327

328-
w.Local? tempLocalForType;
329-
330328
void setupParamLocal(VariableDeclaration variable, int index,
331329
Constant? defaultValue, bool isRequired) {
332330
w.Local local = paramLocals[implicitParams + index];
@@ -362,9 +360,6 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
362360
}
363361
if (!translator.options.omitImplicitTypeChecks) {
364362
if (variable.isCovariantByClass || variable.isCovariantByDeclaration) {
365-
final typeLocal = tempLocalForType ??= addLocal(
366-
translator.classInfo[translator.typeClass]!.nonNullableType);
367-
368363
final boxedType = variable.type.isPotentiallyNullable
369364
? translator.topInfo.nullableType
370365
: translator.topInfo.nonNullableType;
@@ -379,9 +374,8 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
379374
_generateArgumentTypeCheck(
380375
variable.name!,
381376
() => b.local_get(operand),
382-
() => types.makeType(this, variable.type),
377+
variable.type,
383378
operand,
384-
typeLocal,
385379
);
386380
}
387381
}
@@ -3348,11 +3342,6 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
33483342
// Local for the argument.
33493343
final argLocal = addLocal(translator.topInfo.nullableType);
33503344

3351-
// Local for the expected type of the argument.
3352-
final typeType =
3353-
translator.classInfo[translator.typeClass]!.nonNullableType;
3354-
final argTypeLocal = addLocal(typeType);
3355-
33563345
final member_ = member;
33573346
DartType paramType;
33583347
if (member_ is Field) {
@@ -3361,13 +3350,14 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
33613350
paramType = (member_ as Procedure).setterType;
33623351
}
33633352

3364-
_generateArgumentTypeCheck(
3365-
member.name.text,
3366-
() => b.local_get(positionalArgLocal),
3367-
() => types.makeType(this, paramType),
3368-
argLocal,
3369-
argTypeLocal,
3370-
);
3353+
if (!translator.options.omitImplicitTypeChecks) {
3354+
_generateArgumentTypeCheck(
3355+
member.name.text,
3356+
() => b.local_get(positionalArgLocal),
3357+
paramType,
3358+
argLocal,
3359+
);
3360+
}
33713361

33723362
ClassInfo info = translator.classInfo[member_.enclosingClass]!;
33733363
if (member_ is Field) {
@@ -3465,14 +3455,10 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
34653455
final List<VariableDeclaration> memberPositionalParams =
34663456
procedure.function.positionalParameters;
34673457

3468-
// Local for the current argument being checked. Used to avoid indexing the
3469-
// positional parameters array again when throwing type error.
3458+
// Local for the current argument being checked. Used to avoid indexing
3459+
// the positional parameters array again when throwing type error.
34703460
final argLocal = addLocal(translator.topInfo.nullableType);
34713461

3472-
// Local for the expected type of the current positional arguments. Used to
3473-
// avoid generating the type again when throwing type error.
3474-
final argTypeLocal = addLocal(typeType);
3475-
34763462
for (int positionalParamIdx = 0;
34773463
positionalParamIdx < memberPositionalParams.length;
34783464
positionalParamIdx += 1) {
@@ -3484,11 +3470,8 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
34843470
b.i32_const(positionalParamIdx);
34853471
b.array_get(translator.nullableObjectArrayType);
34863472
},
3487-
() {
3488-
types.makeType(this, param.type);
3489-
},
3473+
param.type,
34903474
argLocal,
3491-
argTypeLocal,
34923475
);
34933476
}
34943477

@@ -3519,11 +3502,8 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
35193502
b.i32_const(mapNamedParameterToArrayIndex(param.name!));
35203503
b.array_get(translator.nullableObjectArrayType);
35213504
},
3522-
() {
3523-
types.makeType(this, param.type);
3524-
},
3505+
param.type,
35253506
argLocal,
3526-
argTypeLocal,
35273507
);
35283508
}
35293509
}
@@ -3582,39 +3562,42 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
35823562
/// Does not expect any values on stack and does not leave any values on
35833563
/// stack.
35843564
///
3585-
/// Locals [argLocal] and [argExpectedTypeLocal] are used to store values
3586-
/// pushed by [pushArg] and [pushArgExpectedType] and reuse the values.
3565+
/// Locals [argLocal] are used to store values pushed by [pushArg]
3566+
/// and reuse the values.
35873567
///
35883568
/// [argName] is used in the type error as the name of the argument that
35893569
/// doesn't match the expected type.
35903570
void _generateArgumentTypeCheck(
35913571
String argName,
35923572
void Function() pushArg,
3593-
void Function() pushArgExpectedType,
3573+
DartType testedAgainstType,
35943574
w.Local argLocal,
3595-
w.Local argExpectedTypeLocal,
35963575
) {
3597-
// Argument
3598-
pushArg();
3599-
b.local_tee(argLocal);
3600-
3601-
// Expected type
3602-
pushArgExpectedType();
3603-
b.local_tee(argExpectedTypeLocal);
3604-
3605-
// Check that argument type is subtype of expected type
3606-
call(translator.isSubtype.reference);
3607-
3608-
b.i32_eqz();
3609-
b.if_();
3610-
// Type check failed
3611-
b.local_get(argLocal);
3612-
b.local_get(argExpectedTypeLocal);
3613-
_emitString(argName);
3614-
call(translator.stackTraceCurrent.reference);
3615-
call(translator.throwArgumentTypeCheckError.reference);
3616-
b.unreachable();
3617-
b.end();
3576+
if (translator.options.minify) {
3577+
// We don't need to include the name in the error message, so we can use
3578+
// the optimized `as` checks.
3579+
pushArg();
3580+
types.emitAsCheck(
3581+
this,
3582+
testedAgainstType,
3583+
translator.coreTypes.objectNullableRawType,
3584+
argLocal.type as w.RefType);
3585+
b.drop();
3586+
} else {
3587+
pushArg();
3588+
b.local_tee(argLocal);
3589+
types.emitIsTest(
3590+
this, testedAgainstType, translator.coreTypes.objectNullableRawType);
3591+
b.i32_eqz();
3592+
b.if_();
3593+
b.local_get(argLocal);
3594+
types.makeType(this, testedAgainstType);
3595+
_emitString(argName);
3596+
call(translator.stackTraceCurrent.reference);
3597+
call(translator.throwArgumentTypeCheckError.reference);
3598+
b.unreachable();
3599+
b.end();
3600+
}
36183601
}
36193602

36203603
void _generateTypeArgumentBoundCheck(

0 commit comments

Comments
 (0)