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

Unified Diff: pkg/compiler/lib/src/ssa/builder.dart

Issue 1182913003: Split TypedSelector into Selector and TypeMask. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 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: pkg/compiler/lib/src/ssa/builder.dart
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 0ef26591b908ce4d5ecb0c34336f8993d993030a..0224c9a01ce45949aa1cf1d568375c8057a142c9 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -1297,6 +1297,7 @@ class SsaBuilder extends NewResolvedVisitor {
*/
bool tryInlineMethod(Element element,
Selector selector,
+ TypeMask mask,
List<HInstruction> providedArguments,
ast.Node currentNode,
{InterfaceType instanceType}) {
@@ -1328,8 +1329,11 @@ class SsaBuilder extends NewResolvedVisitor {
Elements.isStaticOrTopLevel(element) ||
element.isGenerativeConstructorBody,
message: "Missing selector for inlining of $element."));
- if (selector != null && !selector.applies(function, compiler.world)) {
- return false;
+ if (selector != null) {
+ if (!selector.applies(function, compiler.world)) return false;
+ if (mask != null && !mask.canHit(function, selector, compiler.world)) {
+ return false;
+ }
}
// Don't inline operator== methods if the parameter can be null.
@@ -1448,9 +1452,9 @@ class SsaBuilder extends NewResolvedVisitor {
// Add an explicit null check on the receiver before doing the
// inlining. We use [element] to get the same name in the
// NoSuchMethodError message as if we had called it.
- if (element.isInstanceMember
- && !element.isGenerativeConstructorBody
- && (selector.mask == null || selector.mask.isNullable)) {
+ if (element.isInstanceMember &&
+ !element.isGenerativeConstructorBody &&
+ (mask == null || mask.isNullable)) {
addWithPosition(
new HFieldGet(null, providedArguments[0], backend.dynamicType,
isAssignable: false),
@@ -2297,7 +2301,7 @@ class SsaBuilder extends NewResolvedVisitor {
}
if (!isNativeUpgradeFactory && // TODO(13836): Fix inlining.
- tryInlineMethod(body, null, bodyCallInputs, function)) {
+ tryInlineMethod(body, null, null, bodyCallInputs, function)) {
pop();
} else {
HInvokeConstructorBody invoke = new HInvokeConstructorBody(
@@ -2450,6 +2454,7 @@ class SsaBuilder extends NewResolvedVisitor {
pushInvokeDynamic(
null,
new Selector.call(name, backend.jsHelperLibrary, 1),
+ null,
arguments);
return new HTypeConversion(type, kind, original.instructionType, pop());
@@ -3192,7 +3197,11 @@ class SsaBuilder extends NewResolvedVisitor {
}
}
- pushInvokeDynamic(node, elements.getSelector(node), [operand]);
+ pushInvokeDynamic(
+ node,
+ elements.getSelector(node),
+ elements.getTypeMask(node),
+ [operand]);
}
@override
@@ -3224,6 +3233,7 @@ class SsaBuilder extends NewResolvedVisitor {
visitAndPop(left),
visitAndPop(right),
elements.getSelector(node),
+ elements.getTypeMask(node),
node,
location: node.selector);
}
@@ -3233,9 +3243,10 @@ class SsaBuilder extends NewResolvedVisitor {
void visitBinarySend(HInstruction left,
HInstruction right,
Selector selector,
+ TypeMask mask,
ast.Send send,
{ast.Node location}) {
- pushInvokeDynamic(send, selector, [left, right], location: location);
+ pushInvokeDynamic(send, selector, mask, [left, right], location: location);
}
HInstruction generateInstanceSendReceiver(ast.Send send) {
@@ -3257,12 +3268,14 @@ class SsaBuilder extends NewResolvedVisitor {
* Returns a set of interceptor classes that contain the given
* [selector].
*/
- void generateInstanceGetterWithCompiledReceiver(ast.Send send,
- Selector selector,
- HInstruction receiver) {
+ void generateInstanceGetterWithCompiledReceiver(
+ ast.Send send,
+ Selector selector,
+ TypeMask mask,
+ HInstruction receiver) {
assert(Elements.isInstanceSend(send, elements));
assert(selector.isGetter);
- pushInvokeDynamic(send, selector, [receiver]);
+ pushInvokeDynamic(send, selector, mask, [receiver]);
}
/// Inserts a call to checkDeferredIsLoaded for [prefixElement].
@@ -3380,7 +3393,7 @@ class SsaBuilder extends NewResolvedVisitor {
void generateDynamicGet(ast.Send node) {
HInstruction receiver = generateInstanceSendReceiver(node);
generateInstanceGetterWithCompiledReceiver(
- node, elements.getSelector(node), receiver);
+ node, elements.getSelector(node), elements.getTypeMask(node), receiver);
}
/// Generate a closurization of the static or top level [function].
@@ -3427,8 +3440,13 @@ class SsaBuilder extends NewResolvedVisitor {
pushCheckNull(expression);
},
() => stack.add(expression),
- () => generateInstanceGetterWithCompiledReceiver(
- node, elements.getSelector(node), expression));
+ () {
+ generateInstanceGetterWithCompiledReceiver(
+ node,
+ elements.getSelector(node),
+ elements.getTypeMask(node),
+ expression);
+ });
}
/// Pushes a boolean checking [expression] against null.
@@ -3512,6 +3530,7 @@ class SsaBuilder extends NewResolvedVisitor {
HInstruction pushReceiver(),
HInstruction pushValue(),
{Selector selector,
+ TypeMask mask,
ast.Node location}) {
if (send.isConditional) {
SsaBranchBuilder brancher = new SsaBranchBuilder(this, send);
@@ -3531,11 +3550,11 @@ class SsaBuilder extends NewResolvedVisitor {
() => stack.add(receiver),
() => generateInstanceSetterWithCompiledReceiver(
send, receiver, pushValue(),
- selector: selector, location: location));
+ selector: selector, mask: mask, location: location));
} else {
generateInstanceSetterWithCompiledReceiver(
send, pushReceiver(), pushValue(),
- selector: selector, location: location);
+ selector: selector, mask: mask, location: location);
}
}
@@ -3543,18 +3562,22 @@ class SsaBuilder extends NewResolvedVisitor {
HInstruction receiver,
HInstruction value,
{Selector selector,
+ TypeMask mask,
ast.Node location}) {
assert(send == null || Elements.isInstanceSend(send, elements));
if (selector == null) {
assert(send != null);
selector = elements.getSelector(send);
+ if (mask == null) {
+ mask = elements.getTypeMask(send);
+ }
}
if (location == null) {
assert(send != null);
location = send;
}
assert(selector.isSetter);
- pushInvokeDynamic(location, selector, [receiver, value]);
+ pushInvokeDynamic(location, selector, mask, [receiver, value]);
pop();
stack.add(value);
}
@@ -3689,7 +3712,9 @@ class SsaBuilder extends NewResolvedVisitor {
if (type.isFunctionType) {
List arguments = [buildFunctionType(type), expression];
pushInvokeDynamic(
- node, new Selector.call('_isTest', backend.jsHelperLibrary, 1),
+ node,
+ new Selector.call('_isTest', backend.jsHelperLibrary, 1),
+ null,
arguments);
return new HIs.compound(type, expression, pop(), backend.boolType);
} else if (type.isTypeVariable) {
@@ -3811,12 +3836,13 @@ class SsaBuilder extends NewResolvedVisitor {
void _generateDynamicSend(ast.Send node, HInstruction receiver) {
Selector selector = elements.getSelector(node);
+ TypeMask mask = elements.getTypeMask(node);
List<HInstruction> inputs = <HInstruction>[];
inputs.add(receiver);
addDynamicSendArgumentsToList(node, inputs);
- pushInvokeDynamic(node, selector, inputs);
+ pushInvokeDynamic(node, selector, mask, inputs);
if (selector.isSetter || selector.isIndexSet) {
pop();
stack.add(inputs.last);
@@ -4180,8 +4206,7 @@ class SsaBuilder extends NewResolvedVisitor {
// If the isolate library is not used, we just invoke the
// closure.
visit(link.tail.head);
- Selector selector = new Selector.callClosure(0);
- push(new HInvokeClosure(selector,
+ push(new HInvokeClosure(new Selector.callClosure(0),
<HInstruction>[pop()],
backend.dynamicType));
} else {
@@ -4323,7 +4348,7 @@ class SsaBuilder extends NewResolvedVisitor {
// class is _not_ the default implementation from [Object], in
// case the [noSuchMethod] implementation calls
// [JSInvocationMirror._invokeOn].
- registry.registerSelectorUse(selector.asUntyped);
+ registry.registerSelectorUse(selector);
}
String publicName = name;
if (selector.isSetter) publicName += '=';
@@ -5339,9 +5364,11 @@ class SsaBuilder extends NewResolvedVisitor {
Selector selector = elements.getSelector(node);
List<HInstruction> inputs = <HInstruction>[target];
addDynamicSendArgumentsToList(node, inputs);
- Selector closureSelector = new Selector.callClosureFrom(selector);
pushWithPosition(
- new HInvokeClosure(closureSelector, inputs, backend.dynamicType), node);
+ new HInvokeClosure(
+ new Selector.callClosureFrom(selector),
+ inputs, backend.dynamicType),
+ node);
}
visitGetterSend(ast.Send node) {
@@ -5470,6 +5497,7 @@ class SsaBuilder extends NewResolvedVisitor {
void pushInvokeDynamic(ast.Node node,
Selector selector,
+ TypeMask mask,
List<HInstruction> arguments,
{ast.Node location}) {
if (location == null) location = node;
@@ -5510,15 +5538,21 @@ class SsaBuilder extends NewResolvedVisitor {
return false;
}
- Element element = compiler.world.locateSingleElement(selector);
- if (element != null
- && !element.isField
- && !(element.isGetter && selector.isCall)
- && !(element.isFunction && selector.isGetter)
- && !isOptimizableOperation(selector, element)) {
- if (tryInlineMethod(element, selector, arguments, node)) {
+ Element element = compiler.world.locateSingleElement(selector, mask);
+ if (element != null &&
+ !element.isField &&
+ !(element.isGetter && selector.isCall) &&
+ !(element.isFunction && selector.isGetter) &&
+ !isOptimizableOperation(selector, element)) {
+ if (selector.name == 'double') {
+ //debugPrint('Try to inline $node call to $element');
+ }
+ if (tryInlineMethod(element, selector, mask, arguments, node)) {
return;
}
+ if (selector.name == 'double') {
karlklose 2015/06/17 12:43:11 Remove debug code.
Johnni Winther 2015/06/17 13:03:52 Done.
+ //debugPrint('Failed to inline $node');
+ }
}
HInstruction receiver = arguments[0];
@@ -5528,18 +5562,19 @@ class SsaBuilder extends NewResolvedVisitor {
inputs.add(invokeInterceptor(receiver));
}
inputs.addAll(arguments);
- TypeMask type = TypeMaskFactory.inferredTypeForSelector(selector, compiler);
+ TypeMask type =
+ TypeMaskFactory.inferredTypeForSelector(selector, mask, compiler);
if (selector.isGetter) {
pushWithPosition(
- new HInvokeDynamicGetter(selector, null, inputs, type),
+ new HInvokeDynamicGetter(selector, mask, null, inputs, type),
location);
} else if (selector.isSetter) {
pushWithPosition(
- new HInvokeDynamicSetter(selector, null, inputs, type),
+ new HInvokeDynamicSetter(selector, mask, null, inputs, type),
location);
} else {
pushWithPosition(
- new HInvokeDynamicMethod(selector, inputs, type, isIntercepted),
+ new HInvokeDynamicMethod(selector, mask, inputs, type, isIntercepted),
location);
}
}
@@ -5549,7 +5584,7 @@ class SsaBuilder extends NewResolvedVisitor {
List<HInstruction> arguments,
{TypeMask typeMask,
InterfaceType instanceType}) {
- if (tryInlineMethod(element, null, arguments, location,
+ if (tryInlineMethod(element, null, null, arguments, location,
instanceType: instanceType)) {
return;
}
@@ -5604,7 +5639,8 @@ class SsaBuilder extends NewResolvedVisitor {
inputs,
type,
isSetter: selector.isSetter || selector.isIndexSet);
- instruction.sideEffects = compiler.world.getSideEffectsOfSelector(selector);
+ instruction.sideEffects =
+ compiler.world.getSideEffectsOfSelector(selector, null);
return instruction;
}
@@ -5621,6 +5657,7 @@ class SsaBuilder extends NewResolvedVisitor {
}
visitBinarySend(receiver, rhs,
elements.getOperatorSelectorInComplexSendSet(node),
+ elements.getOperatorTypeMaskInComplexSendSet(node),
node,
location: node.assignmentOperator);
}
@@ -5715,6 +5752,7 @@ class SsaBuilder extends NewResolvedVisitor {
pushInvokeDynamic(
node,
elements.getGetterSelectorInComplexSendSet(node),
+ elements.getGetterTypeMaskInComplexSendSet(node),
[receiver, index]);
HInstruction getterInstruction = pop();
if (node.isIfNullAssignment) {
@@ -5729,7 +5767,10 @@ class SsaBuilder extends NewResolvedVisitor {
visit(arguments.head);
HInstruction value = pop();
pushInvokeDynamic(
- node, elements.getSelector(node), [receiver, index, value]);
+ node,
+ elements.getSelector(node),
+ elements.getTypeMask(node),
+ [receiver, index, value]);
pop();
stack.add(value);
});
@@ -5737,7 +5778,10 @@ class SsaBuilder extends NewResolvedVisitor {
handleComplexOperatorSend(node, getterInstruction, arguments);
HInstruction value = pop();
pushInvokeDynamic(
- node, elements.getSelector(node), [receiver, index, value]);
+ node,
+ elements.getSelector(node),
+ elements.getTypeMask(node),
+ [receiver, index, value]);
pop();
if (node.isPostfix) {
stack.add(getterInstruction);
@@ -5781,7 +5825,10 @@ class SsaBuilder extends NewResolvedVisitor {
void generateAssignment(HInstruction receiver) {
// desugars `e.x op= e2` to `e.x = e.x op e2`
generateInstanceGetterWithCompiledReceiver(
- node, elements.getGetterSelectorInComplexSendSet(node), receiver);
+ node,
+ elements.getGetterSelectorInComplexSendSet(node),
+ elements.getGetterTypeMaskInComplexSendSet(node),
+ receiver);
HInstruction getterInstruction = pop();
if (node.isIfNullAssignment) {
SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
@@ -6209,7 +6256,8 @@ class SsaBuilder extends NewResolvedVisitor {
HInstruction buildCondition() {
Selector selector = elements.getMoveNextSelector(node);
- pushInvokeDynamic(node, selector, [streamIterator]);
+ TypeMask mask = elements.getMoveNextTypeMask(node);
+ pushInvokeDynamic(node, selector, mask, [streamIterator]);
HInstruction future = pop();
push(new HAwait(future, new TypeMask.subclass(compiler.objectClass,
compiler.world)));
@@ -6217,11 +6265,13 @@ class SsaBuilder extends NewResolvedVisitor {
}
void buildBody() {
Selector call = elements.getCurrentSelector(node);
- pushInvokeDynamic(node, call, [streamIterator]);
+ TypeMask callMask = elements.getCurrentTypeMask(node);
+ pushInvokeDynamic(node, call, callMask, [streamIterator]);
ast.Node identifier = node.declaredIdentifier;
Element variable = elements.getForInVariable(node);
Selector selector = elements.getSelector(identifier);
+ TypeMask mask = elements.getTypeMask(identifier);
HInstruction value = pop();
if (identifier.asSend() != null
@@ -6233,6 +6283,7 @@ class SsaBuilder extends NewResolvedVisitor {
receiver,
value,
selector: selector,
+ mask: mask,
location: identifier);
} else {
generateNonInstanceSetter(
@@ -6252,7 +6303,9 @@ class SsaBuilder extends NewResolvedVisitor {
buildUpdate,
buildBody);
}, () {
- pushInvokeDynamic(node, new Selector.call("cancel", null, 0),
+ pushInvokeDynamic(node,
+ new Selector.call("cancel", null, 0),
+ null,
[streamIterator]);
push(new HAwait(pop(), new TypeMask.subclass(compiler.objectClass,
compiler.world)));
@@ -6272,7 +6325,7 @@ class SsaBuilder extends NewResolvedVisitor {
// case.
Selector selector = elements.getIteratorSelector(node);
- TypeMask mask = selector.mask;
+ TypeMask mask = elements.getIteratorTypeMask(node);
ClassWorld classWorld = compiler.world;
if (mask != null && mask.satisfies(backend.jsIndexableClass, classWorld)) {
@@ -6294,21 +6347,24 @@ class SsaBuilder extends NewResolvedVisitor {
void buildInitializer() {
Selector selector = elements.getIteratorSelector(node);
+ TypeMask mask = elements.getIteratorTypeMask(node);
visit(node.expression);
HInstruction receiver = pop();
- pushInvokeDynamic(node, selector, [receiver]);
+ pushInvokeDynamic(node, selector, mask, [receiver]);
iterator = pop();
}
HInstruction buildCondition() {
Selector selector = elements.getMoveNextSelector(node);
- pushInvokeDynamic(node, selector, [iterator]);
+ TypeMask mask = elements.getMoveNextTypeMask(node);
+ pushInvokeDynamic(node, selector, mask, [iterator]);
return popBoolified();
}
void buildBody() {
Selector call = elements.getCurrentSelector(node);
- pushInvokeDynamic(node, call, [iterator]);
+ TypeMask mask = elements.getCurrentTypeMask(node);
+ pushInvokeDynamic(node, call, mask, [iterator]);
buildAssignLoopVariable(node, pop());
visit(node.body);
}
@@ -6320,6 +6376,7 @@ class SsaBuilder extends NewResolvedVisitor {
ast.Node identifier = node.declaredIdentifier;
Element variable = elements.getForInVariable(node);
Selector selector = elements.getSelector(identifier);
+ TypeMask mask = elements.getTypeMask(identifier);
if (identifier.asSend() != null &&
Elements.isInstanceSend(identifier, elements)) {
@@ -6330,6 +6387,7 @@ class SsaBuilder extends NewResolvedVisitor {
receiver,
value,
selector: selector,
+ mask: mask,
location: identifier);
} else {
generateNonInstanceSetter(null, variable, value, location: identifier);
@@ -6409,9 +6467,8 @@ class SsaBuilder extends NewResolvedVisitor {
// example, `get current` includes null.
// TODO(sra): The element type of a container type mask might be better.
Selector selector = new Selector.index();
- Selector refined = new TypedSelector(arrayType, selector, compiler.world);
- TypeMask type =
- TypeMaskFactory.inferredTypeForSelector(refined, compiler);
+ TypeMask type = TypeMaskFactory.inferredTypeForSelector(
+ selector, arrayType, compiler);
HInstruction index = localsHandler.readLocal(indexVariable);
HInstruction value = new HIndex(array, index, null, type);
@@ -7328,12 +7385,12 @@ class StringBuilderVisitor extends ast.Visitor {
// If the `toString` method is guaranteed to return a string we can call it
// directly.
- Selector selector =
- new TypedSelector(expression.instructionType,
- new Selector.call('toString', null, 0), compiler.world);
- TypeMask type = TypeMaskFactory.inferredTypeForSelector(selector, compiler);
+ Selector selector = new Selector.call('toString', null, 0);
+ TypeMask type = TypeMaskFactory.inferredTypeForSelector(
+ selector, expression.instructionType, compiler);
if (type.containsOnlyString(compiler.world)) {
- builder.pushInvokeDynamic(node, selector, <HInstruction>[expression]);
+ builder.pushInvokeDynamic(
+ node, selector, expression.instructionType, <HInstruction>[expression]);
append(builder.pop());
return;
}

Powered by Google App Engine
This is Rietveld 408576698