Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/js_backend/backend.dart |
| =================================================================== |
| --- sdk/lib/_internal/compiler/implementation/js_backend/backend.dart (revision 19046) |
| +++ sdk/lib/_internal/compiler/implementation/js_backend/backend.dart (working copy) |
| @@ -642,7 +642,6 @@ |
| ClassElement jsFunctionClass; |
| ClassElement jsNullClass; |
| ClassElement jsBoolClass; |
| - ClassElement objectInterceptorClass; |
| Element jsArrayLength; |
| Element jsStringLength; |
| Element jsArrayRemoveLast; |
| @@ -651,6 +650,7 @@ |
| Element jsStringConcat; |
| Element jsStringToString; |
| Element getInterceptorMethod; |
| + Element interceptedNames; |
| Element fixedLengthListConstructor; |
| bool seenAnyClass = false; |
| @@ -705,11 +705,9 @@ |
| final Map<String, Collection<ClassElement>> specializedGetInterceptors; |
| /** |
| - * Set of classes whose instances are intercepted. Implemented as a |
| - * [LinkedHashMap] to preserve the insertion order. |
| - * TODO(ngeoffray): No need to preserve order anymore. |
| + * Set of classes whose methods are intercepted. |
| */ |
| - final Map<ClassElement, ClassElement> interceptedClasses; |
| + final Set<ClassElement> interceptedClasses; |
| /** |
| * Set of selectors that are used from within loops. Used by the |
| @@ -735,7 +733,7 @@ |
| rti = new RuntimeTypeInformation(compiler), |
| specializedGetInterceptors = |
| new Map<String, Collection<ClassElement>>(), |
| - interceptedClasses = new LinkedHashMap<ClassElement, ClassElement>(), |
| + interceptedClasses = new Set<ClassElement>(), |
| super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM) { |
| emitter = disableEval |
| // TODO(8522): Restore --disallow-unsafe-eval. |
| @@ -756,7 +754,7 @@ |
| bool isInterceptorClass(Element element) { |
| if (element == null) return false; |
| - return interceptedClasses.containsKey(element); |
| + return interceptedClasses.contains(element); |
| } |
| void addInterceptedSelector(Selector selector) { |
| @@ -764,7 +762,7 @@ |
| } |
| String registerOneShotInterceptor(Selector selector) { |
| - Set<ClassElement> classes = getInterceptedClassesOn(selector); |
| + Set<ClassElement> classes = getInterceptedClassesOn(selector.name); |
| String name = namer.getOneShotInterceptorName(selector, classes); |
| if (!oneShotInterceptors.containsKey(name)) { |
| registerSpecializedGetInterceptor(classes); |
| @@ -773,50 +771,45 @@ |
| return name; |
| } |
| - final Map<Selector, Set<ClassElement>> interceptedClassesCache = |
| - new Map<Selector, Set<ClassElement>>(); |
| - final Map<Selector, Set<ClassElement>> interceptedClassesNonNullCache = |
| - new Map<Selector, Set<ClassElement>>(); |
| + bool isInterceptedMethod(Element element) { |
| + return element.isInstanceMember() |
| + && interceptedElements[element.name] != null; |
| + } |
| + bool isInterceptedName(SourceString name) { |
| + return interceptedElements[name] != null; |
| + } |
| + |
| + final Map<SourceString, Set<ClassElement>> interceptedClassesCache = |
| + new Map<SourceString, Set<ClassElement>>(); |
| + |
| /** |
| - * Returns a set of interceptor classes that contain a member whose |
| - * signature matches the given [selector]. Returns [:null:] if there |
| - * is no class. |
| + * Returns a set of interceptor classes that contain a member named |
| + * [name[. Returns [:null:] if there is no class. |
|
sra1
2013/02/27 05:13:28
[name]
ngeoffray
2013/02/28 10:39:42
Done.
|
| */ |
| - Set<ClassElement> getInterceptedClassesOn(Selector selector, |
| - {bool canBeNull: true}) { |
| - Set<Element> intercepted = interceptedElements[selector.name]; |
| + Set<ClassElement> getInterceptedClassesOn(SourceString name) { |
| + Set<Element> intercepted = interceptedElements[name]; |
| if (intercepted == null) return null; |
| - // Pick the right cache and query it. |
| - Map<Selector, Set<ClassElement>> cache = canBeNull |
| - ? interceptedClassesCache |
| - : interceptedClassesNonNullCache; |
| - if (cache.containsKey(selector)) return cache[selector]; |
| + if (interceptedClassesCache.containsKey(name)) { |
| + return interceptedClassesCache[name]; |
| + } |
| // Populate the cache by running through all the elements and |
| // determine if the given selector applies to them. |
| Set<ClassElement> result = new Set<ClassElement>(); |
| for (Element element in intercepted) { |
| - ClassElement enclosing = element.getEnclosingClass(); |
| - // We have to treat null as a bottom type, so we use the untyped |
| - // applies method for those elements that are implemented on the |
| - // null class. |
| - bool applies = (enclosing == jsNullClass) |
| - ? canBeNull && selector.appliesUntyped(element, compiler) |
| - : selector.applies(element, compiler); |
| - if (applies) result.add(enclosing); |
| + result.add(element.getEnclosingClass()); |
| } |
| - if (result.isEmpty) result = null; |
| - cache[selector] = result; |
| - assert(cache.containsKey(selector)); |
| + interceptedClassesCache[name] = result; |
| return result; |
| } |
| void initializeInterceptorElements() { |
| - objectInterceptorClass = |
| - compiler.findInterceptor(const SourceString('ObjectInterceptor')); |
| getInterceptorMethod = |
| compiler.findInterceptor(const SourceString('getInterceptor')); |
| + interceptedNames = |
| + compiler.findInterceptor(const SourceString('interceptedNames')); |
| List<ClassElement> classes = [ |
| + compiler.objectClass, |
| jsStringClass = compiler.findInterceptor(const SourceString('JSString')), |
| jsArrayClass = compiler.findInterceptor(const SourceString('JSArray')), |
| // The int class must be before the double class, because the |
| @@ -848,7 +841,7 @@ |
| jsStringClass, const SourceString('toString')); |
| for (ClassElement cls in classes) { |
| - if (cls != null) interceptedClasses[cls] = null; |
| + if (cls != null) interceptedClasses.add(cls); |
| } |
| } |
| @@ -866,23 +859,11 @@ |
| } |
| void registerSpecializedGetInterceptor(Set<ClassElement> classes) { |
| - compiler.enqueuer.codegen.registerInstantiatedClass(objectInterceptorClass); |
| String name = namer.getInterceptorName(getInterceptorMethod, classes); |
| if (classes.contains(compiler.objectClass)) { |
| // We can't use a specialized [getInterceptorMethod], so we make |
| // sure we emit the one with all checks. |
| - specializedGetInterceptors.putIfAbsent(name, () { |
| - // It is important to take the order provided by the map, |
| - // because we want the int type check to happen before the |
| - // double type check: the double type check covers the int |
| - // type check. Also we don't need to do a number type check |
| - // because that is covered by the double type check. |
| - List<ClassElement> keys = <ClassElement>[]; |
| - interceptedClasses.forEach((ClassElement cls, _) { |
| - if (cls != jsNumberClass) keys.add(cls); |
| - }); |
| - return keys; |
| - }); |
| + specializedGetInterceptors[name] = interceptedClasses; |
| } else { |
| specializedGetInterceptors[name] = classes; |
| } |