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

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

Issue 10855174: Lazy implementation of final variables. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix tests. 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
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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 : interceptors = new Interceptors(backend.compiler), 146 : interceptors = new Interceptors(backend.compiler),
147 closureDataCache = new HashMap<Node, ClosureData>(), 147 closureDataCache = new HashMap<Node, ClosureData>(),
148 emitter = backend.emitter, 148 emitter = backend.emitter,
149 functionsCalledInLoop = new Set<FunctionElement>(), 149 functionsCalledInLoop = new Set<FunctionElement>(),
150 selectorsCalledInLoop = new Map<SourceString, Selector>(), 150 selectorsCalledInLoop = new Map<SourceString, Selector>(),
151 backend = backend, 151 backend = backend,
152 super(backend.compiler); 152 super(backend.compiler);
153 153
154 HGraph build(WorkItem work) { 154 HGraph build(WorkItem work) {
155 return measure(() { 155 return measure(() {
156 FunctionElement element = work.element; 156 Element element = work.element;
157 HInstruction.idCounter = 0; 157 HInstruction.idCounter = 0;
158 SsaBuilder builder = new SsaBuilder(this, work); 158 SsaBuilder builder = new SsaBuilder(this, work);
159 HGraph graph; 159 HGraph graph;
160 ElementKind kind = element.kind; 160 ElementKind kind = element.kind;
161 if (kind === ElementKind.GENERATIVE_CONSTRUCTOR) { 161 if (kind === ElementKind.GENERATIVE_CONSTRUCTOR) {
162 graph = compileConstructor(builder, work); 162 graph = compileConstructor(builder, work);
163 } else if (kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY || 163 } else if (kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
164 kind === ElementKind.FUNCTION || 164 kind === ElementKind.FUNCTION ||
165 kind === ElementKind.GETTER || 165 kind === ElementKind.GETTER ||
166 kind === ElementKind.SETTER) { 166 kind === ElementKind.SETTER) {
167 graph = builder.buildMethod(work.element); 167 graph = builder.buildMethod(work.element);
168 } else if (kind === ElementKind.FIELD) {
169 graph = builder.buildLazyInitializer(work.element);
168 } 170 }
169 assert(graph.isValid()); 171 assert(graph.isValid());
170 bool inLoop = functionsCalledInLoop.contains(element); 172 if (kind !== ElementKind.FIELD) {
171 if (!inLoop) { 173 bool inLoop = functionsCalledInLoop.contains(element);
172 Selector selector = selectorsCalledInLoop[element.name]; 174 if (!inLoop) {
173 inLoop = selector !== null && selector.applies(element, compiler); 175 Selector selector = selectorsCalledInLoop[element.name];
174 } 176 inLoop = selector !== null && selector.applies(element, compiler);
175 graph.calledInLoop = inLoop; 177 }
178 graph.calledInLoop = inLoop;
176 179
177 // If there is an estimate of the parameter types assume these types when 180 // If there is an estimate of the parameter types assume these types
178 // compiling. 181 // when compiling.
179 List<HType> parameterTypes = 182 List<HType> parameterTypes =
180 backend.optimisticParameterTypesWithRecompilationOnTypeChange( 183 backend.optimisticParameterTypesWithRecompilationOnTypeChange(
181 element); 184 element);
182 if (parameterTypes != null) { 185 if (parameterTypes != null) {
183 FunctionSignature signature = element.computeSignature(compiler); 186 FunctionElement functionElement = element;
184 int i = 0; 187 FunctionSignature signature =
185 signature.forEachParameter((Element param) { 188 functionElement.computeSignature(compiler);
186 builder.parameters[param].guaranteedType = parameterTypes[i++]; 189 int i = 0;
187 }); 190 signature.forEachParameter((Element param) {
191 builder.parameters[param].guaranteedType = parameterTypes[i++];
192 });
193 }
188 } 194 }
189 195
190 if (compiler.tracer.enabled) { 196 if (compiler.tracer.enabled) {
191 String name; 197 String name;
192 if (element.isMember()) { 198 if (element.isMember()) {
193 String className = element.getEnclosingClass().name.slowToString(); 199 String className = element.getEnclosingClass().name.slowToString();
194 String memberName = element.name.slowToString(); 200 String memberName = element.name.slowToString();
195 name = "$className.$memberName"; 201 name = "$className.$memberName";
196 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) { 202 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) {
197 name = "$name (body)"; 203 name = "$name (body)";
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 methodInterceptionEnabled = true; 859 methodInterceptionEnabled = true;
854 } 860 }
855 861
856 HGraph buildMethod(FunctionElement functionElement) { 862 HGraph buildMethod(FunctionElement functionElement) {
857 FunctionExpression function = functionElement.parseNode(compiler); 863 FunctionExpression function = functionElement.parseNode(compiler);
858 openFunction(functionElement, function); 864 openFunction(functionElement, function);
859 function.body.accept(this); 865 function.body.accept(this);
860 return closeFunction(); 866 return closeFunction();
861 } 867 }
862 868
869 HGraph buildLazyInitializer(VariableElement variable) {
870 HBasicBlock block = graph.addNewBlock();
871 open(graph.entry);
872 close(new HGoto()).addSuccessor(block);
873 open(block);
874 SendSet node = variable.parseNode(compiler);
875 Link<Node> link = node.arguments;
876 assert(!link.isEmpty() && link.tail.isEmpty());
877 visit(link.head);
878 close(new HReturn(pop())).addSuccessor(graph.exit);
879 graph.finalize();
880 return graph;
881 }
882
863 /** 883 /**
864 * Returns the constructor body associated with the given constructor or 884 * Returns the constructor body associated with the given constructor or
865 * creates a new constructor body, if none can be found. 885 * creates a new constructor body, if none can be found.
866 * 886 *
867 * Returns [:null:] if the constructor does not have a body. 887 * Returns [:null:] if the constructor does not have a body.
868 */ 888 */
869 ConstructorBodyElement getConstructorBody(FunctionElement constructor) { 889 ConstructorBodyElement getConstructorBody(FunctionElement constructor) {
870 assert(constructor.kind === ElementKind.GENERATIVE_CONSTRUCTOR); 890 assert(constructor.kind === ElementKind.GENERATIVE_CONSTRUCTOR);
871 if (constructor is SynthesizedConstructorElement) return null; 891 if (constructor is SynthesizedConstructorElement) return null;
872 FunctionExpression node = constructor.parseNode(compiler); 892 FunctionExpression node = constructor.parseNode(compiler);
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1044 // Call the JavaScript constructor with the fields as argument. 1064 // Call the JavaScript constructor with the fields as argument.
1045 List<HInstruction> constructorArguments = <HInstruction>[]; 1065 List<HInstruction> constructorArguments = <HInstruction>[];
1046 classElement.forEachInstanceField( 1066 classElement.forEachInstanceField(
1047 includeBackendMembers: true, 1067 includeBackendMembers: true,
1048 includeSuperMembers: true, 1068 includeSuperMembers: true,
1049 f: (ClassElement enclosingClass, Element member) { 1069 f: (ClassElement enclosingClass, Element member) {
1050 HInstruction value = fieldValues[member]; 1070 HInstruction value = fieldValues[member];
1051 if (value === null) { 1071 if (value === null) {
1052 // The field has no value in the initializer list. Initialize it 1072 // The field has no value in the initializer list. Initialize it
1053 // with the declaration-site constant (if any). 1073 // with the declaration-site constant (if any).
1054 Constant fieldValue = compiler.constantHandler.compileVariable(member); 1074 Constant fieldValue = compiler.compileConstant(member);
1055 value = graph.addConstant(fieldValue); 1075 value = graph.addConstant(fieldValue);
1056 } 1076 }
1057 constructorArguments.add(value); 1077 constructorArguments.add(value);
1058 }); 1078 });
1059 1079
1060 HForeignNew newObject = new HForeignNew(classElement, constructorArguments); 1080 HForeignNew newObject = new HForeignNew(classElement, constructorArguments);
1061 add(newObject); 1081 add(newObject);
1062 // Generate calls to the constructor bodies. 1082 // Generate calls to the constructor bodies.
1063 for (int index = constructors.length - 1; index >= 0; index--) { 1083 for (int index = constructors.length - 1; index >= 0; index--) {
1064 FunctionElement constructor = constructors[index]; 1084 FunctionElement constructor = constructors[index];
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
1761 add(target); 1781 add(target);
1762 List<HInstruction> inputs = <HInstruction>[target, receiver]; 1782 List<HInstruction> inputs = <HInstruction>[target, receiver];
1763 push(new HInvokeInterceptor(selector, getterName, inputs, getter: true)); 1783 push(new HInvokeInterceptor(selector, getterName, inputs, getter: true));
1764 } else { 1784 } else {
1765 push(new HInvokeDynamicGetter(selector, null, getterName, receiver)); 1785 push(new HInvokeDynamicGetter(selector, null, getterName, receiver));
1766 } 1786 }
1767 } 1787 }
1768 1788
1769 void generateGetter(Send send, Element element) { 1789 void generateGetter(Send send, Element element) {
1770 if (Elements.isStaticOrTopLevelField(element)) { 1790 if (Elements.isStaticOrTopLevelField(element)) {
1791 Constant value;
1771 if (element.kind == ElementKind.FIELD && !element.isAssignable()) { 1792 if (element.kind == ElementKind.FIELD && !element.isAssignable()) {
kasperl 2012/08/16 14:41:37 isField?
floitsch 2012/08/16 22:52:33 Done.
1772 // A static final. Get its constant value and inline it. 1793 // A static final or const. Get its constant value and inline it if
1773 Constant value = compiler.constantHandler.compileVariable(element); 1794 // the value can be compiled eagerly.
1795 value = compiler.compileVariable(element);
1796 }
1797 if (value != null) {
1774 stack.add(graph.addConstant(value)); 1798 stack.add(graph.addConstant(value));
1799 } else if (element.kind == ElementKind.FIELD &&
1800 compiler.isLazilyInitialized(element)) {
1801 assert(element.kind == ElementKind.FIELD);
kasperl 2012/08/16 14:41:37 Seems like a completely trivial assert given the c
floitsch 2012/08/16 22:52:33 Done.
1802 push(new HLazyStatic(element));
1775 } else { 1803 } else {
1776 Selector selector = elements.getSelector(send); 1804 Selector selector = elements.getSelector(send);
1777 push(new HStatic(element)); 1805 push(new HStatic(element));
1778 if (element.kind == ElementKind.GETTER) { 1806 if (element.kind == ElementKind.GETTER) {
1779 push(new HInvokeStatic(selector, <HInstruction>[pop()])); 1807 push(new HInvokeStatic(selector, <HInstruction>[pop()]));
1780 } 1808 }
1781 } 1809 }
1782 } else if (Elements.isInstanceSend(send, elements)) { 1810 } else if (Elements.isInstanceSend(send, elements)) {
1783 HInstruction receiver = generateInstanceSendReceiver(send); 1811 HInstruction receiver = generateInstanceSendReceiver(send);
1784 generateInstanceGetterWithCompiledReceiver(send, receiver); 1812 generateInstanceGetterWithCompiledReceiver(send, receiver);
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
1968 bool addStaticSendArgumentsToList(Selector selector, 1996 bool addStaticSendArgumentsToList(Selector selector,
1969 Link<Node> arguments, 1997 Link<Node> arguments,
1970 FunctionElement element, 1998 FunctionElement element,
1971 List<HInstruction> list) { 1999 List<HInstruction> list) {
1972 HInstruction compileArgument(Node argument) { 2000 HInstruction compileArgument(Node argument) {
1973 visit(argument); 2001 visit(argument);
1974 return pop(); 2002 return pop();
1975 } 2003 }
1976 2004
1977 HInstruction compileConstant(Element constantElement) { 2005 HInstruction compileConstant(Element constantElement) {
1978 Constant constant = compiler.compileVariable(constantElement); 2006 Constant constant = compiler.compileConstant(constantElement);
1979 return graph.addConstant(constant); 2007 return graph.addConstant(constant);
1980 } 2008 }
1981 2009
1982 return selector.addArgumentsToList(arguments, 2010 return selector.addArgumentsToList(arguments,
1983 list, 2011 list,
1984 element, 2012 element,
1985 compileArgument, 2013 compileArgument,
1986 compileConstant, 2014 compileConstant,
1987 compiler); 2015 compiler);
1988 } 2016 }
(...skipping 1625 matching lines...) Expand 10 before | Expand all | Expand 10 after
3614 new HSubGraphBlockInformation(elseBranch.graph)); 3642 new HSubGraphBlockInformation(elseBranch.graph));
3615 3643
3616 HBasicBlock conditionStartBlock = conditionBranch.block; 3644 HBasicBlock conditionStartBlock = conditionBranch.block;
3617 conditionStartBlock.setBlockFlow(info, joinBlock); 3645 conditionStartBlock.setBlockFlow(info, joinBlock);
3618 SubGraph conditionGraph = conditionBranch.graph; 3646 SubGraph conditionGraph = conditionBranch.graph;
3619 HIf branch = conditionGraph.end.last; 3647 HIf branch = conditionGraph.end.last;
3620 assert(branch is HIf); 3648 assert(branch is HIf);
3621 branch.blockInformation = conditionStartBlock.blockFlow; 3649 branch.blockInformation = conditionStartBlock.blockFlow;
3622 } 3650 }
3623 } 3651 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698