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

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

Powered by Google App Engine
This is Rietveld 408576698