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

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

Issue 10917285: Stub implementation of patch invariants for the patch refactoring. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments Created 8 years, 3 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 typedef void Recompile(Element element); 5 typedef void Recompile(Element element);
6 6
7 class ReturnInfo { 7 class ReturnInfo {
8 HType returnType; 8 HType returnType;
9 List<Element> compiledFunctions; 9 List<Element> compiledFunctions;
10 10
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 }); 218 });
219 return result; 219 return result;
220 } 220 }
221 221
222 String toString() => 222 String toString() =>
223 allUnknown ? "HTypeList.ALL_UNKNOWN" : "HTypeList $types"; 223 allUnknown ? "HTypeList.ALL_UNKNOWN" : "HTypeList $types";
224 } 224 }
225 225
226 class ArgumentTypesRegistry { 226 class ArgumentTypesRegistry {
227 final JavaScriptBackend backend; 227 final JavaScriptBackend backend;
228
229 /**
230 * Documentation wanted -- johnniwinther
231 *
232 * Invariant: Keys must be declaration elements.
233 */
228 final Map<Element, HTypeList> staticTypeMap; 234 final Map<Element, HTypeList> staticTypeMap;
235
236 /**
237 * Documentation wanted -- johnniwinther
238 *
239 * Invariant: Elements must be declaration elements.
240 */
229 final Set<Element> optimizedStaticFunctions; 241 final Set<Element> optimizedStaticFunctions;
230 final SelectorMap<HTypeList> selectorTypeMap; 242 final SelectorMap<HTypeList> selectorTypeMap;
231 final FunctionSet optimizedFunctions; 243 final FunctionSet optimizedFunctions;
244
245 /**
246 * Documentation wanted -- johnniwinther
247 *
248 * Invariant: Keys must be declaration elements.
249 */
232 final Map<Element, HTypeList> optimizedTypes; 250 final Map<Element, HTypeList> optimizedTypes;
233 final Map<Element, OptionalParameterTypes> optimizedDefaultValueTypes; 251 final Map<Element, OptionalParameterTypes> optimizedDefaultValueTypes;
234 252
235 ArgumentTypesRegistry(JavaScriptBackend backend) 253 ArgumentTypesRegistry(JavaScriptBackend backend)
236 : staticTypeMap = new Map<Element, HTypeList>(), 254 : staticTypeMap = new Map<Element, HTypeList>(),
237 optimizedStaticFunctions = new Set<Element>(), 255 optimizedStaticFunctions = new Set<Element>(),
238 selectorTypeMap = new SelectorMap<HTypeList>(backend.compiler), 256 selectorTypeMap = new SelectorMap<HTypeList>(backend.compiler),
239 optimizedFunctions = new FunctionSet(backend.compiler), 257 optimizedFunctions = new FunctionSet(backend.compiler),
240 optimizedTypes = new Map<Element, HTypeList>(), 258 optimizedTypes = new Map<Element, HTypeList>(),
241 optimizedDefaultValueTypes = 259 optimizedDefaultValueTypes =
242 new Map<Element, OptionalParameterTypes>(), 260 new Map<Element, OptionalParameterTypes>(),
243 this.backend = backend; 261 this.backend = backend;
244 262
245 Compiler get compiler => backend.compiler; 263 Compiler get compiler => backend.compiler;
246 264
247 void registerStaticInvocation(HInvokeStatic node, HTypeMap types) { 265 void registerStaticInvocation(HInvokeStatic node, HTypeMap types) {
248 Element element = node.element; 266 Element element = node.element;
267 assert(invariant(node, element.isDeclaration));
249 HTypeList oldTypes = staticTypeMap[element]; 268 HTypeList oldTypes = staticTypeMap[element];
250 if (oldTypes == null) { 269 if (oldTypes == null) {
251 staticTypeMap[element] = new HTypeList.fromStaticInvocation(node, types); 270 staticTypeMap[element] = new HTypeList.fromStaticInvocation(node, types);
252 } else { 271 } else {
253 if (oldTypes.allUnknown) return; 272 if (oldTypes.allUnknown) return;
254 HTypeList newTypes = oldTypes.unionWithInvoke(node, types); 273 HTypeList newTypes = oldTypes.unionWithInvoke(node, types);
255 if (newTypes === oldTypes) return; 274 if (newTypes === oldTypes) return;
256 staticTypeMap[element] = newTypes; 275 staticTypeMap[element] = newTypes;
257 if (optimizedStaticFunctions.contains(element)) { 276 if (optimizedStaticFunctions.contains(element)) {
258 backend.scheduleForRecompilation(element); 277 backend.scheduleForRecompilation(element);
259 } 278 }
260 } 279 }
261 } 280 }
262 281
263 void registerNonCallStaticUse(HStatic node) { 282 void registerNonCallStaticUse(HStatic node) {
264 // When a static is used for anything else than a call target we cannot 283 // When a static is used for anything else than a call target we cannot
265 // infer anything about its parameter types. 284 // infer anything about its parameter types.
266 Element element = node.element; 285 Element element = node.element;
286 assert(invariant(node, element.isDeclaration));
267 if (optimizedStaticFunctions.contains(element)) { 287 if (optimizedStaticFunctions.contains(element)) {
268 backend.scheduleForRecompilation(element); 288 backend.scheduleForRecompilation(element);
269 } 289 }
270 staticTypeMap[element] = HTypeList.ALL_UNKNOWN; 290 staticTypeMap[element] = HTypeList.ALL_UNKNOWN;
271 } 291 }
272 292
273 void registerDynamicInvocation(HInvokeDynamicMethod node, 293 void registerDynamicInvocation(HInvokeDynamicMethod node,
274 Selector selector, 294 Selector selector,
275 HTypeMap types) { 295 HTypeMap types) {
276 // If there are any getters for this method we cannot know anything about 296 // If there are any getters for this method we cannot know anything about
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 break; 340 break;
321 } 341 }
322 } 342 }
323 } 343 }
324 if (recompile) backend.scheduleForRecompilation(element); 344 if (recompile) backend.scheduleForRecompilation(element);
325 }); 345 });
326 } 346 }
327 347
328 HTypeList parameterTypes(FunctionElement element, 348 HTypeList parameterTypes(FunctionElement element,
329 OptionalParameterTypes defaultValueTypes) { 349 OptionalParameterTypes defaultValueTypes) {
350 assert(invariant(element, element.isDeclaration));
330 // Handle static functions separately. 351 // Handle static functions separately.
331 if (Elements.isStaticOrTopLevelFunction(element) || 352 if (Elements.isStaticOrTopLevelFunction(element) ||
332 element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) { 353 element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
333 HTypeList types = staticTypeMap[element]; 354 HTypeList types = staticTypeMap[element];
334 if (types !== null) { 355 if (types !== null) {
335 if (!optimizedStaticFunctions.contains(element)) { 356 if (!optimizedStaticFunctions.contains(element)) {
336 optimizedStaticFunctions.add(element); 357 optimizedStaticFunctions.add(element);
337 } 358 }
338 return types; 359 return types;
339 } else { 360 } else {
(...skipping 20 matching lines...) Expand all
360 assert(types.allUnknown || types.length == signature.parameterCount); 381 assert(types.allUnknown || types.length == signature.parameterCount);
361 found = (found === null) ? types : found.union(types); 382 found = (found === null) ? types : found.union(types);
362 return !found.allUnknown; 383 return !found.allUnknown;
363 }); 384 });
364 return found !== null ? found : HTypeList.ALL_UNKNOWN; 385 return found !== null ? found : HTypeList.ALL_UNKNOWN;
365 } 386 }
366 387
367 void registerOptimization(Element element, 388 void registerOptimization(Element element,
368 HTypeList parameterTypes, 389 HTypeList parameterTypes,
369 OptionalParameterTypes defaultValueTypes) { 390 OptionalParameterTypes defaultValueTypes) {
391 assert(invariant(element, element.isDeclaration));
370 if (Elements.isStaticOrTopLevelFunction(element)) { 392 if (Elements.isStaticOrTopLevelFunction(element)) {
371 if (parameterTypes.allUnknown) { 393 if (parameterTypes.allUnknown) {
372 optimizedStaticFunctions.remove(element); 394 optimizedStaticFunctions.remove(element);
373 } else { 395 } else {
374 optimizedStaticFunctions.add(element); 396 optimizedStaticFunctions.add(element);
375 } 397 }
376 } 398 }
377 399
378 // TODO(kasperl): What kind of non-members do we get here? 400 // TODO(kasperl): What kind of non-members do we get here?
379 if (!element.isMember()) return; 401 if (!element.isMember()) return;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 * libraries. 442 * libraries.
421 */ 443 */
422 ClassElement jsIndexingBehaviorInterface; 444 ClassElement jsIndexingBehaviorInterface;
423 445
424 final Map<Element, Map<Element, HType>> fieldInitializers; 446 final Map<Element, Map<Element, HType>> fieldInitializers;
425 final Map<Element, Map<Element, HType>> fieldConstructorSetters; 447 final Map<Element, Map<Element, HType>> fieldConstructorSetters;
426 final Map<Element, Map<Element, HType>> fieldSettersType; 448 final Map<Element, Map<Element, HType>> fieldSettersType;
427 449
428 final Map<Element, ReturnInfo> returnInfo; 450 final Map<Element, ReturnInfo> returnInfo;
429 451
452 /**
453 * Documentation wanted -- johnniwinther
454 *
455 * Invariant: Elements must be declaration elements.
456 */
430 final List<Element> invalidateAfterCodegen; 457 final List<Element> invalidateAfterCodegen;
431 ArgumentTypesRegistry argumentTypes; 458 ArgumentTypesRegistry argumentTypes;
432 459
433 List<CompilerTask> get tasks { 460 List<CompilerTask> get tasks {
434 return <CompilerTask>[builder, optimizer, generator, emitter]; 461 return <CompilerTask>[builder, optimizer, generator, emitter];
435 } 462 }
436 463
437 JavaScriptBackend(Compiler compiler, bool generateSourceMap) 464 JavaScriptBackend(Compiler compiler, bool generateSourceMap)
438 : fieldInitializers = new Map<Element, Map<Element, HType>>(), 465 : fieldInitializers = new Map<Element, Map<Element, HType>>(),
439 fieldConstructorSetters = new Map<Element, Map<Element, HType>>(), 466 fieldConstructorSetters = new Map<Element, Map<Element, HType>>(),
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 assert(field.isMember()); 632 assert(field.isMember());
606 ClassElement enclosingClass = field.getEnclosingClass(); 633 ClassElement enclosingClass = field.getEnclosingClass();
607 if (!fieldSettersType.containsKey(enclosingClass)) { 634 if (!fieldSettersType.containsKey(enclosingClass)) {
608 return HType.CONFLICTING; 635 return HType.CONFLICTING;
609 } 636 }
610 Map<Element, HType> fields = fieldSettersType[enclosingClass]; 637 Map<Element, HType> fields = fieldSettersType[enclosingClass];
611 if (!fields.containsKey(field)) return HType.CONFLICTING; 638 if (!fields.containsKey(field)) return HType.CONFLICTING;
612 return fields[field]; 639 return fields[field];
613 } 640 }
614 641
642 /**
643 * Documentation wanted -- johnniwinther
644 *
645 * Invariant: [element] must be a declaration element.
646 */
615 void scheduleForRecompilation(Element element) { 647 void scheduleForRecompilation(Element element) {
648 assert(invariant(element, element.isDeclaration));
616 if (compiler.phase == Compiler.PHASE_COMPILING) { 649 if (compiler.phase == Compiler.PHASE_COMPILING) {
617 invalidateAfterCodegen.add(element); 650 invalidateAfterCodegen.add(element);
618 } 651 }
619 } 652 }
620 653
621 /** 654 /**
622 * Register a dynamic invocation and collect the provided types for the 655 * Register a dynamic invocation and collect the provided types for the
623 * named selector. 656 * named selector.
624 */ 657 */
625 void registerDynamicInvocation(HInvokeDynamicMethod node, 658 void registerDynamicInvocation(HInvokeDynamicMethod node,
(...skipping 15 matching lines...) Expand all
641 * target. 674 * target.
642 */ 675 */
643 void registerNonCallStaticUse(HStatic node) { 676 void registerNonCallStaticUse(HStatic node) {
644 argumentTypes.registerNonCallStaticUse(node); 677 argumentTypes.registerNonCallStaticUse(node);
645 } 678 }
646 679
647 /** 680 /**
648 * Retrieve the types of the parameters used for calling the [element] 681 * Retrieve the types of the parameters used for calling the [element]
649 * function. The types are optimistic in the sense as they are based on the 682 * function. The types are optimistic in the sense as they are based on the
650 * possible invocations of the function seen so far. 683 * possible invocations of the function seen so far.
684 *
685 * Invariant: [element] must be a declaration element.
651 */ 686 */
652 HTypeList optimisticParameterTypes( 687 HTypeList optimisticParameterTypes(
653 FunctionElement element, 688 FunctionElement element,
654 OptionalParameterTypes defaultValueTypes) { 689 OptionalParameterTypes defaultValueTypes) {
690 assert(invariant(element, element.isDeclaration));
655 if (element.parameterCount(compiler) == 0) return HTypeList.ALL_UNKNOWN; 691 if (element.parameterCount(compiler) == 0) return HTypeList.ALL_UNKNOWN;
656 return argumentTypes.parameterTypes(element, defaultValueTypes); 692 return argumentTypes.parameterTypes(element, defaultValueTypes);
657 } 693 }
658 694
659 /** 695 /**
660 * Register that the function [element] has been optimized under the 696 * Register that the function [element] has been optimized under the
661 * assumptions that the types [parameterType] will be used for calling it. 697 * assumptions that the types [parameterType] will be used for calling it.
662 * The passed [defaultValueTypes] holds the types of default values for 698 * The passed [defaultValueTypes] holds the types of default values for
663 * the optional parameters. If this assumption fail the function will be 699 * the optional parameters. If this assumption fail the function will be
664 * scheduled for recompilation. 700 * scheduled for recompilation.
701 *
702 * Invariant: [element] must be a declaration element.
665 */ 703 */
666 registerParameterTypesOptimization( 704 registerParameterTypesOptimization(
667 FunctionElement element, 705 FunctionElement element,
668 HTypeList parameterTypes, 706 HTypeList parameterTypes,
669 OptionalParameterTypes defaultValueTypes) { 707 OptionalParameterTypes defaultValueTypes) {
708 assert(invariant(element, element.isDeclaration));
670 if (element.parameterCount(compiler) == 0) return; 709 if (element.parameterCount(compiler) == 0) return;
671 argumentTypes.registerOptimization( 710 argumentTypes.registerOptimization(
672 element, parameterTypes, defaultValueTypes); 711 element, parameterTypes, defaultValueTypes);
673 } 712 }
674 713
714 /**
715 * Documentation wanted -- johnniwinther
716 *
717 * Invariant: [element] must be a declaration element.
718 */
675 void registerReturnType(FunctionElement element, HType returnType) { 719 void registerReturnType(FunctionElement element, HType returnType) {
720 assert(invariant(element, element.isDeclaration));
676 ReturnInfo info = returnInfo[element]; 721 ReturnInfo info = returnInfo[element];
677 if (info != null) { 722 if (info != null) {
678 info.update(returnType, scheduleForRecompilation); 723 info.update(returnType, scheduleForRecompilation);
679 } else { 724 } else {
680 returnInfo[element] = new ReturnInfo(returnType); 725 returnInfo[element] = new ReturnInfo(returnType);
681 } 726 }
682 } 727 }
683 728
684 /** 729 /**
685 * Retrieve the return type of the function [callee]. The type is optimistic 730 * Retrieve the return type of the function [callee]. The type is optimistic
686 * in the sense that is is based on the compilation of [callee]. If [callee] 731 * in the sense that is is based on the compilation of [callee]. If [callee]
687 * is recompiled the return type might change to someting broader. For that 732 * is recompiled the return type might change to someting broader. For that
688 * reason [caller] is registered for recompilation if this happens. If the 733 * reason [caller] is registered for recompilation if this happens. If the
689 * function [callee] has not yet been compiled the returned type is [null]. 734 * function [callee] has not yet been compiled the returned type is [null].
735 *
736 * Invariant: Both [caller] and [callee] must be declaration elements.
690 */ 737 */
691 HType optimisticReturnTypesWithRecompilationOnTypeChange( 738 HType optimisticReturnTypesWithRecompilationOnTypeChange(
692 Element caller, FunctionElement callee) { 739 Element caller, FunctionElement callee) {
740 assert(invariant(callee, callee.isDeclaration));
693 returnInfo.putIfAbsent(callee, () => new ReturnInfo.unknownType()); 741 returnInfo.putIfAbsent(callee, () => new ReturnInfo.unknownType());
694 ReturnInfo info = returnInfo[callee]; 742 ReturnInfo info = returnInfo[callee];
695 if (info.returnType != HType.UNKNOWN && caller != null) { 743 if (info.returnType != HType.UNKNOWN && caller != null) {
744 assert(invariant(caller, caller.isDeclaration));
696 info.addCompiledFunction(caller); 745 info.addCompiledFunction(caller);
697 } 746 }
698 return info.returnType; 747 return info.returnType;
699 } 748 }
700 749
701 void dumpReturnTypes() { 750 void dumpReturnTypes() {
702 returnInfo.forEach((Element element, ReturnInfo info) { 751 returnInfo.forEach((Element element, ReturnInfo info) {
703 if (info.returnType != HType.UNKNOWN) { 752 if (info.returnType != HType.UNKNOWN) {
704 print("Inferred $element has return type ${info.returnType}"); 753 print("Inferred $element has return type ${info.returnType}");
705 } 754 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 ? const SourceString('listSuperNativeTypeCheck') 787 ? const SourceString('listSuperNativeTypeCheck')
739 : const SourceString('listSuperTypeCheck'); 788 : const SourceString('listSuperTypeCheck');
740 } else { 789 } else {
741 return nativeCheck 790 return nativeCheck
742 ? const SourceString('callTypeCheck') 791 ? const SourceString('callTypeCheck')
743 : const SourceString('propertyTypeCheck'); 792 : const SourceString('propertyTypeCheck');
744 } 793 }
745 } 794 }
746 } 795 }
747 } 796 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/enqueue.dart ('k') | lib/compiler/implementation/js_backend/emitter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698