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

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

Issue 12525007: Record dependency information to implement first version of dependency (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased/merged Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of ssa; 5 part of ssa;
6 6
7 class SsaCodeGeneratorTask extends CompilerTask { 7 class SsaCodeGeneratorTask extends CompilerTask {
8 8
9 final JavaScriptBackend backend; 9 final JavaScriptBackend backend;
10 10
(...skipping 1508 matching lines...) Expand 10 before | Expand all | Expand 10 after
1519 methodName = name.slowToString(); 1519 methodName = name.slowToString();
1520 } else if (!node.isInterceptorCall) { 1520 } else if (!node.isInterceptorCall) {
1521 if (target == backend.jsArrayAdd) { 1521 if (target == backend.jsArrayAdd) {
1522 methodName = 'push'; 1522 methodName = 'push';
1523 } else if (target == backend.jsArrayRemoveLast) { 1523 } else if (target == backend.jsArrayRemoveLast) {
1524 methodName = 'pop'; 1524 methodName = 'pop';
1525 } else if (target == backend.jsStringSplit) { 1525 } else if (target == backend.jsStringSplit) {
1526 methodName = 'split'; 1526 methodName = 'split';
1527 // Split returns a List, so we make sure the backend knows the 1527 // Split returns a List, so we make sure the backend knows the
1528 // list class is instantiated. 1528 // list class is instantiated.
1529 world.registerInstantiatedClass(compiler.listClass); 1529 world.registerInstantiatedClass(
1530 compiler.listClass, work.resolutionTree);
1530 } else if (target == backend.jsStringConcat) { 1531 } else if (target == backend.jsStringConcat) {
1531 push(new js.Binary('+', object, arguments[0]), node); 1532 push(new js.Binary('+', object, arguments[0]), node);
1532 return; 1533 return;
1533 } else if (target.isNative() 1534 } else if (target.isNative()
1534 && !compiler.enableTypeAssertions 1535 && !compiler.enableTypeAssertions
1535 && target.isFunction()) { 1536 && target.isFunction()) {
1536 // Enable direct calls to a native method only if we don't 1537 // Enable direct calls to a native method only if we don't
1537 // run in checked mode, where the Dart version may have 1538 // run in checked mode, where the Dart version may have
1538 // type annotations on parameters and return type that it 1539 // type annotations on parameters and return type that it
1539 // should check. 1540 // should check.
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1640 HType valueType = node.isInterceptorCall 1641 HType valueType = node.isInterceptorCall
1641 ? node.inputs[2].instructionType 1642 ? node.inputs[2].instructionType
1642 : node.inputs[1].instructionType; 1643 : node.inputs[1].instructionType;
1643 backend.addedDynamicSetter(selector, valueType); 1644 backend.addedDynamicSetter(selector, valueType);
1644 registerInvoke(node, selector); 1645 registerInvoke(node, selector);
1645 } 1646 }
1646 1647
1647 void registerGetter(HInvokeDynamic node) { 1648 void registerGetter(HInvokeDynamic node) {
1648 Selector selector = getOptimizedSelectorFor(node, node.selector); 1649 Selector selector = getOptimizedSelectorFor(node, node.selector);
1649 world.registerDynamicGetter(selector.name, selector); 1650 world.registerDynamicGetter(selector.name, selector);
1650 world.registerInstantiatedClass(compiler.functionClass); 1651 world.registerInstantiatedClass(
1652 compiler.functionClass, work.resolutionTree);
1651 registerInvoke(node, selector); 1653 registerInvoke(node, selector);
1652 } 1654 }
1653 1655
1654 visitInvokeDynamicSetter(HInvokeDynamicSetter node) { 1656 visitInvokeDynamicSetter(HInvokeDynamicSetter node) {
1655 use(node.receiver); 1657 use(node.receiver);
1656 String name = backend.namer.invocationName(node.selector); 1658 String name = backend.namer.invocationName(node.selector);
1657 push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); 1659 push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node);
1658 registerSetter(node); 1660 registerSetter(node);
1659 } 1661 }
1660 1662
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1768 use(node.value); 1770 use(node.value);
1769 assignVariable(variableNames.getName(node.receiver), pop()); 1771 assignVariable(variableNames.getName(node.receiver), pop());
1770 } 1772 }
1771 1773
1772 void registerForeignType(HType type) { 1774 void registerForeignType(HType type) {
1773 DartType dartType = type.computeType(compiler); 1775 DartType dartType = type.computeType(compiler);
1774 if (dartType == null) { 1776 if (dartType == null) {
1775 assert(type == HType.UNKNOWN); 1777 assert(type == HType.UNKNOWN);
1776 return; 1778 return;
1777 } 1779 }
1778 world.registerInstantiatedClass(dartType.element); 1780 world.registerInstantiatedClass(dartType.element, work.resolutionTree);
1779 } 1781 }
1780 1782
1781 visitForeign(HForeign node) { 1783 visitForeign(HForeign node) {
1782 String code = node.code.slowToString(); 1784 String code = node.code.slowToString();
1783 List<HInstruction> inputs = node.inputs; 1785 List<HInstruction> inputs = node.inputs;
1784 if (node.isJsStatement()) { 1786 if (node.isJsStatement()) {
1785 if (!inputs.isEmpty) { 1787 if (!inputs.isEmpty) {
1786 compiler.internalError("foreign statement with inputs: $code", 1788 compiler.internalError("foreign statement with inputs: $code",
1787 instruction: node); 1789 instruction: node);
1788 } 1790 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1831 push(backend.emitter.constantReference(constant)); 1833 push(backend.emitter.constantReference(constant));
1832 } 1834 }
1833 1835
1834 visitConstant(HConstant node) { 1836 visitConstant(HConstant node) {
1835 assert(isGenerateAtUseSite(node)); 1837 assert(isGenerateAtUseSite(node));
1836 generateConstant(node.constant); 1838 generateConstant(node.constant);
1837 DartType type = node.constant.computeType(compiler); 1839 DartType type = node.constant.computeType(compiler);
1838 if (node.constant is ConstructedConstant || 1840 if (node.constant is ConstructedConstant ||
1839 node.constant is InterceptorConstant) { 1841 node.constant is InterceptorConstant) {
1840 ConstantHandler handler = compiler.constantHandler; 1842 ConstantHandler handler = compiler.constantHandler;
1841 handler.registerCompileTimeConstant(node.constant); 1843 handler.registerCompileTimeConstant(node.constant, work.resolutionTree);
1842 } 1844 }
1843 if (node.constant is! InterceptorConstant) { 1845 if (node.constant is! InterceptorConstant) {
1844 world.registerInstantiatedClass(type.element); 1846 world.registerInstantiatedClass(type.element, work.resolutionTree);
1845 } 1847 }
1846 } 1848 }
1847 1849
1848 visitNot(HNot node) { 1850 visitNot(HNot node) {
1849 assert(node.inputs.length == 1); 1851 assert(node.inputs.length == 1);
1850 generateNot(node.inputs[0]); 1852 generateNot(node.inputs[0]);
1851 attachLocationToLast(node); 1853 attachLocationToLast(node);
1852 } 1854 }
1853 1855
1854 static String mapRelationalOperator(String op, bool inverse) { 1856 static String mapRelationalOperator(String op, bool inverse) {
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
2044 // Switches are handled using [visitSwitchInfo]. 2046 // Switches are handled using [visitSwitchInfo].
2045 } 2047 }
2046 2048
2047 void visitStatic(HStatic node) { 2049 void visitStatic(HStatic node) {
2048 // Check whether this static is used for anything else than as a target in 2050 // Check whether this static is used for anything else than as a target in
2049 // a static call. 2051 // a static call.
2050 node.usedBy.forEach((HInstruction instr) { 2052 node.usedBy.forEach((HInstruction instr) {
2051 if (instr is !HInvokeStatic) { 2053 if (instr is !HInvokeStatic) {
2052 backend.registerNonCallStaticUse(node); 2054 backend.registerNonCallStaticUse(node);
2053 if (node.element.isFunction()) { 2055 if (node.element.isFunction()) {
2054 world.registerInstantiatedClass(compiler.functionClass); 2056 world.registerInstantiatedClass(
2057 compiler.functionClass, work.resolutionTree);
2055 } 2058 }
2056 } else if (instr.target != node) { 2059 } else if (instr.target != node) {
2057 backend.registerNonCallStaticUse(node); 2060 backend.registerNonCallStaticUse(node);
2058 } 2061 }
2059 }); 2062 });
2060 Element element = node.element; 2063 Element element = node.element;
2061 world.registerStaticUse(element); 2064 world.registerStaticUse(element);
2062 ClassElement cls = element.getEnclosingClass(); 2065 ClassElement cls = element.getEnclosingClass();
2063 if (element.isGenerativeConstructor() 2066 if (element.isGenerativeConstructor()
2064 || (element.isFactoryConstructor() && cls == compiler.listClass)) { 2067 || (element.isFactoryConstructor() && cls == compiler.listClass)) {
2065 world.registerInstantiatedClass(cls); 2068 world.registerInstantiatedClass(cls, work.resolutionTree);
2066 } 2069 }
2067 push(new js.VariableUse(backend.namer.isolateAccess(node.element))); 2070 push(new js.VariableUse(backend.namer.isolateAccess(node.element)));
2068 } 2071 }
2069 2072
2070 void visitLazyStatic(HLazyStatic node) { 2073 void visitLazyStatic(HLazyStatic node) {
2071 Element element = node.element; 2074 Element element = node.element;
2072 world.registerStaticUse(element); 2075 world.registerStaticUse(element);
2073 String lazyGetter = backend.namer.isolateLazyInitializerAccess(element); 2076 String lazyGetter = backend.namer.isolateLazyInitializerAccess(element);
2074 js.VariableUse target = new js.VariableUse(lazyGetter); 2077 js.VariableUse target = new js.VariableUse(lazyGetter);
2075 js.Call call = new js.Call(target, <js.Expression>[]); 2078 js.Call call = new js.Call(target, <js.Expression>[]);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2111 Element convertToString = backend.getStringInterpolationHelper(); 2114 Element convertToString = backend.getStringInterpolationHelper();
2112 world.registerStaticUse(convertToString); 2115 world.registerStaticUse(convertToString);
2113 js.VariableUse variableUse = 2116 js.VariableUse variableUse =
2114 new js.VariableUse(backend.namer.isolateAccess(convertToString)); 2117 new js.VariableUse(backend.namer.isolateAccess(convertToString));
2115 use(node); 2118 use(node);
2116 push(new js.Call(variableUse, <js.Expression>[pop()]), node); 2119 push(new js.Call(variableUse, <js.Expression>[pop()]), node);
2117 } 2120 }
2118 } 2121 }
2119 2122
2120 void visitLiteralList(HLiteralList node) { 2123 void visitLiteralList(HLiteralList node) {
2121 world.registerInstantiatedClass(compiler.listClass); 2124 world.registerInstantiatedClass(
2125 compiler.listClass, work.resolutionTree);
2122 generateArrayLiteral(node); 2126 generateArrayLiteral(node);
2123 } 2127 }
2124 2128
2125 void generateArrayLiteral(HLiteralList node) { 2129 void generateArrayLiteral(HLiteralList node) {
2126 int len = node.inputs.length; 2130 int len = node.inputs.length;
2127 List<js.ArrayElement> elements = <js.ArrayElement>[]; 2131 List<js.ArrayElement> elements = <js.ArrayElement>[];
2128 for (int i = 0; i < len; i++) { 2132 for (int i = 0; i < len; i++) {
2129 use(node.inputs[i]); 2133 use(node.inputs[i]);
2130 elements.add(new js.ArrayElement(i, pop())); 2134 elements.add(new js.ArrayElement(i, pop()));
2131 } 2135 }
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
2245 js.Expression objectTest = pop(); 2249 js.Expression objectTest = pop();
2246 checkType(input, type); 2250 checkType(input, type);
2247 push(new js.Binary('||', 2251 push(new js.Binary('||',
2248 functionTest, 2252 functionTest,
2249 new js.Binary('&&', objectTest, pop()))); 2253 new js.Binary('&&', objectTest, pop())));
2250 } 2254 }
2251 2255
2252 void checkType(HInstruction input, DartType type, {bool negative: false}) { 2256 void checkType(HInstruction input, DartType type, {bool negative: false}) {
2253 assert(invariant(input, !type.isMalformed, 2257 assert(invariant(input, !type.isMalformed,
2254 message: 'Attempt to check malformed type $type')); 2258 message: 'Attempt to check malformed type $type'));
2255 world.registerIsCheck(type); 2259 world.registerIsCheck(type, work.resolutionTree);
2256 Element element = type.element; 2260 Element element = type.element;
2257 use(input); 2261 use(input);
2258 js.PropertyAccess field = 2262 js.PropertyAccess field =
2259 new js.PropertyAccess.field(pop(), backend.namer.operatorIs(element)); 2263 new js.PropertyAccess.field(pop(), backend.namer.operatorIs(element));
2260 if (backend.emitter.nativeEmitter.requiresNativeIsCheck(element)) { 2264 if (backend.emitter.nativeEmitter.requiresNativeIsCheck(element)) {
2261 push(new js.Call(field, <js.Expression>[])); 2265 push(new js.Call(field, <js.Expression>[]));
2262 if (negative) push(new js.Prefix('!', pop())); 2266 if (negative) push(new js.Prefix('!', pop()));
2263 } else { 2267 } else {
2264 // We always negate at least once so that the result is boolified. 2268 // We always negate at least once so that the result is boolified.
2265 push(new js.Prefix('!', field)); 2269 push(new js.Prefix('!', field));
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2307 checkArray(input, '==='); 2311 checkArray(input, '===');
2308 js.Expression arrayTest = pop(); 2312 js.Expression arrayTest = pop();
2309 checkType(input, type); 2313 checkType(input, type);
2310 push(new js.Binary('&&', 2314 push(new js.Binary('&&',
2311 objectTest, 2315 objectTest,
2312 new js.Binary('||', arrayTest, pop()))); 2316 new js.Binary('||', arrayTest, pop())));
2313 } 2317 }
2314 2318
2315 void visitIs(HIs node) { 2319 void visitIs(HIs node) {
2316 DartType type = node.typeExpression; 2320 DartType type = node.typeExpression;
2317 world.registerIsCheck(type); 2321 world.registerIsCheck(type, work.resolutionTree);
2318 Element element = type.element; 2322 Element element = type.element;
2319 if (identical(element.kind, ElementKind.TYPE_VARIABLE)) { 2323 if (identical(element.kind, ElementKind.TYPE_VARIABLE)) {
2320 compiler.unimplemented("visitIs for type variables", 2324 compiler.unimplemented("visitIs for type variables",
2321 instruction: node.expression); 2325 instruction: node.expression);
2322 } 2326 }
2323 LibraryElement coreLibrary = compiler.coreLibrary; 2327 LibraryElement coreLibrary = compiler.coreLibrary;
2324 ClassElement objectClass = compiler.objectClass; 2328 ClassElement objectClass = compiler.objectClass;
2325 HInstruction input = node.expression; 2329 HInstruction input = node.expression;
2326 2330
2327 if (identical(element, objectClass) || 2331 if (identical(element, objectClass) ||
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2380 if (node.nullOk) { 2384 if (node.nullOk) {
2381 checkNull(input); 2385 checkNull(input);
2382 push(new js.Binary('||', pop(), pop()), node); 2386 push(new js.Binary('||', pop(), pop()), node);
2383 } 2387 }
2384 } 2388 }
2385 2389
2386 void visitTypeConversion(HTypeConversion node) { 2390 void visitTypeConversion(HTypeConversion node) {
2387 if (node.isChecked) { 2391 if (node.isChecked) {
2388 DartType type = node.instructionType.computeType(compiler); 2392 DartType type = node.instructionType.computeType(compiler);
2389 Element element = type.element; 2393 Element element = type.element;
2390 world.registerIsCheck(type); 2394 world.registerIsCheck(type, work.resolutionTree);
2391 2395
2392 if (node.isArgumentTypeCheck) { 2396 if (node.isArgumentTypeCheck) {
2393 if (element == backend.jsIntClass) { 2397 if (element == backend.jsIntClass) {
2394 checkInt(node.checkedInput, '!=='); 2398 checkInt(node.checkedInput, '!==');
2395 } else { 2399 } else {
2396 assert(element == backend.jsNumberClass); 2400 assert(element == backend.jsNumberClass);
2397 checkNum(node.checkedInput, '!=='); 2401 checkNum(node.checkedInput, '!==');
2398 } 2402 }
2399 js.Expression test = pop(); 2403 js.Expression test = pop();
2400 js.Block oldContainer = currentContainer; 2404 js.Block oldContainer = currentContainer;
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
2965 if (leftType.canBeNull() && rightType.canBeNull()) { 2969 if (leftType.canBeNull() && rightType.canBeNull()) {
2966 if (left.isConstantNull() || right.isConstantNull() || 2970 if (left.isConstantNull() || right.isConstantNull() ||
2967 (leftType.isPrimitive() && leftType == rightType)) { 2971 (leftType.isPrimitive() && leftType == rightType)) {
2968 return '=='; 2972 return '==';
2969 } 2973 }
2970 return null; 2974 return null;
2971 } else { 2975 } else {
2972 return '==='; 2976 return '===';
2973 } 2977 }
2974 } 2978 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698