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

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

Issue 10855026: Don't rely on the existence of an element in field gets. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 80 chars. Created 8 years, 4 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 | « no previous file | lib/compiler/implementation/ssa/optimize.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 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 1827 matching lines...) Expand 10 before | Expand all | Expand 10 after
1838 } 1838 }
1839 1839
1840 visitFieldGet(HFieldGet node) { 1840 visitFieldGet(HFieldGet node) {
1841 String name = 1841 String name =
1842 compiler.namer.instanceFieldName(node.library, node.fieldName); 1842 compiler.namer.instanceFieldName(node.library, node.fieldName);
1843 beginExpression(JSPrecedence.MEMBER_PRECEDENCE); 1843 beginExpression(JSPrecedence.MEMBER_PRECEDENCE);
1844 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE); 1844 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE);
1845 buffer.add('.'); 1845 buffer.add('.');
1846 buffer.add(name); 1846 buffer.add(name);
1847 beginExpression(JSPrecedence.MEMBER_PRECEDENCE); 1847 beginExpression(JSPrecedence.MEMBER_PRECEDENCE);
1848 Type type = node.receiver.propagatedType.computeType(compiler); 1848 if (node.element == null) {
1849 if (type != null) { 1849 // If we don't have an element we register a dynamic field getter.
1850 world.registerFieldGetter(node.element.name, type); 1850 // This might lead to unnecessary getters, but these cases should be
1851 // rare.
1852 world.registerDynamicGetter(node.fieldName, Selector.GETTER);
1853 } else {
1854 Type type = node.receiver.propagatedType.computeType(compiler);
1855 if (type != null) {
1856 world.registerFieldGetter(node.element.name, type);
1857 }
1851 } 1858 }
1852 } 1859 }
1853 1860
1854 // Determine if an instruction is a simple number computation 1861 // Determine if an instruction is a simple number computation
1855 // involving only things with guaranteed number types and a given 1862 // involving only things with guaranteed number types and a given
1856 // field. 1863 // field.
1857 bool isSimpleFieldNumberComputation(HInstruction value, HFieldSet node) { 1864 bool isSimpleFieldNumberComputation(HInstruction value, HFieldSet node) {
1858 if (value.guaranteedType.union(HType.NUMBER) == HType.NUMBER) return true; 1865 if (value.guaranteedType.union(HType.NUMBER) == HType.NUMBER) return true;
1859 if (value is HBinaryArithmetic) { 1866 if (value is HBinaryArithmetic) {
1860 return (isSimpleFieldNumberComputation(value.left, node) && 1867 return (isSimpleFieldNumberComputation(value.left, node) &&
1861 isSimpleFieldNumberComputation(value.right, node)); 1868 isSimpleFieldNumberComputation(value.right, node));
1862 } 1869 }
1863 if (value is HFieldGet) return value.element == node.element; 1870 if (value is HFieldGet) return value.element == node.element;
1864 return false; 1871 return false;
1865 } 1872 }
1866 1873
1867 visitFieldSet(HFieldSet node) { 1874 visitFieldSet(HFieldSet node) {
1868 if (work.element.isGenerativeConstructorBody() && 1875 if (node.element != null &&
1876 work.element.isGenerativeConstructorBody() &&
1869 node.element.enclosingElement.isClass() && 1877 node.element.enclosingElement.isClass() &&
1870 node.value.hasGuaranteedType() && 1878 node.value.hasGuaranteedType() &&
1871 node.block.dominates(currentGraph.exit)) { 1879 node.block.dominates(currentGraph.exit)) {
1872 backend.updateFieldConstructorSetters(node.element, 1880 backend.updateFieldConstructorSetters(node.element,
1873 node.value.guaranteedType); 1881 node.value.guaranteedType);
1874 } 1882 }
1875 String name = 1883 String name =
1876 compiler.namer.instanceFieldName(node.library, node.fieldName); 1884 compiler.namer.instanceFieldName(node.library, node.fieldName);
1877 beginExpression(JSPrecedence.ASSIGNMENT_PRECEDENCE); 1885 beginExpression(JSPrecedence.ASSIGNMENT_PRECEDENCE);
1878 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE); 1886 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE);
1879 buffer.add('.'); 1887 buffer.add('.');
1880 buffer.add(name); 1888 buffer.add(name);
1881 Type type = node.receiver.propagatedType.computeType(compiler); 1889 if (node.element == null) {
1882 if (type != null) { 1890 // If we don't have an element we register a dynamic field setter.
1883 if (!work.element.isGenerativeConstructorBody()) { 1891 // This might lead to unnecessary setters, but these cases should be
1884 world.registerFieldSetter(node.element.name, type); 1892 // rare.
1885 } 1893 world.registerDynamicSetter(node.fieldName, Selector.SETTER);
1886 // Determine the types seen so far for the field. If only number 1894 } else {
1887 // types have been seen and the value of the field set is a 1895 Type type = node.receiver.propagatedType.computeType(compiler);
1888 // simple number computation only depending on that field, we 1896 if (type != null) {
1889 // can safely keep the number type for the field. 1897 if (!work.element.isGenerativeConstructorBody()) {
1890 HType fieldSettersType = backend.fieldSettersTypeSoFar(node.element); 1898 world.registerFieldSetter(node.element.name, type);
1891 HType initializersType = backend.typeFromInitializersSoFar(node.element); 1899 }
1892 HType fieldType = fieldSettersType.union(initializersType); 1900 // Determine the types seen so far for the field. If only number
1893 if (HType.NUMBER.union(fieldType) == HType.NUMBER && 1901 // types have been seen and the value of the field set is a
1894 isSimpleFieldNumberComputation(node.value, node)) { 1902 // simple number computation only depending on that field, we
1895 backend.updateFieldSetters(node.element, HType.NUMBER); 1903 // can safely keep the number type for the field.
1896 } else { 1904 HType fieldSettersType = backend.fieldSettersTypeSoFar(node.element);
1897 backend.updateFieldSetters(node.element, 1905 HType initializersType =
1898 node.value.propagatedType); 1906 backend.typeFromInitializersSoFar(node.element);
1907 HType fieldType = fieldSettersType.union(initializersType);
1908 if (HType.NUMBER.union(fieldType) == HType.NUMBER &&
1909 isSimpleFieldNumberComputation(node.value, node)) {
1910 backend.updateFieldSetters(node.element, HType.NUMBER);
1911 } else {
1912 backend.updateFieldSetters(node.element,
1913 node.value.propagatedType);
1914 }
1899 } 1915 }
1900 } 1916 }
1901 buffer.add(' = '); 1917 buffer.add(' = ');
1902 use(node.value, JSPrecedence.ASSIGNMENT_PRECEDENCE); 1918 use(node.value, JSPrecedence.ASSIGNMENT_PRECEDENCE);
1903 endExpression(JSPrecedence.ASSIGNMENT_PRECEDENCE); 1919 endExpression(JSPrecedence.ASSIGNMENT_PRECEDENCE);
1904 } 1920 }
1905 1921
1906 visitLocalGet(HLocalGet node) { 1922 visitLocalGet(HLocalGet node) {
1907 use(node.receiver, JSPrecedence.EXPRESSION_PRECEDENCE); 1923 use(node.receiver, JSPrecedence.EXPRESSION_PRECEDENCE);
1908 } 1924 }
(...skipping 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after
3192 if (leftType.canBeNull() && rightType.canBeNull()) { 3208 if (leftType.canBeNull() && rightType.canBeNull()) {
3193 if (left.isConstantNull() || right.isConstantNull() || 3209 if (left.isConstantNull() || right.isConstantNull() ||
3194 (leftType.isPrimitive() && leftType == rightType)) { 3210 (leftType.isPrimitive() && leftType == rightType)) {
3195 return '=='; 3211 return '==';
3196 } 3212 }
3197 return null; 3213 return null;
3198 } else { 3214 } else {
3199 return '==='; 3215 return '===';
3200 } 3216 }
3201 } 3217 }
OLDNEW
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/optimize.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698