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

Unified Diff: sdk/lib/_internal/compiler/implementation/js_backend/backend.dart

Issue 11413184: Create specialized versions of getInterceptor. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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: sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
===================================================================
--- sdk/lib/_internal/compiler/implementation/js_backend/backend.dart (revision 15381)
+++ sdk/lib/_internal/compiler/implementation/js_backend/backend.dart (working copy)
@@ -635,14 +635,6 @@
Element jsArrayLength;
Element jsStringLength;
Element getInterceptorMethod;
- Element arrayInterceptor;
- Element boolInterceptor;
- Element doubleInterceptor;
- Element functionInterceptor;
- Element intInterceptor;
- Element nullInterceptor;
- Element numberInterceptor;
- Element stringInterceptor;
bool _interceptorsAreInitialized = false;
final Namer namer;
@@ -679,8 +671,23 @@
* name to the list of members that have that name. This map is used
* by the codegen to know whether a send must be intercepted or not.
*/
- final Map<SourceString, Set<Element>> interceptedElements;
+ final Map<SourceString, Set<Element>> interceptedElements;
+ /**
+ * A map of specialized versions of the [getInterceptorMethod].
+ * Since [getInterceptorMethod] is a hot method at runtime, we're
+ * always specializing it based on the incoming type. The keys in
+ * the map are the names of these specialized versions. Note that
+ * the generic version that contains all possible type checks is
+ * also stored in this map.
+ */
+ final Map<String, Collection<ClassElement>> specializedGetInterceptors;
ahe 2012/11/27 14:29:45 What is the key?
ngeoffray 2012/11/27 15:50:54 It's in the comment above: the name of the special
+
+ /**
+ * Set of classes whose instances are intercepted.
+ */
+ final Set<ClassElement> interceptedClasses;
+
List<CompilerTask> get tasks {
return <CompilerTask>[builder, optimizer, generator, emitter];
}
@@ -695,6 +702,9 @@
usedInterceptors = new Set<Selector>(),
interceptedElements = new Map<SourceString, Set<Element>>(),
rti = new RuntimeTypeInformation(compiler),
+ specializedGetInterceptors =
+ new Map<String, Collection<ClassElement>>(),
+ interceptedClasses = new Set<ClassElement>(),
super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM) {
emitter = disableEval
? new CodeEmitterNoEvalTask(compiler, namer, generateSourceMap)
@@ -714,14 +724,7 @@
bool isInterceptorClass(Element element) {
if (element == null) return false;
- return element == jsStringClass
- || element == jsArrayClass
- || element == jsIntClass
- || element == jsDoubleClass
- || element == jsNullClass
- || element == jsFunctionClass
- || element == jsBoolClass
- || element == jsNumberClass;
+ return interceptedClasses.contains(element);
}
void addInterceptedSelector(Selector selector) {
@@ -746,6 +749,12 @@
return result;
}
+ List<ClassElement> getListOfInterceptedClasses() {
+ return <ClassElement>[jsStringClass, jsArrayClass, jsIntClass,
ahe 2012/11/27 14:29:45 I suggest you create this list in initializeInterc
ngeoffray 2012/11/27 15:50:54 Done.
+ jsDoubleClass, jsNumberClass, jsNullClass,
+ jsFunctionClass, jsBoolClass];
+ }
+
void initializeInterceptorElements() {
objectInterceptorClass =
compiler.findInterceptor(const SourceString('ObjectInterceptor'));
@@ -774,22 +783,7 @@
jsStringLength =
jsStringClass.lookupLocalMember(const SourceString('length'));
- arrayInterceptor =
- compiler.findInterceptor(const SourceString('arrayInterceptor'));
- boolInterceptor =
- compiler.findInterceptor(const SourceString('boolInterceptor'));
- doubleInterceptor =
- compiler.findInterceptor(const SourceString('doubleInterceptor'));
- functionInterceptor =
- compiler.findInterceptor(const SourceString('functionInterceptor'));
- intInterceptor =
- compiler.findInterceptor(const SourceString('intInterceptor'));
- nullInterceptor =
- compiler.findInterceptor(const SourceString('nullInterceptor'));
- stringInterceptor =
- compiler.findInterceptor(const SourceString('stringInterceptor'));
- numberInterceptor =
- compiler.findInterceptor(const SourceString('numberInterceptor'));
+ interceptedClasses.addAll(getListOfInterceptedClasses());
}
void addInterceptors(ClassElement cls) {
@@ -802,24 +796,34 @@
includeSuperMembers: true);
}
+ String registerSpecializedGetInterceptor(
+ Set<ClassElement> interceptedClasses) {
+ compiler.enqueuer.codegen.registerInstantiatedClass(objectInterceptorClass);
+ if (interceptedClasses.contains(compiler.objectClass)) {
+ // We can't use a specialized [getInterceptorMethod], so we make
+ // sure we emit the one with all checks.
+ String name = namer.getName(getInterceptorMethod);
+ specializedGetInterceptors.putIfAbsent(name, () {
ahe 2012/11/27 14:29:45 I don't understand why you do this. Why shouldn't
ngeoffray 2012/11/27 15:50:54 Because I did not want to call getListOfIntercepte
+ // It is important to take the order provided by this list,
+ // because we want the int type check to happen before the
+ // double type check: the double type check covers the int
+ // type check.
+ return getListOfInterceptedClasses();
+ });
+ return namer.isolateAccess(getInterceptorMethod);
+ } else {
+ String name = namer.getSpecializedName(getInterceptorMethod,
+ interceptedClasses);
+ specializedGetInterceptors[name] = interceptedClasses;
+ return '${namer.CURRENT_ISOLATE}.$name';
+ }
+ }
+
void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) {
ClassElement result = null;
if (!_interceptorsAreInitialized) {
initializeInterceptorElements();
_interceptorsAreInitialized = true;
- // The null interceptor and the function interceptor are
- // currently always instantiated if a new class is instantiated.
- // TODO(ngeoffray): do this elsewhere for the function
- // interceptor?
- if (jsNullClass != null) {
- addInterceptors(jsNullClass);
- enqueuer.registerInstantiatedClass(jsNullClass);
- }
- if (jsFunctionClass != null) {
- addInterceptors(jsFunctionClass);
- enqueuer.registerInstantiatedClass(jsFunctionClass);
- }
- enqueuer.addToWorkList(getInterceptorMethod);
}
if (cls == compiler.stringClass) {
result = jsStringClass;
@@ -827,12 +831,16 @@
result = jsArrayClass;
} else if (cls == compiler.intClass) {
result = jsIntClass;
+ enqueuer.registerInstantiatedClass(jsNumberClass);
} else if (cls == compiler.doubleClass) {
result = jsDoubleClass;
+ enqueuer.registerInstantiatedClass(jsNumberClass);
} else if (cls == compiler.functionClass) {
result = jsFunctionClass;
} else if (cls == compiler.boolClass) {
result = jsBoolClass;
+ } else if (cls == compiler.nullClass) {
+ result = jsNullClass;
}
if (result == null) return;

Powered by Google App Engine
This is Rietveld 408576698