mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 05:36:49 +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? _node;
|
||||||
|
|
||||||
NamedNode? get node {
|
NamedNode? get node {
|
||||||
if (_node == null) {
|
return _node ?? _tryLoadNode();
|
||||||
// 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.
|
|
||||||
|
|
||||||
CanonicalName? canonicalNameParent = canonicalName?.parent;
|
/// If the node belongs to a lazy-loaded class load the class.
|
||||||
while (canonicalNameParent != null) {
|
///
|
||||||
if (canonicalNameParent.name.startsWith("@")) {
|
/// Should only be called if [_node] is null, meaning that either this
|
||||||
break;
|
/// 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
|
||||||
canonicalNameParent = canonicalNameParent.parent;
|
/// will load the class and set [_node].
|
||||||
|
NamedNode? _tryLoadNode() {
|
||||||
|
CanonicalName? canonicalNameParent = canonicalName?.parent;
|
||||||
|
while (canonicalNameParent != null) {
|
||||||
|
if (canonicalNameParent.name.startsWith("@")) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (canonicalNameParent != null) {
|
canonicalNameParent = canonicalNameParent.parent;
|
||||||
NamedNode? parentNamedNode =
|
}
|
||||||
canonicalNameParent.parent?.reference._node;
|
if (canonicalNameParent != null) {
|
||||||
if (parentNamedNode is Class) {
|
NamedNode? parentNamedNode = canonicalNameParent.parent?.reference._node;
|
||||||
Class parentClass = parentNamedNode;
|
if (parentNamedNode is Class) {
|
||||||
if (parentClass.lazyBuilder != null) {
|
Class parentClass = parentNamedNode;
|
||||||
parentClass.ensureLoaded();
|
if (parentClass.lazyBuilder != null) {
|
||||||
}
|
parentClass.ensureLoaded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -499,6 +502,7 @@ class Reference {
|
||||||
}
|
}
|
||||||
|
|
||||||
Library get asLibrary {
|
Library get asLibrary {
|
||||||
|
NamedNode? node = this.node;
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
throw '$this is not bound to an AST node. A library was expected';
|
throw '$this is not bound to an AST node. A library was expected';
|
||||||
}
|
}
|
||||||
|
@ -506,6 +510,7 @@ class Reference {
|
||||||
}
|
}
|
||||||
|
|
||||||
Class get asClass {
|
Class get asClass {
|
||||||
|
NamedNode? node = this.node;
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
throw '$this is not bound to an AST node. A class was expected';
|
throw '$this is not bound to an AST node. A class was expected';
|
||||||
}
|
}
|
||||||
|
@ -513,6 +518,7 @@ class Reference {
|
||||||
}
|
}
|
||||||
|
|
||||||
Member get asMember {
|
Member get asMember {
|
||||||
|
NamedNode? node = this.node;
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
throw '$this is not bound to an AST node. A member was expected';
|
throw '$this is not bound to an AST node. A member was expected';
|
||||||
}
|
}
|
||||||
|
@ -520,6 +526,7 @@ class Reference {
|
||||||
}
|
}
|
||||||
|
|
||||||
Field get asField {
|
Field get asField {
|
||||||
|
NamedNode? node = this.node;
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
throw '$this is not bound to an AST node. A field was expected';
|
throw '$this is not bound to an AST node. A field was expected';
|
||||||
}
|
}
|
||||||
|
@ -527,6 +534,7 @@ class Reference {
|
||||||
}
|
}
|
||||||
|
|
||||||
Constructor get asConstructor {
|
Constructor get asConstructor {
|
||||||
|
NamedNode? node = this.node;
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
throw '$this is not bound to an AST node. A constructor was expected';
|
throw '$this is not bound to an AST node. A constructor was expected';
|
||||||
}
|
}
|
||||||
|
@ -534,6 +542,7 @@ class Reference {
|
||||||
}
|
}
|
||||||
|
|
||||||
Procedure get asProcedure {
|
Procedure get asProcedure {
|
||||||
|
NamedNode? node = this.node;
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
throw '$this is not bound to an AST node. A procedure was expected';
|
throw '$this is not bound to an AST node. A procedure was expected';
|
||||||
}
|
}
|
||||||
|
@ -541,6 +550,7 @@ class Reference {
|
||||||
}
|
}
|
||||||
|
|
||||||
Typedef get asTypedef {
|
Typedef get asTypedef {
|
||||||
|
NamedNode? node = this.node;
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
throw '$this is not bound to an AST node. A typedef was expected';
|
throw '$this is not bound to an AST node. A typedef was expected';
|
||||||
}
|
}
|
||||||
|
@ -548,6 +558,7 @@ class Reference {
|
||||||
}
|
}
|
||||||
|
|
||||||
Extension get asExtension {
|
Extension get asExtension {
|
||||||
|
NamedNode? node = this.node;
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
throw '$this is not bound to an AST node. An extension was expected';
|
throw '$this is not bound to an AST node. An extension was expected';
|
||||||
}
|
}
|
||||||
|
@ -555,6 +566,7 @@ class Reference {
|
||||||
}
|
}
|
||||||
|
|
||||||
InlineClass get asInlineClass {
|
InlineClass get asInlineClass {
|
||||||
|
NamedNode? node = this.node;
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
throw '$this is not bound to an AST node. An inline class was expected';
|
throw '$this is not bound to an AST node. An inline class was expected';
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue