Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(532)

Unified Diff: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart

Issue 1375213003: dart2js cps: Maintain parent pointers instead of recomputing them. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
index 19b0543c179877ab2a4d7ba2c7061d8822b6f116..7b8ebb205938cb97c619d7e42b1239c0ec8c961b 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
@@ -28,7 +28,16 @@ abstract class Node {
static int _usedHashCodes = 0;
final int hashCode = ++_usedHashCodes;
+ Node() {
+ setParentPointers();
+ }
+
accept(Visitor visitor);
+
+ /// Updates the [parent] of the immediate children to refer to this node.
+ ///
+ /// All constructors call this method to initialize parent pointers.
+ void setParentPointers();
}
/// Expressions can be evaluated, and may diverge, throw, and/or have
@@ -318,8 +327,12 @@ class LetPrim extends InteriorExpression {
}
accept(Visitor visitor) => visitor.visitLetPrim(this);
-}
+ void setParentPointers() {
+ primitive.parent = this;
+ if (body != null) body.parent = this;
+ }
+}
/// Binding continuations.
///
@@ -354,6 +367,11 @@ class LetCont extends InteriorExpression {
}
accept(Visitor visitor) => visitor.visitLetCont(this);
+
+ void setParentPointers() {
+ _setParentsOnNodes(continuations, this);
+ if (body != null) body.parent = this;
+ }
}
// Binding an exception handler.
@@ -372,6 +390,11 @@ class LetHandler extends InteriorExpression {
LetHandler(this.handler, this.body);
accept(Visitor visitor) => visitor.visitLetHandler(this);
+
+ void setParentPointers() {
+ handler.parent = this;
+ if (body != null) body.parent = this;
+ }
}
/// Binding mutable variables.
@@ -396,6 +419,12 @@ class LetMutable extends InteriorExpression {
}
accept(Visitor visitor) => visitor.visitLetMutable(this);
+
+ void setParentPointers() {
+ variable.parent = this;
+ value.parent = this;
+ if (body != null) body.parent = this;
+ }
}
/// Invoke a static function.
@@ -428,6 +457,11 @@ class InvokeStatic extends CallExpression {
[this.sourceInformation]);
accept(Visitor visitor) => visitor.visitInvokeStatic(this);
+
+ void setParentPointers() {
+ _setParentsOnList(arguments, this);
+ continuation.parent = this;
+ }
}
/// Invoke a method on an object.
@@ -479,6 +513,12 @@ class InvokeMethod extends CallExpression {
this.sourceInformation);
accept(Visitor visitor) => visitor.visitInvokeMethod(this);
+
+ void setParentPointers() {
+ receiver.parent = this;
+ _setParentsOnList(arguments, this);
+ continuation.parent = this;
+ }
}
/// Invoke [target] on [receiver], bypassing dispatch and override semantics.
@@ -519,6 +559,12 @@ class InvokeMethodDirectly extends CallExpression {
this.continuation = new Reference<Continuation>(continuation);
accept(Visitor visitor) => visitor.visitInvokeMethodDirectly(this);
+
+ void setParentPointers() {
+ receiver.parent = this;
+ _setParentsOnList(arguments, this);
+ continuation.parent = this;
+ }
}
/// Non-const call to a constructor.
@@ -554,6 +600,11 @@ class InvokeConstructor extends CallExpression {
continuation = new Reference<Continuation>(cont);
accept(Visitor visitor) => visitor.visitInvokeConstructor(this);
+
+ void setParentPointers() {
+ _setParentsOnList(arguments, this);
+ continuation.parent = this;
+ }
}
/// An alias for [value] in a context where the value is known to satisfy
@@ -576,6 +627,10 @@ class Refinement extends Primitive {
accept(Visitor visitor) => visitor.visitRefinement(this);
Primitive get effectiveDefinition => value.definition.effectiveDefinition;
+
+ void setParentPointers() {
+ value.parent = this;
+ }
}
/// An "is" type test.
@@ -612,6 +667,11 @@ class TypeTest extends Primitive {
bool get isSafeForElimination => true;
bool get isSafeForReordering => true;
+
+ void setParentPointers() {
+ value.parent = this;
+ _setParentsOnList(typeArguments, this);
+ }
}
/// An "as" type cast.
@@ -641,6 +701,10 @@ class TypeCast extends CallExpression {
this.continuation = new Reference<Continuation>(cont);
accept(Visitor visitor) => visitor.visitTypeCast(this);
+
+ void setParentPointers() {
+ value.parent = this;
+ }
}
/// Apply a built-in operator.
@@ -660,6 +724,10 @@ class ApplyBuiltinOperator extends Primitive {
bool get isSafeForElimination => true;
bool get isSafeForReordering => true;
+
+ void setParentPointers() {
+ _setParentsOnList(arguments, this);
+ }
}
/// Apply a built-in method.
@@ -685,6 +753,11 @@ class ApplyBuiltinMethod extends Primitive {
bool get isSafeForElimination => false;
bool get isSafeForReordering => false;
+
+ void setParentPointers() {
+ receiver.parent = this;
+ _setParentsOnList(arguments, this);
+ }
}
/// Throw a value.
@@ -697,6 +770,10 @@ class Throw extends TailExpression {
Throw(Primitive value) : value = new Reference<Primitive>(value);
accept(Visitor visitor) => visitor.visitThrow(this);
+
+ void setParentPointers() {
+ value.parent = this;
+ }
}
/// Rethrow
@@ -706,6 +783,7 @@ class Throw extends TailExpression {
/// the same stack trace as the enclosing handler.
class Rethrow extends TailExpression {
accept(Visitor visitor) => visitor.visitRethrow(this);
+ void setParentPointers() {}
}
/// An expression that is known to be unreachable.
@@ -714,6 +792,7 @@ class Rethrow extends TailExpression {
/// known never to invoke it, e.g. because the calling expression always throws.
class Unreachable extends TailExpression {
accept(Visitor visitor) => visitor.visitUnreachable(this);
+ void setParentPointers() {}
}
/// Gets the value from a [MutableVariable].
@@ -733,6 +812,10 @@ class GetMutable extends Primitive {
bool get isSafeForElimination => true;
bool get isSafeForReordering => false;
+
+ void setParentPointers() {
+ variable.parent = this;
+ }
}
/// Assign a [MutableVariable].
@@ -753,6 +836,11 @@ class SetMutable extends Primitive {
bool get isSafeForElimination => false;
bool get isSafeForReordering => false;
+
+ void setParentPointers() {
+ variable.parent = this;
+ value.parent = this;
+ }
}
/// Invoke a continuation in tail position.
@@ -791,6 +879,11 @@ class InvokeContinuation extends TailExpression {
sourceInformation = null;
accept(Visitor visitor) => visitor.visitInvokeContinuation(this);
+
+ void setParentPointers() {
+ if (continuation != null) continuation.parent = this;
+ if (arguments != null) _setParentsOnList(arguments, this);
+ }
}
/// Choose between a pair of continuations based on a condition value.
@@ -825,6 +918,12 @@ class Branch extends TailExpression {
this.isStrictCheck = false;
accept(Visitor visitor) => visitor.visitBranch(this);
+
+ void setParentPointers() {
+ condition.parent = this;
+ trueContinuation.parent = this;
+ falseContinuation.parent = this;
+ }
}
/// Directly assigns to a field on a given object.
@@ -841,6 +940,11 @@ class SetField extends Primitive {
bool get isSafeForElimination => false;
bool get isSafeForReordering => false;
+
+ void setParentPointers() {
+ object.parent = this;
+ value.parent = this;
+ }
}
/// Directly reads from a field on a given object.
@@ -864,6 +968,10 @@ class GetField extends Primitive {
bool get isSafeForReordering => false;
toString() => 'GetField($field)';
+
+ void setParentPointers() {
+ object.parent = this;
+ }
}
/// Get the length of a string or native list.
@@ -879,6 +987,10 @@ class GetLength extends Primitive {
bool get isSafeForReordering => false;
accept(Visitor v) => v.visitGetLength(this);
+
+ void setParentPointers() {
+ object.parent = this;
+ }
}
/// Read an entry from a string or native list.
@@ -900,6 +1012,11 @@ class GetIndex extends Primitive {
bool get isSafeForReordering => false;
accept(Visitor v) => v.visitGetIndex(this);
+
+ void setParentPointers() {
+ object.parent = this;
+ index.parent = this;
+ }
}
/// Set an entry on a native list.
@@ -921,6 +1038,12 @@ class SetIndex extends Primitive {
bool get isSafeForReordering => false;
accept(Visitor v) => v.visitSetIndex(this);
+
+ void setParentPointers() {
+ object.parent = this;
+ index.parent = this;
+ value.parent = this;
+ }
}
/// Reads the value of a static field or tears off a static method.
@@ -941,6 +1064,8 @@ class GetStatic extends Primitive {
bool get isSafeForReordering {
return element is FunctionElement || element.isFinal;
}
+
+ void setParentPointers() {}
}
/// Sets the value of a static field.
@@ -956,6 +1081,10 @@ class SetStatic extends Primitive {
bool get isSafeForElimination => false;
bool get isSafeForReordering => false;
+
+ void setParentPointers() {
+ value.parent = this;
+ }
}
/// Reads the value of a lazily initialized static field.
@@ -975,6 +1104,10 @@ class GetLazyStatic extends CallExpression {
: continuation = new Reference<Continuation>(continuation);
accept(Visitor visitor) => visitor.visitGetLazyStatic(this);
+
+ void setParentPointers() {
+ continuation.parent = this;
+ }
}
/// Creates an object for holding boxed variables captured by a closure.
@@ -983,6 +1116,8 @@ class CreateBox extends Primitive {
bool get isSafeForElimination => true;
bool get isSafeForReordering => true;
+
+ void setParentPointers() {}
}
/// Creates an instance of a class and initializes its fields and runtime type
@@ -1015,6 +1150,11 @@ class CreateInstance extends Primitive {
bool get isSafeForReordering => true;
toString() => 'CreateInstance($classElement)';
+
+ void setParentPointers() {
+ _setParentsOnList(arguments, this);
+ if (typeInformation != null) _setParentsOnList(typeInformation, this);
+ }
}
class Interceptor extends Primitive {
@@ -1041,6 +1181,10 @@ class Interceptor extends Primitive {
bool get isSafeForElimination => true;
bool get isSafeForReordering => true;
+
+ void setParentPointers() {
+ input.parent = this;
+ }
}
/// Create an instance of [Invocation] for use in a call to `noSuchMethod`.
@@ -1055,6 +1199,10 @@ class CreateInvocationMirror extends Primitive {
bool get isSafeForElimination => true;
bool get isSafeForReordering => true;
+
+ void setParentPointers() {
+ _setParentsOnList(arguments, this);
+ }
}
class ForeignCode extends CallExpression {
@@ -1071,6 +1219,11 @@ class ForeignCode extends CallExpression {
this.continuation = new Reference<Continuation>(continuation);
accept(Visitor visitor) => visitor.visitForeignCode(this);
+
+ void setParentPointers() {
+ _setParentsOnList(arguments, this);
+ continuation.parent = this;
+ }
}
class Constant extends Primitive {
@@ -1085,6 +1238,8 @@ class Constant extends Primitive {
bool get isSafeForElimination => true;
bool get isSafeForReordering => true;
+
+ void setParentPointers() {}
}
class LiteralList extends Primitive {
@@ -1099,6 +1254,10 @@ class LiteralList extends Primitive {
bool get isSafeForElimination => true;
bool get isSafeForReordering => true;
+
+ void setParentPointers() {
+ _setParentsOnList(values, this);
+ }
}
class LiteralMapEntry {
@@ -1120,6 +1279,13 @@ class LiteralMap extends Primitive {
bool get isSafeForElimination => true;
bool get isSafeForReordering => true;
+
+ void setParentPointers() {
+ for (LiteralMapEntry entry in entries) {
+ entry.key.parent = this;
+ entry.value.parent = this;
+ }
+ }
}
/// Currently unused.
@@ -1141,6 +1307,8 @@ class CreateFunction extends Primitive {
bool get isSafeForElimination => true;
bool get isSafeForReordering => true;
+
+ void setParentPointers() {}
}
class Parameter extends Primitive {
@@ -1148,18 +1316,14 @@ class Parameter extends Primitive {
super.hint = hint;
}
- // In addition to a parent pointer to the containing Continuation or
- // FunctionDefinition, parameters have an index into the list of parameters
- // bound by the parent. This gives constant-time access to the continuation
- // from the parent.
- int parentIndex;
-
accept(Visitor visitor) => visitor.visitParameter(this);
String toString() => 'Parameter(${hint == null ? null : hint.name})';
bool get isSafeForElimination => true;
bool get isSafeForReordering => true;
+
+ void setParentPointers() {}
}
/// Continuations are normally bound by 'let cont'. A continuation with one
@@ -1169,11 +1333,6 @@ class Continuation extends Definition<Continuation> implements InteriorNode {
final List<Parameter> parameters;
Expression body = null;
- // In addition to a parent pointer to the containing LetCont, continuations
- // have an index into the list of continuations bound by the LetCont. This
- // gives constant-time access to the continuation from the parent.
- int parent_index;
-
// A continuation is recursive if it has any recursive invocations.
bool isRecursive;
@@ -1186,6 +1345,11 @@ class Continuation extends Definition<Continuation> implements InteriorNode {
isRecursive = false;
accept(Visitor visitor) => visitor.visitContinuation(this);
+
+ void setParentPointers() {
+ _setParentsOnNodes(parameters, this);
+ if (body != null) body.parent = this;
+ }
}
/// Common interface for [Primitive] and [MutableVariable].
@@ -1203,6 +1367,8 @@ class MutableVariable extends Variable<MutableVariable> {
MutableVariable(this.hint);
accept(Visitor v) => v.visitMutableVariable(this);
+
+ void setParentPointers() {}
}
/// A function definition, consisting of parameters and a body.
@@ -1223,6 +1389,13 @@ class FunctionDefinition extends InteriorNode {
this.body);
accept(Visitor visitor) => visitor.visitFunctionDefinition(this);
+
+ void setParentPointers() {
+ if (thisParameter != null) thisParameter.parent = this;
+ _setParentsOnNodes(parameters, this);
+ returnContinuation.parent = this;
+ if (body != null) body.parent = this;
+ }
}
/// Converts the internal representation of a type to a Dart object of type
@@ -1242,6 +1415,10 @@ class ReifyRuntimeType extends Primitive {
bool get isSafeForElimination => true;
bool get isSafeForReordering => true;
+
+ void setParentPointers() {
+ value.parent = this;
+ }
}
/// Read the value the type variable [variable] from the target object.
@@ -1262,6 +1439,10 @@ class ReadTypeVariable extends Primitive {
bool get isSafeForElimination => true;
bool get isSafeForReordering => true;
+
+ void setParentPointers() {
+ target.parent = this;
+ }
}
/// Representation of a closed type (that is, a type without type variables).
@@ -1287,6 +1468,10 @@ class TypeExpression extends Primitive {
bool get isSafeForElimination => true;
bool get isSafeForReordering => true;
+
+ void setParentPointers() {
+ _setParentsOnList(arguments, this);
+ }
}
class Await extends CallExpression {
@@ -1301,6 +1486,11 @@ class Await extends CallExpression {
accept(Visitor visitor) {
return visitor.visitAwait(this);
}
+
+ void setParentPointers() {
+ input.parent = this;
+ continuation.parent = this;
+ }
}
class Yield extends CallExpression {
@@ -1316,12 +1506,29 @@ class Yield extends CallExpression {
accept(Visitor visitor) {
return visitor.visitYield(this);
}
+
+ void setParentPointers() {
+ input.parent = this;
+ continuation.parent = this;
+ }
}
List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) {
return definitions.map((e) => new Reference<Primitive>(e)).toList();
}
+void _setParentsOnNodes(List<Node> nodes, Node parent) {
+ for (Node node in nodes) {
+ node.parent = parent;
+ }
+}
+
+void _setParentsOnList(List<Reference> nodes, Node parent) {
+ for (Reference node in nodes) {
+ node.parent = parent;
+ }
+}
+
abstract class Visitor<T> {
const Visitor();
@@ -1382,13 +1589,20 @@ abstract class Visitor<T> {
T visitForeignCode(ForeignCode node);
}
-/// Visits all non-recursive children of a CPS term, i.e. anything
-/// not of type [Expression] or [Continuation].
+/// Recursively visits all children of a CPS term.
+///
+/// The user of the class is responsible for avoiding stack overflows from
+/// deep recursion, e.g. by overriding methods to cut off recursion at certain
+/// points.
+///
+/// All recursive invocations occur through the [visit] method, which the
+/// subclass may override as a generic way to control the visitor without
+/// overriding all visitor methods.
///
/// The `process*` methods are called in pre-order for every node visited.
/// These can be overridden without disrupting the visitor traversal.
-class LeafVisitor implements Visitor {
- const LeafVisitor();
+class DeepRecursiveVisitor implements Visitor {
+ const DeepRecursiveVisitor();
visit(Node node) => node.accept(this);
@@ -1400,25 +1614,36 @@ class LeafVisitor implements Visitor {
if (node.thisParameter != null) visit(node.thisParameter);
node.parameters.forEach(visit);
visit(node.returnContinuation);
+ visit(node.body);
}
- // Expressions.
+ processContinuation(Continuation node) {}
+ visitContinuation(Continuation node) {
+ processContinuation(node);
+ node.parameters.forEach(visit);
+ if (node.body != null) visit(node.body);
+ }
+ // Expressions.
processLetPrim(LetPrim node) {}
visitLetPrim(LetPrim node) {
processLetPrim(node);
visit(node.primitive);
+ visit(node.body);
}
processLetCont(LetCont node) {}
visitLetCont(LetCont node) {
processLetCont(node);
node.continuations.forEach(visit);
+ visit(node.body);
}
processLetHandler(LetHandler node) {}
visitLetHandler(LetHandler node) {
processLetHandler(node);
+ visit(node.handler);
+ visit(node.body);
}
processLetMutable(LetMutable node) {}
@@ -1426,6 +1651,7 @@ class LeafVisitor implements Visitor {
processLetMutable(node);
visit(node.variable);
processReference(node.value);
+ visit(node.body);
}
processInvokeStatic(InvokeStatic node) {}
@@ -1554,12 +1780,6 @@ class LeafVisitor implements Visitor {
processParameter(node);
}
- processContinuation(Continuation node) {}
- visitContinuation(Continuation node) {
- processContinuation(node);
- node.parameters.forEach(visitParameter);
- }
-
processInterceptor(Interceptor node) {}
visitInterceptor(Interceptor node) {
processInterceptor(node);
@@ -1720,7 +1940,7 @@ typedef void StackAction();
///
/// Subclasses should not override the `visit` methods for the nodes that have
/// a `traverse` method.
-class RecursiveVisitor extends LeafVisitor {
+class TrampolineRecursiveVisitor extends DeepRecursiveVisitor {
List<StackAction> _stack = <StackAction>[];
void pushAction(StackAction callback) {
@@ -1815,7 +2035,7 @@ class RecursiveVisitor extends LeafVisitor {
}
/// Visit a just-deleted subterm and unlink all [Reference]s in it.
-class RemovalVisitor extends RecursiveVisitor {
+class RemovalVisitor extends TrampolineRecursiveVisitor {
processReference(Reference reference) {
reference.unlink();
}

Powered by Google App Engine
This is Rietveld 408576698