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

Side by Side Diff: lib/compiler/implementation/ssa/builder.dart

Issue 10825386: Use JavaScript runtime semantics when constant folding. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 8 years, 3 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
« no previous file with comments | « lib/compiler/implementation/operations.dart ('k') | lib/compiler/implementation/ssa/nodes.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 class Interceptors { 5 class Interceptors {
6 Compiler compiler; 6 Compiler compiler;
7 Interceptors(Compiler this.compiler); 7 Interceptors(Compiler this.compiler);
8 8
9 SourceString mapOperatorToMethodName(Operator op) { 9 SourceString mapOperatorToMethodName(Operator op) {
10 String name = op.source.stringValue; 10 String name = op.source.stringValue;
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 emitter = backend.emitter, 150 emitter = backend.emitter,
151 functionsCalledInLoop = new Set<FunctionElement>(), 151 functionsCalledInLoop = new Set<FunctionElement>(),
152 selectorsCalledInLoop = new Map<SourceString, Selector>(), 152 selectorsCalledInLoop = new Map<SourceString, Selector>(),
153 backend = backend, 153 backend = backend,
154 super(backend.compiler); 154 super(backend.compiler);
155 155
156 HGraph build(WorkItem work) { 156 HGraph build(WorkItem work) {
157 return measure(() { 157 return measure(() {
158 Element element = work.element; 158 Element element = work.element;
159 HInstruction.idCounter = 0; 159 HInstruction.idCounter = 0;
160 SsaBuilder builder = new SsaBuilder(this, work); 160 ConstantSystem constantSystem = compiler.backend.constantSystem;
161 SsaBuilder builder = new SsaBuilder(constantSystem, this, work);
161 HGraph graph; 162 HGraph graph;
162 ElementKind kind = element.kind; 163 ElementKind kind = element.kind;
163 if (kind === ElementKind.GENERATIVE_CONSTRUCTOR) { 164 if (kind === ElementKind.GENERATIVE_CONSTRUCTOR) {
164 graph = compileConstructor(builder, work); 165 graph = compileConstructor(builder, work);
165 } else if (kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY || 166 } else if (kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
166 kind === ElementKind.FUNCTION || 167 kind === ElementKind.FUNCTION ||
167 kind === ElementKind.GETTER || 168 kind === ElementKind.GETTER ||
168 kind === ElementKind.SETTER) { 169 kind === ElementKind.SETTER) {
169 graph = builder.buildMethod(work.element); 170 graph = builder.buildMethod(work.element);
170 } else if (kind === ElementKind.FIELD) { 171 } else if (kind === ElementKind.FIELD) {
(...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 result.add(element); 801 result.add(element);
801 } 802 }
802 return (result === null) ? const <LabelElement>[] : result; 803 return (result === null) ? const <LabelElement>[] : result;
803 } 804 }
804 } 805 }
805 806
806 class SsaBuilder extends ResolvedVisitor implements Visitor { 807 class SsaBuilder extends ResolvedVisitor implements Visitor {
807 final SsaBuilderTask builder; 808 final SsaBuilderTask builder;
808 final Interceptors interceptors; 809 final Interceptors interceptors;
809 final WorkItem work; 810 final WorkItem work;
811 final ConstantSystem constantSystem;
810 bool methodInterceptionEnabled; 812 bool methodInterceptionEnabled;
811 HGraph graph; 813 HGraph graph;
812 LocalsHandler localsHandler; 814 LocalsHandler localsHandler;
813 HInstruction rethrowableException; 815 HInstruction rethrowableException;
814 Map<Element, HParameterValue> parameters; 816 Map<Element, HParameterValue> parameters;
815 817
816 Map<TargetElement, JumpHandler> jumpTargets; 818 Map<TargetElement, JumpHandler> jumpTargets;
817 819
818 /** 820 /**
819 * Variables stored in the current activation. These variables are 821 * Variables stored in the current activation. These variables are
(...skipping 11 matching lines...) Expand all
831 // The most recently opened block. Has the same value as [current] while 833 // The most recently opened block. Has the same value as [current] while
832 // the block is open, but unlike [current], it isn't cleared when the current 834 // the block is open, but unlike [current], it isn't cleared when the current
833 // block is closed. 835 // block is closed.
834 HBasicBlock lastOpenedBlock; 836 HBasicBlock lastOpenedBlock;
835 837
836 LibraryElement get currentLibrary => work.element.getLibrary(); 838 LibraryElement get currentLibrary => work.element.getLibrary();
837 Element get currentElement => work.element; 839 Element get currentElement => work.element;
838 Compiler get compiler => builder.compiler; 840 Compiler get compiler => builder.compiler;
839 CodeEmitterTask get emitter => builder.emitter; 841 CodeEmitterTask get emitter => builder.emitter;
840 842
841 SsaBuilder(SsaBuilderTask builder, WorkItem work) 843 SsaBuilder(this.constantSystem, SsaBuilderTask builder, WorkItem work)
842 : this.builder = builder, 844 : this.builder = builder,
843 this.work = work, 845 this.work = work,
844 interceptors = builder.interceptors, 846 interceptors = builder.interceptors,
845 methodInterceptionEnabled = true, 847 methodInterceptionEnabled = true,
846 graph = new HGraph(), 848 graph = new HGraph(),
847 stack = new List<HInstruction>(), 849 stack = new List<HInstruction>(),
848 activationVariables = new Map<Element, HLocalValue>(), 850 activationVariables = new Map<Element, HLocalValue>(),
849 jumpTargets = new Map<TargetElement, JumpHandler>(), 851 jumpTargets = new Map<TargetElement, JumpHandler>(),
850 parameters = new Map<Element, HParameterValue>(), 852 parameters = new Map<Element, HParameterValue>(),
851 inliningStack = <InliningState>[], 853 inliningStack = <InliningState>[],
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 compiledArguments); 945 compiledArguments);
944 assert(succeeded); 946 assert(succeeded);
945 947
946 InliningState state = 948 InliningState state =
947 new InliningState(function, returnElement, elements, stack); 949 new InliningState(function, returnElement, elements, stack);
948 inliningStack.add(state); 950 inliningStack.add(state);
949 stack = <HInstruction>[]; 951 stack = <HInstruction>[];
950 returnElement = new Element(const SourceString("result"), 952 returnElement = new Element(const SourceString("result"),
951 ElementKind.VARIABLE, 953 ElementKind.VARIABLE,
952 function); 954 function);
953 localsHandler.updateLocal(returnElement, graph.addConstantNull()); 955 localsHandler.updateLocal(returnElement,
956 graph.addConstantNull(constantSystem));
954 elements = compiler.enqueuer.resolution.getCachedElements(function); 957 elements = compiler.enqueuer.resolution.getCachedElements(function);
955 FunctionSignature signature = function.computeSignature(compiler); 958 FunctionSignature signature = function.computeSignature(compiler);
956 int index = 0; 959 int index = 0;
957 signature.forEachParameter((Element parameter) { 960 signature.forEachParameter((Element parameter) {
958 HInstruction argument = compiledArguments[index++]; 961 HInstruction argument = compiledArguments[index++];
959 localsHandler.updateLocal(parameter, argument); 962 localsHandler.updateLocal(parameter, argument);
960 potentiallyCheckType(argument, parameter); 963 potentiallyCheckType(argument, parameter);
961 }); 964 });
962 return state; 965 return state;
963 } 966 }
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 Map<Element, HInstruction> fieldValues) { 1132 Map<Element, HInstruction> fieldValues) {
1130 classElement.forEachInstanceField( 1133 classElement.forEachInstanceField(
1131 includeBackendMembers: true, 1134 includeBackendMembers: true,
1132 includeSuperMembers: false, 1135 includeSuperMembers: false,
1133 f: (ClassElement enclosingClass, Element member) { 1136 f: (ClassElement enclosingClass, Element member) {
1134 TreeElements definitions = compiler.analyzeElement(member); 1137 TreeElements definitions = compiler.analyzeElement(member);
1135 Node node = member.parseNode(compiler); 1138 Node node = member.parseNode(compiler);
1136 SendSet assignment = node.asSendSet(); 1139 SendSet assignment = node.asSendSet();
1137 HInstruction value; 1140 HInstruction value;
1138 if (assignment === null) { 1141 if (assignment === null) {
1139 value = graph.addConstantNull(); 1142 value = graph.addConstantNull(constantSystem);
1140 } else { 1143 } else {
1141 Node right = assignment.arguments.head; 1144 Node right = assignment.arguments.head;
1142 TreeElements savedElements = elements; 1145 TreeElements savedElements = elements;
1143 elements = definitions; 1146 elements = definitions;
1144 right.accept(this); 1147 right.accept(this);
1145 elements = savedElements; 1148 elements = savedElements;
1146 value = pop(); 1149 value = pop();
1147 } 1150 }
1148 fieldValues[member] = value; 1151 fieldValues[member] = value;
1149 }); 1152 });
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1262 // foo([a = 42]) { 1265 // foo([a = 42]) {
1263 // var t1 = a === sentinel; 1266 // var t1 = a === sentinel;
1264 // if (t1) a = 42; 1267 // if (t1) a = 42;
1265 // if (!t1) print('parameter passed ' + a); 1268 // if (!t1) print('parameter passed ' + a);
1266 // } 1269 // }
1267 1270
1268 // Fetch the original default value of [element]; 1271 // Fetch the original default value of [element];
1269 ConstantHandler handler = compiler.constantHandler; 1272 ConstantHandler handler = compiler.constantHandler;
1270 Constant constant = handler.compileVariable(element); 1273 Constant constant = handler.compileVariable(element);
1271 HConstant defaultValue = constant == null 1274 HConstant defaultValue = constant == null
1272 ? graph.addConstantNull() 1275 ? graph.addConstantNull(constantSystem)
1273 : graph.addConstant(constant); 1276 : graph.addConstant(constant);
1274 1277
1275 // Emit the equality check with the sentinel. 1278 // Emit the equality check with the sentinel.
1276 HConstant sentinel = graph.addConstant(SentinelConstant.SENTINEL); 1279 HConstant sentinel = graph.addConstant(SentinelConstant.SENTINEL);
1277 Element equalsHelper = interceptors.getTripleEqualsInterceptor(); 1280 Element equalsHelper = interceptors.getTripleEqualsInterceptor();
1278 HInstruction target = new HStatic(equalsHelper); 1281 HInstruction target = new HStatic(equalsHelper);
1279 add(target); 1282 add(target);
1280 HInstruction operand = parameters[element]; 1283 HInstruction operand = parameters[element];
1281 HInstruction check = new HIdentity(target, sentinel, operand); 1284 HInstruction check = new HIdentity(target, sentinel, operand);
1282 add(check); 1285 add(check);
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
1663 Node initializer = node.initializer; 1666 Node initializer = node.initializer;
1664 if (initializer !== null) { 1667 if (initializer !== null) {
1665 visit(initializer); 1668 visit(initializer);
1666 if (initializer.asExpression() !== null) { 1669 if (initializer.asExpression() !== null) {
1667 pop(); 1670 pop();
1668 } 1671 }
1669 } 1672 }
1670 } 1673 }
1671 HInstruction buildCondition() { 1674 HInstruction buildCondition() {
1672 if (node.condition === null) { 1675 if (node.condition === null) {
1673 return graph.addConstantBool(true); 1676 return graph.addConstantBool(true, constantSystem);
1674 } 1677 }
1675 visit(node.condition); 1678 visit(node.condition);
1676 return popBoolified(); 1679 return popBoolified();
1677 } 1680 }
1678 void buildUpdate() { 1681 void buildUpdate() {
1679 for (Expression expression in node.update) { 1682 for (Expression expression in node.update) {
1680 visit(expression); 1683 visit(expression);
1681 assert(!isAborted()); 1684 assert(!isAborted());
1682 // The result of the update instruction isn't used, and can just 1685 // The result of the update instruction isn't used, and can just
1683 // be dropped. 1686 // be dropped.
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1878 switch (value) { 1881 switch (value) {
1879 case "-": result = new HNegate(target, operand); break; 1882 case "-": result = new HNegate(target, operand); break;
1880 case "~": result = new HBitNot(target, operand); break; 1883 case "~": result = new HBitNot(target, operand); break;
1881 default: 1884 default:
1882 compiler.internalError('Unexpected unary operator: $value.', node: op); 1885 compiler.internalError('Unexpected unary operator: $value.', node: op);
1883 break; 1886 break;
1884 } 1887 }
1885 // See if we can constant-fold right away. This avoids rewrites later on. 1888 // See if we can constant-fold right away. This avoids rewrites later on.
1886 if (operand is HConstant) { 1889 if (operand is HConstant) {
1887 HConstant constant = operand; 1890 HConstant constant = operand;
1888 Constant folded = result.operation.fold(constant.constant); 1891 Constant folded =
1892 result.operation(constantSystem).fold(constant.constant);
1889 if (folded !== null) { 1893 if (folded !== null) {
1890 stack.add(graph.addConstant(folded)); 1894 stack.add(graph.addConstant(folded));
1891 return; 1895 return;
1892 } 1896 }
1893 } 1897 }
1894 pushWithPosition(result, node); 1898 pushWithPosition(result, node);
1895 } 1899 }
1896 1900
1897 void visitBinary(HInstruction left, Operator op, HInstruction right) { 1901 void visitBinary(HInstruction left, Operator op, HInstruction right) {
1898 Element element = interceptors.getOperatorInterceptor(op); 1902 Element element = interceptors.getOperatorInterceptor(op);
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
2167 HInstruction typeInfo = null; 2171 HInstruction typeInfo = null;
2168 if (compiler.codegenWorld.rti.hasTypeArguments(type)) { 2172 if (compiler.codegenWorld.rti.hasTypeArguments(type)) {
2169 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), expression); 2173 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), expression);
2170 typeInfo = pop(); 2174 typeInfo = pop();
2171 } 2175 }
2172 if (type.element.isTypeVariable()) { 2176 if (type.element.isTypeVariable()) {
2173 // TODO(karlklose): We emulate the behavior of the old frog 2177 // TODO(karlklose): We emulate the behavior of the old frog
2174 // compiler and answer true to any is check involving a type variable 2178 // compiler and answer true to any is check involving a type variable
2175 // -- both is T and is !T -- until we have a proper implementation of 2179 // -- both is T and is !T -- until we have a proper implementation of
2176 // reified generics. 2180 // reified generics.
2177 stack.add(graph.addConstantBool(true)); 2181 stack.add(graph.addConstantBool(true, constantSystem));
2178 } else { 2182 } else {
2179 HInstruction instruction; 2183 HInstruction instruction;
2180 if (typeInfo !== null) { 2184 if (typeInfo !== null) {
2181 instruction = new HIs.withTypeInfoCall(type, expression, typeInfo); 2185 instruction = new HIs.withTypeInfoCall(type, expression, typeInfo);
2182 } else { 2186 } else {
2183 instruction = new HIs(type, expression); 2187 instruction = new HIs(type, expression);
2184 } 2188 }
2185 if (isNot) { 2189 if (isNot) {
2186 add(instruction); 2190 add(instruction);
2187 instruction = new HNot(instruction); 2191 instruction = new HNot(instruction);
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
2503 generateSuperNoSuchMethodSend(Send node) { 2507 generateSuperNoSuchMethodSend(Send node) {
2504 ClassElement cls = work.element.getEnclosingClass(); 2508 ClassElement cls = work.element.getEnclosingClass();
2505 Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD); 2509 Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD);
2506 HStatic target = new HStatic(element); 2510 HStatic target = new HStatic(element);
2507 add(target); 2511 add(target);
2508 HInstruction self = localsHandler.readThis(); 2512 HInstruction self = localsHandler.readThis();
2509 Identifier identifier = node.selector.asIdentifier(); 2513 Identifier identifier = node.selector.asIdentifier();
2510 String name = identifier.source.slowToString(); 2514 String name = identifier.source.slowToString();
2511 // TODO(ahe): Add the arguments to this list. 2515 // TODO(ahe): Add the arguments to this list.
2512 push(new HLiteralList([])); 2516 push(new HLiteralList([]));
2517 Constant nameConstant =
2518 constantSystem.createString(new DartString.literal(name), node);
2513 var inputs = <HInstruction>[ 2519 var inputs = <HInstruction>[
2514 target, 2520 target,
2515 self, 2521 self,
2516 graph.addConstantString(new DartString.literal(name), node), 2522 graph.addConstant(nameConstant),
2517 pop()]; 2523 pop()];
2518 push(new HInvokeSuper(inputs)); 2524 push(new HInvokeSuper(inputs));
2519 } 2525 }
2520 2526
2521 visitSend(Send node) { 2527 visitSend(Send node) {
2522 Element element = elements[node]; 2528 Element element = elements[node];
2523 if (element !== null && element === work.element) { 2529 if (element !== null && element === work.element) {
2524 graph.isRecursiveMethod = true; 2530 graph.isRecursiveMethod = true;
2525 } 2531 }
2526 super.visitSend(node); 2532 super.visitSend(node);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2574 return foreign; 2580 return foreign;
2575 } else { 2581 } else {
2576 // TODO(ngeoffray): Match the VM behavior and throw an 2582 // TODO(ngeoffray): Match the VM behavior and throw an
2577 // exception at runtime. 2583 // exception at runtime.
2578 compiler.cancel('Unimplemented unresolved type variable', 2584 compiler.cancel('Unimplemented unresolved type variable',
2579 node: currentNode); 2585 node: currentNode);
2580 } 2586 }
2581 } else { 2587 } else {
2582 // The type variable is a type (e.g. int). 2588 // The type variable is a type (e.g. int).
2583 return graph.addConstantString( 2589 return graph.addConstantString(
2584 new LiteralDartString('$argument'), currentNode); 2590 new LiteralDartString('$argument'), currentNode, constantSystem);
2585 } 2591 }
2586 } 2592 }
2587 2593
2588 visitNewSend(Send node) { 2594 visitNewSend(Send node) {
2589 computeType(element) { 2595 computeType(element) {
2590 Element originalElement = elements[node]; 2596 Element originalElement = elements[node];
2591 if (originalElement.getEnclosingClass() === compiler.listClass) { 2597 if (originalElement.getEnclosingClass() === compiler.listClass) {
2592 if (node.arguments.isEmpty()) { 2598 if (node.arguments.isEmpty()) {
2593 return HType.EXTENDABLE_ARRAY; 2599 return HType.EXTENDABLE_ARRAY;
2594 } else { 2600 } else {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2632 2638
2633 HType elementType = computeType(constructor); 2639 HType elementType = computeType(constructor);
2634 HInstruction newInstance = new HInvokeStatic(inputs, elementType); 2640 HInstruction newInstance = new HInvokeStatic(inputs, elementType);
2635 pushWithPosition(newInstance, node); 2641 pushWithPosition(newInstance, node);
2636 } 2642 }
2637 2643
2638 visitStaticSend(Send node) { 2644 visitStaticSend(Send node) {
2639 Selector selector = elements.getSelector(node); 2645 Selector selector = elements.getSelector(node);
2640 Element element = elements[node]; 2646 Element element = elements[node];
2641 if (element === compiler.assertMethod && !compiler.enableUserAssertions) { 2647 if (element === compiler.assertMethod && !compiler.enableUserAssertions) {
2642 stack.add(graph.addConstantNull()); 2648 stack.add(graph.addConstantNull(constantSystem));
2643 return; 2649 return;
2644 } 2650 }
2645 compiler.ensure(!element.isGenerativeConstructor()); 2651 compiler.ensure(!element.isGenerativeConstructor());
2646 if (element.isFunction()) { 2652 if (element.isFunction()) {
2647 if (tryInlineMethod(element, selector, node.arguments)) return; 2653 if (tryInlineMethod(element, selector, node.arguments)) return;
2648 2654
2649 HInstruction target = new HStatic(element); 2655 HInstruction target = new HStatic(element);
2650 add(target); 2656 add(target);
2651 var inputs = <HInstruction>[target]; 2657 var inputs = <HInstruction>[target];
2652 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2658 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
(...skipping 23 matching lines...) Expand all
2676 generateGetter(node, elements[node]); 2682 generateGetter(node, elements[node]);
2677 } 2683 }
2678 2684
2679 // TODO(antonm): migrate rest of SsaBuilder to internalError. 2685 // TODO(antonm): migrate rest of SsaBuilder to internalError.
2680 internalError(String reason, [Node node]) { 2686 internalError(String reason, [Node node]) {
2681 compiler.internalError(reason, node: node); 2687 compiler.internalError(reason, node: node);
2682 } 2688 }
2683 2689
2684 void generateRuntimeError(Node node, String message) { 2690 void generateRuntimeError(Node node, String message) {
2685 DartString messageObject = new DartString.literal(message); 2691 DartString messageObject = new DartString.literal(message);
2686 HInstruction errorMessage = graph.addConstantString(messageObject, node); 2692 Constant messageConstant =
2693 constantSystem.createString(messageObject, node);
2694 HInstruction errorMessage = graph.addConstant(messageConstant);
2687 Element helper = interceptors.getThrowRuntimeError(); 2695 Element helper = interceptors.getThrowRuntimeError();
2688 pushInvokeHelper1(helper, errorMessage); 2696 pushInvokeHelper1(helper, errorMessage);
2689 } 2697 }
2690 2698
2691 visitNewExpression(NewExpression node) { 2699 visitNewExpression(NewExpression node) {
2692 Element element = elements[node.send]; 2700 Element element = elements[node.send];
2693 if (element != null && element.isErroneous()) { 2701 if (element != null && element.isErroneous()) {
2694 ErroneousElement error = element; 2702 ErroneousElement error = element;
2695 Message message = error.errorMessage; 2703 Message message = error.errorMessage;
2696 if (message.kind === MessageKind.CANNOT_FIND_CONSTRUCTOR) { 2704 if (message.kind === MessageKind.CANNOT_FIND_CONSTRUCTOR) {
2697 Element helper = 2705 Element helper =
2698 compiler.findHelper(const SourceString('throwNoSuchMethod')); 2706 compiler.findHelper(const SourceString('throwNoSuchMethod'));
2699 DartString receiverLiteral = new DartString.literal(''); 2707 DartString receiverLiteral = new DartString.literal('');
2700 HInstruction receiver = graph.addConstantString(receiverLiteral, node); 2708 Constant receiverConstant =
2709 constantSystem.createString(receiverLiteral, node);
2710 HInstruction receiver = graph.addConstant(receiverConstant);
2701 String constructorName = 'constructor ${message.arguments[0]}'; 2711 String constructorName = 'constructor ${message.arguments[0]}';
2702 DartString nameLiteral = new DartString.literal(constructorName); 2712 DartString nameLiteral = new DartString.literal(constructorName);
2703 HInstruction name = graph.addConstantString(nameLiteral, node.send); 2713 Constant nameConstant =
2714 constantSystem.createString(nameLiteral, node.send);
2715 HInstruction name = graph.addConstant(nameConstant);
2704 List<HInstruction> inputs = <HInstruction>[]; 2716 List<HInstruction> inputs = <HInstruction>[];
2705 node.send.arguments.forEach((argumentNode) { 2717 node.send.arguments.forEach((argumentNode) {
2706 visit(argumentNode); 2718 visit(argumentNode);
2707 HInstruction value = pop(); 2719 HInstruction value = pop();
2708 inputs.add(value); 2720 inputs.add(value);
2709 }); 2721 });
2710 HInstruction arguments = new HLiteralList(inputs); 2722 HInstruction arguments = new HLiteralList(inputs);
2711 add(arguments); 2723 add(arguments);
2712 pushInvokeHelper3(helper, receiver, name, arguments); 2724 pushInvokeHelper3(helper, receiver, name, arguments);
2713 } else if (message.kind === MessageKind.CANNOT_RESOLVE) { 2725 } else if (message.kind === MessageKind.CANNOT_RESOLVE) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2762 HInstruction index; 2774 HInstruction index;
2763 bool isCompoundAssignment = op.source.stringValue.endsWith('='); 2775 bool isCompoundAssignment = op.source.stringValue.endsWith('=');
2764 // Compound assignments are considered as being prefix. 2776 // Compound assignments are considered as being prefix.
2765 bool isPrefix = !node.isPostfix; 2777 bool isPrefix = !node.isPostfix;
2766 Element getter = elements[node.selector]; 2778 Element getter = elements[node.selector];
2767 if (isCompoundAssignment) { 2779 if (isCompoundAssignment) {
2768 value = pop(); 2780 value = pop();
2769 index = pop(); 2781 index = pop();
2770 } else { 2782 } else {
2771 index = pop(); 2783 index = pop();
2772 value = graph.addConstantInt(1); 2784 value = graph.addConstantInt(1, constantSystem);
2773 } 2785 }
2774 HStatic indexMethod = new HStatic(interceptors.getIndexInterceptor()); 2786 HStatic indexMethod = new HStatic(interceptors.getIndexInterceptor());
2775 add(indexMethod); 2787 add(indexMethod);
2776 HInstruction left = new HIndex(indexMethod, receiver, index); 2788 HInstruction left = new HIndex(indexMethod, receiver, index);
2777 add(left); 2789 add(left);
2778 Element opElement = elements[op]; 2790 Element opElement = elements[op];
2779 visitBinary(left, op, value); 2791 visitBinary(left, op, value);
2780 value = pop(); 2792 value = pop();
2781 HInstruction assign = new HIndexAssign( 2793 HInstruction assign = new HIndexAssign(
2782 target, receiver, index, value); 2794 target, receiver, index, value);
(...skipping 29 matching lines...) Expand all
2812 generateInstanceGetterWithCompiledReceiver(node, receiver); 2824 generateInstanceGetterWithCompiledReceiver(node, receiver);
2813 } else { 2825 } else {
2814 generateGetter(node, elements[node.selector]); 2826 generateGetter(node, elements[node.selector]);
2815 } 2827 }
2816 HInstruction left = pop(); 2828 HInstruction left = pop();
2817 HInstruction right; 2829 HInstruction right;
2818 if (isCompoundAssignment) { 2830 if (isCompoundAssignment) {
2819 visit(node.argumentsNode); 2831 visit(node.argumentsNode);
2820 right = pop(); 2832 right = pop();
2821 } else { 2833 } else {
2822 right = graph.addConstantInt(1); 2834 right = graph.addConstantInt(1, constantSystem);
2823 } 2835 }
2824 visitBinary(left, op, right); 2836 visitBinary(left, op, right);
2825 HInstruction operation = pop(); 2837 HInstruction operation = pop();
2826 assert(operation !== null); 2838 assert(operation !== null);
2827 if (Elements.isInstanceSend(node, elements)) { 2839 if (Elements.isInstanceSend(node, elements)) {
2828 assert(receiver !== null); 2840 assert(receiver !== null);
2829 generateInstanceSetterWithCompiledReceiver(node, receiver, operation); 2841 generateInstanceSetterWithCompiledReceiver(node, receiver, operation);
2830 } else { 2842 } else {
2831 assert(receiver === null); 2843 assert(receiver === null);
2832 generateSetter(node, element, operation); 2844 generateSetter(node, element, operation);
2833 } 2845 }
2834 if (!isPrefix) { 2846 if (!isPrefix) {
2835 pop(); 2847 pop();
2836 stack.add(left); 2848 stack.add(left);
2837 } 2849 }
2838 } 2850 }
2839 } 2851 }
2840 2852
2841 void visitLiteralInt(LiteralInt node) { 2853 void visitLiteralInt(LiteralInt node) {
2842 stack.add(graph.addConstantInt(node.value)); 2854 stack.add(graph.addConstantInt(node.value, constantSystem));
2843 } 2855 }
2844 2856
2845 void visitLiteralDouble(LiteralDouble node) { 2857 void visitLiteralDouble(LiteralDouble node) {
2846 stack.add(graph.addConstantDouble(node.value)); 2858 stack.add(graph.addConstantDouble(node.value, constantSystem));
2847 } 2859 }
2848 2860
2849 void visitLiteralBool(LiteralBool node) { 2861 void visitLiteralBool(LiteralBool node) {
2850 stack.add(graph.addConstantBool(node.value)); 2862 stack.add(graph.addConstantBool(node.value, constantSystem));
2851 } 2863 }
2852 2864
2853 void visitLiteralString(LiteralString node) { 2865 void visitLiteralString(LiteralString node) {
2854 stack.add(graph.addConstantString(node.dartString, node)); 2866 stack.add(graph.addConstantString(node.dartString, node, constantSystem));
2855 } 2867 }
2856 2868
2857 void visitStringJuxtaposition(StringJuxtaposition node) { 2869 void visitStringJuxtaposition(StringJuxtaposition node) {
2858 if (!node.isInterpolation) { 2870 if (!node.isInterpolation) {
2859 // This is a simple string with no interpolations. 2871 // This is a simple string with no interpolations.
2860 stack.add(graph.addConstantString(node.dartString, node)); 2872 stack.add(graph.addConstantString(node.dartString, node, constantSystem));
2861 return; 2873 return;
2862 } 2874 }
2863 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); 2875 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node);
2864 stringBuilder.visit(node); 2876 stringBuilder.visit(node);
2865 stack.add(stringBuilder.result); 2877 stack.add(stringBuilder.result);
2866 } 2878 }
2867 2879
2868 void visitLiteralNull(LiteralNull node) { 2880 void visitLiteralNull(LiteralNull node) {
2869 stack.add(graph.addConstantNull()); 2881 stack.add(graph.addConstantNull(constantSystem));
2870 } 2882 }
2871 2883
2872 visitNodeList(NodeList node) { 2884 visitNodeList(NodeList node) {
2873 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { 2885 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) {
2874 if (isAborted()) { 2886 if (isAborted()) {
2875 compiler.reportWarning(link.head, 'dead code'); 2887 compiler.reportWarning(link.head, 'dead code');
2876 } else { 2888 } else {
2877 visit(link.head); 2889 visit(link.head);
2878 } 2890 }
2879 } 2891 }
(...skipping 19 matching lines...) Expand all
2899 dup(); 2911 dup();
2900 } 2912 }
2901 2913
2902 visitReturn(Return node) { 2914 visitReturn(Return node) {
2903 if (node.getBeginToken().stringValue === 'native') { 2915 if (node.getBeginToken().stringValue === 'native') {
2904 native.handleSsaNative(this, node.expression); 2916 native.handleSsaNative(this, node.expression);
2905 return; 2917 return;
2906 } 2918 }
2907 HInstruction value; 2919 HInstruction value;
2908 if (node.expression === null) { 2920 if (node.expression === null) {
2909 value = graph.addConstantNull(); 2921 value = graph.addConstantNull(constantSystem);
2910 } else { 2922 } else {
2911 visit(node.expression); 2923 visit(node.expression);
2912 value = pop(); 2924 value = pop();
2913 } 2925 }
2914 if (!inliningStack.isEmpty()) { 2926 if (!inliningStack.isEmpty()) {
2915 localsHandler.updateLocal(returnElement, value); 2927 localsHandler.updateLocal(returnElement, value);
2916 } else { 2928 } else {
2917 close(attachPosition(new HReturn(value), node)).addSuccessor(graph.exit); 2929 close(attachPosition(new HReturn(value), node)).addSuccessor(graph.exit);
2918 } 2930 }
2919 } 2931 }
2920 2932
2921 visitThrow(Throw node) { 2933 visitThrow(Throw node) {
2922 if (node.expression === null) { 2934 if (node.expression === null) {
2923 HInstruction exception = rethrowableException; 2935 HInstruction exception = rethrowableException;
2924 if (exception === null) { 2936 if (exception === null) {
2925 exception = graph.addConstantNull(); 2937 exception = graph.addConstantNull(constantSystem);
2926 compiler.reportError(node, 2938 compiler.reportError(node,
2927 'throw without expression outside catch block'); 2939 'throw without expression outside catch block');
2928 } 2940 }
2929 close(new HThrow(exception, isRethrow: true)); 2941 close(new HThrow(exception, isRethrow: true));
2930 } else { 2942 } else {
2931 visit(node.expression); 2943 visit(node.expression);
2932 close(new HThrow(pop())); 2944 close(new HThrow(pop()));
2933 } 2945 }
2934 } 2946 }
2935 2947
2936 visitTypeAnnotation(TypeAnnotation node) { 2948 visitTypeAnnotation(TypeAnnotation node) {
2937 compiler.internalError('visiting type annotation in SSA builder', 2949 compiler.internalError('visiting type annotation in SSA builder',
2938 node: node); 2950 node: node);
2939 } 2951 }
2940 2952
2941 visitVariableDefinitions(VariableDefinitions node) { 2953 visitVariableDefinitions(VariableDefinitions node) {
2942 for (Link<Node> link = node.definitions.nodes; 2954 for (Link<Node> link = node.definitions.nodes;
2943 !link.isEmpty(); 2955 !link.isEmpty();
2944 link = link.tail) { 2956 link = link.tail) {
2945 Node definition = link.head; 2957 Node definition = link.head;
2946 if (definition is Identifier) { 2958 if (definition is Identifier) {
2947 HInstruction initialValue = graph.addConstantNull(); 2959 HInstruction initialValue = graph.addConstantNull(constantSystem);
2948 localsHandler.updateLocal(elements[definition], initialValue); 2960 localsHandler.updateLocal(elements[definition], initialValue);
2949 } else { 2961 } else {
2950 assert(definition is SendSet); 2962 assert(definition is SendSet);
2951 visitSendSet(definition); 2963 visitSendSet(definition);
2952 pop(); // Discard value. 2964 pop(); // Discard value.
2953 } 2965 }
2954 } 2966 }
2955 } 2967 }
2956 2968
2957 visitLiteralList(LiteralList node) { 2969 visitLiteralList(LiteralList node) {
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
3535 compiler.cancel('On with unresolved type', 3547 compiler.cancel('On with unresolved type',
3536 node: catchBlock.type); 3548 node: catchBlock.type);
3537 } 3549 }
3538 HInstruction condition = new HIs(type, unwrappedException); 3550 HInstruction condition = new HIs(type, unwrappedException);
3539 push(condition); 3551 push(condition);
3540 } 3552 }
3541 else { 3553 else {
3542 VariableDefinitions declaration = catchBlock.formals.nodes.head; 3554 VariableDefinitions declaration = catchBlock.formals.nodes.head;
3543 HInstruction condition = null; 3555 HInstruction condition = null;
3544 if (declaration.type == null) { 3556 if (declaration.type == null) {
3545 condition = graph.addConstantBool(true); 3557 condition = graph.addConstantBool(true, constantSystem);
3546 stack.add(condition); 3558 stack.add(condition);
3547 } else { 3559 } else {
3548 // TODO(aprelev@gmail.com): Once old catch syntax is removed 3560 // TODO(aprelev@gmail.com): Once old catch syntax is removed
3549 // "if" condition above and this "else" branch should be deleted as 3561 // "if" condition above and this "else" branch should be deleted as
3550 // type of declared variable won't matter for the catch 3562 // type of declared variable won't matter for the catch
3551 // condition. 3563 // condition.
3552 DartType type = elements.getType(declaration.type); 3564 DartType type = elements.getType(declaration.type);
3553 if (type == null) { 3565 if (type == null) {
3554 compiler.cancel('Catch with unresolved type', node: catchBlock); 3566 compiler.cancel('Catch with unresolved type', node: catchBlock);
3555 } 3567 }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
3646 if (element === builder.compiler.intClass) return HType.INTEGER; 3658 if (element === builder.compiler.intClass) return HType.INTEGER;
3647 if (element === builder.compiler.listClass) return HType.READABLE_ARRAY; 3659 if (element === builder.compiler.listClass) return HType.READABLE_ARRAY;
3648 if (element === builder.compiler.nullClass) return HType.NULL; 3660 if (element === builder.compiler.nullClass) return HType.NULL;
3649 if (element === builder.compiler.stringClass) return HType.STRING; 3661 if (element === builder.compiler.stringClass) return HType.STRING;
3650 return HType.UNKNOWN; 3662 return HType.UNKNOWN;
3651 } 3663 }
3652 3664
3653 /** HACK HACK HACK */ 3665 /** HACK HACK HACK */
3654 void hackAroundPossiblyAbortingBody(Node statement, void body()) { 3666 void hackAroundPossiblyAbortingBody(Node statement, void body()) {
3655 visitCondition() { 3667 visitCondition() {
3656 stack.add(graph.addConstantBool(true)); 3668 stack.add(graph.addConstantBool(true, constantSystem));
3657 } 3669 }
3658 buildBody() { 3670 buildBody() {
3659 // TODO(lrn): Make sure to take continue into account. 3671 // TODO(lrn): Make sure to take continue into account.
3660 body(); 3672 body();
3661 } 3673 }
3662 handleIf(statement, visitCondition, buildBody, null); 3674 handleIf(statement, visitCondition, buildBody, null);
3663 } 3675 }
3664 } 3676 }
3665 3677
3666 /** 3678 /**
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
3938 builder.push(new HNot(builder.pop())); 3950 builder.push(new HNot(builder.pop()));
3939 } 3951 }
3940 } 3952 }
3941 3953
3942 void visitThen() { 3954 void visitThen() {
3943 right(); 3955 right();
3944 boolifiedRight = builder.popBoolified(); 3956 boolifiedRight = builder.popBoolified();
3945 } 3957 }
3946 3958
3947 handleIf(visitCondition, visitThen, null); 3959 handleIf(visitCondition, visitThen, null);
3960 HConstant notIsAnd =
3961 builder.graph.addConstantBool(!isAnd, builder.constantSystem);
3948 HPhi result = new HPhi.manyInputs(null, 3962 HPhi result = new HPhi.manyInputs(null,
3949 <HInstruction>[boolifiedRight, builder.graph.addConstantBool(!isAnd)]); 3963 <HInstruction>[boolifiedRight, notIsAnd]);
3950 builder.current.addPhi(result); 3964 builder.current.addPhi(result);
3951 builder.stack.add(result); 3965 builder.stack.add(result);
3952 } 3966 }
3953 3967
3954 void handleLogicalAndOrWithLeftNode(Node left, 3968 void handleLogicalAndOrWithLeftNode(Node left,
3955 void visitRight(), 3969 void visitRight(),
3956 [bool isAnd]) { 3970 [bool isAnd]) {
3957 // This method is similar to [handleLogicalAndOr] but optimizes the case 3971 // This method is similar to [handleLogicalAndOr] but optimizes the case
3958 // where left is a logical "and" or logical "or". 3972 // where left is a logical "and" or logical "or".
3959 // 3973 //
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
4026 new HSubGraphBlockInformation(elseBranch.graph)); 4040 new HSubGraphBlockInformation(elseBranch.graph));
4027 4041
4028 HBasicBlock conditionStartBlock = conditionBranch.block; 4042 HBasicBlock conditionStartBlock = conditionBranch.block;
4029 conditionStartBlock.setBlockFlow(info, joinBlock); 4043 conditionStartBlock.setBlockFlow(info, joinBlock);
4030 SubGraph conditionGraph = conditionBranch.graph; 4044 SubGraph conditionGraph = conditionBranch.graph;
4031 HIf branch = conditionGraph.end.last; 4045 HIf branch = conditionGraph.end.last;
4032 assert(branch is HIf); 4046 assert(branch is HIf);
4033 branch.blockInformation = conditionStartBlock.blockFlow; 4047 branch.blockInformation = conditionStartBlock.blockFlow;
4034 } 4048 }
4035 } 4049 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/operations.dart ('k') | lib/compiler/implementation/ssa/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698