Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |