| 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 library dart2js.common.codegen; | 5 library dart2js.common.codegen; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../compiler.dart' show | 8 import '../compiler.dart' show |
| 9 Compiler; | 9 Compiler; |
| 10 import '../constants/values.dart' show | 10 import '../constants/values.dart' show |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 CodegenEnqueuer; | 22 CodegenEnqueuer; |
| 23 import '../js_backend/js_backend.dart' show | 23 import '../js_backend/js_backend.dart' show |
| 24 JavaScriptBackend; | 24 JavaScriptBackend; |
| 25 import '../resolution/tree_elements.dart' show | 25 import '../resolution/tree_elements.dart' show |
| 26 TreeElements; | 26 TreeElements; |
| 27 import '../universe/selector.dart' show | 27 import '../universe/selector.dart' show |
| 28 Selector; | 28 Selector; |
| 29 import '../universe/universe.dart' show | 29 import '../universe/universe.dart' show |
| 30 UniverseSelector; | 30 UniverseSelector; |
| 31 import '../universe/world_impact.dart' show | 31 import '../universe/world_impact.dart' show |
| 32 WorldImpact; | 32 WorldImpact, |
| 33 WorldImpactBuilder; |
| 33 import '../util/util.dart' show | 34 import '../util/util.dart' show |
| 35 Pair, |
| 34 Setlet; | 36 Setlet; |
| 35 import 'registry.dart' show | 37 import 'registry.dart' show |
| 36 Registry; | 38 Registry, |
| 39 EagerRegistry; |
| 37 import 'work.dart' show | 40 import 'work.dart' show |
| 38 ItemCompilationContext, | 41 ItemCompilationContext, |
| 39 WorkItem; | 42 WorkItem; |
| 40 | 43 |
| 44 class CodegenImpact extends WorldImpact { |
| 45 const CodegenImpact(); |
| 46 |
| 47 // TODO(johnniwinther): Remove this. |
| 48 Registry get registry => null; |
| 49 |
| 50 Iterable<Element> get getterForSuperElements => const <Element>[]; |
| 51 |
| 52 Iterable<Element> get fieldGetters => const <Element>[]; |
| 53 |
| 54 Iterable<Element> get fieldSetters => const <Element>[]; |
| 55 |
| 56 Iterable<ConstantValue> get compileTimeConstants => const <ConstantValue>[]; |
| 57 |
| 58 Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks { |
| 59 return const <Pair<DartType, DartType>>[]; |
| 60 } |
| 61 |
| 62 Iterable<String> get constSymbols => const <String>[]; |
| 63 |
| 64 Iterable<Set<ClassElement>> get specializedGetInterceptors { |
| 65 return const <Set<ClassElement>>[]; |
| 66 } |
| 67 |
| 68 bool get usesInterceptor => false; |
| 69 |
| 70 Iterable<ClassElement> get typeConstants => const <ClassElement>[]; |
| 71 |
| 72 Iterable<Element> get asyncMarkers => const <FunctionElement>[]; |
| 73 } |
| 74 |
| 75 class _CodegenImpact extends WorldImpactBuilder implements CodegenImpact { |
| 76 // TODO(johnniwinther): Remove this. |
| 77 final Registry registry; |
| 78 |
| 79 |
| 80 Setlet<Element> _getterForSuperElements; |
| 81 Setlet<Element> _fieldGetters; |
| 82 Setlet<Element> _fieldSetters; |
| 83 Setlet<ConstantValue> _compileTimeConstants; |
| 84 Setlet<Pair<DartType, DartType>> _typeVariableBoundsSubtypeChecks; |
| 85 Setlet<String> _constSymbols; |
| 86 List<Set<ClassElement>> _specializedGetInterceptors; |
| 87 bool _usesInterceptor = false; |
| 88 Setlet<ClassElement> _typeConstants; |
| 89 Setlet<FunctionElement> _asyncMarkers; |
| 90 |
| 91 _CodegenImpact(this.registry); |
| 92 |
| 93 void registerGetterForSuperMethod(Element element) { |
| 94 if (_getterForSuperElements == null) { |
| 95 _getterForSuperElements = new Setlet<Element>(); |
| 96 } |
| 97 _getterForSuperElements.add(element); |
| 98 } |
| 99 |
| 100 Iterable<Element> get getterForSuperElements { |
| 101 return _getterForSuperElements != null |
| 102 ? _getterForSuperElements : const <Element>[]; |
| 103 } |
| 104 |
| 105 void registerFieldGetter(Element element) { |
| 106 if (_fieldGetters == null) { |
| 107 _fieldGetters = new Setlet<Element>(); |
| 108 } |
| 109 _fieldGetters.add(element); |
| 110 } |
| 111 |
| 112 Iterable<Element> get fieldGetters { |
| 113 return _fieldGetters != null |
| 114 ? _fieldGetters : const <Element>[]; |
| 115 } |
| 116 |
| 117 void registerFieldSetter(Element element) { |
| 118 if (_fieldSetters == null) { |
| 119 _fieldSetters = new Setlet<Element>(); |
| 120 } |
| 121 _fieldSetters.add(element); |
| 122 } |
| 123 |
| 124 Iterable<Element> get fieldSetters { |
| 125 return _fieldSetters != null |
| 126 ? _fieldSetters : const <Element>[]; |
| 127 } |
| 128 |
| 129 void registerCompileTimeConstant(ConstantValue constant) { |
| 130 if (_compileTimeConstants == null) { |
| 131 _compileTimeConstants = new Setlet<ConstantValue>(); |
| 132 } |
| 133 _compileTimeConstants.add(constant); |
| 134 } |
| 135 |
| 136 Iterable<ConstantValue> get compileTimeConstants { |
| 137 return _compileTimeConstants != null |
| 138 ? _compileTimeConstants : const <ConstantValue>[]; |
| 139 } |
| 140 |
| 141 void registerTypeVariableBoundsSubtypeCheck(DartType subtype, |
| 142 DartType supertype) { |
| 143 if (_typeVariableBoundsSubtypeChecks == null) { |
| 144 _typeVariableBoundsSubtypeChecks = new Setlet<Pair<DartType, DartType>>(); |
| 145 } |
| 146 _typeVariableBoundsSubtypeChecks.add( |
| 147 new Pair<DartType, DartType>(subtype, supertype)); |
| 148 } |
| 149 |
| 150 Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks { |
| 151 return _typeVariableBoundsSubtypeChecks != null |
| 152 ? _typeVariableBoundsSubtypeChecks : const <Pair<DartType, DartType>>[]; |
| 153 } |
| 154 |
| 155 void registerConstSymbol(String name) { |
| 156 if (_constSymbols == null) { |
| 157 _constSymbols = new Setlet<String>(); |
| 158 } |
| 159 _constSymbols.add(name); |
| 160 } |
| 161 |
| 162 Iterable<String> get constSymbols { |
| 163 return _constSymbols != null |
| 164 ? _constSymbols : const <String>[]; |
| 165 } |
| 166 |
| 167 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { |
| 168 if (_specializedGetInterceptors == null) { |
| 169 _specializedGetInterceptors = <Set<ClassElement>>[]; |
| 170 } |
| 171 _specializedGetInterceptors.add(classes); |
| 172 } |
| 173 |
| 174 Iterable<Set<ClassElement>> get specializedGetInterceptors { |
| 175 return _specializedGetInterceptors != null |
| 176 ? _specializedGetInterceptors : const <Set<ClassElement>>[]; |
| 177 } |
| 178 |
| 179 void registerUseInterceptor() { |
| 180 _usesInterceptor = true; |
| 181 } |
| 182 |
| 183 bool get usesInterceptor => _usesInterceptor; |
| 184 |
| 185 void registerTypeConstant(ClassElement element) { |
| 186 if (_typeConstants == null) { |
| 187 _typeConstants = new Setlet<ClassElement>(); |
| 188 } |
| 189 _typeConstants.add(element); |
| 190 } |
| 191 |
| 192 Iterable<ClassElement> get typeConstants { |
| 193 return _typeConstants != null |
| 194 ? _typeConstants : const <ClassElement>[]; |
| 195 } |
| 196 |
| 197 void registerAsyncMarker(FunctionElement element) { |
| 198 if (_asyncMarkers == null) { |
| 199 _asyncMarkers = new Setlet<FunctionElement>(); |
| 200 } |
| 201 _asyncMarkers.add(element); |
| 202 } |
| 203 |
| 204 Iterable<Element> get asyncMarkers { |
| 205 return _asyncMarkers != null |
| 206 ? _asyncMarkers : const <FunctionElement>[]; |
| 207 } |
| 208 } |
| 209 |
| 41 // TODO(johnniwinther): Split this class into interface and implementation. | 210 // TODO(johnniwinther): Split this class into interface and implementation. |
| 42 // TODO(johnniwinther): Move this implementation to the JS backend. | 211 // TODO(johnniwinther): Move this implementation to the JS backend. |
| 43 class CodegenRegistry extends Registry { | 212 class CodegenRegistry extends Registry { |
| 44 final Compiler compiler; | 213 final Compiler compiler; |
| 45 final TreeElements treeElements; | 214 final Element currentElement; |
| 46 | 215 final _CodegenImpact worldImpact; |
| 47 CodegenRegistry(this.compiler, this.treeElements); | 216 |
| 217 CodegenRegistry(Compiler compiler, AstElement currentElement) |
| 218 : this.compiler = compiler, |
| 219 this.currentElement = currentElement, |
| 220 this.worldImpact = new _CodegenImpact(new EagerRegistry( |
| 221 'EagerRegistry for $currentElement', compiler.enqueuer.codegen)); |
| 48 | 222 |
| 49 bool get isForResolution => false; | 223 bool get isForResolution => false; |
| 50 | 224 |
| 51 Element get currentElement => treeElements.analyzedElement; | |
| 52 | |
| 53 String toString() => 'CodegenRegistry for $currentElement'; | 225 String toString() => 'CodegenRegistry for $currentElement'; |
| 54 | 226 |
| 55 CodegenEnqueuer get world => compiler.enqueuer.codegen; | |
| 56 JavaScriptBackend get backend => compiler.backend; | |
| 57 | |
| 58 void registerAssert(bool hasMessage) { | |
| 59 // Codegen does not register asserts. They have been lowered to calls. | |
| 60 assert(false); | |
| 61 } | |
| 62 | |
| 63 void registerInstantiatedClass(ClassElement element) { | 227 void registerInstantiatedClass(ClassElement element) { |
| 64 backend.registerInstantiatedType(element.rawType, world, this); | 228 registerInstantiatedType(element.rawType); |
| 65 } | 229 } |
| 66 | 230 |
| 67 void registerInstantiatedType(InterfaceType type) { | 231 void registerInstantiatedType(InterfaceType type) { |
| 68 backend.registerInstantiatedType(type, world, this); | 232 worldImpact.registerInstantiatedType(type); |
| 69 } | 233 } |
| 70 | 234 |
| 71 void registerStaticUse(Element element) { | 235 void registerStaticUse(Element element) { |
| 72 world.registerStaticUse(element); | 236 worldImpact.registerStaticUse(element); |
| 73 } | 237 } |
| 74 | 238 |
| 75 void registerDynamicInvocation(UniverseSelector selector) { | 239 void registerDynamicInvocation(UniverseSelector selector) { |
| 76 world.registerDynamicInvocation(selector); | 240 worldImpact.registerDynamicInvocation(selector); |
| 77 compiler.dumpInfoTask.elementUsesSelector(currentElement, selector); | 241 compiler.dumpInfoTask.elementUsesSelector(currentElement, selector); |
| 78 } | 242 } |
| 79 | 243 |
| 80 void registerDynamicSetter(UniverseSelector selector) { | 244 void registerDynamicSetter(UniverseSelector selector) { |
| 81 world.registerDynamicSetter(selector); | 245 worldImpact.registerDynamicSetter(selector); |
| 82 compiler.dumpInfoTask.elementUsesSelector(currentElement, selector); | 246 compiler.dumpInfoTask.elementUsesSelector(currentElement, selector); |
| 83 } | 247 } |
| 84 | 248 |
| 85 void registerDynamicGetter(UniverseSelector selector) { | 249 void registerDynamicGetter(UniverseSelector selector) { |
| 86 world.registerDynamicGetter(selector); | 250 worldImpact.registerDynamicGetter(selector); |
| 87 compiler.dumpInfoTask.elementUsesSelector(currentElement, selector); | 251 compiler.dumpInfoTask.elementUsesSelector(currentElement, selector); |
| 88 } | 252 } |
| 89 | 253 |
| 90 void registerGetterForSuperMethod(Element element) { | 254 void registerGetterForSuperMethod(Element element) { |
| 91 world.registerGetterForSuperMethod(element); | 255 worldImpact.registerGetterForSuperMethod(element); |
| 92 } | 256 } |
| 93 | 257 |
| 94 void registerFieldGetter(Element element) { | 258 void registerFieldGetter(Element element) { |
| 95 world.registerFieldGetter(element); | 259 worldImpact.registerFieldGetter(element); |
| 96 } | 260 } |
| 97 | 261 |
| 98 void registerFieldSetter(Element element) { | 262 void registerFieldSetter(Element element) { |
| 99 world.registerFieldSetter(element); | 263 worldImpact.registerFieldSetter(element); |
| 100 } | 264 } |
| 101 | 265 |
| 102 void registerIsCheck(DartType type) { | 266 void registerIsCheck(DartType type) { |
| 103 world.registerIsCheck(type); | 267 worldImpact.registerIsCheck(type); |
| 104 backend.registerIsCheckForCodegen(type, world, this); | |
| 105 } | 268 } |
| 106 | 269 |
| 107 void registerCompileTimeConstant(ConstantValue constant) { | 270 void registerCompileTimeConstant(ConstantValue constant) { |
| 108 backend.registerCompileTimeConstant(constant, this); | 271 worldImpact.registerCompileTimeConstant(constant); |
| 109 backend.addCompileTimeConstantForEmission(constant); | |
| 110 } | 272 } |
| 111 | 273 |
| 112 void registerTypeVariableBoundsSubtypeCheck(DartType subtype, | 274 void registerTypeVariableBoundsSubtypeCheck(DartType subtype, |
| 113 DartType supertype) { | 275 DartType supertype) { |
| 114 backend.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); | 276 worldImpact.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); |
| 115 } | 277 } |
| 116 | 278 |
| 117 void registerInstantiatedClosure(LocalFunctionElement element) { | 279 void registerInstantiatedClosure(LocalFunctionElement element) { |
| 118 backend.registerInstantiatedClosure(element, this); | 280 worldImpact.registerClosure(element); |
| 119 } | 281 } |
| 120 | 282 |
| 121 void registerGetOfStaticFunction(FunctionElement element) { | 283 void registerGetOfStaticFunction(FunctionElement element) { |
| 122 world.registerGetOfStaticFunction(element); | 284 worldImpact.registerClosurizedFunction(element); |
| 123 } | 285 } |
| 124 | 286 |
| 125 void registerSelectorUse(Selector selector) { | 287 void registerSelectorUse(Selector selector) { |
| 126 world.registerSelectorUse(new UniverseSelector(selector, null)); | 288 if (selector.isGetter) { |
| 289 registerDynamicGetter(new UniverseSelector(selector, null)); |
| 290 } else if (selector.isSetter) { |
| 291 registerDynamicSetter(new UniverseSelector(selector, null)); |
| 292 } else { |
| 293 registerDynamicInvocation(new UniverseSelector(selector, null)); |
| 294 } |
| 127 } | 295 } |
| 128 | 296 |
| 129 void registerConstSymbol(String name) { | 297 void registerConstSymbol(String name) { |
| 130 backend.registerConstSymbol(name); | 298 worldImpact.registerConstSymbol(name); |
| 131 } | 299 } |
| 132 | 300 |
| 133 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { | 301 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { |
| 134 backend.registerSpecializedGetInterceptor(classes); | 302 worldImpact.registerSpecializedGetInterceptor(classes); |
| 135 } | 303 } |
| 136 | 304 |
| 137 void registerUseInterceptor() { | 305 void registerUseInterceptor() { |
| 138 backend.registerUseInterceptor(world); | 306 worldImpact.registerUseInterceptor(); |
| 139 } | 307 } |
| 140 | 308 |
| 141 void registerTypeConstant(ClassElement element) { | 309 void registerTypeConstant(ClassElement element) { |
| 142 backend.customElementsAnalysis.registerTypeConstant(element, world); | 310 worldImpact.registerTypeConstant(element); |
| 143 backend.lookupMapAnalysis.registerTypeConstant(element); | |
| 144 } | 311 } |
| 145 | 312 |
| 146 void registerStaticInvocation(Element element) { | 313 void registerStaticInvocation(Element element) { |
| 147 world.registerStaticUse(element); | 314 registerStaticUse(element); |
| 148 } | 315 } |
| 149 | 316 |
| 150 void registerSuperInvocation(Element element) { | 317 void registerSuperInvocation(Element element) { |
| 151 world.registerStaticUse(element); | 318 registerStaticUse(element); |
| 152 } | 319 } |
| 153 | 320 |
| 154 void registerDirectInvocation(Element element) { | 321 void registerDirectInvocation(Element element) { |
| 155 world.registerStaticUse(element); | 322 registerStaticUse(element); |
| 156 } | 323 } |
| 157 | 324 |
| 158 void registerInstantiation(InterfaceType type) { | 325 void registerInstantiation(InterfaceType type) { |
| 159 backend.registerInstantiatedType(type, world, this); | 326 registerInstantiatedType(type); |
| 160 } | 327 } |
| 161 | 328 |
| 162 void registerAsyncMarker(FunctionElement element) { | 329 void registerAsyncMarker(FunctionElement element) { |
| 163 backend.registerAsyncMarker(element, world, this); | 330 worldImpact.registerAsyncMarker(element); |
| 164 } | 331 } |
| 165 | |
| 166 } | 332 } |
| 167 | 333 |
| 168 /// [WorkItem] used exclusively by the [CodegenEnqueuer]. | 334 /// [WorkItem] used exclusively by the [CodegenEnqueuer]. |
| 169 class CodegenWorkItem extends WorkItem { | 335 class CodegenWorkItem extends WorkItem { |
| 170 CodegenRegistry registry; | 336 CodegenRegistry registry; |
| 171 | 337 |
| 172 factory CodegenWorkItem( | 338 factory CodegenWorkItem( |
| 173 Compiler compiler, | 339 Compiler compiler, |
| 174 AstElement element, | 340 AstElement element, |
| 175 ItemCompilationContext compilationContext) { | 341 ItemCompilationContext compilationContext) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 188 CodegenWorkItem.internal( | 354 CodegenWorkItem.internal( |
| 189 AstElement element, | 355 AstElement element, |
| 190 ItemCompilationContext compilationContext) | 356 ItemCompilationContext compilationContext) |
| 191 : super(element, compilationContext); | 357 : super(element, compilationContext); |
| 192 | 358 |
| 193 TreeElements get resolutionTree => element.resolvedAst.elements; | 359 TreeElements get resolutionTree => element.resolvedAst.elements; |
| 194 | 360 |
| 195 WorldImpact run(Compiler compiler, CodegenEnqueuer world) { | 361 WorldImpact run(Compiler compiler, CodegenEnqueuer world) { |
| 196 if (world.isProcessed(element)) return const WorldImpact(); | 362 if (world.isProcessed(element)) return const WorldImpact(); |
| 197 | 363 |
| 198 registry = new CodegenRegistry(compiler, resolutionTree); | 364 registry = new CodegenRegistry(compiler, element); |
| 199 return compiler.codegen(this, world); | 365 return compiler.codegen(this, world); |
| 200 } | 366 } |
| 201 } | 367 } |
| OLD | NEW |