| 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 part of js_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 7 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
| 8 final Set<HInstruction> boundsChecked; | 8 final Set<HInstruction> boundsChecked; |
| 9 | 9 |
| 10 JavaScriptItemCompilationContext() | 10 JavaScriptItemCompilationContext() |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 /// List of symbols that the user has requested for reflection. | 326 /// List of symbols that the user has requested for reflection. |
| 327 final Set<String> symbolsUsed = new Set<String>(); | 327 final Set<String> symbolsUsed = new Set<String>(); |
| 328 | 328 |
| 329 /// List of elements that the user has requested for reflection. | 329 /// List of elements that the user has requested for reflection. |
| 330 final Set<Element> targetsUsed = new Set<Element>(); | 330 final Set<Element> targetsUsed = new Set<Element>(); |
| 331 | 331 |
| 332 /// List of annotations provided by user that indicate that the annotated | 332 /// List of annotations provided by user that indicate that the annotated |
| 333 /// element must be retained. | 333 /// element must be retained. |
| 334 final Set<Element> metaTargetsUsed = new Set<Element>(); | 334 final Set<Element> metaTargetsUsed = new Set<Element>(); |
| 335 | 335 |
| 336 /// List of elements that the backend may use. |
| 337 final Set<Element> helpersUsed = new Set<Element>(); |
| 338 |
| 336 JavaScriptBackend(Compiler compiler, bool generateSourceMap, bool disableEval) | 339 JavaScriptBackend(Compiler compiler, bool generateSourceMap, bool disableEval) |
| 337 : namer = determineNamer(compiler), | 340 : namer = determineNamer(compiler), |
| 338 oneShotInterceptors = new Map<String, Selector>(), | 341 oneShotInterceptors = new Map<String, Selector>(), |
| 339 interceptedElements = new Map<SourceString, Set<Element>>(), | 342 interceptedElements = new Map<SourceString, Set<Element>>(), |
| 340 rti = new RuntimeTypes(compiler), | 343 rti = new RuntimeTypes(compiler), |
| 341 specializedGetInterceptors = new Map<String, Set<ClassElement>>(), | 344 specializedGetInterceptors = new Map<String, Set<ClassElement>>(), |
| 342 super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM) { | 345 super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM) { |
| 343 emitter = disableEval | 346 emitter = disableEval |
| 344 ? new CodeEmitterNoEvalTask(compiler, namer, generateSourceMap) | 347 ? new CodeEmitterNoEvalTask(compiler, namer, generateSourceMap) |
| 345 : new CodeEmitterTask(compiler, namer, generateSourceMap); | 348 : new CodeEmitterTask(compiler, namer, generateSourceMap); |
| 346 builder = new SsaBuilderTask(this); | 349 builder = new SsaBuilderTask(this); |
| 347 optimizer = new SsaOptimizerTask(this); | 350 optimizer = new SsaOptimizerTask(this); |
| 348 generator = new SsaCodeGeneratorTask(this); | 351 generator = new SsaCodeGeneratorTask(this); |
| 349 } | 352 } |
| 350 | 353 |
| 351 static Namer determineNamer(Compiler compiler) { | 354 static Namer determineNamer(Compiler compiler) { |
| 352 return compiler.enableMinification ? | 355 return compiler.enableMinification ? |
| 353 new MinifyNamer(compiler) : | 356 new MinifyNamer(compiler) : |
| 354 new Namer(compiler); | 357 new Namer(compiler); |
| 355 } | 358 } |
| 356 | 359 |
| 360 bool canBeUsedForGlobalOptimizations(Element element) { |
| 361 if (element.isParameter() || element.isFieldParameter()) { |
| 362 element = element.enclosingElement; |
| 363 } |
| 364 return !helpersUsed.contains(element.declaration); |
| 365 } |
| 366 |
| 357 bool isInterceptorClass(ClassElement element) { | 367 bool isInterceptorClass(ClassElement element) { |
| 358 if (element == null) return false; | 368 if (element == null) return false; |
| 359 if (element.isNative()) return true; | 369 if (element.isNative()) return true; |
| 360 if (interceptedClasses.contains(element)) return true; | 370 if (interceptedClasses.contains(element)) return true; |
| 361 if (classesMixedIntoNativeClasses.contains(element)) return true; | 371 if (classesMixedIntoNativeClasses.contains(element)) return true; |
| 362 return false; | 372 return false; |
| 363 } | 373 } |
| 364 | 374 |
| 365 String registerOneShotInterceptor(Selector selector) { | 375 String registerOneShotInterceptor(Selector selector) { |
| 366 Set<ClassElement> classes = getInterceptedClassesOn(selector.name); | 376 Set<ClassElement> classes = getInterceptedClassesOn(selector.name); |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 world.registerStaticUse( | 744 world.registerStaticUse( |
| 735 compiler.findInterceptor(const SourceString('dispatchPropertyName'))); | 745 compiler.findInterceptor(const SourceString('dispatchPropertyName'))); |
| 736 } | 746 } |
| 737 | 747 |
| 738 if (compiler.enableTypeAssertions) { | 748 if (compiler.enableTypeAssertions) { |
| 739 // Unconditionally register the helper that checks if the | 749 // Unconditionally register the helper that checks if the |
| 740 // expression in an if/while/for is a boolean. | 750 // expression in an if/while/for is a boolean. |
| 741 // TODO(ngeoffray): Should we have the resolver register those instead? | 751 // TODO(ngeoffray): Should we have the resolver register those instead? |
| 742 Element e = | 752 Element e = |
| 743 compiler.findHelper(const SourceString('boolConversionCheck')); | 753 compiler.findHelper(const SourceString('boolConversionCheck')); |
| 744 if (e != null) world.addToWorkList(e); | 754 if (e != null) enqueue(world, e, elements); |
| 745 } | 755 } |
| 746 } | 756 } |
| 747 | 757 |
| 748 onResolutionComplete() => rti.computeClassesNeedingRti(); | 758 onResolutionComplete() => rti.computeClassesNeedingRti(); |
| 749 | 759 |
| 750 void registerStringInterpolation(TreeElements elements) { | 760 void registerStringInterpolation(TreeElements elements) { |
| 751 enqueueInResolution(getStringInterpolationHelper(), elements); | 761 enqueueInResolution(getStringInterpolationHelper(), elements); |
| 752 } | 762 } |
| 753 | 763 |
| 754 void registerCatchStatement(Enqueuer enqueuer, TreeElements elements) { | 764 void registerCatchStatement(Enqueuer enqueuer, TreeElements elements) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 838 } | 848 } |
| 839 | 849 |
| 840 void registerIsCheck(DartType type, Enqueuer world, TreeElements elements) { | 850 void registerIsCheck(DartType type, Enqueuer world, TreeElements elements) { |
| 841 type = type.unalias(compiler); | 851 type = type.unalias(compiler); |
| 842 world.registerInstantiatedClass(compiler.boolClass, elements); | 852 world.registerInstantiatedClass(compiler.boolClass, elements); |
| 843 bool inCheckedMode = compiler.enableTypeAssertions; | 853 bool inCheckedMode = compiler.enableTypeAssertions; |
| 844 // [registerIsCheck] is also called for checked mode checks, so we | 854 // [registerIsCheck] is also called for checked mode checks, so we |
| 845 // need to register checked mode helpers. | 855 // need to register checked mode helpers. |
| 846 if (inCheckedMode) { | 856 if (inCheckedMode) { |
| 847 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: false); | 857 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: false); |
| 848 if (helper != null) world.addToWorkList(helper.getElement(compiler)); | 858 if (helper != null) enqueue(world, helper.getElement(compiler), elements); |
| 849 // We also need the native variant of the check (for DOM types). | 859 // We also need the native variant of the check (for DOM types). |
| 850 helper = getNativeCheckedModeHelper(type, typeCast: false); | 860 helper = getNativeCheckedModeHelper(type, typeCast: false); |
| 851 if (helper != null) world.addToWorkList(helper.getElement(compiler)); | 861 if (helper != null) enqueue(world, helper.getElement(compiler), elements); |
| 852 } | 862 } |
| 853 bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE; | 863 bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE; |
| 854 if (!type.isRaw || type.containsTypeVariables) { | 864 if (!type.isRaw || type.containsTypeVariables) { |
| 855 enqueueInResolution(getSetRuntimeTypeInfo(), elements); | 865 enqueueInResolution(getSetRuntimeTypeInfo(), elements); |
| 856 enqueueInResolution(getGetRuntimeTypeInfo(), elements); | 866 enqueueInResolution(getGetRuntimeTypeInfo(), elements); |
| 857 enqueueInResolution(getGetRuntimeTypeArgument(), elements); | 867 enqueueInResolution(getGetRuntimeTypeArgument(), elements); |
| 858 if (inCheckedMode) { | 868 if (inCheckedMode) { |
| 859 enqueueInResolution(getAssertSubtype(), elements); | 869 enqueueInResolution(getAssertSubtype(), elements); |
| 860 } | 870 } |
| 861 enqueueInResolution(getCheckSubtype(), elements); | 871 enqueueInResolution(getCheckSubtype(), elements); |
| 862 if (isTypeVariable) { | 872 if (isTypeVariable) { |
| 863 enqueueInResolution(getCheckSubtypeOfRuntimeType(), elements); | 873 enqueueInResolution(getCheckSubtypeOfRuntimeType(), elements); |
| 864 if (inCheckedMode) { | 874 if (inCheckedMode) { |
| 865 enqueueInResolution(getAssertSubtypeOfRuntimeType(), elements); | 875 enqueueInResolution(getAssertSubtypeOfRuntimeType(), elements); |
| 866 } | 876 } |
| 867 } | 877 } |
| 868 world.registerInstantiatedClass(compiler.listClass, elements); | 878 world.registerInstantiatedClass(compiler.listClass, elements); |
| 869 } | 879 } |
| 870 if (type is FunctionType) { | 880 if (type is FunctionType) { |
| 871 enqueueInResolution(getCheckFunctionSubtype(), elements); | 881 enqueueInResolution(getCheckFunctionSubtype(), elements); |
| 872 } | 882 } |
| 873 if (type.element.isNative()) { | 883 if (type.element.isNative()) { |
| 874 // We will neeed to add the "$is" and "$as" properties on the | 884 // We will neeed to add the "$is" and "$as" properties on the |
| 875 // JavaScript object prototype, so we make sure | 885 // JavaScript object prototype, so we make sure |
| 876 // [:defineProperty:] is compiled. | 886 // [:defineProperty:] is compiled. |
| 877 world.addToWorkList( | 887 enqueue(world, |
| 878 compiler.findHelper(const SourceString('defineProperty'))); | 888 compiler.findHelper(const SourceString('defineProperty')), |
| 889 elements); |
| 879 } | 890 } |
| 880 } | 891 } |
| 881 | 892 |
| 882 void registerAsCheck(DartType type, TreeElements elements) { | 893 void registerAsCheck(DartType type, TreeElements elements) { |
| 883 type = type.unalias(compiler); | 894 type = type.unalias(compiler); |
| 884 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: true); | 895 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: true); |
| 885 enqueueInResolution(helper.getElement(compiler), elements); | 896 enqueueInResolution(helper.getElement(compiler), elements); |
| 886 // We also need the native variant of the check (for DOM types). | 897 // We also need the native variant of the check (for DOM types). |
| 887 helper = getNativeCheckedModeHelper(type, typeCast: true); | 898 helper = getNativeCheckedModeHelper(type, typeCast: true); |
| 888 if (helper != null) { | 899 if (helper != null) { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 969 return classElement == compiler.objectClass | 980 return classElement == compiler.objectClass |
| 970 || classElement == jsInterceptorClass | 981 || classElement == jsInterceptorClass |
| 971 || classElement == jsNullClass; | 982 || classElement == jsNullClass; |
| 972 } | 983 } |
| 973 | 984 |
| 974 bool methodNeedsRti(FunctionElement function) { | 985 bool methodNeedsRti(FunctionElement function) { |
| 975 return rti.methodsNeedingRti.contains(function) || | 986 return rti.methodsNeedingRti.contains(function) || |
| 976 compiler.enabledRuntimeType; | 987 compiler.enabledRuntimeType; |
| 977 } | 988 } |
| 978 | 989 |
| 990 // Enqueue [e] in [enqueuer]. |
| 991 // |
| 992 // The backend must *always* call this method when enqueuing an |
| 993 // element. Calls done by the backend are not seen by global |
| 994 // optimizations, so they would make these optimizations unsound. |
| 995 // Therefore we need to collect the list of helpers the backend may |
| 996 // use. |
| 979 void enqueue(Enqueuer enqueuer, Element e, TreeElements elements) { | 997 void enqueue(Enqueuer enqueuer, Element e, TreeElements elements) { |
| 998 helpersUsed.add(e.declaration); |
| 980 enqueuer.addToWorkList(e); | 999 enqueuer.addToWorkList(e); |
| 981 elements.registerDependency(e); | 1000 elements.registerDependency(e); |
| 982 } | 1001 } |
| 983 | 1002 |
| 984 void enqueueInResolution(Element e, TreeElements elements) { | 1003 void enqueueInResolution(Element e, TreeElements elements) { |
| 985 if (e == null) return; | 1004 if (e == null) return; |
| 986 ResolutionEnqueuer enqueuer = compiler.enqueuer.resolution; | 1005 ResolutionEnqueuer enqueuer = compiler.enqueuer.resolution; |
| 987 enqueue(enqueuer, e, elements); | 1006 enqueue(enqueuer, e, elements); |
| 988 } | 1007 } |
| 989 | 1008 |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1322 } | 1341 } |
| 1323 | 1342 |
| 1324 Element getCreateInvocationMirror() { | 1343 Element getCreateInvocationMirror() { |
| 1325 return compiler.findHelper(Compiler.CREATE_INVOCATION_MIRROR); | 1344 return compiler.findHelper(Compiler.CREATE_INVOCATION_MIRROR); |
| 1326 } | 1345 } |
| 1327 | 1346 |
| 1328 Element getCyclicThrowHelper() { | 1347 Element getCyclicThrowHelper() { |
| 1329 return compiler.findHelper(const SourceString("throwCyclicInit")); | 1348 return compiler.findHelper(const SourceString("throwCyclicInit")); |
| 1330 } | 1349 } |
| 1331 | 1350 |
| 1332 /** | |
| 1333 * Remove [element] from the set of generated code, and put it back | |
| 1334 * into the worklist. | |
| 1335 * | |
| 1336 * Invariant: [element] must be a declaration element. | |
| 1337 */ | |
| 1338 void eagerRecompile(Element element) { | |
| 1339 assert(invariant(element, element.isDeclaration)); | |
| 1340 generatedCode.remove(element); | |
| 1341 generatedBailoutCode.remove(element); | |
| 1342 compiler.enqueuer.codegen.addToWorkList(element); | |
| 1343 } | |
| 1344 | |
| 1345 bool isNullImplementation(ClassElement cls) { | 1351 bool isNullImplementation(ClassElement cls) { |
| 1346 return cls == jsNullClass; | 1352 return cls == jsNullClass; |
| 1347 } | 1353 } |
| 1348 | 1354 |
| 1349 ClassElement get intImplementation => jsIntClass; | 1355 ClassElement get intImplementation => jsIntClass; |
| 1350 ClassElement get doubleImplementation => jsDoubleClass; | 1356 ClassElement get doubleImplementation => jsDoubleClass; |
| 1351 ClassElement get numImplementation => jsNumberClass; | 1357 ClassElement get numImplementation => jsNumberClass; |
| 1352 ClassElement get stringImplementation => jsStringClass; | 1358 ClassElement get stringImplementation => jsStringClass; |
| 1353 ClassElement get listImplementation => jsArrayClass; | 1359 ClassElement get listImplementation => jsArrayClass; |
| 1354 ClassElement get constListImplementation => jsArrayClass; | 1360 ClassElement get constListImplementation => jsArrayClass; |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1577 copy(constant.values); | 1583 copy(constant.values); |
| 1578 copy(constant.protoValue); | 1584 copy(constant.protoValue); |
| 1579 copy(constant); | 1585 copy(constant); |
| 1580 } | 1586 } |
| 1581 | 1587 |
| 1582 void visitConstructed(ConstructedConstant constant) { | 1588 void visitConstructed(ConstructedConstant constant) { |
| 1583 copy(constant.fields); | 1589 copy(constant.fields); |
| 1584 copy(constant); | 1590 copy(constant); |
| 1585 } | 1591 } |
| 1586 } | 1592 } |
| OLD | NEW |