Skip to content

Commit dc77baa

Browse files
jensjohaCommit Queue
authored andcommitted
[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 <[email protected]> Commit-Queue: Jens Johansen <[email protected]>
1 parent e5c2dd2 commit dc77baa

File tree

1 file changed

+31
-19
lines changed

1 file changed

+31
-19
lines changed

pkg/kernel/lib/canonical_name.dart

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -438,26 +438,29 @@ class Reference {
438438
NamedNode? _node;
439439

440440
NamedNode? get node {
441-
if (_node == null) {
442-
// Either this is an unbound reference or it belongs to a lazy-loaded
443-
// (and not yet loaded) class. If it belongs to a lazy-loaded class,
444-
// load the class.
445-
446-
CanonicalName? canonicalNameParent = canonicalName?.parent;
447-
while (canonicalNameParent != null) {
448-
if (canonicalNameParent.name.startsWith("@")) {
449-
break;
450-
}
451-
canonicalNameParent = canonicalNameParent.parent;
441+
return _node ?? _tryLoadNode();
442+
}
443+
444+
/// If the node belongs to a lazy-loaded class load the class.
445+
///
446+
/// Should only be called if [_node] is null, meaning that either this
447+
/// is an unbound reference or it belongs to a lazy-loaded
448+
/// (and not yet loaded) class. If it belongs to a lazy-loaded class this call
449+
/// will load the class and set [_node].
450+
NamedNode? _tryLoadNode() {
451+
CanonicalName? canonicalNameParent = canonicalName?.parent;
452+
while (canonicalNameParent != null) {
453+
if (canonicalNameParent.name.startsWith("@")) {
454+
break;
452455
}
453-
if (canonicalNameParent != null) {
454-
NamedNode? parentNamedNode =
455-
canonicalNameParent.parent?.reference._node;
456-
if (parentNamedNode is Class) {
457-
Class parentClass = parentNamedNode;
458-
if (parentClass.lazyBuilder != null) {
459-
parentClass.ensureLoaded();
460-
}
456+
canonicalNameParent = canonicalNameParent.parent;
457+
}
458+
if (canonicalNameParent != null) {
459+
NamedNode? parentNamedNode = canonicalNameParent.parent?.reference._node;
460+
if (parentNamedNode is Class) {
461+
Class parentClass = parentNamedNode;
462+
if (parentClass.lazyBuilder != null) {
463+
parentClass.ensureLoaded();
461464
}
462465
}
463466
}
@@ -499,62 +502,71 @@ class Reference {
499502
}
500503

501504
Library get asLibrary {
505+
NamedNode? node = this.node;
502506
if (node == null) {
503507
throw '$this is not bound to an AST node. A library was expected';
504508
}
505509
return node as Library;
506510
}
507511

508512
Class get asClass {
513+
NamedNode? node = this.node;
509514
if (node == null) {
510515
throw '$this is not bound to an AST node. A class was expected';
511516
}
512517
return node as Class;
513518
}
514519

515520
Member get asMember {
521+
NamedNode? node = this.node;
516522
if (node == null) {
517523
throw '$this is not bound to an AST node. A member was expected';
518524
}
519525
return node as Member;
520526
}
521527

522528
Field get asField {
529+
NamedNode? node = this.node;
523530
if (node == null) {
524531
throw '$this is not bound to an AST node. A field was expected';
525532
}
526533
return node as Field;
527534
}
528535

529536
Constructor get asConstructor {
537+
NamedNode? node = this.node;
530538
if (node == null) {
531539
throw '$this is not bound to an AST node. A constructor was expected';
532540
}
533541
return node as Constructor;
534542
}
535543

536544
Procedure get asProcedure {
545+
NamedNode? node = this.node;
537546
if (node == null) {
538547
throw '$this is not bound to an AST node. A procedure was expected';
539548
}
540549
return node as Procedure;
541550
}
542551

543552
Typedef get asTypedef {
553+
NamedNode? node = this.node;
544554
if (node == null) {
545555
throw '$this is not bound to an AST node. A typedef was expected';
546556
}
547557
return node as Typedef;
548558
}
549559

550560
Extension get asExtension {
561+
NamedNode? node = this.node;
551562
if (node == null) {
552563
throw '$this is not bound to an AST node. An extension was expected';
553564
}
554565
return node as Extension;
555566
}
556567

557568
InlineClass get asInlineClass {
569+
NamedNode? node = this.node;
558570
if (node == null) {
559571
throw '$this is not bound to an AST node. An inline class was expected';
560572
}

0 commit comments

Comments
 (0)