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

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

Issue 11412105: - Move length getter and setter interceptors to the new interceptor scheme. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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 18 matching lines...) Expand all
29 R visitGreaterEqual(HGreaterEqual node); 29 R visitGreaterEqual(HGreaterEqual node);
30 R visitIdentity(HIdentity node); 30 R visitIdentity(HIdentity node);
31 R visitIf(HIf node); 31 R visitIf(HIf node);
32 R visitIndex(HIndex node); 32 R visitIndex(HIndex node);
33 R visitIndexAssign(HIndexAssign node); 33 R visitIndexAssign(HIndexAssign node);
34 R visitIntegerCheck(HIntegerCheck node); 34 R visitIntegerCheck(HIntegerCheck node);
35 R visitInvokeClosure(HInvokeClosure node); 35 R visitInvokeClosure(HInvokeClosure node);
36 R visitInvokeDynamicGetter(HInvokeDynamicGetter node); 36 R visitInvokeDynamicGetter(HInvokeDynamicGetter node);
37 R visitInvokeDynamicMethod(HInvokeDynamicMethod node); 37 R visitInvokeDynamicMethod(HInvokeDynamicMethod node);
38 R visitInvokeDynamicSetter(HInvokeDynamicSetter node); 38 R visitInvokeDynamicSetter(HInvokeDynamicSetter node);
39 R visitInvokeInterceptor(HInvokeInterceptor node);
40 R visitInvokeStatic(HInvokeStatic node); 39 R visitInvokeStatic(HInvokeStatic node);
41 R visitInvokeSuper(HInvokeSuper node); 40 R visitInvokeSuper(HInvokeSuper node);
42 R visitIs(HIs node); 41 R visitIs(HIs node);
43 R visitLazyStatic(HLazyStatic node); 42 R visitLazyStatic(HLazyStatic node);
44 R visitLess(HLess node); 43 R visitLess(HLess node);
45 R visitLessEqual(HLessEqual node); 44 R visitLessEqual(HLessEqual node);
46 R visitLiteralList(HLiteralList node); 45 R visitLiteralList(HLiteralList node);
47 R visitLocalGet(HLocalGet node); 46 R visitLocalGet(HLocalGet node);
48 R visitLocalSet(HLocalSet node); 47 R visitLocalSet(HLocalSet node);
49 R visitLocalValue(HLocalValue node); 48 R visitLocalValue(HLocalValue node);
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 visitIndexAssign(HIndexAssign node) => visitInvokeStatic(node); 292 visitIndexAssign(HIndexAssign node) => visitInvokeStatic(node);
294 visitIntegerCheck(HIntegerCheck node) => visitCheck(node); 293 visitIntegerCheck(HIntegerCheck node) => visitCheck(node);
295 visitInvokeClosure(HInvokeClosure node) 294 visitInvokeClosure(HInvokeClosure node)
296 => visitInvokeDynamic(node); 295 => visitInvokeDynamic(node);
297 visitInvokeDynamicMethod(HInvokeDynamicMethod node) 296 visitInvokeDynamicMethod(HInvokeDynamicMethod node)
298 => visitInvokeDynamic(node); 297 => visitInvokeDynamic(node);
299 visitInvokeDynamicGetter(HInvokeDynamicGetter node) 298 visitInvokeDynamicGetter(HInvokeDynamicGetter node)
300 => visitInvokeDynamicField(node); 299 => visitInvokeDynamicField(node);
301 visitInvokeDynamicSetter(HInvokeDynamicSetter node) 300 visitInvokeDynamicSetter(HInvokeDynamicSetter node)
302 => visitInvokeDynamicField(node); 301 => visitInvokeDynamicField(node);
303 visitInvokeInterceptor(HInvokeInterceptor node)
304 => visitInvokeStatic(node);
305 visitInvokeStatic(HInvokeStatic node) => visitInvoke(node); 302 visitInvokeStatic(HInvokeStatic node) => visitInvoke(node);
306 visitInvokeSuper(HInvokeSuper node) => visitInvoke(node); 303 visitInvokeSuper(HInvokeSuper node) => visitInvoke(node);
307 visitJump(HJump node) => visitControlFlow(node); 304 visitJump(HJump node) => visitControlFlow(node);
308 visitLazyStatic(HLazyStatic node) => visitStatic(node); 305 visitLazyStatic(HLazyStatic node) => visitStatic(node);
309 visitLess(HLess node) => visitRelational(node); 306 visitLess(HLess node) => visitRelational(node);
310 visitLessEqual(HLessEqual node) => visitRelational(node); 307 visitLessEqual(HLessEqual node) => visitRelational(node);
311 visitLiteralList(HLiteralList node) => visitInstruction(node); 308 visitLiteralList(HLiteralList node) => visitInstruction(node);
312 visitLocalGet(HLocalGet node) => visitFieldGet(node); 309 visitLocalGet(HLocalGet node) => visitFieldGet(node);
313 visitLocalSet(HLocalSet node) => visitFieldSet(node); 310 visitLocalSet(HLocalSet node) => visitFieldSet(node);
314 visitLocalValue(HLocalValue node) => visitInstruction(node); 311 visitLocalValue(HLocalValue node) => visitInstruction(node);
(...skipping 999 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 1311
1315 abstract class HInvokeDynamic extends HInvoke { 1312 abstract class HInvokeDynamic extends HInvoke {
1316 final Selector selector; 1313 final Selector selector;
1317 Element element; 1314 Element element;
1318 1315
1319 HInvokeDynamic(this.selector, this.element, List<HInstruction> inputs) 1316 HInvokeDynamic(this.selector, this.element, List<HInstruction> inputs)
1320 : super(inputs); 1317 : super(inputs);
1321 toString() => 'invoke dynamic: $selector'; 1318 toString() => 'invoke dynamic: $selector';
1322 HInstruction get receiver => inputs[0]; 1319 HInstruction get receiver => inputs[0];
1323 1320
1324 // TODO(floitsch): make class abstract instead of adding an abstract method.
1325 accept(HVisitor visitor); 1321 accept(HVisitor visitor);
ahe 2012/11/23 06:51:23 Remove this method? I believe it was only there t
ngeoffray 2012/11/23 12:01:17 Done.
1322
1323 bool get isInterceptorCall {
1324 // We know it's a selector call if it follows the interceptor
1325 // calling convention, which adds the actual receiver as a
1326 // parameter to the call.
1327 return inputs.length - 2 == selector.argumentCount;
1328 }
1326 } 1329 }
1327 1330
1328 class HInvokeClosure extends HInvokeDynamic { 1331 class HInvokeClosure extends HInvokeDynamic {
1329 HInvokeClosure(Selector selector, List<HInstruction> inputs) 1332 HInvokeClosure(Selector selector, List<HInstruction> inputs)
1330 : super(selector, null, inputs); 1333 : super(selector, null, inputs);
1331 accept(HVisitor visitor) => visitor.visitInvokeClosure(this); 1334 accept(HVisitor visitor) => visitor.visitInvokeClosure(this);
1332 } 1335 }
1333 1336
1334 class HInvokeDynamicMethod extends HInvokeDynamic { 1337 class HInvokeDynamicMethod extends HInvokeDynamic {
1335 HInvokeDynamicMethod(Selector selector, List<HInstruction> inputs) 1338 HInvokeDynamicMethod(Selector selector, List<HInstruction> inputs)
1336 : super(selector, null, inputs); 1339 : super(selector, null, inputs);
1337 toString() => 'invoke dynamic method: $selector'; 1340 toString() => 'invoke dynamic method: $selector';
1338 accept(HVisitor visitor) => visitor.visitInvokeDynamicMethod(this); 1341 accept(HVisitor visitor) => visitor.visitInvokeDynamicMethod(this);
1339 } 1342 }
1340 1343
1341 abstract class HInvokeDynamicField extends HInvokeDynamic { 1344 abstract class HInvokeDynamicField extends HInvokeDynamic {
1342 final bool isSideEffectFree; 1345 final bool isSideEffectFree;
1343 HInvokeDynamicField( 1346 HInvokeDynamicField(
1344 Selector selector, Element element, List<HInstruction> inputs, 1347 Selector selector, Element element, List<HInstruction> inputs,
1345 this.isSideEffectFree) 1348 this.isSideEffectFree)
1346 : super(selector, element, inputs); 1349 : super(selector, element, inputs);
1347 toString() => 'invoke dynamic field: $selector'; 1350 toString() => 'invoke dynamic field: $selector';
1348 1351
1349 // TODO(floitsch): make class abstract instead of adding an abstract method.
1350 accept(HVisitor visitor); 1352 accept(HVisitor visitor);
ahe 2012/11/23 06:51:23 Remove this method?
ngeoffray 2012/11/23 12:01:17 Done.
1351 } 1353 }
1352 1354
1353 class HInvokeDynamicGetter extends HInvokeDynamicField { 1355 class HInvokeDynamicGetter extends HInvokeDynamicField {
1354 HInvokeDynamicGetter( 1356 HInvokeDynamicGetter(
1355 selector, element, receiver, isSideEffectFree) 1357 selector, element, receiver, isSideEffectFree)
1356 : super(selector, element, [receiver], isSideEffectFree); 1358 : super(selector, element, [receiver], isSideEffectFree);
1357 toString() => 'invoke dynamic getter: $selector'; 1359 toString() => 'invoke dynamic getter: $selector';
1358 accept(HVisitor visitor) => visitor.visitInvokeDynamicGetter(this); 1360 accept(HVisitor visitor) => visitor.visitInvokeDynamicGetter(this);
1359 1361
1360 void prepareGvn(HTypeMap types) { 1362 void prepareGvn(HTypeMap types) {
(...skipping 21 matching lines...) Expand all
1382 clearAllSideEffects(); 1384 clearAllSideEffects();
1383 if (isSideEffectFree) { 1385 if (isSideEffectFree) {
1384 setChangesInstanceProperty(); 1386 setChangesInstanceProperty();
1385 } else { 1387 } else {
1386 setAllSideEffects(); 1388 setAllSideEffects();
1387 } 1389 }
1388 } 1390 }
1389 } 1391 }
1390 1392
1391 class HInvokeStatic extends HInvoke { 1393 class HInvokeStatic extends HInvoke {
1394 bool isSideEffectFree = false;
1392 /** The first input must be the target. */ 1395 /** The first input must be the target. */
1393 HInvokeStatic(inputs, [HType knownType = HType.UNKNOWN]) : super(inputs) { 1396 HInvokeStatic(inputs, [HType knownType = HType.UNKNOWN]) : super(inputs) {
1394 guaranteedType = knownType; 1397 guaranteedType = knownType;
1395 } 1398 }
1396 1399
1397 toString() => 'invoke static: ${element.name}'; 1400 toString() => 'invoke static: ${element.name}';
1398 accept(HVisitor visitor) => visitor.visitInvokeStatic(this); 1401 accept(HVisitor visitor) => visitor.visitInvokeStatic(this);
1399 int typeCode() => HInstruction.INVOKE_STATIC_TYPECODE; 1402 int typeCode() => HInstruction.INVOKE_STATIC_TYPECODE;
1400 Element get element => target.element; 1403 Element get element => target.element;
1401 HStatic get target => inputs[0]; 1404 HStatic get target => inputs[0];
1402 1405
1403 HType computeDesiredTypeForInput(HInstruction input, 1406 HType computeDesiredTypeForInput(HInstruction input,
1404 HTypeMap types, 1407 HTypeMap types,
1405 Compiler compiler) { 1408 Compiler compiler) {
1406 // TODO(floitsch): we want the target to be a function. 1409 // TODO(floitsch): we want the target to be a function.
1407 if (input == target) return HType.UNKNOWN; 1410 if (input == target) return HType.UNKNOWN;
1408 return computeDesiredTypeForNonTargetInput(input, types, compiler); 1411 return computeDesiredTypeForNonTargetInput(input, types, compiler);
1409 } 1412 }
1410 1413
1411 HType computeDesiredTypeForNonTargetInput(HInstruction input, 1414 HType computeDesiredTypeForNonTargetInput(HInstruction input,
1412 HTypeMap types, 1415 HTypeMap types,
1413 Compiler compiler) { 1416 Compiler compiler) {
1414 return HType.UNKNOWN; 1417 return HType.UNKNOWN;
1415 } 1418 }
1419
1420 void prepareGvn(HTypeMap types) {
1421 clearAllSideEffects();
1422 if (!isSideEffectFree) {
1423 setAllSideEffects();
1424 }
1425 }
1416 } 1426 }
1417 1427
1418 class HInvokeSuper extends HInvokeStatic { 1428 class HInvokeSuper extends HInvokeStatic {
1419 final bool isSetter; 1429 final bool isSetter;
1420 HInvokeSuper(inputs, {this.isSetter: false}) : super(inputs); 1430 HInvokeSuper(inputs, {this.isSetter: false}) : super(inputs);
1421 toString() => 'invoke super: ${element.name}'; 1431 toString() => 'invoke super: ${element.name}';
1422 accept(HVisitor visitor) => visitor.visitInvokeSuper(this); 1432 accept(HVisitor visitor) => visitor.visitInvokeSuper(this);
1423 1433
1424 HInstruction get value { 1434 HInstruction get value {
1425 assert(isSetter); 1435 assert(isSetter);
1426 // Index 0: the element, index 1: 'this'. 1436 // Index 0: the element, index 1: 'this'.
1427 return inputs[2]; 1437 return inputs[2];
1428 } 1438 }
1429 } 1439 }
1430 1440
1431 class HInvokeInterceptor extends HInvokeStatic {
1432 final Selector selector;
1433 final bool isSideEffectFree;
1434
1435 HInvokeInterceptor(this.selector,
1436 List<HInstruction> inputs,
1437 [bool this.isSideEffectFree = false])
1438 : super(inputs);
1439
1440 toString() => 'invoke interceptor: ${element.name}';
1441 accept(HVisitor visitor) => visitor.visitInvokeInterceptor(this);
1442
1443 bool isLengthGetter() {
1444 return selector.isGetter() &&
1445 selector.name == const SourceString('length');
1446 }
1447
1448 bool isPopCall(HTypeMap types) {
1449 return selector.isCall()
1450 && inputs[1].isExtendableArray(types)
1451 && selector.name == const SourceString('removeLast')
1452 && selector.argumentCount == 0;
1453 }
1454
1455 bool isLengthGetterOnStringOrArray(HTypeMap types) {
1456 return isLengthGetter() && inputs[1].isIndexablePrimitive(types);
1457 }
1458
1459 HType computeLikelyType(HTypeMap types, Compiler compiler) {
1460 // In general a length getter or method returns an int.
1461 if (isLengthGetter()) return HType.INTEGER;
1462 return HType.UNKNOWN;
1463 }
1464
1465 HType computeTypeFromInputTypes(HTypeMap types, Compiler compiler) {
1466 if (isLengthGetterOnStringOrArray(types)) return HType.INTEGER;
1467 return HType.UNKNOWN;
1468 }
1469
1470 HType computeDesiredTypeForNonTargetInput(HInstruction input,
1471 HTypeMap types,
1472 Compiler compiler) {
1473 // If the first argument is a string or an array and we invoke methods
1474 // on it that mutate it, then we want to restrict the incoming type to be
1475 // a mutable array.
1476 if (input == inputs[1] && input.isIndexablePrimitive(types)) {
1477 // TODO(kasperl): Should we check that the selector is a call selector?
1478 if (selector.name == const SourceString('add')
1479 || selector.name == const SourceString('removeLast')) {
1480 return HType.MUTABLE_ARRAY;
1481 }
1482 }
1483 return HType.UNKNOWN;
1484 }
1485
1486 void prepareGvn(HTypeMap types) {
1487 clearAllSideEffects();
1488 if (isLengthGetterOnStringOrArray(types)) {
1489 setUseGvn();
1490 // If the input is a string or a fixed length array, we know
1491 // the length cannot change.
1492 if (!inputs[1].isString(types) && !inputs[1].isFixedArray(types)) {
1493 setDependsOnInstancePropertyStore();
1494 }
1495 } else if (isSideEffectFree) {
1496 setUseGvn();
1497 setDependsOnSomething();
1498 } else {
1499 setAllSideEffects();
1500 }
1501 }
1502
1503 int typeCode() => HInstruction.INVOKE_INTERCEPTOR_TYPECODE;
1504 bool typeEquals(other) => other is HInvokeInterceptor;
1505 bool dataEquals(HInvokeInterceptor other) => selector == other.selector;
1506 }
1507
1508 abstract class HFieldAccess extends HInstruction { 1441 abstract class HFieldAccess extends HInstruction {
1509 final Element element; 1442 final Element element;
1510 1443
1511 HFieldAccess(Element element, List<HInstruction> inputs) 1444 HFieldAccess(Element element, List<HInstruction> inputs)
1512 : this.element = element, 1445 : this.element = element,
1513 super(inputs); 1446 super(inputs);
1514 } 1447 }
1515 1448
1516 class HFieldGet extends HFieldAccess { 1449 class HFieldGet extends HFieldAccess {
1517 final bool isAssignable; 1450 final bool isAssignable;
(...skipping 1498 matching lines...) Expand 10 before | Expand all | Expand 10 after
3016 HBasicBlock get start => expression.start; 2949 HBasicBlock get start => expression.start;
3017 HBasicBlock get end { 2950 HBasicBlock get end {
3018 // We don't create a switch block if there are no cases. 2951 // We don't create a switch block if there are no cases.
3019 assert(!statements.isEmpty); 2952 assert(!statements.isEmpty);
3020 return statements.last.end; 2953 return statements.last.end;
3021 } 2954 }
3022 2955
3023 bool accept(HStatementInformationVisitor visitor) => 2956 bool accept(HStatementInformationVisitor visitor) =>
3024 visitor.visitSwitchInfo(this); 2957 visitor.visitSwitchInfo(this);
3025 } 2958 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698