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

Unified Diff: sdk/lib/_internal/compiler/implementation/ssa/codegen.dart

Issue 12033056: Implement "one-shot" interceptors. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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: sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
===================================================================
--- sdk/lib/_internal/compiler/implementation/ssa/codegen.dart (revision 17552)
+++ sdk/lib/_internal/compiler/implementation/ssa/codegen.dart (working copy)
@@ -1499,12 +1499,13 @@
}
void visitInterceptor(HInterceptor node) {
- String name =
- backend.registerSpecializedGetInterceptor(node.interceptedClasses);
- js.VariableUse interceptor = new js.VariableUse(name);
+ backend.registerSpecializedGetInterceptor(node.interceptedClasses);
+ String name = backend.namer.getInterceptorName(
+ backend.getInterceptorMethod, node.interceptedClasses);
+ var isolate = new js.VariableUse(backend.namer.CURRENT_ISOLATE);
use(node.receiver);
List<js.Expression> arguments = <js.Expression>[pop()];
- push(new js.Call(interceptor, arguments), node);
+ push(jsPropertyCall(isolate, name, arguments), node);
}
visitInvokeDynamicMethod(HInvokeDynamicMethod node) {
@@ -1537,39 +1538,28 @@
if (methodName == null) {
methodName = backend.namer.invocationName(node.selector);
- bool inLoop = node.block.enclosingLoopHeader != null;
-
- Selector selector = getOptimizedSelectorFor(node, node.selector);
- if (node.isInterceptorCall) {
- backend.addInterceptedSelector(selector);
- }
- // Register this invocation to collect the types used at all call sites.
- backend.registerDynamicInvocation(node, selector, types);
-
- // If we don't know what we're calling or if we are calling a getter,
- // we need to register that fact that we may be calling a closure
- // with the same arguments.
- if (target == null || target.isGetter()) {
- // TODO(kasperl): If we have a typed selector for the call, we
- // may know something about the types of closures that need
- // the specific closure call method.
- Selector call = new Selector.callClosureFrom(selector);
- world.registerDynamicInvocation(call.name, call);
- }
-
- if (target != null) {
- // If we know we're calling a specific method, register that
- // method only.
- if (inLoop) backend.builder.functionsCalledInLoop.add(target);
- world.registerDynamicInvocationOf(target);
- } else {
- if (inLoop) backend.builder.selectorsCalledInLoop[name] = selector;
- world.registerDynamicInvocation(name, selector);
- }
+ registerMethodInvoke(node);
}
push(jsPropertyCall(object, methodName, arguments), node);
}
+ void visitOneShotInterceptor(HOneShotInterceptor node) {
+ List<js.Expression> arguments = visitArguments(node.inputs);
+ var isolate = new js.VariableUse(backend.namer.CURRENT_ISOLATE);
+ Selector selector = node.selector;
+ String methodName = backend.namer.oneShotInterceptorName(selector);
+ push(jsPropertyCall(isolate, methodName, arguments), node);
+ backend.registerSpecializedGetInterceptor(node.interceptedClasses);
+ backend.addOneShotInterceptor(selector);
+ if (selector.isGetter()) {
+ registerGetter(node);
+ } else if (selector.isSetter()) {
+ registerSetter(node);
+ } else {
+ registerMethodInvoke(node);
+ }
+ }
+
Selector getOptimizedSelectorFor(HInvokeDynamic node,
Selector defaultSelector) {
// TODO(4434): For private members we need to use the untyped selector.
@@ -1592,21 +1582,75 @@
}
}
+ void registerInvoke(HInvokeDynamic node) {
+ bool inLoop = node.block.enclosingLoopHeader != null;
+ SourceString name = node.selector.name;
+ if (inLoop) {
+ Element target = node.element;
+ if (target != null) {
+ backend.builder.functionsCalledInLoop.add(target);
+ } else {
+ backend.builder.selectorsCalledInLoop[name] = node.selector;
+ }
+ }
+
+ if (node.isInterceptorCall) {
+ backend.addInterceptedSelector(node.selector);
+ }
+ }
+
+ void registerMethodInvoke(HInvokeDynamic node) {
+ Selector selector = getOptimizedSelectorFor(node, node.selector);
+ // Register this invocation to collect the types used at all call sites.
+ backend.registerDynamicInvocation(node, selector, types);
+
+ // If we don't know what we're calling or if we are calling a getter,
+ // we need to register that fact that we may be calling a closure
+ // with the same arguments.
+ Element target = node.element;
+ if (target == null || target.isGetter()) {
+ // TODO(kasperl): If we have a typed selector for the call, we
+ // may know something about the types of closures that need
+ // the specific closure call method.
+ Selector call = new Selector.callClosureFrom(selector);
+ world.registerDynamicInvocation(call.name, call);
+ }
+
+ if (target != null) {
+ // If we know we're calling a specific method, register that
+ // method only.
+ world.registerDynamicInvocationOf(target);
+ } else {
+ SourceString name = node.selector.name;
+ world.registerDynamicInvocation(name, selector);
+ }
+ registerInvoke(node);
+ }
+
+ void registerSetter(HInvokeDynamic node) {
+ Selector selector = getOptimizedSelectorFor(node, node.selector);
+ world.registerDynamicSetter(selector.name, selector);
+ HType valueType = node.isInterceptorCall
+ ? types[node.inputs[2]]
+ : types[node.inputs[1]];
+ backend.addedDynamicSetter(selector, valueType);
+ registerInvoke(node);
+ }
+
+ void registerGetter(HInvokeDynamic node) {
+ Selector getter = node.selector;
+ world.registerDynamicGetter(
+ getter.name, getOptimizedSelectorFor(node, getter));
+ world.registerInstantiatedClass(compiler.functionClass);
+ registerInvoke(node);
+ }
+
visitInvokeDynamicSetter(HInvokeDynamicSetter node) {
use(node.receiver);
Selector setter = node.selector;
String name = backend.namer.invocationName(setter);
push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node);
- Selector selector = getOptimizedSelectorFor(node, setter);
- world.registerDynamicSetter(setter.name, selector);
- HType valueType;
- if (node.isInterceptorCall) {
- valueType = types[node.inputs[2]];
- backend.addInterceptedSelector(setter);
- } else {
- valueType = types[node.inputs[1]];
- }
- backend.addedDynamicSetter(selector, valueType);
+ registerSetter(node);
}
visitInvokeDynamicGetter(HInvokeDynamicGetter node) {
@@ -1614,12 +1658,7 @@
Selector getter = node.selector;
String name = backend.namer.invocationName(getter);
push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node);
- world.registerDynamicGetter(
- getter.name, getOptimizedSelectorFor(node, getter));
- if (node.isInterceptorCall) {
- backend.addInterceptedSelector(getter);
- }
- world.registerInstantiatedClass(compiler.functionClass);
+ registerGetter(node);
}
visitInvokeClosure(HInvokeClosure node) {

Powered by Google App Engine
This is Rietveld 408576698