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

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

Issue 1409803003: dart2js cps: More interceptor optimizations and fixes. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix indentation Created 5 years, 2 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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 cbb45f0e81aa9504dbe05bdf5a26d544672b77a4..1df27b6739fb4e551e378f0aa142018eb6f18a1e 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
@@ -1184,22 +1184,85 @@ class CreateInstance extends Primitive {
}
}
+/// Obtains the interceptor for the given value. This is a method table
+/// corresponding to the Dart class of the value.
+///
+/// All values are either intercepted or self-intercepted. The interceptor for
+/// an "intercepted value" is one of the subclasses of Interceptor.
+/// The interceptor for a "self-intercepted value" is the value itself.
+///
+/// If the input is an intercepted value, and any of its superclasses is in
+/// [interceptedClasses], the method table for the input is returned.
+/// Otherwise, the input itself is returned.
+///
+/// There are thus three significant cases:
+/// - the input is a self-interceptor
+/// - the input is an intercepted value and is caught by [interceptedClasses]
+/// - the input is an intercepted value but is bypassed by [interceptedClasses]
+///
+/// The [flags] field indicates which of the above cases may happen, with
+/// additional special cases for null (which can either by intercepted or
+/// bypassed).
class Interceptor extends Primitive {
final Reference<Primitive> input;
final Set<ClassElement> interceptedClasses = new Set<ClassElement>();
final SourceInformation sourceInformation;
- /// If non-null, all uses of this the interceptor call are guaranteed to
- /// see this value.
- ///
- /// The interceptor call is not immediately replaced by the constant, because
- /// that might prevent the interceptor from being shared.
- ///
- /// The precise input type is not known when sharing interceptors, because
- /// refinement nodes have been removed by then. So this field carries the
- /// known constant until we know if it should be shared or replaced by
- /// the constant.
- values.InterceptorConstantValue constantValue;
+ /// The input was a self-interceptor.
+ static const int SELF_INTERCEPT = 1 << 0;
+
+ /// A non-null value was mapped to an interceptor that was mentioned in
+ /// [interceptedClasses].
+ static const int NON_NULL_INTERCEPT_EXACT = 1 << 1;
+
+ /// A non-null value was mapped to an interceptor that is a subclass of
+ /// one mentioned in [interceptedClasses].
+ static const int NON_NULL_INTERCEPT_SUBCLASS = 1 << 2;
+
+ /// A non-null intercepted value was bypassed because none of its supertypes
+ /// were mentioned in [interceptedClasses].
+ static const int NON_NULL_BYPASS = 1 << 3;
+
+ /// Null was returned as-is.
+ static const int NULL_BYPASS = 1 << 4;
+
+ /// Null was mapped to JSNull, which was mentioned in [interceptedClasses].
+ static const int NULL_INTERCEPT_EXACT = 1 << 5;
+
+ /// Null was mapped to JSNull, because a superclass thereof (the interceptor
+ /// root class) was mentioned in [interceptedClasses].
+ static const int NULL_INTERCEPT_SUBCLASS = 1 << 6;
+
+ static const int NON_NULL_INTERCEPT = NON_NULL_INTERCEPT_EXACT |
+ NON_NULL_INTERCEPT_SUBCLASS;
+ static const int NULL_INTERCEPT = NULL_INTERCEPT_EXACT |
+ NULL_INTERCEPT_SUBCLASS;
+ static const int NULL = NULL_BYPASS |
+ NULL_INTERCEPT;
+ static const int INTERCEPT_EXACT = NON_NULL_INTERCEPT_EXACT |
+ NULL_INTERCEPT_EXACT;
+ static const int INTERCEPT_SUBCLASS = NON_NULL_INTERCEPT_SUBCLASS |
+ NULL_INTERCEPT_SUBCLASS;
+ static const int INTERCEPT = NULL_INTERCEPT | NON_NULL_INTERCEPT;
+ static const int BYPASS = NULL_BYPASS | NON_NULL_BYPASS;
+
+ static const int ALL_FLAGS = SELF_INTERCEPT | BYPASS | INTERCEPT;
+
+ /// Which of the above cases may happen at runtime. Set by type propagation.
+ int flags = ALL_FLAGS;
+
+ void clearFlag(int flag) {
+ flags &= ~flag;
+ }
+
+ bool get isAlwaysIntercepted => flags & ~INTERCEPT == 0;
+ bool get isAlwaysNullOrIntercepted => flags & ~(NULL | INTERCEPT) == 0;
+
+ /// If the value is intercepted, it always matches exactly a class in
+ /// [interceptedClasses].
+ bool get isInterceptedClassAlwaysExact {
+ return flags & (INTERCEPT & ~INTERCEPT_EXACT) == 0;
+ }
Interceptor(Primitive input, this.sourceInformation)
: this.input = new Reference<Primitive>(input);
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698