[CFE] Introduce forEachMember on kernel Library and class; change verifier slightly

verify_with_lazy_loading: instructions:u: -0.1311% +/- 0.0001% (-1182610.00 +/- 971.82)
verify_without_lazy_loading: instructions:u: -0.1267% +/- 0.0002% (-1124839.67 +/- 1776.77)

Change-Id: Idef856c7f6ad99c12deaa07ab95598e77a51f57e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/349863
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
This commit is contained in:
Jens Johansen 2024-02-05 10:36:59 +00:00 committed by Commit Queue
parent dff831dbfc
commit b7eb3f3c92
4 changed files with 87 additions and 51 deletions

View file

@ -0,0 +1,28 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import "dart:io";
import "package:kernel/binary/ast_from_binary.dart";
import "package:kernel/kernel.dart";
import "package:kernel/target/targets.dart";
import "package:kernel/verifier.dart";
import "package:vm/target/vm.dart";
void main(List<String> args) {
if (args.length != 1) throw "Usage: dart <script> <dill>";
Component component = loadComponent(new File(args.single));
Target target = new VmTarget(new TargetFlags());
verifyComponent(
target,
VerificationStage.afterModularTransformations,
component,
);
}
Component loadComponent(File f) {
Component component = new Component();
new BinaryBuilder(f.readAsBytesSync()).readComponent(component);
return component;
}

View file

@ -0,0 +1,29 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import "dart:io";
import "package:kernel/binary/ast_from_binary.dart";
import "package:kernel/kernel.dart";
import "package:kernel/target/targets.dart";
import "package:kernel/verifier.dart";
import "package:vm/target/vm.dart";
void main(List<String> args) {
if (args.length != 1) throw "Usage: dart <script> <dill>";
Component component = loadComponent(new File(args.single));
Target target = new VmTarget(new TargetFlags());
verifyComponent(
target,
VerificationStage.afterModularTransformations,
component,
);
}
Component loadComponent(File f) {
Component component = new Component();
new BinaryBuilder(f.readAsBytesSync(), disableLazyReading: true)
.readComponent(component);
return component;
}

View file

@ -472,6 +472,11 @@ class Library extends NamedNode
Iterable<Member> get members =>
<Iterable<Member>>[fields, procedures].expand((x) => x);
void forEachMember(void action(Member element)) {
fields.forEach(action);
procedures.forEach(action);
}
@override
void addAnnotation(Expression node) {
node.parent = this;
@ -1417,6 +1422,12 @@ class Class extends NamedNode implements TypeDeclaration {
procedures,
].expand((x) => x);
void forEachMember(void action(Member element)) {
fields.forEach(action);
constructors.forEach(action);
procedures.forEach(action);
}
/// The immediately extended, mixed-in, and implemented types.
///
/// This getter is for convenience, not efficiency. Consider manually

View file

@ -283,18 +283,6 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
exitTreeNode(node);
}
void declareMember(Member member) {
if (member.transformerFlags & TransformerFlag.seenByVerifier != 0) {
problem(member.function,
"Member '$member' has been declared more than once.");
}
member.transformerFlags |= TransformerFlag.seenByVerifier;
}
void undeclareMember(Member member) {
member.transformerFlags &= ~TransformerFlag.seenByVerifier;
}
void declareVariable(VariableDeclaration variable) {
if (variableDeclarationsInScope.contains(variable)) {
problem(variable, "Variable '$variable' declared more than once.");
@ -359,6 +347,18 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
@override
void visitComponent(Component component) {
void declareMember(Member member) {
if (member.transformerFlags & TransformerFlag.seenByVerifier != 0) {
problem(member.function,
"Member '$member' has been declared more than once.");
}
member.transformerFlags |= TransformerFlag.seenByVerifier;
}
void undeclareMember(Member member) {
member.transformerFlags &= ~TransformerFlag.seenByVerifier;
}
try {
for (Library library in component.libraries) {
for (Class class_ in library.classes) {
@ -372,61 +372,29 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
}
}
for (Field field in library.fields) {
declareMember(field);
}
for (Procedure procedure in library.procedures) {
declareMember(procedure);
}
library.forEachMember(declareMember);
for (Class class_ in library.classes) {
for (Field field in class_.fields) {
declareMember(field);
}
for (Procedure procedure in class_.procedures) {
declareMember(procedure);
}
for (Constructor constructor in class_.constructors) {
declareMember(constructor);
}
class_.forEachMember(declareMember);
}
for (ExtensionTypeDeclaration extensionTypeDeclaration
in library.extensionTypeDeclarations) {
for (Procedure procedure in extensionTypeDeclaration.procedures) {
declareMember(procedure);
}
extensionTypeDeclaration.procedures.forEach(declareMember);
}
}
visitChildren(component);
} finally {
for (Library library in component.libraries) {
for (Field field in library.fields) {
undeclareMember(field);
}
for (Procedure procedure in library.procedures) {
undeclareMember(procedure);
}
library.forEachMember(undeclareMember);
for (Class class_ in library.classes) {
for (Field field in class_.fields) {
undeclareMember(field);
}
for (Procedure procedure in class_.procedures) {
undeclareMember(procedure);
}
for (Constructor constructor in class_.constructors) {
undeclareMember(constructor);
}
class_.forEachMember(undeclareMember);
}
for (ExtensionTypeDeclaration extensionTypeDeclaration
in library.extensionTypeDeclarations) {
for (Procedure procedure in extensionTypeDeclaration.procedures) {
undeclareMember(procedure);
}
extensionTypeDeclaration.procedures.forEach(undeclareMember);
}
}
for (VariableDeclaration variable in variableStack) {
undeclareVariable(variable);
}
variableStack.forEach(undeclareVariable);
}
}