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

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 return !helpersUsed.contains(element.declaration);
362 }
363
357 bool isInterceptorClass(ClassElement element) { 364 bool isInterceptorClass(ClassElement element) {
358 if (element == null) return false; 365 if (element == null) return false;
359 if (element.isNative()) return true; 366 if (element.isNative()) return true;
360 if (interceptedClasses.contains(element)) return true; 367 if (interceptedClasses.contains(element)) return true;
361 if (classesMixedIntoNativeClasses.contains(element)) return true; 368 if (classesMixedIntoNativeClasses.contains(element)) return true;
362 return false; 369 return false;
363 } 370 }
364 371
365 String registerOneShotInterceptor(Selector selector) { 372 String registerOneShotInterceptor(Selector selector) {
366 Set<ClassElement> classes = getInterceptedClassesOn(selector.name); 373 Set<ClassElement> classes = getInterceptedClassesOn(selector.name);
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 world.registerStaticUse( 741 world.registerStaticUse(
735 compiler.findInterceptor(const SourceString('dispatchPropertyName'))); 742 compiler.findInterceptor(const SourceString('dispatchPropertyName')));
736 } 743 }
737 744
738 if (compiler.enableTypeAssertions) { 745 if (compiler.enableTypeAssertions) {
739 // Unconditionally register the helper that checks if the 746 // Unconditionally register the helper that checks if the
740 // expression in an if/while/for is a boolean. 747 // expression in an if/while/for is a boolean.
741 // TODO(ngeoffray): Should we have the resolver register those instead? 748 // TODO(ngeoffray): Should we have the resolver register those instead?
742 Element e = 749 Element e =
743 compiler.findHelper(const SourceString('boolConversionCheck')); 750 compiler.findHelper(const SourceString('boolConversionCheck'));
744 if (e != null) world.addToWorkList(e); 751 if (e != null) enqueue(world, e, elements);
745 } 752 }
746 } 753 }
747 754
748 onResolutionComplete() => rti.computeClassesNeedingRti(); 755 onResolutionComplete() => rti.computeClassesNeedingRti();
749 756
750 void registerStringInterpolation(TreeElements elements) { 757 void registerStringInterpolation(TreeElements elements) {
751 enqueueInResolution(getStringInterpolationHelper(), elements); 758 enqueueInResolution(getStringInterpolationHelper(), elements);
752 } 759 }
753 760
754 void registerCatchStatement(Enqueuer enqueuer, TreeElements elements) { 761 void registerCatchStatement(Enqueuer enqueuer, TreeElements elements) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 } 845 }
839 846
840 void registerIsCheck(DartType type, Enqueuer world, TreeElements elements) { 847 void registerIsCheck(DartType type, Enqueuer world, TreeElements elements) {
841 type = type.unalias(compiler); 848 type = type.unalias(compiler);
842 world.registerInstantiatedClass(compiler.boolClass, elements); 849 world.registerInstantiatedClass(compiler.boolClass, elements);
843 bool inCheckedMode = compiler.enableTypeAssertions; 850 bool inCheckedMode = compiler.enableTypeAssertions;
844 // [registerIsCheck] is also called for checked mode checks, so we 851 // [registerIsCheck] is also called for checked mode checks, so we
845 // need to register checked mode helpers. 852 // need to register checked mode helpers.
846 if (inCheckedMode) { 853 if (inCheckedMode) {
847 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: false); 854 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: false);
848 if (helper != null) world.addToWorkList(helper.getElement(compiler)); 855 if (helper != null) enqueue(world, helper.getElement(compiler), elements);
849 // We also need the native variant of the check (for DOM types). 856 // We also need the native variant of the check (for DOM types).
850 helper = getNativeCheckedModeHelper(type, typeCast: false); 857 helper = getNativeCheckedModeHelper(type, typeCast: false);
851 if (helper != null) world.addToWorkList(helper.getElement(compiler)); 858 if (helper != null) enqueue(world, helper.getElement(compiler), elements);
852 } 859 }
853 bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE; 860 bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE;
854 if (!type.isRaw || type.containsTypeVariables) { 861 if (!type.isRaw || type.containsTypeVariables) {
855 enqueueInResolution(getSetRuntimeTypeInfo(), elements); 862 enqueueInResolution(getSetRuntimeTypeInfo(), elements);
856 enqueueInResolution(getGetRuntimeTypeInfo(), elements); 863 enqueueInResolution(getGetRuntimeTypeInfo(), elements);
857 enqueueInResolution(getGetRuntimeTypeArgument(), elements); 864 enqueueInResolution(getGetRuntimeTypeArgument(), elements);
858 if (inCheckedMode) { 865 if (inCheckedMode) {
859 enqueueInResolution(getAssertSubtype(), elements); 866 enqueueInResolution(getAssertSubtype(), elements);
860 } 867 }
861 enqueueInResolution(getCheckSubtype(), elements); 868 enqueueInResolution(getCheckSubtype(), elements);
862 if (isTypeVariable) { 869 if (isTypeVariable) {
863 enqueueInResolution(getCheckSubtypeOfRuntimeType(), elements); 870 enqueueInResolution(getCheckSubtypeOfRuntimeType(), elements);
864 if (inCheckedMode) { 871 if (inCheckedMode) {
865 enqueueInResolution(getAssertSubtypeOfRuntimeType(), elements); 872 enqueueInResolution(getAssertSubtypeOfRuntimeType(), elements);
866 } 873 }
867 } 874 }
868 world.registerInstantiatedClass(compiler.listClass, elements); 875 world.registerInstantiatedClass(compiler.listClass, elements);
869 } 876 }
870 if (type is FunctionType) { 877 if (type is FunctionType) {
871 enqueueInResolution(getCheckFunctionSubtype(), elements); 878 enqueueInResolution(getCheckFunctionSubtype(), elements);
872 } 879 }
873 if (type.element.isNative()) { 880 if (type.element.isNative()) {
874 // We will neeed to add the "$is" and "$as" properties on the 881 // We will neeed to add the "$is" and "$as" properties on the
875 // JavaScript object prototype, so we make sure 882 // JavaScript object prototype, so we make sure
876 // [:defineProperty:] is compiled. 883 // [:defineProperty:] is compiled.
877 world.addToWorkList( 884 enqueue(world,
878 compiler.findHelper(const SourceString('defineProperty'))); 885 compiler.findHelper(const SourceString('defineProperty')),
886 elements);
879 } 887 }
880 } 888 }
881 889
882 void registerAsCheck(DartType type, TreeElements elements) { 890 void registerAsCheck(DartType type, TreeElements elements) {
883 type = type.unalias(compiler); 891 type = type.unalias(compiler);
884 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: true); 892 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: true);
885 enqueueInResolution(helper.getElement(compiler), elements); 893 enqueueInResolution(helper.getElement(compiler), elements);
886 // We also need the native variant of the check (for DOM types). 894 // We also need the native variant of the check (for DOM types).
887 helper = getNativeCheckedModeHelper(type, typeCast: true); 895 helper = getNativeCheckedModeHelper(type, typeCast: true);
888 if (helper != null) { 896 if (helper != null) {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 return classElement == compiler.objectClass 977 return classElement == compiler.objectClass
970 || classElement == jsInterceptorClass 978 || classElement == jsInterceptorClass
971 || classElement == jsNullClass; 979 || classElement == jsNullClass;
972 } 980 }
973 981
974 bool methodNeedsRti(FunctionElement function) { 982 bool methodNeedsRti(FunctionElement function) {
975 return rti.methodsNeedingRti.contains(function) || 983 return rti.methodsNeedingRti.contains(function) ||
976 compiler.enabledRuntimeType; 984 compiler.enabledRuntimeType;
977 } 985 }
978 986
987 // Enqueue [e] in [enqueuer].
988 //
989 // The backend must *always* call this method when enqueuing an
990 // element. Calls done by the backend are not seen by global
991 // optimizations, so they would make these optimizations unsound.
992 // Therefore we need to collect the list of helpers the backend may
993 // use.
979 void enqueue(Enqueuer enqueuer, Element e, TreeElements elements) { 994 void enqueue(Enqueuer enqueuer, Element e, TreeElements elements) {
995 helpersUsed.add(e.declaration);
980 enqueuer.addToWorkList(e); 996 enqueuer.addToWorkList(e);
981 elements.registerDependency(e); 997 elements.registerDependency(e);
982 } 998 }
983 999
984 void enqueueInResolution(Element e, TreeElements elements) { 1000 void enqueueInResolution(Element e, TreeElements elements) {
985 if (e == null) return; 1001 if (e == null) return;
986 ResolutionEnqueuer enqueuer = compiler.enqueuer.resolution; 1002 ResolutionEnqueuer enqueuer = compiler.enqueuer.resolution;
987 enqueue(enqueuer, e, elements); 1003 enqueue(enqueuer, e, elements);
988 } 1004 }
989 1005
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
1322 } 1338 }
1323 1339
1324 Element getCreateInvocationMirror() { 1340 Element getCreateInvocationMirror() {
1325 return compiler.findHelper(Compiler.CREATE_INVOCATION_MIRROR); 1341 return compiler.findHelper(Compiler.CREATE_INVOCATION_MIRROR);
1326 } 1342 }
1327 1343
1328 Element getCyclicThrowHelper() { 1344 Element getCyclicThrowHelper() {
1329 return compiler.findHelper(const SourceString("throwCyclicInit")); 1345 return compiler.findHelper(const SourceString("throwCyclicInit"));
1330 } 1346 }
1331 1347
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) { 1348 bool isNullImplementation(ClassElement cls) {
1346 return cls == jsNullClass; 1349 return cls == jsNullClass;
1347 } 1350 }
1348 1351
1349 ClassElement get intImplementation => jsIntClass; 1352 ClassElement get intImplementation => jsIntClass;
1350 ClassElement get doubleImplementation => jsDoubleClass; 1353 ClassElement get doubleImplementation => jsDoubleClass;
1351 ClassElement get numImplementation => jsNumberClass; 1354 ClassElement get numImplementation => jsNumberClass;
1352 ClassElement get stringImplementation => jsStringClass; 1355 ClassElement get stringImplementation => jsStringClass;
1353 ClassElement get listImplementation => jsArrayClass; 1356 ClassElement get listImplementation => jsArrayClass;
1354 ClassElement get constListImplementation => jsArrayClass; 1357 ClassElement get constListImplementation => jsArrayClass;
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1577 copy(constant.values); 1580 copy(constant.values);
1578 copy(constant.protoValue); 1581 copy(constant.protoValue);
1579 copy(constant); 1582 copy(constant);
1580 } 1583 }
1581 1584
1582 void visitConstructed(ConstructedConstant constant) { 1585 void visitConstructed(ConstructedConstant constant) {
1583 copy(constant.fields); 1586 copy(constant.fields);
1584 copy(constant); 1587 copy(constant);
1585 } 1588 }
1586 } 1589 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698