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

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

Issue 10408059: Move registering to the enqueuer. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 7 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 class SsaCodeGeneratorTask extends CompilerTask { 5 class SsaCodeGeneratorTask extends CompilerTask {
6 final JavaScriptBackend backend; 6 final JavaScriptBackend backend;
7 SsaCodeGeneratorTask(JavaScriptBackend backend) 7 SsaCodeGeneratorTask(JavaScriptBackend backend)
8 : this.backend = backend, 8 : this.backend = backend,
9 super(backend.compiler); 9 super(backend.compiler);
10 String get name() => 'SSA code generator'; 10 String get name() => 'SSA code generator';
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 176
177 // Records a block-information that is being handled specially. 177 // Records a block-information that is being handled specially.
178 // Used to break bad recursion. 178 // Used to break bad recursion.
179 HBlockInformation currentBlockInformation; 179 HBlockInformation currentBlockInformation;
180 // The subgraph is used to delimit traversal for some constructions, e.g., 180 // The subgraph is used to delimit traversal for some constructions, e.g.,
181 // if branches. 181 // if branches.
182 SubGraph subGraph; 182 SubGraph subGraph;
183 183
184 LibraryElement get currentLibrary() => work.element.getLibrary(); 184 LibraryElement get currentLibrary() => work.element.getLibrary();
185 Compiler get compiler() => backend.compiler; 185 Compiler get compiler() => backend.compiler;
186 Enqueuer get world() => backend.compiler.enqueuer.codegen;
186 187
187 bool isGenerateAtUseSite(HInstruction instruction) { 188 bool isGenerateAtUseSite(HInstruction instruction) {
188 return generateAtUseSite.contains(instruction); 189 return generateAtUseSite.contains(instruction);
189 } 190 }
190 191
191 SsaCodeGenerator(this.backend, 192 SsaCodeGenerator(this.backend,
192 this.work, 193 this.work,
193 this.parameters, 194 this.parameters,
194 this.parameterNames) 195 this.parameterNames)
195 : names = new Map<int, String>(), 196 : names = new Map<int, String>(),
(...skipping 1275 matching lines...) Expand 10 before | Expand all | Expand 10 after
1471 // SsaBuilder.buildFactory. Is there a cleaner way to do this? 1472 // SsaBuilder.buildFactory. Is there a cleaner way to do this?
1472 node.name.printOn(buffer); 1473 node.name.printOn(buffer);
1473 visitArguments(node.inputs); 1474 visitArguments(node.inputs);
1474 } else { 1475 } else {
1475 buffer.add(compiler.namer.instanceMethodInvocationName( 1476 buffer.add(compiler.namer.instanceMethodInvocationName(
1476 currentLibrary, node.name, node.selector)); 1477 currentLibrary, node.name, node.selector));
1477 visitArguments(node.inputs); 1478 visitArguments(node.inputs);
1478 if (node.element !== null) { 1479 if (node.element !== null) {
1479 // If we know we're calling a specific method, register that 1480 // If we know we're calling a specific method, register that
1480 // method only. 1481 // method only.
1481 compiler.registerDynamicInvocationOf(node.element); 1482 world.registerDynamicInvocationOf(node.element);
1482 } else { 1483 } else {
1483 compiler.registerDynamicInvocation( 1484 world.registerDynamicInvocation(
1484 node.name, getOptimizedSelectorFor(node, node.selector)); 1485 node.name, getOptimizedSelectorFor(node, node.selector));
1485 } 1486 }
1486 } 1487 }
1487 endExpression(JSPrecedence.CALL_PRECEDENCE); 1488 endExpression(JSPrecedence.CALL_PRECEDENCE);
1488 } 1489 }
1489 1490
1490 Selector getOptimizedSelectorFor(HInvoke node, Selector defaultSelector) { 1491 Selector getOptimizedSelectorFor(HInvoke node, Selector defaultSelector) {
1491 Type receiverType = node.inputs[0].propagatedType.computeType(compiler); 1492 Type receiverType = node.inputs[0].propagatedType.computeType(compiler);
1492 if (receiverType !== null) { 1493 if (receiverType !== null) {
1493 return new TypedSelector(receiverType, defaultSelector); 1494 return new TypedSelector(receiverType, defaultSelector);
1494 } else { 1495 } else {
1495 return defaultSelector; 1496 return defaultSelector;
1496 } 1497 }
1497 } 1498 }
1498 1499
1499 visitInvokeDynamicSetter(HInvokeDynamicSetter node) { 1500 visitInvokeDynamicSetter(HInvokeDynamicSetter node) {
1500 beginExpression(JSPrecedence.CALL_PRECEDENCE); 1501 beginExpression(JSPrecedence.CALL_PRECEDENCE);
1501 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE); 1502 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE);
1502 buffer.add('.'); 1503 buffer.add('.');
1503 buffer.add(compiler.namer.setterName(currentLibrary, node.name)); 1504 buffer.add(compiler.namer.setterName(currentLibrary, node.name));
1504 visitArguments(node.inputs); 1505 visitArguments(node.inputs);
1505 compiler.registerDynamicSetter( 1506 world.registerDynamicSetter(
1506 node.name, getOptimizedSelectorFor(node, Selector.SETTER)); 1507 node.name, getOptimizedSelectorFor(node, Selector.SETTER));
1507 endExpression(JSPrecedence.CALL_PRECEDENCE); 1508 endExpression(JSPrecedence.CALL_PRECEDENCE);
1508 } 1509 }
1509 1510
1510 visitInvokeDynamicGetter(HInvokeDynamicGetter node) { 1511 visitInvokeDynamicGetter(HInvokeDynamicGetter node) {
1511 beginExpression(JSPrecedence.CALL_PRECEDENCE); 1512 beginExpression(JSPrecedence.CALL_PRECEDENCE);
1512 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE); 1513 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE);
1513 buffer.add('.'); 1514 buffer.add('.');
1514 buffer.add(compiler.namer.getterName(currentLibrary, node.name)); 1515 buffer.add(compiler.namer.getterName(currentLibrary, node.name));
1515 visitArguments(node.inputs); 1516 visitArguments(node.inputs);
1516 compiler.registerDynamicGetter( 1517 world.registerDynamicGetter(
1517 node.name, getOptimizedSelectorFor(node, Selector.GETTER)); 1518 node.name, getOptimizedSelectorFor(node, Selector.GETTER));
1518 endExpression(JSPrecedence.CALL_PRECEDENCE); 1519 endExpression(JSPrecedence.CALL_PRECEDENCE);
1519 } 1520 }
1520 1521
1521 visitInvokeClosure(HInvokeClosure node) { 1522 visitInvokeClosure(HInvokeClosure node) {
1522 beginExpression(JSPrecedence.CALL_PRECEDENCE); 1523 beginExpression(JSPrecedence.CALL_PRECEDENCE);
1523 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE); 1524 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE);
1524 buffer.add('.'); 1525 buffer.add('.');
1525 buffer.add(compiler.namer.closureInvocationName(node.selector)); 1526 buffer.add(compiler.namer.closureInvocationName(node.selector));
1526 visitArguments(node.inputs); 1527 visitArguments(node.inputs);
1527 // TODO(floitsch): we should have a separate list for closure invocations. 1528 // TODO(floitsch): we should have a separate list for closure invocations.
1528 compiler.registerDynamicInvocation(Namer.CLOSURE_INVOCATION_NAME, 1529 world.registerDynamicInvocation(Namer.CLOSURE_INVOCATION_NAME,
1529 node.selector); 1530 node.selector);
1530 endExpression(JSPrecedence.CALL_PRECEDENCE); 1531 endExpression(JSPrecedence.CALL_PRECEDENCE);
1531 } 1532 }
1532 1533
1533 visitInvokeStatic(HInvokeStatic node) { 1534 visitInvokeStatic(HInvokeStatic node) {
1534 beginExpression(JSPrecedence.CALL_PRECEDENCE); 1535 beginExpression(JSPrecedence.CALL_PRECEDENCE);
1535 use(node.target, JSPrecedence.CALL_PRECEDENCE); 1536 use(node.target, JSPrecedence.CALL_PRECEDENCE);
1536 visitArguments(node.inputs); 1537 visitArguments(node.inputs);
1537 endExpression(JSPrecedence.CALL_PRECEDENCE); 1538 endExpression(JSPrecedence.CALL_PRECEDENCE);
1538 } 1539 }
1539 1540
(...skipping 12 matching lines...) Expand all
1552 visitArguments(node.inputs); 1553 visitArguments(node.inputs);
1553 } else if (superMethod.kind == ElementKind.FIELD) { 1554 } else if (superMethod.kind == ElementKind.FIELD) {
1554 buffer.add('this.${compiler.namer.getName(superMethod)}'); 1555 buffer.add('this.${compiler.namer.getName(superMethod)}');
1555 } else { 1556 } else {
1556 assert(superMethod.kind == ElementKind.GETTER); 1557 assert(superMethod.kind == ElementKind.GETTER);
1557 String methodName = 1558 String methodName =
1558 compiler.namer.getterName(currentLibrary, superMethod.name); 1559 compiler.namer.getterName(currentLibrary, superMethod.name);
1559 buffer.add('$className.prototype.$methodName.call()'); 1560 buffer.add('$className.prototype.$methodName.call()');
1560 } 1561 }
1561 endExpression(JSPrecedence.CALL_PRECEDENCE); 1562 endExpression(JSPrecedence.CALL_PRECEDENCE);
1562 compiler.registerStaticUse(superMethod); 1563 world.registerStaticUse(superMethod);
1563 } 1564 }
1564 1565
1565 visitFieldGet(HFieldGet node) { 1566 visitFieldGet(HFieldGet node) {
1566 if (node.receiver !== null) { 1567 if (node.receiver !== null) {
1567 String name = 1568 String name =
1568 compiler.namer.instanceFieldName(currentLibrary, node.name); 1569 compiler.namer.instanceFieldName(currentLibrary, node.name);
1569 beginExpression(JSPrecedence.MEMBER_PRECEDENCE); 1570 beginExpression(JSPrecedence.MEMBER_PRECEDENCE);
1570 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE); 1571 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE);
1571 buffer.add('.'); 1572 buffer.add('.');
1572 buffer.add(name); 1573 buffer.add(name);
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1806 use(node.value, JSPrecedence.EQUALITY_PRECEDENCE); 1807 use(node.value, JSPrecedence.EQUALITY_PRECEDENCE);
1807 buffer.add(' !== ('); 1808 buffer.add(' !== (');
1808 use(node.value, JSPrecedence.BITWISE_OR_PRECEDENCE); 1809 use(node.value, JSPrecedence.BITWISE_OR_PRECEDENCE);
1809 buffer.add(" | 0)) "); 1810 buffer.add(" | 0)) ");
1810 } 1811 }
1811 generateThrowWithHelper('iae', node.value); 1812 generateThrowWithHelper('iae', node.value);
1812 } 1813 }
1813 1814
1814 void generateThrowWithHelper(String helperName, HInstruction argument) { 1815 void generateThrowWithHelper(String helperName, HInstruction argument) {
1815 Element helper = compiler.findHelper(new SourceString(helperName)); 1816 Element helper = compiler.findHelper(new SourceString(helperName));
1816 compiler.registerStaticUse(helper); 1817 world.registerStaticUse(helper);
1817 buffer.add('throw '); 1818 buffer.add('throw ');
1818 beginExpression(JSPrecedence.EXPRESSION_PRECEDENCE); 1819 beginExpression(JSPrecedence.EXPRESSION_PRECEDENCE);
1819 beginExpression(JSPrecedence.CALL_PRECEDENCE); 1820 beginExpression(JSPrecedence.CALL_PRECEDENCE);
1820 buffer.add(compiler.namer.isolateAccess(helper)); 1821 buffer.add(compiler.namer.isolateAccess(helper));
1821 visitArguments([null, argument]); 1822 visitArguments([null, argument]);
1822 endExpression(JSPrecedence.CALL_PRECEDENCE); 1823 endExpression(JSPrecedence.CALL_PRECEDENCE);
1823 endExpression(JSPrecedence.EXPRESSION_PRECEDENCE); 1824 endExpression(JSPrecedence.EXPRESSION_PRECEDENCE);
1824 } 1825 }
1825 1826
1826 void addIndentation() { 1827 void addIndentation() {
1827 for (int i = 0; i < indent; i++) { 1828 for (int i = 0; i < indent; i++) {
1828 buffer.add(' '); 1829 buffer.add(' ');
1829 } 1830 }
1830 } 1831 }
1831 1832
1832 void addIndented(String text) { 1833 void addIndented(String text) {
1833 addIndentation(); 1834 addIndentation();
1834 buffer.add(text); 1835 buffer.add(text);
1835 } 1836 }
1836 1837
1837 void visitStatic(HStatic node) { 1838 void visitStatic(HStatic node) {
1838 compiler.registerStaticUse(node.element); 1839 world.registerStaticUse(node.element);
1839 buffer.add(compiler.namer.isolateAccess(node.element)); 1840 buffer.add(compiler.namer.isolateAccess(node.element));
1840 } 1841 }
1841 1842
1842 void visitStaticStore(HStaticStore node) { 1843 void visitStaticStore(HStaticStore node) {
1843 compiler.registerStaticUse(node.element); 1844 world.registerStaticUse(node.element);
1844 beginExpression(JSPrecedence.ASSIGNMENT_PRECEDENCE); 1845 beginExpression(JSPrecedence.ASSIGNMENT_PRECEDENCE);
1845 buffer.add(compiler.namer.isolateAccess(node.element)); 1846 buffer.add(compiler.namer.isolateAccess(node.element));
1846 buffer.add(' = '); 1847 buffer.add(' = ');
1847 use(node.inputs[0], JSPrecedence.ASSIGNMENT_PRECEDENCE); 1848 use(node.inputs[0], JSPrecedence.ASSIGNMENT_PRECEDENCE);
1848 endExpression(JSPrecedence.ASSIGNMENT_PRECEDENCE); 1849 endExpression(JSPrecedence.ASSIGNMENT_PRECEDENCE);
1849 } 1850 }
1850 1851
1851 void visitLiteralList(HLiteralList node) { 1852 void visitLiteralList(HLiteralList node) {
1852 generateArrayLiteral(node); 1853 generateArrayLiteral(node);
1853 } 1854 }
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
2096 } 2097 }
2097 2098
2098 void visitIs(HIs node) { 2099 void visitIs(HIs node) {
2099 Type type = node.typeExpression; 2100 Type type = node.typeExpression;
2100 Element element = type.element; 2101 Element element = type.element;
2101 if (element.kind === ElementKind.TYPE_VARIABLE) { 2102 if (element.kind === ElementKind.TYPE_VARIABLE) {
2102 compiler.unimplemented("visitIs for type variables", instruction: node); 2103 compiler.unimplemented("visitIs for type variables", instruction: node);
2103 } else if (element.kind === ElementKind.TYPEDEF) { 2104 } else if (element.kind === ElementKind.TYPEDEF) {
2104 compiler.unimplemented("visitIs for typedefs", instruction: node); 2105 compiler.unimplemented("visitIs for typedefs", instruction: node);
2105 } 2106 }
2106 compiler.registerIsCheck(type.element); 2107 world.registerIsCheck(type.element);
2107 LibraryElement coreLibrary = compiler.coreLibrary; 2108 LibraryElement coreLibrary = compiler.coreLibrary;
2108 ClassElement objectClass = compiler.objectClass; 2109 ClassElement objectClass = compiler.objectClass;
2109 HInstruction input = node.expression; 2110 HInstruction input = node.expression;
2110 2111
2111 if (node.nullOk) { 2112 if (node.nullOk) {
2112 beginExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); 2113 beginExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE);
2113 checkNull(input); 2114 checkNull(input);
2114 buffer.add(' || '); 2115 buffer.add(' || ');
2115 } 2116 }
2116 if (element === objectClass || element === compiler.dynamicClass) { 2117 if (element === objectClass || element === compiler.dynamicClass) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2163 }); 2164 });
2164 } 2165 }
2165 if (node.nullOk) { 2166 if (node.nullOk) {
2166 endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); 2167 endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE);
2167 } 2168 }
2168 } 2169 }
2169 2170
2170 void visitTypeConversion(HTypeConversion node) { 2171 void visitTypeConversion(HTypeConversion node) {
2171 if (node.checked) { 2172 if (node.checked) {
2172 Element element = node.type.computeType(compiler).element; 2173 Element element = node.type.computeType(compiler).element;
2173 compiler.registerIsCheck(element); 2174 world.registerIsCheck(element);
2174 SourceString helper; 2175 SourceString helper;
2175 String additionalArgument; 2176 String additionalArgument;
2176 bool nativeCheck = 2177 bool nativeCheck =
2177 backend.emitter.nativeEmitter.requiresNativeIsCheck(element); 2178 backend.emitter.nativeEmitter.requiresNativeIsCheck(element);
2178 beginExpression(JSPrecedence.CALL_PRECEDENCE); 2179 beginExpression(JSPrecedence.CALL_PRECEDENCE);
2179 2180
2180 if (element == compiler.stringClass) { 2181 if (element == compiler.stringClass) {
2181 helper = const SourceString('stringTypeCheck'); 2182 helper = const SourceString('stringTypeCheck');
2182 } else if (element == compiler.doubleClass) { 2183 } else if (element == compiler.doubleClass) {
2183 helper = const SourceString('doubleTypeCheck'); 2184 helper = const SourceString('doubleTypeCheck');
(...skipping 21 matching lines...) Expand all
2205 } else { 2206 } else {
2206 helper = const SourceString('listSuperTypeCheck'); 2207 helper = const SourceString('listSuperTypeCheck');
2207 } 2208 }
2208 } else if (nativeCheck) { 2209 } else if (nativeCheck) {
2209 helper = const SourceString('callTypeCheck'); 2210 helper = const SourceString('callTypeCheck');
2210 } else { 2211 } else {
2211 helper = const SourceString('propertyTypeCheck'); 2212 helper = const SourceString('propertyTypeCheck');
2212 } 2213 }
2213 } 2214 }
2214 Element helperElement = compiler.findHelper(helper); 2215 Element helperElement = compiler.findHelper(helper);
2215 compiler.registerStaticUse(helperElement); 2216 world.registerStaticUse(helperElement);
2216 buffer.add(compiler.namer.isolateAccess(helperElement)); 2217 buffer.add(compiler.namer.isolateAccess(helperElement));
2217 buffer.add('('); 2218 buffer.add('(');
2218 use(node.checkedInput, JSPrecedence.EXPRESSION_PRECEDENCE); 2219 use(node.checkedInput, JSPrecedence.EXPRESSION_PRECEDENCE);
2219 if (additionalArgument !== null) buffer.add(", '$additionalArgument'"); 2220 if (additionalArgument !== null) buffer.add(", '$additionalArgument'");
2220 buffer.add(')'); 2221 buffer.add(')');
2221 endExpression(JSPrecedence.CALL_PRECEDENCE); 2222 endExpression(JSPrecedence.CALL_PRECEDENCE);
2222 } else { 2223 } else {
2223 use(node.checkedInput, expectedPrecedence); 2224 use(node.checkedInput, expectedPrecedence);
2224 } 2225 }
2225 } 2226 }
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
2621 startBailoutSwitch(); 2622 startBailoutSwitch();
2622 } 2623 }
2623 } 2624 }
2624 2625
2625 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { 2626 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
2626 if (labeledBlockInfo.body.start.hasGuards()) { 2627 if (labeledBlockInfo.body.start.hasGuards()) {
2627 endBailoutSwitch(); 2628 endBailoutSwitch();
2628 } 2629 }
2629 } 2630 }
2630 } 2631 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698