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

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, 1 month 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 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
476 void registerStaticInvocation(HInvokeStatic node, HTypeMap types) { 452 void registerStaticInvocation(HInvokeStatic node, HTypeMap types) {
477 Element element = node.element; 453 Element element = node.element;
478 assert(invariant(node, element.isDeclaration)); 454 assert(invariant(node, element.isDeclaration));
479 HTypeList oldTypes = staticTypeMap[element]; 455 HTypeList oldTypes = staticTypeMap[element];
456 HTypeList newTypes = new HTypeList.fromStaticInvocation(node, types);
480 if (oldTypes == null) { 457 if (oldTypes == null) {
481 staticTypeMap[element] = new HTypeList.fromStaticInvocation(node, types); 458 staticTypeMap[element] = newTypes;
482 } else { 459 } else {
483 if (oldTypes.allUnknown) return; 460 if (oldTypes.allUnknown) return;
484 HTypeList newTypes = 461 newTypes = oldTypes.union(newTypes, backend.compiler);
485 oldTypes.unionWithInvoke(node, types, backend.compiler);
486 if (identical(newTypes, oldTypes)) return; 462 if (identical(newTypes, oldTypes)) return;
487 staticTypeMap[element] = newTypes; 463 staticTypeMap[element] = newTypes;
ahe 2012/11/27 10:19:11 Seems like the above lines should be a helper meth
ngeoffray 2012/11/27 10:41:04 Good refactoring suggestion. Done.
488 if (optimizedStaticFunctions.contains(element)) { 464 if (optimizedStaticFunctions.contains(element)) {
489 backend.scheduleForRecompilation(element); 465 backend.scheduleForRecompilation(element);
490 } 466 }
491 } 467 }
492 } 468 }
493 469
494 void registerNonCallStaticUse(HStatic node) { 470 void registerNonCallStaticUse(HStatic node) {
495 // When a static is used for anything else than a call target we cannot 471 // When a static is used for anything else than a call target we cannot
496 // infer anything about its parameter types. 472 // infer anything about its parameter types.
497 Element element = node.element; 473 Element element = node.element;
(...skipping 19 matching lines...) Expand all
517 resolverWorld.hasInvokedGetter(element, compiler))) { 493 resolverWorld.hasInvokedGetter(element, compiler))) {
518 return; 494 return;
519 } 495 }
520 496
521 HTypeList providedTypes = 497 HTypeList providedTypes =
522 new HTypeList.fromDynamicInvocation(node, selector, types); 498 new HTypeList.fromDynamicInvocation(node, selector, types);
523 if (!selectorTypeMap.containsKey(selector)) { 499 if (!selectorTypeMap.containsKey(selector)) {
524 selectorTypeMap[selector] = providedTypes; 500 selectorTypeMap[selector] = providedTypes;
525 } else { 501 } else {
526 HTypeList oldTypes = selectorTypeMap[selector]; 502 HTypeList oldTypes = selectorTypeMap[selector];
527 HTypeList newTypes = 503 HTypeList newTypes = oldTypes.union(providedTypes, backend.compiler);
528 oldTypes.unionWithInvoke(node, types, backend.compiler);
529 if (identical(newTypes, oldTypes)) return; 504 if (identical(newTypes, oldTypes)) return;
530 selectorTypeMap[selector] = newTypes; 505 selectorTypeMap[selector] = newTypes;
ahe 2012/11/27 10:19:11 This method could be reused here.
ahe 2012/11/27 10:19:57 By "this method", I probably mean "that method", a
ngeoffray 2012/11/27 10:41:04 Done.
531 } 506 }
532 507
533 // If we're not compiling, we don't have to do anything. 508 // If we're not compiling, we don't have to do anything.
534 if (compiler.phase != Compiler.PHASE_COMPILING) return; 509 if (compiler.phase != Compiler.PHASE_COMPILING) return;
535 510
536 // Run through all optimized functions and figure out if they need 511 // Run through all optimized functions and figure out if they need
537 // to be recompiled because of this new invocation. 512 // to be recompiled because of this new invocation.
538 optimizedFunctions.filterBySelector(selector).forEach((Element element) { 513 optimizedFunctions.filterBySelector(selector).forEach((Element element) {
539 // TODO(kasperl): Maybe check if the element is already marked for 514 // TODO(kasperl): Maybe check if the element is already marked for
540 // recompilation? Could be pretty cheap compared to computing 515 // recompilation? Could be pretty cheap compared to computing
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 ClassElement jsNumberClass; 626 ClassElement jsNumberClass;
652 ClassElement jsIntClass; 627 ClassElement jsIntClass;
653 ClassElement jsDoubleClass; 628 ClassElement jsDoubleClass;
654 ClassElement jsFunctionClass; 629 ClassElement jsFunctionClass;
655 ClassElement jsNullClass; 630 ClassElement jsNullClass;
656 ClassElement jsBoolClass; 631 ClassElement jsBoolClass;
657 ClassElement objectInterceptorClass; 632 ClassElement objectInterceptorClass;
658 Element jsArrayLength; 633 Element jsArrayLength;
659 Element jsStringLength; 634 Element jsStringLength;
660 Element getInterceptorMethod; 635 Element getInterceptorMethod;
636 Element arrayInterceptor;
637 Element boolInterceptor;
638 Element doubleInterceptor;
639 Element functionInterceptor;
640 Element intInterceptor;
641 Element nullInterceptor;
642 Element numberInterceptor;
643 Element stringInterceptor;
661 bool _interceptorsAreInitialized = false; 644 bool _interceptorsAreInitialized = false;
662 645
663 final Namer namer; 646 final Namer namer;
664 647
665 /** 648 /**
666 * Interface used to determine if an object has the JavaScript 649 * Interface used to determine if an object has the JavaScript
667 * indexing behavior. The interface is only visible to specific 650 * indexing behavior. The interface is only visible to specific
668 * libraries. 651 * libraries.
669 */ 652 */
670 ClassElement jsIndexingBehaviorInterface; 653 ClassElement jsIndexingBehaviorInterface;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 jsFunctionClass = 764 jsFunctionClass =
782 compiler.findInterceptor(const SourceString('JSFunction')); 765 compiler.findInterceptor(const SourceString('JSFunction'));
783 jsBoolClass = 766 jsBoolClass =
784 compiler.findInterceptor(const SourceString('JSBool')); 767 compiler.findInterceptor(const SourceString('JSBool'));
785 jsArrayClass.ensureResolved(compiler); 768 jsArrayClass.ensureResolved(compiler);
786 jsArrayLength = 769 jsArrayLength =
787 jsArrayClass.lookupLocalMember(const SourceString('length')); 770 jsArrayClass.lookupLocalMember(const SourceString('length'));
788 jsStringClass.ensureResolved(compiler); 771 jsStringClass.ensureResolved(compiler);
789 jsStringLength = 772 jsStringLength =
790 jsStringClass.lookupLocalMember(const SourceString('length')); 773 jsStringClass.lookupLocalMember(const SourceString('length'));
774
775 arrayInterceptor =
776 compiler.findInterceptor(const SourceString('arrayInterceptor'));
777 boolInterceptor =
778 compiler.findInterceptor(const SourceString('boolInterceptor'));
779 doubleInterceptor =
780 compiler.findInterceptor(const SourceString('doubleInterceptor'));
781 functionInterceptor =
782 compiler.findInterceptor(const SourceString('functionInterceptor'));
783 intInterceptor =
784 compiler.findInterceptor(const SourceString('intInterceptor'));
785 nullInterceptor =
786 compiler.findInterceptor(const SourceString('nullInterceptor'));
787 stringInterceptor =
788 compiler.findInterceptor(const SourceString('stringInterceptor'));
789 numberInterceptor =
790 compiler.findInterceptor(const SourceString('numberInterceptor'));
791 } 791 }
792 792
793 void addInterceptors(ClassElement cls) { 793 void addInterceptors(ClassElement cls) {
794 cls.ensureResolved(compiler); 794 cls.ensureResolved(compiler);
795 cls.forEachMember((ClassElement classElement, Element member) { 795 cls.forEachMember((ClassElement classElement, Element member) {
796 Set<Element> set = interceptedElements.putIfAbsent( 796 Set<Element> set = interceptedElements.putIfAbsent(
797 member.name, () => new Set<Element>()); 797 member.name, () => new Set<Element>());
798 set.add(member); 798 set.add(member);
799 }, 799 },
800 includeSuperMembers: true); 800 includeSuperMembers: true);
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
1100 print("Inferred return types:"); 1100 print("Inferred return types:");
1101 print("----------------------"); 1101 print("----------------------");
1102 dumpReturnTypes(); 1102 dumpReturnTypes();
1103 print(""); 1103 print("");
1104 print("Inferred field types:"); 1104 print("Inferred field types:");
1105 print("------------------------"); 1105 print("------------------------");
1106 fieldTypes.dump(); 1106 fieldTypes.dump();
1107 print(""); 1107 print("");
1108 } 1108 }
1109 } 1109 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698