mirror of
https://github.com/dart-lang/sdk
synced 2024-09-06 00:59:09 +00:00
[kernel] Call Reference.node less; make it inlinable
This CL splits up `Reference.node` in to the most-often fast-case and the has-to-load case, making the procedure smaller which makes the VM inline it. This was "verified" by looking at the VMs optimized flow graph for `Reference.asClass`. This CL furthermore reduces the number of "calls" to `Reference.node` by almost half (a reduction of over 3 mio calls when compiling `compile.dart`) by "caching" the `.node` call in the `as*` methods. Change-Id: I7b5497397a11f05fdeaf05d6cc420072d98dc030 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/298101 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Jens Johansen <jensj@google.com>
This commit is contained in:
parent
e5c2dd28c7
commit
dc77baa5a8
|
@ -438,26 +438,29 @@ class Reference {
|
|||
NamedNode? _node;
|
||||
|
||||
NamedNode? get node {
|
||||
if (_node == null) {
|
||||
// Either this is an unbound reference or it belongs to a lazy-loaded
|
||||
// (and not yet loaded) class. If it belongs to a lazy-loaded class,
|
||||
// load the class.
|
||||
return _node ?? _tryLoadNode();
|
||||
}
|
||||
|
||||
CanonicalName? canonicalNameParent = canonicalName?.parent;
|
||||
while (canonicalNameParent != null) {
|
||||
if (canonicalNameParent.name.startsWith("@")) {
|
||||
break;
|
||||
}
|
||||
canonicalNameParent = canonicalNameParent.parent;
|
||||
/// If the node belongs to a lazy-loaded class load the class.
|
||||
///
|
||||
/// Should only be called if [_node] is null, meaning that either this
|
||||
/// is an unbound reference or it belongs to a lazy-loaded
|
||||
/// (and not yet loaded) class. If it belongs to a lazy-loaded class this call
|
||||
/// will load the class and set [_node].
|
||||
NamedNode? _tryLoadNode() {
|
||||
CanonicalName? canonicalNameParent = canonicalName?.parent;
|
||||
while (canonicalNameParent != null) {
|
||||
if (canonicalNameParent.name.startsWith("@")) {
|
||||
break;
|
||||
}
|
||||
if (canonicalNameParent != null) {
|
||||
NamedNode? parentNamedNode =
|
||||
canonicalNameParent.parent?.reference._node;
|
||||
if (parentNamedNode is Class) {
|
||||
Class parentClass = parentNamedNode;
|
||||
if (parentClass.lazyBuilder != null) {
|
||||
parentClass.ensureLoaded();
|
||||
}
|
||||
canonicalNameParent = canonicalNameParent.parent;
|
||||
}
|
||||
if (canonicalNameParent != null) {
|
||||
NamedNode? parentNamedNode = canonicalNameParent.parent?.reference._node;
|
||||
if (parentNamedNode is Class) {
|
||||
Class parentClass = parentNamedNode;
|
||||
if (parentClass.lazyBuilder != null) {
|
||||
parentClass.ensureLoaded();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -499,6 +502,7 @@ class Reference {
|
|||
}
|
||||
|
||||
Library get asLibrary {
|
||||
NamedNode? node = this.node;
|
||||
if (node == null) {
|
||||
throw '$this is not bound to an AST node. A library was expected';
|
||||
}
|
||||
|
@ -506,6 +510,7 @@ class Reference {
|
|||
}
|
||||
|
||||
Class get asClass {
|
||||
NamedNode? node = this.node;
|
||||
if (node == null) {
|
||||
throw '$this is not bound to an AST node. A class was expected';
|
||||
}
|
||||
|
@ -513,6 +518,7 @@ class Reference {
|
|||
}
|
||||
|
||||
Member get asMember {
|
||||
NamedNode? node = this.node;
|
||||
if (node == null) {
|
||||
throw '$this is not bound to an AST node. A member was expected';
|
||||
}
|
||||
|
@ -520,6 +526,7 @@ class Reference {
|
|||
}
|
||||
|
||||
Field get asField {
|
||||
NamedNode? node = this.node;
|
||||
if (node == null) {
|
||||
throw '$this is not bound to an AST node. A field was expected';
|
||||
}
|
||||
|
@ -527,6 +534,7 @@ class Reference {
|
|||
}
|
||||
|
||||
Constructor get asConstructor {
|
||||
NamedNode? node = this.node;
|
||||
if (node == null) {
|
||||
throw '$this is not bound to an AST node. A constructor was expected';
|
||||
}
|
||||
|
@ -534,6 +542,7 @@ class Reference {
|
|||
}
|
||||
|
||||
Procedure get asProcedure {
|
||||
NamedNode? node = this.node;
|
||||
if (node == null) {
|
||||
throw '$this is not bound to an AST node. A procedure was expected';
|
||||
}
|
||||
|
@ -541,6 +550,7 @@ class Reference {
|
|||
}
|
||||
|
||||
Typedef get asTypedef {
|
||||
NamedNode? node = this.node;
|
||||
if (node == null) {
|
||||
throw '$this is not bound to an AST node. A typedef was expected';
|
||||
}
|
||||
|
@ -548,6 +558,7 @@ class Reference {
|
|||
}
|
||||
|
||||
Extension get asExtension {
|
||||
NamedNode? node = this.node;
|
||||
if (node == null) {
|
||||
throw '$this is not bound to an AST node. An extension was expected';
|
||||
}
|
||||
|
@ -555,6 +566,7 @@ class Reference {
|
|||
}
|
||||
|
||||
InlineClass get asInlineClass {
|
||||
NamedNode? node = this.node;
|
||||
if (node == null) {
|
||||
throw '$this is not bound to an AST node. An inline class was expected';
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue