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

Unified Diff: pkg/compiler/lib/src/universe/function_set.dart

Issue 1303363006: Cleanup of function_set.dart (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comments + fix Created 5 years, 4 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 | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/universe/function_set.dart
diff --git a/pkg/compiler/lib/src/universe/function_set.dart b/pkg/compiler/lib/src/universe/function_set.dart
index 0b4b0bc9990cddaea99aa8426fa507bc4e1e7696..5f8dedd36783087462b216921ff5359afc8b719a 100644
--- a/pkg/compiler/lib/src/universe/function_set.dart
+++ b/pkg/compiler/lib/src/universe/function_set.dart
@@ -13,6 +13,8 @@ class FunctionSet {
new Map<String, FunctionSetNode>();
FunctionSet(this.compiler);
+ ClassWorld get classWorld => compiler.world;
+
FunctionSetNode newNode(String name)
=> new FunctionSetNode(name);
@@ -44,30 +46,50 @@ class FunctionSet {
: false;
}
- /**
- * Returns an object that allows iterating over all the functions
- * that may be invoked with the given [selector].
- */
+ /// Returns an object that allows iterating over all the functions
+ /// that may be invoked with the given [selector].
Iterable<Element> filter(Selector selector, TypeMask mask) {
return query(selector, mask).functions;
}
+ /// Returns the mask for the potential receivers of a dynamic call to
+ /// [selector] on [mask].
+ ///
+ /// This will reduce the set of classes in [mask] to a [TypeMask] of the set
+ /// of classes that actually implement the selected member or implement the
+ /// handling 'noSuchMethod' where the selected member is unimplemented.
TypeMask receiverType(Selector selector, TypeMask mask) {
- return query(selector, mask).computeMask(compiler.world);
+ return query(selector, mask).computeMask(classWorld);
+ }
+
+ SelectorMask _createSelectorMask(
+ Selector selector, TypeMask mask, ClassWorld classWorld) {
+ return mask != null
+ ? new SelectorMask(selector, mask)
+ : new SelectorMask(selector,
+ new TypeMask.subclass(classWorld.objectClass, classWorld));
}
+ /// Returns the set of functions that can be the target of a call to
+ /// [selector] on a receiver of type [mask] including 'noSuchMethod' methods
+ /// where applicable.
FunctionSetQuery query(Selector selector, TypeMask mask) {
String name = selector.name;
+ SelectorMask selectorMask = _createSelectorMask(selector, mask, classWorld);
+ SelectorMask noSuchMethodMask =
+ new SelectorMask(Selectors.noSuchMethod_, selectorMask.mask);
FunctionSetNode node = nodes[name];
FunctionSetNode noSuchMethods = nodes[Identifiers.noSuchMethod_];
if (node != null) {
- return node.query(selector, mask, compiler, noSuchMethods);
+ return node.query(
+ selectorMask, classWorld, noSuchMethods, noSuchMethodMask);
}
// If there is no method that matches [selector] we know we can
// only hit [:noSuchMethod:].
- if (noSuchMethods == null) return const FunctionSetQuery(const <Element>[]);
- return noSuchMethods.query(
- Selectors.noSuchMethod_, mask, compiler, null);
+ if (noSuchMethods == null) {
+ return const EmptyFunctionSetQuery();
+ }
+ return noSuchMethods.query(noSuchMethodMask, classWorld);
}
void forEach(Function action) {
@@ -77,6 +99,8 @@ class FunctionSet {
}
}
+/// A selector/mask pair representing the dynamic invocation of [selector] on
+/// a receiver of type [mask].
class SelectorMask {
final Selector selector;
final TypeMask mask;
@@ -86,16 +110,21 @@ class SelectorMask {
: this.selector = selector,
this.mask = mask,
this.hashCode =
- Hashing.mixHashCodeBits(selector.hashCode, mask.hashCode);
+ Hashing.mixHashCodeBits(selector.hashCode, mask.hashCode) {
+ assert(mask != null);
+ }
String get name => selector.name;
bool applies(Element element, ClassWorld classWorld) {
if (!selector.appliesUnnamed(element, classWorld)) return false;
- if (mask == null) return true;
return mask.canHit(element, selector, classWorld);
}
+ bool needsNoSuchMethodHandling(ClassWorld classWorld) {
+ return mask.needsNoSuchMethodHandling(selector, classWorld);
+ }
+
bool operator ==(other) {
if (identical(this, other)) return true;
return selector == other.selector && mask == other.mask;
@@ -104,6 +133,8 @@ class SelectorMask {
String toString() => '($selector,$mask)';
}
+/// A node in the [FunctionSet] caching all [FunctionSetQuery] object for
+/// selectors with the same [name].
class FunctionSetNode {
final String name;
final Map<SelectorMask, FunctionSetQuery> cache =
@@ -164,24 +195,13 @@ class FunctionSetNode {
elements.forEach(action);
}
- TypeMask getNonNullTypeMaskOfSelector(TypeMask mask, ClassWorld classWorld) {
- // TODO(ngeoffray): We should probably change untyped selector
- // to always be a subclass of Object.
- return mask != null
- ? mask
- : new TypeMask.subclass(classWorld.objectClass, classWorld);
- }
-
- // TODO(johnniwinther): Use [SelectorMask] instead of [Selector] and
- // [TypeMask].
- FunctionSetQuery query(Selector selector,
- TypeMask mask,
- Compiler compiler,
- FunctionSetNode noSuchMethods) {
- mask = getNonNullTypeMaskOfSelector(mask, compiler.world);
- SelectorMask selectorMask = new SelectorMask(selector, mask);
- ClassWorld classWorld = compiler.world;
- assert(selector.name == name);
+ /// Returns the set of functions that can be the target of [selectorMask]
+ /// including no such method handling where applicable.
+ FunctionSetQuery query(SelectorMask selectorMask,
+ ClassWorld classWorld,
+ [FunctionSetNode noSuchMethods,
+ SelectorMask noSuchMethodMask]) {
+ assert(selectorMask.name == name);
FunctionSetQuery result = cache[selectorMask];
if (result != null) return result;
@@ -201,13 +221,10 @@ class FunctionSetNode {
// If we cannot ensure a method will be found at runtime, we also
// add [noSuchMethod] implementations that apply to [mask] as
// potential targets.
- if (noSuchMethods != null
- && mask.needsNoSuchMethodHandling(selector, classWorld)) {
- FunctionSetQuery noSuchMethodQuery = noSuchMethods.query(
- Selectors.noSuchMethod_,
- mask,
- compiler,
- null);
+ if (noSuchMethods != null &&
+ selectorMask.needsNoSuchMethodHandling(classWorld)) {
+ FunctionSetQuery noSuchMethodQuery =
+ noSuchMethods.query(noSuchMethodMask, classWorld);
if (!noSuchMethodQuery.functions.isEmpty) {
if (functions == null) {
functions = new Setlet<Element>.from(noSuchMethodQuery.functions);
@@ -217,31 +234,43 @@ class FunctionSetNode {
}
}
cache[selectorMask] = result = (functions != null)
- ? newQuery(functions, selector, mask, compiler)
- : const FunctionSetQuery(const <Element>[]);
+ ? new FullFunctionSetQuery(functions)
+ : const EmptyFunctionSetQuery();
return result;
}
+}
- FunctionSetQuery newQuery(Iterable<Element> functions,
- Selector selector,
- TypeMask mask,
- Compiler compiler) {
- return new FullFunctionSetQuery(functions);
- }
+/// A set of functions that are the potential targets of all call sites sharing
+/// the same receiver mask and selector.
+abstract class FunctionSetQuery {
+ const FunctionSetQuery();
+
+ /// Compute the type of all potential receivers of this function set.
+ TypeMask computeMask(ClassWorld classWorld);
+
+ /// Returns all potential targets of this function set.
+ Iterable<Element> get functions;
}
-class FunctionSetQuery {
- final Iterable<Element> functions;
+class EmptyFunctionSetQuery implements FunctionSetQuery {
+ const EmptyFunctionSetQuery();
+
+ @override
TypeMask computeMask(ClassWorld classWorld) => const TypeMask.nonNullEmpty();
- const FunctionSetQuery(this.functions);
+
+ @override
+ Iterable<Element> get functions => const <Element>[];
}
-class FullFunctionSetQuery extends FunctionSetQuery {
+class FullFunctionSetQuery implements FunctionSetQuery {
+ @override
+ final Iterable<Element> functions;
+
TypeMask _mask;
- /**
- * Compute the type of all potential receivers of this function set.
- */
+ FullFunctionSetQuery(this.functions);
+
+ @override
TypeMask computeMask(ClassWorld classWorld) {
assert(classWorld.hasAnyStrictSubclass(classWorld.objectClass));
if (_mask != null) return _mask;
@@ -259,6 +288,4 @@ class FullFunctionSetQuery extends FunctionSetQuery {
}),
classWorld);
}
-
- FullFunctionSetQuery(functions) : super(functions);
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698