Skip to content

Commit

Permalink
Version 2.18.0-136.0.dev
Browse files Browse the repository at this point in the history
Merge commit '95360796c29d04575ccced5fe6105083c181fdb6' into 'dev'
  • Loading branch information
Dart CI committed May 19, 2022
2 parents 9da9305 + 9536079 commit 2108000
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 32 deletions.
3 changes: 3 additions & 0 deletions pkg/analyzer/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 4.2.0-dev
* Update SDK constraints to `>=2.17.0 <3.0.0`.

## 4.1.0
* Deprecated `ParameterElement.isNotOptional`, use `isRequired` instead.
* Deprecated `ResourceProviderMixin.newFile2`, use `newFile` instead.
Expand Down
4 changes: 2 additions & 2 deletions pkg/analyzer/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: analyzer
version: 4.1.0
version: 4.2.0-dev
description: This package provides a library that performs static analysis of Dart code.
repository: https://github.com/dart-lang/sdk/tree/main/pkg/analyzer

environment:
sdk: '>=2.15.0 <3.0.0'
sdk: '>=2.17.0 <3.0.0'

dependencies:
_fe_analyzer_shared: ^40.0.0
Expand Down
166 changes: 139 additions & 27 deletions pkg/compiler/lib/src/dump_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,9 @@ class KernelInfoCollector {
info.coverageId = '${field.hashCode}';
}

_addClosureInfo(info, field,
libraryEntity: fieldEntity.library, memberEntity: fieldEntity);

state.info.fields.add(info);
return info;
}
Expand Down Expand Up @@ -549,9 +552,10 @@ class KernelInfoCollector {
}

