1
0
mirror of https://github.com/dart-lang/sdk synced 2024-07-08 12:06:26 +00:00

[ddc] Fix list literal control flow optimization

Restore the behavior originally added in
https://dart-review.googlesource.com/c/sdk/+/172082 to call `.push()`
on Javascript Arrays directly when it is safe.

After some experimenting this optimization no longer appears to be
as effective for lists of native types (the type check is little
overhead) but is still observable for lists of user defined
interface types.

Change-Id: I034666a512a7886e5022498e2d6bd3f8aaceebbd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/215483
Reviewed-by: Stephen Adams <sra@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
This commit is contained in:
Nicholas Shahan 2021-10-08 20:41:37 +00:00 committed by commit-bot@chromium.org
parent a25f41f605
commit 1345eb8baa

View File

@ -4803,21 +4803,33 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
/// list and the element type is known to be invariant so it can skip the
/// type check.
bool isNativeListInvariantAdd(InvocationExpression node) {
Expression receiver;
if (receiver != null && node.name.text == 'add') {
if (node is InstanceInvocation &&
node.isInvariant &&
node.name.text == 'add') {
// The call to add is marked as invariant, so the type check on the
// parameter to add is not needed.
var receiver = node.receiver;
if (receiver is VariableGet &&
receiver.variable.isFinal &&
!receiver.variable.isLate) {
// The receiver is a final variable, so it only contains the
// initializer value. Also, avoid late variables in case the CFE
// lowering of late variables is changed in the future.
if (receiver.variable.initializer is ListLiteral) {
var initializer = receiver.variable.initializer;
if (initializer is ListLiteral) {
// The initializer is a list literal, so we know the list can be
// grown, modified, and is represented by a JavaScript Array.
return true;
}
if (initializer is StaticInvocation &&
initializer.target.enclosingClass == _coreTypes.listClass &&
initializer.target.name.text == 'of' &&
initializer.arguments.named.isEmpty) {
// The initializer is a `List.of()` call from the dart:core library
// and the growable named argument has not been passed (it defaults
// to true).
return true;
}
}
}
return false;