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

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

Powered by Google App Engine
This is Rietveld 408576698