FunctionInfo visitFunction(ir.FunctionNode function,
{FunctionEntity functionEntity}) {
var parent = function.parent;
String name = parent.toStringInternal();
{FunctionEntity functionEntity, LocalFunctionInfo localFunctionInfo}) {
final parent = function.parent;
String name =
parent is ir.LocalFunction ? 'call' : parent.toStringInternal();
bool isConstructor = parent is ir.Constructor;
bool isFactory = parent is ir.Procedure && parent.isFactory;
// Kernel `isStatic` refers to static members, constructors, and top-level
Expand Down Expand Up @@ -632,6 +636,15 @@ class KernelInfoCollector {
outputUnit: null);
state.entityToInfo[functionEntity] = info;

if (function.parent is ir.Member)
_addClosureInfo(info, function.parent,
libraryEntity: functionEntity.library, memberEntity: functionEntity);
else {
// This branch is only reached when function is a 'call' method.
// TODO(markzipan): Ensure call methods never have children.
info.closures = [];
}

if (compiler.options.experimentCallInstrumentation) {
// We use function.hashCode because it is globally unique and it is
// available while we are doing codegen.
Expand All @@ -641,6 +654,41 @@ class KernelInfoCollector {
state.info.functions.add(info);
return info;
}

/// Adds closure information to [info], using all nested closures in [member].
void _addClosureInfo(Info info, ir.Member member,
{LibraryEntity libraryEntity, MemberEntity memberEntity}) {
final localFunctionInfoCollector = LocalFunctionInfoCollector();
member.accept(localFunctionInfoCollector);
List<ClosureInfo> nestedClosures = <ClosureInfo>[];
localFunctionInfoCollector.localFunctions.forEach((key, value) {
FunctionEntity closureEntity;
environment.forEachNestedClosure(memberEntity, (closure) {
if (closure.enclosingClass.name == value.name) {
closureEntity = closure;
}
});
final closureClassEntity = closureEntity.enclosingClass;
final closureInfo =
ClosureInfo(name: value.name, outputUnit: null, size: null);
state.entityToInfo[closureClassEntity] = closureInfo;

FunctionEntity callMethod = closedWorld.elementEnvironment
.lookupClassMember(closureClassEntity, Identifiers.call);
final functionInfo = visitFunction(key.function,
functionEntity: callMethod, localFunctionInfo: value);
state.entityToInfo[closureEntity] = functionInfo;

closureInfo.function = functionInfo;
functionInfo.parent = closureInfo;
state.info.closures.add(closureInfo);

closureInfo.parent = info;
nestedClosures.add(closureInfo);
});
if (info is FunctionInfo) info.closures = nestedClosures;
if (info is FieldInfo) info.closures = nestedClosures;
}
}

/// Annotates [KernelInfoCollector] with info extracted from closed-world
Expand Down Expand Up @@ -853,24 +901,25 @@ class DumpInfoAnnotator {
}

ClosureInfo visitClosureClass(ClassEntity element) {
ClosureInfo closureInfo = ClosureInfo(
name: element.name,
outputUnit: _unitInfoForClass(element),
size: dumpInfoTask.sizeOf(element));
kernelInfo.state.entityToInfo[element] = closureInfo;
final kClosureInfos = kernelInfo.state.info.closures
.where((info) => info.name == element.name)
.toList();
assert(
kClosureInfos.length == 1,
'Ambiguous closure resolution. '
'Expected singleton, found $kClosureInfos');
final kClosureInfo = kClosureInfos.first;

kClosureInfo.outputUnit = _unitInfoForClass(element);
kClosureInfo.size = dumpInfoTask.sizeOf(element);

FunctionEntity callMethod = closedWorld.elementEnvironment
.lookupClassMember(element, Identifiers.call);

FunctionInfo functionInfo = visitFunction(callMethod, element.name);
if (functionInfo == null) return null;

closureInfo.function = functionInfo;
functionInfo.parent = closureInfo;
closureInfo.treeShakenStatus = TreeShakenStatus.Live;
visitFunction(callMethod, element.name);

kernelInfo.state.info.closures.add(closureInfo);
return closureInfo;
kClosureInfo.treeShakenStatus = TreeShakenStatus.Live;
return kClosureInfo;
}

// TODO(markzipan): [parentName] is used for disambiguation, but this might
Expand All @@ -879,8 +928,6 @@ class DumpInfoAnnotator {
int size = dumpInfoTask.sizeOf(function);
// TODO(sigmund): consider adding a small info to represent unreachable
// code here.
if (size == 0 && !shouldKeep(function)) return null;

var compareName = function.name;
if (function.isConstructor) {
compareName = compareName == ""
Expand All @@ -898,9 +945,10 @@ class DumpInfoAnnotator {
!(function.isSetter ^ i.modifiers.isSetter))
.toList();
assert(
kFunctionInfos.length == 1,
kFunctionInfos.length <= 1,
'Ambiguous function resolution. '
'Expected singleton, found $kFunctionInfos');
'Expected single or none, found $kFunctionInfos');
if (kFunctionInfos.length == 0) return null;
final kFunctionInfo = kFunctionInfos.first;

List<CodeSpan> code = dumpInfoTask.codeOf(function);
Expand Down Expand Up @@ -943,19 +991,13 @@ class DumpInfoAnnotator {
int _addClosureInfo(BasicInfo info, MemberEntity member) {
assert(info is FunctionInfo || info is FieldInfo);
int size = 0;
List<ClosureInfo> nestedClosures = <ClosureInfo>[];
environment.forEachNestedClosure(member, (closure) {
ClosureInfo closureInfo = visitClosureClass(closure.enclosingClass);
if (closureInfo != null) {
closureInfo.parent = info;
closureInfo.treeShakenStatus = info.treeShakenStatus;
nestedClosures.add(closureInfo);
closureInfo.treeShakenStatus = TreeShakenStatus.Live;
size += closureInfo.size;
}
});
if (info is FunctionInfo) info.closures = nestedClosures;
if (info is FieldInfo) info.closures = nestedClosures;

return size;
}

Expand Down Expand Up @@ -1432,3 +1474,73 @@ class DumpInfoStateData {

DumpInfoStateData();
}

class LocalFunctionInfo {
final ir.LocalFunction localFunction;
final List<ir.TreeNode> hierarchy;
final String name;
bool isInvoked = false;

LocalFunctionInfo._(this.localFunction, this.hierarchy, this.name);

factory LocalFunctionInfo(ir.LocalFunction localFunction) {
String name = '';
ir.TreeNode node = localFunction;
final hierarchy = <ir.TreeNode>[];
bool inClosure = false;
while (node != null) {
// Only consider nodes used for resolving a closure's full name.
if (node is ir.FunctionDeclaration) {
hierarchy.add(node);
name = '_${node.variable.name}' + name;
inClosure = false;
} else if (node is ir.FunctionExpression) {
hierarchy.add(node);
name = (inClosure ? '_' : '_closure') + name;
inClosure = true;
} else if (node is ir.Member) {
hierarchy.add(node);
var cleanName = node.toStringInternal();
if (cleanName.endsWith('.'))
cleanName = cleanName.substring(0, cleanName.length - 1);
final isFactory = node is ir.Procedure && node.isFactory;
if (isFactory) {
cleanName = cleanName.replaceAll('.', '\$');
cleanName = '${node.enclosingClass.toStringInternal()}_' + cleanName;
} else {
cleanName = cleanName.replaceAll('.', '_');
}
name = cleanName + name;
inClosure = false;
}
node = node.parent;
}

return LocalFunctionInfo._(localFunction, hierarchy, name);
}
}

class LocalFunctionInfoCollector extends ir.RecursiveVisitor<void> {
final localFunctions = <ir.LocalFunction, LocalFunctionInfo>{};

@override
void visitFunctionExpression(ir.FunctionExpression node) {
assert(localFunctions[node] == null);
localFunctions[node] = LocalFunctionInfo(node);
defaultExpression(node);
}

@override
void visitFunctionDeclaration(ir.FunctionDeclaration node) {
assert(localFunctions[node] == null);
localFunctions[node] = LocalFunctionInfo(node);
defaultStatement(node);
}

@override
void visitLocalFunctionInvocation(ir.LocalFunctionInvocation node) {
if (localFunctions[node.localFunction] == null)
visitFunctionDeclaration(node.localFunction);
localFunctions[node.localFunction].isInvoked = true;
}
}
4 changes: 2 additions & 2 deletions runtime/tests/vm/vm.status
Original file line number Diff line number Diff line change
Expand Up @@ -260,14 +260,14 @@ cc/IsolateReload_LibraryLookup: Fail, Crash
dart/appjit*: SkipSlow # DFE too slow
dart/b162922506_test: SkipSlow # Generates large input file
dart/data_uri_spawn_test: Skip # Please triage.
dart/isolates/fast_object_copy_test*: Slow # issue 46740
dart/isolates/fast_object_copy_test*: SkipSlow
dart/minimal_kernel_test: SkipSlow # gen_kernel is too slow on simulated architectures
dart/null_safety_autodetection_in_kernel_compiler_test: SkipSlow # gen_kernel is too slow on simulated architectures
dart/snapshot_version_test: RuntimeError # Please triage.
dart_2/appjit*: SkipSlow # DFE too slow
dart_2/b162922506_test: SkipSlow # Generates large input file
dart_2/data_uri_spawn_test: Skip # Please triage.
dart_2/isolates/fast_object_copy_test*: Slow # issue 46740
dart_2/isolates/fast_object_copy_test*: SkipSlow
dart_2/minimal_kernel_test: SkipSlow # gen_kernel is too slow on simulated architectures
dart_2/null_safety_autodetection_in_kernel_compiler_test: SkipSlow # gen_kernel is too slow on simulated architectures
dart_2/snapshot_version_test: RuntimeError # Please triage.
Expand Down
2 changes: 1 addition & 1 deletion tools/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ CHANNEL dev
MAJOR 2
MINOR 18
PATCH 0
PRERELEASE 135
PRERELEASE 136
PRERELEASE_PATCH 0

0 comments on commit 2108000

Please sign in to comment.