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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart

Issue 15724021: Move array and string related HType from const to a field in the backend. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 ssa; 5 part of ssa;
6 6
7 /** 7 /**
8 * This phase simplifies interceptors in multiple ways: 8 * This phase simplifies interceptors in multiple ways:
9 * 9 *
10 * 1) If the interceptor is for an object whose type is known, it 10 * 1) If the interceptor is for an object whose type is known, it
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 if (input == graph.explicitReceiverParameter) { 84 if (input == graph.explicitReceiverParameter) {
85 // If `explicitReceiverParameter` is set it means the current method is an 85 // If `explicitReceiverParameter` is set it means the current method is an
86 // interceptor method, and `this` is the interceptor. The caller just did 86 // interceptor method, and `this` is the interceptor. The caller just did
87 // `getInterceptor(foo).currentMethod(foo)` to enter the current method. 87 // `getInterceptor(foo).currentMethod(foo)` to enter the current method.
88 return graph.thisInstruction; 88 return graph.thisInstruction;
89 } 89 }
90 90
91 HType type = input.instructionType; 91 HType type = input.instructionType;
92 ClassElement constantInterceptor; 92 ClassElement constantInterceptor;
93 JavaScriptBackend backend = compiler.backend; 93 JavaScriptBackend backend = compiler.backend;
94 if (type.isInteger()) { 94 if (type.canBeNull()) {
95 if (type.isNull()) {
96 constantInterceptor = backend.jsNullClass;
97 }
98 } else if (type.isInteger()) {
95 constantInterceptor = backend.jsIntClass; 99 constantInterceptor = backend.jsIntClass;
96 } else if (type.isDouble()) { 100 } else if (type.isDouble()) {
97 constantInterceptor = backend.jsDoubleClass; 101 constantInterceptor = backend.jsDoubleClass;
98 } else if (type.isBoolean()) { 102 } else if (type.isBoolean()) {
99 constantInterceptor = backend.jsBoolClass; 103 constantInterceptor = backend.jsBoolClass;
100 } else if (type.isString()) { 104 } else if (type.isString(compiler)) {
101 constantInterceptor = backend.jsStringClass; 105 constantInterceptor = backend.jsStringClass;
102 } else if (type.isArray(compiler)) { 106 } else if (type.isArray(compiler)) {
103 constantInterceptor = backend.jsArrayClass; 107 constantInterceptor = backend.jsArrayClass;
104 } else if (type.isNull()) {
105 constantInterceptor = backend.jsNullClass;
106 } else if (type.isNumber() 108 } else if (type.isNumber()
107 && !interceptedClasses.contains(backend.jsIntClass) 109 && !interceptedClasses.contains(backend.jsIntClass)
108 && !interceptedClasses.contains(backend.jsDoubleClass)) { 110 && !interceptedClasses.contains(backend.jsDoubleClass)) {
109 // If the method being intercepted is not defined in [int] or [double] we 111 // If the method being intercepted is not defined in [int] or [double] we
110 // can safely use the number interceptor. This is because none of the 112 // can safely use the number interceptor. This is because none of the
111 // [int] or [double] methods are called from a method defined on [num]. 113 // [int] or [double] methods are called from a method defined on [num].
112 constantInterceptor = backend.jsNumberClass; 114 constantInterceptor = backend.jsNumberClass;
113 } else { 115 } else {
114 // Try to find constant interceptor for a native class. If the receiver 116 // Try to find constant interceptor for a native class. If the receiver
115 // is constrained to a leaf native class, we can use the class's 117 // is constrained to a leaf native class, we can use the class's
116 // interceptor directly. 118 // interceptor directly.
117 119
118 // TODO(sra): Key DOM classes like Node, Element and Event are not leaf 120 // TODO(sra): Key DOM classes like Node, Element and Event are not leaf
119 // classes. When the receiver type is not a leaf class, we might still be 121 // classes. When the receiver type is not a leaf class, we might still be
120 // able to use the receiver class as a constant interceptor. It is 122 // able to use the receiver class as a constant interceptor. It is
121 // usually the case that methods defined on a non-leaf class don't test 123 // usually the case that methods defined on a non-leaf class don't test
122 // for a subclass or call methods defined on a subclass. Provided the 124 // for a subclass or call methods defined on a subclass. Provided the
123 // code is completely insensitive to the specific instance subclasses, we 125 // code is completely insensitive to the specific instance subclasses, we
124 // can use the non-leaf class directly. 126 // can use the non-leaf class directly.
125 127 ClassElement element = type.computeMask(compiler).singleClass(compiler);
126 if (!type.canBeNull()) { 128 if (element != null && element.isNative()) {
127 ClassElement element = type.computeMask(compiler).singleClass(compiler); 129 constantInterceptor = element;
128 if (element != null && element.isNative()) {
129 constantInterceptor = element;
130 }
131 } 130 }
132 } 131 }
133 132
134 if (constantInterceptor == null) return null; 133 if (constantInterceptor == null) return null;
135 if (constantInterceptor == work.element.getEnclosingClass()) { 134 if (constantInterceptor == work.element.getEnclosingClass()) {
136 return graph.thisInstruction; 135 return graph.thisInstruction;
137 } 136 }
138 137
139 Constant constant = new InterceptorConstant( 138 Constant constant = new InterceptorConstant(
140 constantInterceptor.computeType(compiler)); 139 constantInterceptor.computeType(compiler));
141 return graph.addConstant(constant); 140 return graph.addConstant(constant, compiler);
142 } 141 }
143 142
144 HInstruction findDominator(Iterable<HInstruction> instructions) { 143 HInstruction findDominator(Iterable<HInstruction> instructions) {
145 HInstruction result; 144 HInstruction result;
146 L1: for (HInstruction candidate in instructions) { 145 L1: for (HInstruction candidate in instructions) {
147 for (HInstruction current in instructions) { 146 for (HInstruction current in instructions) {
148 if (current != candidate && !candidate.dominates(current)) continue L1; 147 if (current != candidate && !candidate.dominates(current)) continue L1;
149 } 148 }
150 result = candidate; 149 result = candidate;
151 break; 150 break;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 // Try creating a one-shot interceptor. 221 // Try creating a one-shot interceptor.
223 if (node.usedBy.length != 1) return false; 222 if (node.usedBy.length != 1) return false;
224 if (node.usedBy[0] is !HInvokeDynamic) return false; 223 if (node.usedBy[0] is !HInvokeDynamic) return false;
225 224
226 HInvokeDynamic user = node.usedBy[0]; 225 HInvokeDynamic user = node.usedBy[0];
227 226
228 // If [node] was loop hoisted, we keep the interceptor. 227 // If [node] was loop hoisted, we keep the interceptor.
229 if (!user.hasSameLoopHeaderAs(node)) return false; 228 if (!user.hasSameLoopHeaderAs(node)) return false;
230 229
231 // Replace the user with a [HOneShotInterceptor]. 230 // Replace the user with a [HOneShotInterceptor].
232 HConstant nullConstant = graph.addConstantNull(constantSystem); 231 HConstant nullConstant = graph.addConstantNull(compiler);
233 List<HInstruction> inputs = new List<HInstruction>.from(user.inputs); 232 List<HInstruction> inputs = new List<HInstruction>.from(user.inputs);
234 inputs[0] = nullConstant; 233 inputs[0] = nullConstant;
235 HOneShotInterceptor interceptor = new HOneShotInterceptor( 234 HOneShotInterceptor interceptor = new HOneShotInterceptor(
236 user.selector, inputs, node.interceptedClasses); 235 user.selector, inputs, node.interceptedClasses);
237 interceptor.sourcePosition = user.sourcePosition; 236 interceptor.sourcePosition = user.sourcePosition;
238 interceptor.sourceElement = user.sourceElement; 237 interceptor.sourceElement = user.sourceElement;
239 interceptor.instructionType = user.instructionType; 238 interceptor.instructionType = user.instructionType;
240 239
241 HBasicBlock block = user.block; 240 HBasicBlock block = user.block;
242 block.addAfter(user, interceptor); 241 block.addAfter(user, interceptor);
(...skipping 30 matching lines...) Expand all
273 inputs[0] = constant; 272 inputs[0] = constant;
274 instruction = new HInvokeDynamicMethod(selector, inputs, true); 273 instruction = new HInvokeDynamicMethod(selector, inputs, true);
275 } 274 }
276 275
277 HBasicBlock block = node.block; 276 HBasicBlock block = node.block;
278 block.addAfter(node, instruction); 277 block.addAfter(node, instruction);
279 block.rewrite(node, instruction); 278 block.rewrite(node, instruction);
280 return true; 279 return true;
281 } 280 }
282 } 281 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698