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

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

Issue 11421056: Re-apply issue 11308169: GVN getInterceptor and use the interceptor constant when the type is known. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years 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 typedef void Recompile(Element element); 7 typedef void Recompile(Element element);
8 8
9 class ReturnInfo { 9 class ReturnInfo {
10 HType returnType; 10 HType returnType;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 result.types[i] = types[node.inputs[i + 1]]; 94 result.types[i] = types[node.inputs[i + 1]];
95 } 95 }
96 return result; 96 return result;
97 } 97 }
98 98
99 factory HTypeList.fromDynamicInvocation(HInvokeDynamic node, 99 factory HTypeList.fromDynamicInvocation(HInvokeDynamic node,
100 Selector selector, 100 Selector selector,
101 HTypeMap types) { 101 HTypeMap types) {
102 HTypeList result; 102 HTypeList result;
103 int argumentsCount = node.inputs.length - 1; 103 int argumentsCount = node.inputs.length - 1;
104 int startInvokeIndex = HInvoke.ARGUMENTS_OFFSET;
105
106 if (node.isInterceptorCall) {
107 argumentsCount--;
108 startInvokeIndex++;
109 }
110
104 if (selector.namedArgumentCount > 0) { 111 if (selector.namedArgumentCount > 0) {
105 result = 112 result =
106 new HTypeList.withNamedArguments( 113 new HTypeList.withNamedArguments(
107 argumentsCount, selector.namedArguments); 114 argumentsCount, selector.namedArguments);
108 } else { 115 } else {
109 result = new HTypeList(argumentsCount); 116 result = new HTypeList(argumentsCount);
110 } 117 }
118
111 for (int i = 0; i < result.types.length; i++) { 119 for (int i = 0; i < result.types.length; i++) {
112 result.types[i] = types[node.inputs[i + 1]]; 120 result.types[i] = types[node.inputs[i + startInvokeIndex]];
113 } 121 }
114 return result; 122 return result;
115 } 123 }
116 124
117 static const HTypeList ALL_UNKNOWN = const HTypeList.withAllUnknown(); 125 static const HTypeList ALL_UNKNOWN = const HTypeList.withAllUnknown();
118 126
119 bool get allUnknown => types == null; 127 bool get allUnknown => types == null;
120 bool get hasNamedArguments => namedArguments != null; 128 bool get hasNamedArguments => namedArguments != null;
121 int get length => types.length; 129 int get length => types.length;
122 HType operator[](int index) => types[index]; 130 HType operator[](int index) => types[index];
(...skipping 12 matching lines...) Expand all
135 result.types.setRange(0, i, this.types); 143 result.types.setRange(0, i, this.types);
136 } 144 }
137 if (result != this) { 145 if (result != this) {
138 result.types[i] = newType; 146 result.types[i] = newType;
139 } 147 }
140 if (result[i] != HType.UNKNOWN) onlyUnknown = false; 148 if (result[i] != HType.UNKNOWN) onlyUnknown = false;
141 } 149 }
142 return onlyUnknown ? HTypeList.ALL_UNKNOWN : result; 150 return onlyUnknown ? HTypeList.ALL_UNKNOWN : result;
143 } 151 }
144 152
145 /**
146 * Create the union of this [HTypeList] object with the types used by
147 * the [node]. If the union results in exactly the same types the receiver
148 * is returned. Otherwise a different [HTypeList] object is returned
149 * with the type union information.
150 */
151 HTypeList unionWithInvoke(HInvoke node, HTypeMap types, Compiler compiler) {
152 // Union an all unknown list with something stays all unknown.
153 if (allUnknown) return this;
154
155 bool allUnknown = true;
156 if (length != node.inputs.length - 1) {
157 return HTypeList.ALL_UNKNOWN;
158 }
159
160 bool onlyUnknown = true;
161 HTypeList result = this;
162 for (int i = 0; i < length; i++) {
163 HType newType = this[i].union(types[node.inputs[i + 1]], compiler);
164 if (result == this && newType != this[i]) {
165 // Create a new argument types object with the matching types copied.
166 result = new HTypeList(length);
167 result.types.setRange(0, i, this.types);
168 }
169 if (result != this) {
170 result.types[i] = newType;
171 }
172 if (result[i] != HType.UNKNOWN) onlyUnknown = false;
173 }
174 return onlyUnknown ? HTypeList.ALL_UNKNOWN : result;
175 }
176
177 HTypeList unionWithOptionalParameters( 153 HTypeList unionWithOptionalParameters(
178 Selector selector, 154 Selector selector,
179 FunctionSignature signature, 155 FunctionSignature signature,
180 OptionalParameterTypes defaultValueTypes) { 156 OptionalParameterTypes defaultValueTypes) {
181 assert(allUnknown || selector.argumentCount == this.length); 157 assert(allUnknown || selector.argumentCount == this.length);
182 // Create a new HTypeList for holding types for all parameters. 158 // Create a new HTypeList for holding types for all parameters.
183 HTypeList result = new HTypeList(signature.parameterCount); 159 HTypeList result = new HTypeList(signature.parameterCount);
184 160
185 // First fill in the type of the positional arguments. 161 // First fill in the type of the positional arguments.
186 int nextTypeIndex = -1; 162 int nextTypeIndex = -1;
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 optimizedStaticFunctions = new Set<Element>(), 442 optimizedStaticFunctions = new Set<Element>(),
467 selectorTypeMap = new SelectorMap<HTypeList>(backend.compiler), 443 selectorTypeMap = new SelectorMap<HTypeList>(backend.compiler),
468 optimizedFunctions = new FunctionSet(backend.compiler), 444 optimizedFunctions = new FunctionSet(backend.compiler),
469 optimizedTypes = new Map<Element, HTypeList>(), 445 optimizedTypes = new Map<Element, HTypeList>(),
470 optimizedDefaultValueTypes = 446 optimizedDefaultValueTypes =
471 new Map<Element, OptionalParameterTypes>(), 447 new Map<Element, OptionalParameterTypes>(),
472 this.backend = backend; 448 this.backend = backend;
473 449
474 Compiler get compiler => backend.compiler; 450 Compiler get compiler => backend.compiler;
475 451
452 bool updateTypes(HTypeList oldTypes, HTypeList newTypes, var key, var map) {
453 if (oldTypes.allUnknown) return false;
454 newTypes = oldTypes.union(newTypes, backend.compiler);
455 if (identical(newTypes, oldTypes)) return false;
456 map[key] = newTypes;
457 return true;
458 }
459
476 void registerStaticInvocation(HInvokeStatic node, HTypeMap types) { 460 void registerStaticInvocation(HInvokeStatic node, HTypeMap types) {
477 Element element = node.element; 461 Element element = node.element;
478 assert(invariant(node, element.isDeclaration)); 462 assert(invariant(node, element.isDeclaration));
479 HTypeList oldTypes = staticTypeMap[element]; 463 HTypeList oldTypes = staticTypeMap[element];
464 HTypeList newTypes = new HTypeList.fromStaticInvocation(node, types);
480 if (oldTypes == null) { 465 if (oldTypes == null) {
481 staticTypeMap[element] = new HTypeList.fromStaticInvocation(node, types);
482 } else {
483 if (oldTypes.allUnknown) return;
484 HTypeList newTypes =
485 oldTypes.unionWithInvoke(node, types, backend.compiler);
486 if (identical(newTypes, oldTypes)) return;
487 staticTypeMap[element] = newTypes; 466 staticTypeMap[element] = newTypes;
467 } else if (updateTypes(oldTypes, newTypes, element, staticTypeMap)) {
488 if (optimizedStaticFunctions.contains(element)) { 468 if (optimizedStaticFunctions.contains(element)) {
489 backend.scheduleForRecompilation(element); 469 backend.scheduleForRecompilation(element);
490 } 470 }
491 } 471 }
492 } 472 }
493 473
494 void registerNonCallStaticUse(HStatic node) { 474 void registerNonCallStaticUse(HStatic node) {
495 // When a static is used for anything else than a call target we cannot 475 // When a static is used for anything else than a call target we cannot
496 // infer anything about its parameter types. 476 // infer anything about its parameter types.
497 Element element = node.element; 477 Element element = node.element;
(...skipping 19 matching lines...) Expand all
517 resolverWorld.hasInvokedGetter(element, compiler))) { 497 resolverWorld.hasInvokedGetter(element, compiler))) {
518 return; 498 return;
519 } 499 }
520 500
521 HTypeList providedTypes = 501 HTypeList providedTypes =
522 new HTypeList.fromDynamicInvocation(node, selector, types); 502 new HTypeList.fromDynamicInvocation(node, selector, types);
523 if (!selectorTypeMap.containsKey(selector)) { 503 if (!selectorTypeMap.containsKey(selector)) {
524 selectorTypeMap[selector] = providedTypes; 504 selectorTypeMap[selector] = providedTypes;
525 } else { 505 } else {
526 HTypeList oldTypes = selectorTypeMap[selector]; 506 HTypeList oldTypes = selectorTypeMap[selector];
527 HTypeList newTypes = 507 updateTypes(oldTypes, providedTypes, selector, selectorTypeMap);
528 oldTypes.unionWithInvoke(node, types, backend.compiler);
529 if (identical(newTypes, oldTypes)) return;
530 selectorTypeMap[selector] = newTypes;
531 } 508 }
532 509
533 // If we're not compiling, we don't have to do anything. 510 // If we're not compiling, we don't have to do anything.
534 if (compiler.phase != Compiler.PHASE_COMPILING) return; 511 if (compiler.phase != Compiler.PHASE_COMPILING) return;
535 512
536 // Run through all optimized functions and figure out if they need 513 // Run through all optimized functions and figure out if they need
537 // to be recompiled because of this new invocation. 514 // to be recompiled because of this new invocation.
538 optimizedFunctions.filterBySelector(selector).forEach((Element element) { 515 optimizedFunctions.filterBySelector(selector).forEach((Element element) {
539 // TODO(kasperl): Maybe check if the element is already marked for 516 // TODO(kasperl): Maybe check if the element is already marked for
540 // recompilation? Could be pretty cheap compared to computing 517 // recompilation? Could be pretty cheap compared to computing
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 ClassElement jsNumberClass; 628 ClassElement jsNumberClass;
652 ClassElement jsIntClass; 629 ClassElement jsIntClass;
653 ClassElement jsDoubleClass; 630 ClassElement jsDoubleClass;
654 ClassElement jsFunctionClass; 631 ClassElement jsFunctionClass;
655 ClassElement jsNullClass; 632 ClassElement jsNullClass;
656 ClassElement jsBoolClass; 633 ClassElement jsBoolClass;
657 ClassElement objectInterceptorClass; 634 ClassElement objectInterceptorClass;
658 Element jsArrayLength; 635 Element jsArrayLength;
659 Element jsStringLength; 636 Element jsStringLength;
660 Element getInterceptorMethod; 637 Element getInterceptorMethod;
638 Element arrayInterceptor;
639 Element boolInterceptor;
640 Element doubleInterceptor;
641 Element functionInterceptor;
642 Element intInterceptor;
643 Element nullInterceptor;
644 Element numberInterceptor;
645 Element stringInterceptor;
661 bool _interceptorsAreInitialized = false; 646 bool _interceptorsAreInitialized = false;
662 647
663 final Namer namer; 648 final Namer namer;
664 649
665 /** 650 /**
666 * Interface used to determine if an object has the JavaScript 651 * Interface used to determine if an object has the JavaScript
667 * indexing behavior. The interface is only visible to specific 652 * indexing behavior. The interface is only visible to specific
668 * libraries. 653 * libraries.
669 */ 654 */
670 ClassElement jsIndexingBehaviorInterface; 655 ClassElement jsIndexingBehaviorInterface;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 jsFunctionClass = 766 jsFunctionClass =
782 compiler.findInterceptor(const SourceString('JSFunction')); 767 compiler.findInterceptor(const SourceString('JSFunction'));
783 jsBoolClass = 768 jsBoolClass =
784 compiler.findInterceptor(const SourceString('JSBool')); 769 compiler.findInterceptor(const SourceString('JSBool'));
785 jsArrayClass.ensureResolved(compiler); 770 jsArrayClass.ensureResolved(compiler);
786 jsArrayLength = 771 jsArrayLength =
787 jsArrayClass.lookupLocalMember(const SourceString('length')); 772 jsArrayClass.lookupLocalMember(const SourceString('length'));
788 jsStringClass.ensureResolved(compiler); 773 jsStringClass.ensureResolved(compiler);
789 jsStringLength = 774 jsStringLength =
790 jsStringClass.lookupLocalMember(const SourceString('length')); 775 jsStringClass.lookupLocalMember(const SourceString('length'));
776
777 arrayInterceptor =
778 compiler.findInterceptor(const SourceString('arrayInterceptor'));
779 boolInterceptor =
780 compiler.findInterceptor(const SourceString('boolInterceptor'));
781 doubleInterceptor =
782 compiler.findInterceptor(const SourceString('doubleInterceptor'));
783 functionInterceptor =
784 compiler.findInterceptor(const SourceString('functionInterceptor'));
785 intInterceptor =
786 compiler.findInterceptor(const SourceString('intInterceptor'));
787 nullInterceptor =
788 compiler.findInterceptor(const SourceString('nullInterceptor'));
789 stringInterceptor =
790 compiler.findInterceptor(const SourceString('stringInterceptor'));
791 numberInterceptor =
792 compiler.findInterceptor(const SourceString('numberInterceptor'));
791 } 793 }
792 794
793 void addInterceptors(ClassElement cls) { 795 void addInterceptors(ClassElement cls) {
794 cls.ensureResolved(compiler); 796 cls.ensureResolved(compiler);
795 cls.forEachMember((ClassElement classElement, Element member) { 797 cls.forEachMember((ClassElement classElement, Element member) {
796 Set<Element> set = interceptedElements.putIfAbsent( 798 Set<Element> set = interceptedElements.putIfAbsent(
797 member.name, () => new Set<Element>()); 799 member.name, () => new Set<Element>());
798 set.add(member); 800 set.add(member);
799 }, 801 },
800 includeSuperMembers: true); 802 includeSuperMembers: true);
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
1100 print("Inferred return types:"); 1102 print("Inferred return types:");
1101 print("----------------------"); 1103 print("----------------------");
1102 dumpReturnTypes(); 1104 dumpReturnTypes();
1103 print(""); 1105 print("");
1104 print("Inferred field types:"); 1106 print("Inferred field types:");
1105 print("------------------------"); 1107 print("------------------------");
1106 fieldTypes.dump(); 1108 fieldTypes.dump();
1107 print(""); 1109 print("");
1108 } 1110 }
1109 } 1111 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698