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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_backend/backend.dart

Issue 23118007: Ensure the type inferrer does not infer types for runtime helpers used by the backend. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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 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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698