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

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: Leftovers from rebase. 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 /// Invariant: Keys must be declaration elements.
228 final Map<Element, HTypeList> staticTypeMap; 229 final Map<Element, HTypeList> staticTypeMap;
230 /// Invariant: Elements must be declaration elements.
229 final Set<Element> optimizedStaticFunctions; 231 final Set<Element> optimizedStaticFunctions;
230 final SelectorMap<HTypeList> selectorTypeMap; 232 final SelectorMap<HTypeList> selectorTypeMap;
231 final FunctionSet optimizedFunctions; 233 final FunctionSet optimizedFunctions;
234 /// Invariant: Keys must be declaration elements.
232 final Map<Element, HTypeList> optimizedTypes; 235 final Map<Element, HTypeList> optimizedTypes;
233 final Map<Element, OptionalParameterTypes> optimizedDefaultValueTypes; 236 final Map<Element, OptionalParameterTypes> optimizedDefaultValueTypes;
234 237
235 ArgumentTypesRegistry(JavaScriptBackend backend) 238 ArgumentTypesRegistry(JavaScriptBackend backend)
236 : staticTypeMap = new Map<Element, HTypeList>(), 239 : staticTypeMap = new Map<Element, HTypeList>(),
237 optimizedStaticFunctions = new Set<Element>(), 240 optimizedStaticFunctions = new Set<Element>(),
238 selectorTypeMap = new SelectorMap<HTypeList>(backend.compiler), 241 selectorTypeMap = new SelectorMap<HTypeList>(backend.compiler),
239 optimizedFunctions = new FunctionSet(backend.compiler), 242 optimizedFunctions = new FunctionSet(backend.compiler),
240 optimizedTypes = new Map<Element, HTypeList>(), 243 optimizedTypes = new Map<Element, HTypeList>(),
241 optimizedDefaultValueTypes = 244 optimizedDefaultValueTypes =
242 new Map<Element, OptionalParameterTypes>(), 245 new Map<Element, OptionalParameterTypes>(),
243 this.backend = backend; 246 this.backend = backend;
244 247
245 Compiler get compiler => backend.compiler; 248 Compiler get compiler => backend.compiler;
246 249
247 void registerStaticInvocation(HInvokeStatic node, HTypeMap types) { 250 void registerStaticInvocation(HInvokeStatic node, HTypeMap types) {
248 Element element = node.element; 251 Element element = node.element;
252 assert(element.isDeclaration);
249 HTypeList oldTypes = staticTypeMap[element]; 253 HTypeList oldTypes = staticTypeMap[element];
250 if (oldTypes == null) { 254 if (oldTypes == null) {
251 staticTypeMap[element] = new HTypeList.fromStaticInvocation(node, types); 255 staticTypeMap[element] = new HTypeList.fromStaticInvocation(node, types);
252 } else { 256 } else {
253 if (oldTypes.allUnknown) return; 257 if (oldTypes.allUnknown) return;
254 HTypeList newTypes = oldTypes.unionWithInvoke(node, types); 258 HTypeList newTypes = oldTypes.unionWithInvoke(node, types);
255 if (newTypes === oldTypes) return; 259 if (newTypes === oldTypes) return;
256 staticTypeMap[element] = newTypes; 260 staticTypeMap[element] = newTypes;
257 if (optimizedStaticFunctions.contains(element)) { 261 if (optimizedStaticFunctions.contains(element)) {
258 backend.scheduleForRecompilation(element); 262 backend.scheduleForRecompilation(element);
259 } 263 }
260 } 264 }
261 } 265 }
262 266
263 void registerNonCallStaticUse(HStatic node) { 267 void registerNonCallStaticUse(HStatic node) {
264 // When a static is used for anything else than a call target we cannot 268 // When a static is used for anything else than a call target we cannot
265 // infer anything about its parameter types. 269 // infer anything about its parameter types.
266 Element element = node.element; 270 Element element = node.element;
271 assert(element.isDeclaration);
267 if (optimizedStaticFunctions.contains(element)) { 272 if (optimizedStaticFunctions.contains(element)) {
268 backend.scheduleForRecompilation(element); 273 backend.scheduleForRecompilation(element);
269 } 274 }
270 staticTypeMap[element] = HTypeList.ALL_UNKNOWN; 275 staticTypeMap[element] = HTypeList.ALL_UNKNOWN;
271 } 276 }
272 277
273 void registerDynamicInvocation(HInvokeDynamicMethod node, 278 void registerDynamicInvocation(HInvokeDynamicMethod node,
274 Selector selector, 279 Selector selector,
275 HTypeMap types) { 280 HTypeMap types) {
276 // If there are any getters for this method we cannot know anything about 281 // 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; 325 break;
321 } 326 }
322 } 327 }
323 } 328 }
324 if (recompile) backend.scheduleForRecompilation(element); 329 if (recompile) backend.scheduleForRecompilation(element);
325 }); 330 });
326 } 331 }
327 332
328 HTypeList parameterTypes(FunctionElement element, 333 HTypeList parameterTypes(FunctionElement element,
329 OptionalParameterTypes defaultValueTypes) { 334 OptionalParameterTypes defaultValueTypes) {
335 assert(element.isDeclaration);
330 // Handle static functions separately. 336 // Handle static functions separately.
331 if (Elements.isStaticOrTopLevelFunction(element) || 337 if (Elements.isStaticOrTopLevelFunction(element) ||
332 element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) { 338 element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
333 HTypeList types = staticTypeMap[element]; 339 HTypeList types = staticTypeMap[element];
334 if (types !== null) { 340 if (types !== null) {
335 if (!optimizedStaticFunctions.contains(element)) { 341 if (!optimizedStaticFunctions.contains(element)) {
336 optimizedStaticFunctions.add(element); 342 optimizedStaticFunctions.add(element);
337 } 343 }
338 return types; 344 return types;
339 } else { 345 } else {
(...skipping 20 matching lines...) Expand all
360 assert(types.allUnknown || types.length == signature.parameterCount); 366 assert(types.allUnknown || types.length == signature.parameterCount);
361 found = (found === null) ? types : found.union(types); 367 found = (found === null) ? types : found.union(types);
362 return !found.allUnknown; 368 return !found.allUnknown;
363 }); 369 });
364 return found !== null ? found : HTypeList.ALL_UNKNOWN; 370 return found !== null ? found : HTypeList.ALL_UNKNOWN;
365 } 371 }
366 372
367 void registerOptimization(Element element, 373 void registerOptimization(Element element,
368 HTypeList parameterTypes, 374 HTypeList parameterTypes,
369 OptionalParameterTypes defaultValueTypes) { 375 OptionalParameterTypes defaultValueTypes) {
376 assert(element.isDeclaration);
370 if (Elements.isStaticOrTopLevelFunction(element)) { 377 if (Elements.isStaticOrTopLevelFunction(element)) {
371 if (parameterTypes.allUnknown) { 378 if (parameterTypes.allUnknown) {
372 optimizedStaticFunctions.remove(element); 379 optimizedStaticFunctions.remove(element);
373 } else { 380 } else {
374 optimizedStaticFunctions.add(element); 381 optimizedStaticFunctions.add(element);
375 } 382 }
376 } 383 }
377 384
378 // TODO(kasperl): What kind of non-members do we get here? 385 // TODO(kasperl): What kind of non-members do we get here?
379 if (!element.isMember()) return; 386 if (!element.isMember()) return;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 * libraries. 427 * libraries.
421 */ 428 */
422 ClassElement jsIndexingBehaviorInterface; 429 ClassElement jsIndexingBehaviorInterface;
423 430
424 final Map<Element, Map<Element, HType>> fieldInitializers; 431 final Map<Element, Map<Element, HType>> fieldInitializers;
425 final Map<Element, Map<Element, HType>> fieldConstructorSetters; 432 final Map<Element, Map<Element, HType>> fieldConstructorSetters;
426 final Map<Element, Map<Element, HType>> fieldSettersType; 433 final Map<Element, Map<Element, HType>> fieldSettersType;
427 434
428 final Map<Element, ReturnInfo> returnInfo; 435 final Map<Element, ReturnInfo> returnInfo;
429 436
437 /// Invariant: Elements must be declaration elements.
430 final List<Element> invalidateAfterCodegen; 438 final List<Element> invalidateAfterCodegen;
431 ArgumentTypesRegistry argumentTypes; 439 ArgumentTypesRegistry argumentTypes;
432 440
433 List<CompilerTask> get tasks { 441 List<CompilerTask> get tasks {
434 return <CompilerTask>[builder, optimizer, generator, emitter]; 442 return <CompilerTask>[builder, optimizer, generator, emitter];
435 } 443 }
436 444
437 JavaScriptBackend(Compiler compiler, bool generateSourceMap) 445 JavaScriptBackend(Compiler compiler, bool generateSourceMap)
438 : fieldInitializers = new Map<Element, Map<Element, HType>>(), 446 : fieldInitializers = new Map<Element, Map<Element, HType>>(),
439 fieldConstructorSetters = new Map<Element, Map<Element, HType>>(), 447 fieldConstructorSetters = new Map<Element, Map<Element, HType>>(),
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 assert(field.isMember()); 614 assert(field.isMember());
607 ClassElement enclosingClass = field.getEnclosingClass(); 615 ClassElement enclosingClass = field.getEnclosingClass();
608 if (!fieldSettersType.containsKey(enclosingClass)) { 616 if (!fieldSettersType.containsKey(enclosingClass)) {
609 return HType.CONFLICTING; 617 return HType.CONFLICTING;
610 } 618 }
611 Map<Element, HType> fields = fieldSettersType[enclosingClass]; 619 Map<Element, HType> fields = fieldSettersType[enclosingClass];
612 if (!fields.containsKey(field)) return HType.CONFLICTING; 620 if (!fields.containsKey(field)) return HType.CONFLICTING;
613 return fields[field]; 621 return fields[field];
614 } 622 }
615 623
624 /**
625 * Invariant: [element] must be the declaration element.
ahe 2012/09/18 11:25:54 Not documentation.
Johnni Winther 2012/09/20 08:12:23 Done.
626 */
616 void scheduleForRecompilation(Element element) { 627 void scheduleForRecompilation(Element element) {
628 assert(element.isDeclaration);
617 if (compiler.phase == Compiler.PHASE_COMPILING) { 629 if (compiler.phase == Compiler.PHASE_COMPILING) {
618 invalidateAfterCodegen.add(element); 630 invalidateAfterCodegen.add(element);
619 } 631 }
620 } 632 }
621 633
622 /** 634 /**
623 * Register a dynamic invocation and collect the provided types for the 635 * Register a dynamic invocation and collect the provided types for the
624 * named selector. 636 * named selector.
625 */ 637 */
626 void registerDynamicInvocation(HInvokeDynamicMethod node, 638 void registerDynamicInvocation(HInvokeDynamicMethod node,
(...skipping 15 matching lines...) Expand all
642 * target. 654 * target.
643 */ 655 */
644 void registerNonCallStaticUse(HStatic node) { 656 void registerNonCallStaticUse(HStatic node) {
645 argumentTypes.registerNonCallStaticUse(node); 657 argumentTypes.registerNonCallStaticUse(node);
646 } 658 }
647 659
648 /** 660 /**
649 * Retrieve the types of the parameters used for calling the [element] 661 * Retrieve the types of the parameters used for calling the [element]
650 * function. The types are optimistic in the sense as they are based on the 662 * function. The types are optimistic in the sense as they are based on the
651 * possible invocations of the function seen so far. 663 * possible invocations of the function seen so far.
664 *
665 * Invariant: [element] must be the declaration element.
652 */ 666 */
653 HTypeList optimisticParameterTypes( 667 HTypeList optimisticParameterTypes(
654 FunctionElement element, 668 FunctionElement element,
655 OptionalParameterTypes defaultValueTypes) { 669 OptionalParameterTypes defaultValueTypes) {
670 assert(element.isDeclaration);
656 if (element.parameterCount(compiler) == 0) return HTypeList.ALL_UNKNOWN; 671 if (element.parameterCount(compiler) == 0) return HTypeList.ALL_UNKNOWN;
657 return argumentTypes.parameterTypes(element, defaultValueTypes); 672 return argumentTypes.parameterTypes(element, defaultValueTypes);
658 } 673 }
659 674
660 /** 675 /**
661 * Register that the function [element] has been optimized under the 676 * Register that the function [element] has been optimized under the
662 * assumptions that the types [parameterType] will be used for calling it. 677 * assumptions that the types [parameterType] will be used for calling it.
663 * The passed [defaultValueTypes] holds the types of default values for 678 * The passed [defaultValueTypes] holds the types of default values for
664 * the optional parameters. If this assumption fail the function will be 679 * the optional parameters. If this assumption fail the function will be
665 * scheduled for recompilation. 680 * scheduled for recompilation.
681 *
682 * Invariant: [element] must be the declaration element.
666 */ 683 */
667 registerParameterTypesOptimization( 684 registerParameterTypesOptimization(
668 FunctionElement element, 685 FunctionElement element,
669 HTypeList parameterTypes, 686 HTypeList parameterTypes,
670 OptionalParameterTypes defaultValueTypes) { 687 OptionalParameterTypes defaultValueTypes) {
671 if (element.parameterCount(compiler) == 0) return; 688 if (element.parameterCount(compiler) == 0) return;
672 argumentTypes.registerOptimization( 689 argumentTypes.registerOptimization(
673 element, parameterTypes, defaultValueTypes); 690 element, parameterTypes, defaultValueTypes);
674 } 691 }
675 692
693 /**
694 * Invariant: [element] must be the declaration element.
695 */
676 void registerReturnType(FunctionElement element, HType returnType) { 696 void registerReturnType(FunctionElement element, HType returnType) {
697 assert(element.isDeclaration);
677 ReturnInfo info = returnInfo[element]; 698 ReturnInfo info = returnInfo[element];
678 if (info != null) { 699 if (info != null) {
679 info.update(returnType, scheduleForRecompilation); 700 info.update(returnType, scheduleForRecompilation);
680 } else { 701 } else {
681 returnInfo[element] = new ReturnInfo(returnType); 702 returnInfo[element] = new ReturnInfo(returnType);
682 } 703 }
683 } 704 }
684 705
685 /** 706 /**
686 * Retrieve the return type of the function [callee]. The type is optimistic 707 * Retrieve the return type of the function [callee]. The type is optimistic
687 * in the sense that is is based on the compilation of [callee]. If [callee] 708 * in the sense that is is based on the compilation of [callee]. If [callee]
688 * is recompiled the return type might change to someting broader. For that 709 * is recompiled the return type might change to someting broader. For that
689 * reason [caller] is registered for recompilation if this happens. If the 710 * reason [caller] is registered for recompilation if this happens. If the
690 * function [callee] has not yet been compiled the returned type is [null]. 711 * function [callee] has not yet been compiled the returned type is [null].
712 *
713 * Invariant: Both [caller] and [callee] must be the declaration elements.
691 */ 714 */
692 HType optimisticReturnTypesWithRecompilationOnTypeChange( 715 HType optimisticReturnTypesWithRecompilationOnTypeChange(
693 Element caller, FunctionElement callee) { 716 Element caller, FunctionElement callee) {
694 returnInfo.putIfAbsent(callee, () => new ReturnInfo.unknownType()); 717 returnInfo.putIfAbsent(callee, () => new ReturnInfo.unknownType());
695 ReturnInfo info = returnInfo[callee]; 718 ReturnInfo info = returnInfo[callee];
696 if (info.returnType != HType.UNKNOWN && caller != null) { 719 if (info.returnType != HType.UNKNOWN && caller != null) {
697 info.addCompiledFunction(caller); 720 info.addCompiledFunction(caller);
698 } 721 }
699 return info.returnType; 722 return info.returnType;
700 } 723 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 ? const SourceString('listSuperNativeTypeCheck') 762 ? const SourceString('listSuperNativeTypeCheck')
740 : const SourceString('listSuperTypeCheck'); 763 : const SourceString('listSuperTypeCheck');
741 } else { 764 } else {
742 return nativeCheck 765 return nativeCheck
743 ? const SourceString('callTypeCheck') 766 ? const SourceString('callTypeCheck')
744 : const SourceString('propertyTypeCheck'); 767 : const SourceString('propertyTypeCheck');
745 } 768 }
746 } 769 }
747 } 770 }
748 } 771 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698