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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/nodes.dart

Issue 11879047: Add a new class InvokeDynamicSpecializer and subclasses that know what input types are beneficial f… (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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of ssa; 5 part of ssa;
6 6
7 abstract class HVisitor<R> { 7 abstract class HVisitor<R> {
8 R visitAdd(HAdd node); 8 R visitAdd(HAdd node);
9 R visitBailoutTarget(HBailoutTarget node); 9 R visitBailoutTarget(HBailoutTarget node);
10 R visitBitAnd(HBitAnd node); 10 R visitBitAnd(HBitAnd node);
(...skipping 1302 matching lines...) Expand 10 before | Expand all | Expand 10 after
1313 } 1313 }
1314 } 1314 }
1315 1315
1316 class HInvokeClosure extends HInvokeDynamic { 1316 class HInvokeClosure extends HInvokeDynamic {
1317 HInvokeClosure(Selector selector, List<HInstruction> inputs) 1317 HInvokeClosure(Selector selector, List<HInstruction> inputs)
1318 : super(selector, null, inputs); 1318 : super(selector, null, inputs);
1319 accept(HVisitor visitor) => visitor.visitInvokeClosure(this); 1319 accept(HVisitor visitor) => visitor.visitInvokeClosure(this);
1320 } 1320 }
1321 1321
1322 class HInvokeDynamicMethod extends HInvokeDynamic { 1322 class HInvokeDynamicMethod extends HInvokeDynamic {
1323 HInvokeDynamicMethod(Selector selector, List<HInstruction> inputs) 1323 final InvokeDynamicSpecializer specializer;
1324 : super(selector, null, inputs); 1324 HInvokeDynamicMethod(Selector selector,
1325 List<HInstruction> inputs,
1326 [bool isIntercepted = false])
1327 : super(selector, null, inputs),
1328 specializer = isIntercepted
1329 ? InvokeDynamicSpecializer.lookupSpecializer(selector)
1330 : const InvokeDynamicSpecializer();
1325 String toString() => 'invoke dynamic method: $selector'; 1331 String toString() => 'invoke dynamic method: $selector';
1326 accept(HVisitor visitor) => visitor.visitInvokeDynamicMethod(this); 1332 accept(HVisitor visitor) => visitor.visitInvokeDynamicMethod(this);
1327 1333
1328 bool isIndexOperatorOnIndexablePrimitive(HTypeMap types) { 1334 bool isIndexOperatorOnIndexablePrimitive(HTypeMap types) {
1329 return isInterceptorCall 1335 return isInterceptorCall
1330 && selector.kind == SelectorKind.INDEX 1336 && selector.kind == SelectorKind.INDEX
1331 && selector.name == const SourceString('[]') 1337 && selector.name == const SourceString('[]')
1332 && inputs[1].isIndexablePrimitive(types); 1338 && inputs[1].isIndexablePrimitive(types);
1333 } 1339 }
1334 1340
1335 HType computeDesiredTypeForInput(HInstruction input, 1341 HType computeDesiredTypeForInput(HInstruction input,
1336 HTypeMap types, 1342 HTypeMap types,
1337 Compiler compiler) { 1343 Compiler compiler) {
1338 // TODO(ngeoffray): Move this logic into a different class that 1344 return specializer.computeDesiredTypeForInput(this, input, types, compiler);
1339 // will know what type it wants for a given selector.
1340 if (!isInterceptorCall) return HType.UNKNOWN;
1341
1342 if (selector.kind == SelectorKind.INDEX) {
1343 HInstruction index = inputs[2];
1344 if (input == inputs[1] &&
1345 (index.isTypeUnknown(types) || index.isNumber(types))) {
1346 return selector.name == const SourceString('[]')
1347 ? HType.INDEXABLE_PRIMITIVE
1348 : HType.MUTABLE_ARRAY;
1349 }
1350 // The index should be an int when the receiver is a string or array.
1351 // However it turns out that inserting an integer check in the optimized
1352 // version is cheaper than having another bailout case. This is true,
1353 // because the integer check will simply throw if it fails.
1354 return HType.UNKNOWN;
1355 } else if (selector.kind == SelectorKind.OPERATOR) {
1356 HType propagatedType = types[this];
1357 if (selector.name == const SourceString('unary-') && input == inputs[1]) {
1358 // If the outgoing type should be a number (integer, double or both) we
1359 // want the outgoing type to be the input too.
1360 // If we don't know the outgoing type we try to make it a number.
1361 if (propagatedType.isNumber()) return propagatedType;
1362 if (propagatedType.isUnknown()) return HType.NUMBER;
1363 } else if (selector.name == const SourceString('~')
1364 && input == inputs[1]) {
1365 if (propagatedType.isUnknown() || propagatedType.isNumber()) {
1366 return HType.INTEGER;
1367 }
1368 }
1369 return HType.UNKNOWN;
1370 }
1371 return HType.UNKNOWN;
1372 } 1345 }
1373 1346
1374 HType computeTypeFromInputTypes(HTypeMap types, Compiler compiler) { 1347 HType computeTypeFromInputTypes(HTypeMap types, Compiler compiler) {
1375 // TODO(ngeoffray): Move this logic into a different class that 1348 return specializer.computeTypeFromInputTypes(this, types, compiler);
1376 // will know what type it has for a given selector.
1377 if (!isInterceptorCall) return HType.UNKNOWN;
1378
1379 if (selector.kind == SelectorKind.OPERATOR) {
1380 if (selector.name == const SourceString('unary-')) {
1381 HType operandType = types[inputs[1]];
1382 if (operandType.isNumber()) return operandType;
1383 } else if (selector.name == const SourceString('~')) {
1384 // All bitwise operations on primitive types either produce an
1385 // integer or throw an error.
1386 if (inputs[1].isPrimitive(types)) return HType.INTEGER;
1387 }
1388 }
1389 return HType.UNKNOWN;
1390 } 1349 }
1391 } 1350 }
1392 1351
1393 abstract class HInvokeDynamicField extends HInvokeDynamic { 1352 abstract class HInvokeDynamicField extends HInvokeDynamic {
1394 final bool isSideEffectFree; 1353 final bool isSideEffectFree;
1395 HInvokeDynamicField( 1354 HInvokeDynamicField(
1396 Selector selector, Element element, List<HInstruction> inputs, 1355 Selector selector, Element element, List<HInstruction> inputs,
1397 this.isSideEffectFree) 1356 this.isSideEffectFree)
1398 : super(selector, element, inputs); 1357 : super(selector, element, inputs);
1399 toString() => 'invoke dynamic field: $selector'; 1358 toString() => 'invoke dynamic field: $selector';
(...skipping 1532 matching lines...) Expand 10 before | Expand all | Expand 10 after
2932 HBasicBlock get start => expression.start; 2891 HBasicBlock get start => expression.start;
2933 HBasicBlock get end { 2892 HBasicBlock get end {
2934 // We don't create a switch block if there are no cases. 2893 // We don't create a switch block if there are no cases.
2935 assert(!statements.isEmpty); 2894 assert(!statements.isEmpty);
2936 return statements.last.end; 2895 return statements.last.end;
2937 } 2896 }
2938 2897
2939 bool accept(HStatementInformationVisitor visitor) => 2898 bool accept(HStatementInformationVisitor visitor) =>
2940 visitor.visitSwitchInfo(this); 2899 visitor.visitSwitchInfo(this);
2941 } 2900 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698