Do not track parameter types of closures, since closure calls can be generated during the emitter.

Review URL: https://codereview.chromium.org//11958009

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@17134 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
ngeoffray@google.com 2013-01-16 12:10:43 +00:00
parent 8e4757a782
commit 26e11c6263
4 changed files with 35 additions and 5 deletions

View file

@ -485,6 +485,13 @@ class ArgumentTypesRegistry {
void registerDynamicInvocation(HInvokeDynamic node,
Selector selector,
HTypeMap types) {
if (selector.isClosureCall()) {
// We cannot use the current framework to do optimizations based
// on the 'call' selector because we are also generating closure
// calls during the emitter phase, which at this point, does not
// track parameter types, nor invalidates optimized methods.
return;
}
HTypeList providedTypes =
new HTypeList.fromDynamicInvocation(node, selector, types);
if (!selectorTypeMap.containsKey(selector)) {

View file

@ -1649,11 +1649,6 @@ abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
visitArguments(node.inputs)),
node);
world.registerDynamicInvocation(call.name, call);
// A closure can also be invoked through [HInvokeDynamicMethod] by
// explicitly calling the [:call:] method. Therefore, we must also
// register types here to let the backend invalidate wrong
// optimizations.
backend.registerDynamicInvocation(node, call, types);
}
visitInvokeStatic(HInvokeStatic node) {

View file

@ -215,6 +215,10 @@ class Selector {
bool isGetter() => identical(kind, SelectorKind.GETTER);
bool isSetter() => identical(kind, SelectorKind.SETTER);
bool isCall() => identical(kind, SelectorKind.CALL);
bool isClosureCall() {
SourceString callName = Compiler.CALL_OPERATOR_NAME;
return isCall() && name == callName;
}
bool isIndex() => identical(kind, SelectorKind.INDEX) && argumentCount == 1;
bool isIndexSet() => identical(kind, SelectorKind.INDEX) && argumentCount == 2;

View file

@ -0,0 +1,24 @@
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Regression test for dart2js, where the optimizer was too agressive
// about parameter types of closures.
class A {
Function f;
A(this.f);
_do() => f(1);
}
main() {
int invokeCount = 0;
closure(a) {
if (invokeCount++ == 1) {
Expect.isTrue(a is int);
}
}
closure('s');
new A(closure)._do();
Expect.equals(2, invokeCount);
}