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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart

Issue 1201753004: Revert "dart2js cps: Refactor and optimize string concatenations." (Closed) Base URL: git@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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 library dart2js.ir_builder_task; 5 library dart2js.ir_builder_task;
6 6
7 import '../closure.dart' as closurelib; 7 import '../closure.dart' as closurelib;
8 import '../closure.dart' hide ClosureScope; 8 import '../closure.dart' hide ClosureScope;
9 import '../constants/expressions.dart'; 9 import '../constants/expressions.dart';
10 import '../dart_types.dart'; 10 import '../dart_types.dart';
11 import '../dart2jslib.dart'; 11 import '../dart2jslib.dart';
12 import '../elements/elements.dart'; 12 import '../elements/elements.dart';
13 import '../elements/modelx.dart' show SynthesizedConstructorElementX, 13 import '../elements/modelx.dart' show SynthesizedConstructorElementX,
14 ConstructorBodyElementX, FunctionSignatureX; 14 ConstructorBodyElementX, FunctionSignatureX;
15 import '../io/source_information.dart'; 15 import '../io/source_information.dart';
16 import '../js_backend/js_backend.dart' show JavaScriptBackend; 16 import '../js_backend/js_backend.dart' show JavaScriptBackend;
17 import '../resolution/semantic_visitor.dart'; 17 import '../resolution/semantic_visitor.dart';
18 import '../resolution/operators.dart' as op; 18 import '../resolution/operators.dart' as op;
19 import '../tree/tree.dart' as ast; 19 import '../tree/tree.dart' as ast;
20 import '../universe/universe.dart' show SelectorKind, CallStructure; 20 import '../universe/universe.dart' show SelectorKind, CallStructure;
21 import '../constants/values.dart' show ConstantValue;
22 import 'cps_ir_nodes.dart' as ir; 21 import 'cps_ir_nodes.dart' as ir;
23 import 'cps_ir_builder.dart'; 22 import 'cps_ir_builder.dart';
24 import '../native/native.dart' show NativeBehavior; 23 import '../native/native.dart' show NativeBehavior;
25 24
26 // TODO(karlklose): remove. 25 // TODO(karlklose): remove.
27 import '../js/js.dart' as js show js, Template, Expression; 26 import '../js/js.dart' as js show js, Template, Expression;
28 import '../ssa/ssa.dart' show TypeMaskFactory; 27 import '../ssa/ssa.dart' show TypeMaskFactory;
29 import '../types/types.dart' show TypeMask; 28 import '../types/types.dart' show TypeMask;
30 import '../util/util.dart'; 29 import '../util/util.dart';
31 30
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 variableElement: variableElement, 346 variableElement: variableElement,
348 variableSelector: selector, 347 variableSelector: selector,
349 buildBody: subbuild(node.body), 348 buildBody: subbuild(node.body),
350 target: elements.getTargetDefinition(node), 349 target: elements.getTargetDefinition(node),
351 closureScope: getClosureScopeForNode(node)); 350 closureScope: getClosureScopeForNode(node));
352 } 351 }
353 352
354 ir.Primitive visitVariableDefinitions(ast.VariableDefinitions node) { 353 ir.Primitive visitVariableDefinitions(ast.VariableDefinitions node) {
355 assert(irBuilder.isOpen); 354 assert(irBuilder.isOpen);
356 if (node.modifiers.isConst) { 355 if (node.modifiers.isConst) {
357 // Do nothing. 356 for (ast.SendSet definition in node.definitions.nodes) {
358 // handleLocalConstantGet inlines the constant at use-site. 357 assert(!definition.arguments.isEmpty);
358 assert(definition.arguments.tail.isEmpty);
359 VariableElement element = elements[definition];
360 ConstantExpression value = getConstantForVariable(element);
361 irBuilder.declareLocalConstant(element, value);
362 }
359 } else { 363 } else {
360 for (ast.Node definition in node.definitions.nodes) { 364 for (ast.Node definition in node.definitions.nodes) {
361 Element element = elements[definition]; 365 Element element = elements[definition];
362 ir.Primitive initialValue; 366 ir.Primitive initialValue;
363 // Definitions are either SendSets if there is an initializer, or 367 // Definitions are either SendSets if there is an initializer, or
364 // Identifiers if there is no initializer. 368 // Identifiers if there is no initializer.
365 if (definition is ast.SendSet) { 369 if (definition is ast.SendSet) {
366 assert(!definition.arguments.isEmpty); 370 assert(!definition.arguments.isEmpty);
367 assert(definition.arguments.tail.isEmpty); 371 assert(definition.arguments.tail.isEmpty);
368 initialValue = visit(definition.arguments.head); 372 initialValue = visit(definition.arguments.head);
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 ir.Primitive visitLiteralNull(ast.LiteralNull node) { 492 ir.Primitive visitLiteralNull(ast.LiteralNull node) {
489 assert(irBuilder.isOpen); 493 assert(irBuilder.isOpen);
490 return irBuilder.buildNullConstant(); 494 return irBuilder.buildNullConstant();
491 } 495 }
492 496
493 ir.Primitive visitLiteralString(ast.LiteralString node) { 497 ir.Primitive visitLiteralString(ast.LiteralString node) {
494 assert(irBuilder.isOpen); 498 assert(irBuilder.isOpen);
495 return irBuilder.buildDartStringConstant(node.dartString); 499 return irBuilder.buildDartStringConstant(node.dartString);
496 } 500 }
497 501
498 ConstantValue getConstantForNode(ast.Node node) { 502 ConstantExpression getConstantForNode(ast.Node node) {
499 ConstantValue constant = 503 ConstantExpression constant =
500 irBuilder.state.constants.getConstantValueForNode(node, elements); 504 irBuilder.state.constants.getConstantForNode(node, elements);
501 assert(invariant(node, constant != null, 505 assert(invariant(node, constant != null,
502 message: 'No constant computed for $node')); 506 message: 'No constant computed for $node'));
503 return constant; 507 return constant;
504 } 508 }
505 509
506 ConstantValue getConstantForVariable(VariableElement element) { 510 ConstantExpression getConstantForVariable(VariableElement element) {
507 ConstantValue constant = 511 ConstantExpression constant =
508 irBuilder.state.constants.getConstantValueForVariable(element); 512 irBuilder.state.constants.getConstantForVariable(element);
509 assert(invariant(element, constant != null, 513 assert(invariant(element, constant != null,
510 message: 'No constant computed for $element')); 514 message: 'No constant computed for $element'));
511 return constant; 515 return constant;
512 } 516 }
513 517
514 ir.Primitive buildConstantExpression(ConstantExpression expression) { 518 /// Builds a constant pulling the value from the constant environment.
515 return irBuilder.buildConstant( 519 // TODO(johnniwinther): Remove this when [IrBuilder.buildConstant] only takes
520 // a [ConstantExpression].
521 ir.Primitive buildConstant(ConstantExpression expression) {
522 return irBuilder.buildConstant(expression,
516 irBuilder.state.constants.getConstantValue(expression)); 523 irBuilder.state.constants.getConstantValue(expression));
517 } 524 }
518 525
519 ir.Primitive visitLiteralList(ast.LiteralList node) { 526 ir.Primitive visitLiteralList(ast.LiteralList node) {
520 if (node.isConst) { 527 if (node.isConst) {
521 return translateConstant(node); 528 return translateConstant(node);
522 } 529 }
523 List<ir.Primitive> values = node.elements.nodes.mapToList(visit); 530 List<ir.Primitive> values = node.elements.nodes.mapToList(visit);
524 InterfaceType type = elements.getType(node); 531 InterfaceType type = elements.getType(node);
525 return irBuilder.buildListLiteral(type, values); 532 return irBuilder.buildListLiteral(type, values);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 /// Returns `true` if [node] is a super call. 610 /// Returns `true` if [node] is a super call.
604 // TODO(johnniwinther): Remove the need for this. 611 // TODO(johnniwinther): Remove the need for this.
605 bool isSuperCall(ast.Send node) { 612 bool isSuperCall(ast.Send node) {
606 return node != null && node.receiver != null && node.receiver.isSuper(); 613 return node != null && node.receiver != null && node.receiver.isSuper();
607 } 614 }
608 615
609 @override 616 @override
610 ir.Primitive handleConstantGet( 617 ir.Primitive handleConstantGet(
611 ast.Node node, 618 ast.Node node,
612 ConstantExpression constant, _) { 619 ConstantExpression constant, _) {
613 return buildConstantExpression(constant); 620 return buildConstant(constant);
614 } 621 }
615 622
616 /// If [node] is null, returns this. 623 /// If [node] is null, returns this.
617 /// Otherwise visits [node] and returns the result. 624 /// Otherwise visits [node] and returns the result.
618 ir.Primitive translateReceiver(ast.Expression node) { 625 ir.Primitive translateReceiver(ast.Expression node) {
619 return node != null ? visit(node) : irBuilder.buildThis(); 626 return node != null ? visit(node) : irBuilder.buildThis();
620 } 627 }
621 628
622 @override 629 @override
623 ir.Primitive handleDynamicGet( 630 ir.Primitive handleDynamicGet(
(...skipping 16 matching lines...) Expand all
640 return irBuilder.buildIfNotNullSend( 647 return irBuilder.buildIfNotNullSend(
641 target, 648 target,
642 nested(() => irBuilder.buildDynamicGet(target, selector))); 649 nested(() => irBuilder.buildDynamicGet(target, selector)));
643 } 650 }
644 651
645 @override 652 @override
646 ir.Primitive visitDynamicTypeLiteralGet( 653 ir.Primitive visitDynamicTypeLiteralGet(
647 ast.Send node, 654 ast.Send node,
648 ConstantExpression constant, 655 ConstantExpression constant,
649 _) { 656 _) {
650 return buildConstantExpression(constant); 657 return buildConstant(constant);
651 } 658 }
652 659
653 @override 660 @override
654 ir.Primitive visitLocalVariableGet( 661 ir.Primitive visitLocalVariableGet(
655 ast.Send node, 662 ast.Send node,
656 LocalVariableElement element, 663 LocalVariableElement element,
657 _) { 664 _) {
658 return element.isConst 665 return element.isConst
659 ? irBuilder.buildConstant(getConstantForVariable(element)) 666 ? buildConstant(getConstantForVariable(element))
660 : irBuilder.buildLocalVariableGet(element); 667 : irBuilder.buildLocalVariableGet(element);
661 } 668 }
662 669
663 @override 670 @override
664 ir.Primitive handleLocalGet( 671 ir.Primitive handleLocalGet(
665 ast.Send node, 672 ast.Send node,
666 LocalElement element, 673 LocalElement element,
667 _) { 674 _) {
668 return irBuilder.buildLocalVariableGet(element); 675 return irBuilder.buildLocalVariableGet(element);
669 } 676 }
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 translateDynamicArguments(arguments, callStructure)); 966 translateDynamicArguments(arguments, callStructure));
960 } 967 }
961 968
962 @override 969 @override
963 ir.Primitive handleConstantInvoke( 970 ir.Primitive handleConstantInvoke(
964 ast.Send node, 971 ast.Send node,
965 ConstantExpression constant, 972 ConstantExpression constant,
966 ast.NodeList arguments, 973 ast.NodeList arguments,
967 CallStructure callStructure, 974 CallStructure callStructure,
968 _) { 975 _) {
969 ir.Primitive target = buildConstantExpression(constant); 976 ir.Primitive target = buildConstant(constant);
970 return translateCallInvoke(target, arguments, callStructure); 977 return translateCallInvoke(target, arguments, callStructure);
971 } 978 }
972 979
973 @override 980 @override
974 ir.Primitive handleDynamicInvoke( 981 ir.Primitive handleDynamicInvoke(
975 ast.Send node, 982 ast.Send node,
976 ast.Node receiver, 983 ast.Node receiver,
977 ast.NodeList arguments, 984 ast.NodeList arguments,
978 Selector selector, 985 Selector selector,
979 _) { 986 _) {
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
1288 return irBuilder.buildStaticSetterSet(setter, visit(rhs)); 1295 return irBuilder.buildStaticSetterSet(setter, visit(rhs));
1289 } 1296 }
1290 1297
1291 @override 1298 @override
1292 ir.Primitive handleTypeLiteralConstantCompounds( 1299 ir.Primitive handleTypeLiteralConstantCompounds(
1293 ast.SendSet node, 1300 ast.SendSet node,
1294 ConstantExpression constant, 1301 ConstantExpression constant,
1295 CompoundRhs rhs, 1302 CompoundRhs rhs,
1296 arg) { 1303 arg) {
1297 return translateCompounds( 1304 return translateCompounds(
1298 getValue: () => buildConstantExpression(constant), 1305 getValue: () => buildConstant(constant),
1299 rhs: rhs, 1306 rhs: rhs,
1300 setValue: (value) {}); // The binary operator will throw before this. 1307 setValue: (value) {}); // The binary operator will throw before this.
1301 } 1308 }
1302 1309
1303 @override 1310 @override
1304 ir.Primitive handleDynamicCompounds( 1311 ir.Primitive handleDynamicCompounds(
1305 ast.Send node, 1312 ast.Send node,
1306 ast.Node receiver, 1313 ast.Node receiver,
1307 CompoundRhs rhs, 1314 CompoundRhs rhs,
1308 Selector getterSelector, 1315 Selector getterSelector,
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
1509 setValue: (ir.Primitive result) { 1516 setValue: (ir.Primitive result) {
1510 if (isSetterValid) { 1517 if (isSetterValid) {
1511 irBuilder.buildSuperIndexSet(indexSetFunction, indexValue, result); 1518 irBuilder.buildSuperIndexSet(indexSetFunction, indexValue, result);
1512 } else { 1519 } else {
1513 buildInstanceNoSuchMethod( 1520 buildInstanceNoSuchMethod(
1514 new Selector.indexSet(), <ir.Primitive>[indexValue, result]); 1521 new Selector.indexSet(), <ir.Primitive>[indexValue, result]);
1515 } 1522 }
1516 }); 1523 });
1517 } 1524 }
1518 1525
1519 /// Evaluates a string interpolation and appends each part to [accumulator]
1520 /// (after stringify conversion).
1521 void buildStringParts(ast.Node node, List<ir.Primitive> accumulator) {
1522 if (node is ast.StringJuxtaposition) {
1523 buildStringParts(node.first, accumulator);
1524 buildStringParts(node.second, accumulator);
1525 } else if (node is ast.StringInterpolation) {
1526 buildStringParts(node.string, accumulator);
1527 for (ast.StringInterpolationPart part in node.parts) {
1528 buildStringParts(part.expression, accumulator);
1529 buildStringParts(part.string, accumulator);
1530 }
1531 } else if (node is ast.LiteralString) {
1532 // Empty strings often occur at the end of a string interpolation,
1533 // do not bother to include them.
1534 if (!node.dartString.isEmpty) {
1535 accumulator.add(irBuilder.buildDartStringConstant(node.dartString));
1536 }
1537 } else if (node is ast.ParenthesizedExpression) {
1538 buildStringParts(node, accumulator);
1539 } else {
1540 ir.Primitive value = visit(node);
1541 accumulator.add(irBuilder.buildStringify(value));
1542 }
1543 }
1544
1545 ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) { 1526 ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) {
1546 assert(irBuilder.isOpen); 1527 assert(irBuilder.isOpen);
1547 List<ir.Primitive> parts = <ir.Primitive>[]; 1528 ir.Primitive first = visit(node.first);
1548 buildStringParts(node, parts); 1529 ir.Primitive second = visit(node.second);
1549 return irBuilder.buildStringConcatenation(parts); 1530 return irBuilder.buildStringConcatenation([first, second]);
1550 } 1531 }
1551 1532
1552 ir.Primitive visitStringInterpolation(ast.StringInterpolation node) { 1533 ir.Primitive visitStringInterpolation(ast.StringInterpolation node) {
1553 assert(irBuilder.isOpen); 1534 assert(irBuilder.isOpen);
1554 List<ir.Primitive> parts = <ir.Primitive>[]; 1535 List<ir.Primitive> arguments = [];
1555 buildStringParts(node, parts); 1536 arguments.add(visitLiteralString(node.string));
1556 return irBuilder.buildStringConcatenation(parts); 1537 var it = node.parts.iterator;
1538 while (it.moveNext()) {
1539 ast.StringInterpolationPart part = it.current;
1540 arguments.add(visit(part.expression));
1541 arguments.add(visitLiteralString(part.string));
1542 }
1543 return irBuilder.buildStringConcatenation(arguments);
1557 } 1544 }
1558 1545
1559 ir.Primitive translateConstant(ast.Node node) { 1546 ir.Primitive translateConstant(ast.Node node) {
1560 assert(irBuilder.isOpen); 1547 assert(irBuilder.isOpen);
1561 return irBuilder.buildConstant(getConstantForNode(node)); 1548 return buildConstant(getConstantForNode(node));
1562 } 1549 }
1563 1550
1564 ir.Primitive visitThrow(ast.Throw node) { 1551 ir.Primitive visitThrow(ast.Throw node) {
1565 assert(irBuilder.isOpen); 1552 assert(irBuilder.isOpen);
1566 // This function is not called for throw expressions occurring as 1553 // This function is not called for throw expressions occurring as
1567 // statements. 1554 // statements.
1568 return irBuilder.buildNonTailThrow(visit(node.expression)); 1555 return irBuilder.buildNonTailThrow(visit(node.expression));
1569 } 1556 }
1570 1557
1571 ir.Primitive buildStaticNoSuchMethod( 1558 ir.Primitive buildStaticNoSuchMethod(
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
2105 JavaScriptBackend get _backend => _compiler.backend; 2092 JavaScriptBackend get _backend => _compiler.backend;
2106 2093
2107 GlobalProgramInformation(this._compiler); 2094 GlobalProgramInformation(this._compiler);
2108 2095
2109 /// Returns [true], if the analysis could not determine that the type 2096 /// Returns [true], if the analysis could not determine that the type
2110 /// arguments for the class [cls] are never used in the program. 2097 /// arguments for the class [cls] are never used in the program.
2111 bool requiresRuntimeTypesFor(ClassElement cls) { 2098 bool requiresRuntimeTypesFor(ClassElement cls) {
2112 return cls.typeVariables.isNotEmpty && _backend.classNeedsRti(cls); 2099 return cls.typeVariables.isNotEmpty && _backend.classNeedsRti(cls);
2113 } 2100 }
2114 2101
2115 FunctionElement get stringifyFunction {
2116 return _backend.getStringInterpolationHelper();
2117 }
2118
2119 FunctionElement get throwTypeErrorHelper => _backend.getThrowTypeError(); 2102 FunctionElement get throwTypeErrorHelper => _backend.getThrowTypeError();
2120 2103
2121 ClassElement get nullClass => _compiler.nullClass; 2104 ClassElement get nullClass => _compiler.nullClass;
2122 2105
2123 DartType unaliasType(DartType type) => type.unalias(_compiler); 2106 DartType unaliasType(DartType type) => type.unalias(_compiler);
2124 2107
2125 TypeMask getTypeMaskForForeign(NativeBehavior behavior) { 2108 TypeMask getTypeMaskForForeign(NativeBehavior behavior) {
2126 return TypeMaskFactory.fromNativeBehavior(behavior, _compiler); 2109 return TypeMaskFactory.fromNativeBehavior(behavior, _compiler);
2127 } 2110 }
2128 } 2111 }
(...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after
2891 [irBuilder.buildStringConstant(element.name)]); 2874 [irBuilder.buildStringConstant(element.name)]);
2892 } 2875 }
2893 2876
2894 @override 2877 @override
2895 ir.Primitive handleStaticFieldGet(ast.Send node, FieldElement field, _) { 2878 ir.Primitive handleStaticFieldGet(ast.Send node, FieldElement field, _) {
2896 SourceInformation src = sourceInformationBuilder.buildGet(node); 2879 SourceInformation src = sourceInformationBuilder.buildGet(node);
2897 return buildStaticFieldGet(field, src); 2880 return buildStaticFieldGet(field, src);
2898 } 2881 }
2899 2882
2900 ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src) { 2883 ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src) {
2901 ConstantValue constant = getConstantForVariable(field); 2884 ConstantExpression constant =
2885 backend.constants.getConstantForVariable(field);
2902 if (constant != null && !field.isAssignable) { 2886 if (constant != null && !field.isAssignable) {
2903 return irBuilder.buildConstant(constant); 2887 return buildConstant(constant);
2904 } else if (backend.constants.lazyStatics.contains(field)) { 2888 } else if (backend.constants.lazyStatics.contains(field)) {
2905 return irBuilder.buildStaticFieldLazyGet(field, src); 2889 return irBuilder.buildStaticFieldLazyGet(field, src);
2906 } else { 2890 } else {
2907 return irBuilder.buildStaticFieldGet(field, src); 2891 return irBuilder.buildStaticFieldGet(field, src);
2908 } 2892 }
2909 } 2893 }
2910 2894
2911 /// Build code to handle foreign code, that is, native JavaScript code, or 2895 /// Build code to handle foreign code, that is, native JavaScript code, or
2912 /// builtin values and operations of the backend. 2896 /// builtin values and operations of the backend.
2913 ir.Primitive handleForeignCode(ast.Send node, 2897 ir.Primitive handleForeignCode(ast.Send node,
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
3185 } 3169 }
3186 3170
3187 processSetStatic(ir.SetStatic node) { 3171 processSetStatic(ir.SetStatic node) {
3188 node.body = replacementFor(node.body); 3172 node.body = replacementFor(node.body);
3189 } 3173 }
3190 3174
3191 processContinuation(ir.Continuation node) { 3175 processContinuation(ir.Continuation node) {
3192 node.body = replacementFor(node.body); 3176 node.body = replacementFor(node.body);
3193 } 3177 }
3194 } 3178 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart ('k') | pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698