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

Side by Side Diff: pkg/compiler/lib/src/ssa/interceptor_simplifier.dart

Issue 2813093002: Remove BackendClasses and JavaScriptBackendClasses. (Closed)
Patch Set: . Created 3 years, 8 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
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 import '../common_elements.dart' show CommonElements; 5 import '../common_elements.dart' show CommonElements;
6 import '../common/backend_api.dart' show BackendClasses;
7 import '../constants/constant_system.dart'; 6 import '../constants/constant_system.dart';
8 import '../constants/values.dart'; 7 import '../constants/values.dart';
9 import '../elements/entities.dart'; 8 import '../elements/entities.dart';
10 import '../js_backend/interceptor_data.dart'; 9 import '../js_backend/interceptor_data.dart';
11 import '../types/types.dart'; 10 import '../types/types.dart';
12 import '../universe/selector.dart' show Selector; 11 import '../universe/selector.dart' show Selector;
13 import '../world.dart' show ClosedWorld; 12 import '../world.dart' show ClosedWorld;
14 import 'nodes.dart'; 13 import 'nodes.dart';
15 import 'optimize.dart'; 14 import 'optimize.dart';
16 15
(...skipping 22 matching lines...) Expand all
39 final String name = "SsaSimplifyInterceptors"; 38 final String name = "SsaSimplifyInterceptors";
40 final ClosedWorld closedWorld; 39 final ClosedWorld closedWorld;
41 final InterceptorData interceptorData; 40 final InterceptorData interceptorData;
42 final CommonElements _commonElements; 41 final CommonElements _commonElements;
43 final ClassEntity enclosingClass; 42 final ClassEntity enclosingClass;
44 HGraph graph; 43 HGraph graph;
45 44
46 SsaSimplifyInterceptors(this.closedWorld, this._commonElements, 45 SsaSimplifyInterceptors(this.closedWorld, this._commonElements,
47 this.interceptorData, this.enclosingClass); 46 this.interceptorData, this.enclosingClass);
48 47
49 BackendClasses get backendClasses => closedWorld.backendClasses;
50
51 ConstantSystem get constantSystem => closedWorld.constantSystem; 48 ConstantSystem get constantSystem => closedWorld.constantSystem;
52 49
53 void visitGraph(HGraph graph) { 50 void visitGraph(HGraph graph) {
54 this.graph = graph; 51 this.graph = graph;
55 visitDominatorTree(graph); 52 visitDominatorTree(graph);
56 } 53 }
57 54
58 void visitBasicBlock(HBasicBlock node) { 55 void visitBasicBlock(HBasicBlock node) {
59 currentBlock = node; 56 currentBlock = node;
60 57
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 return false; 91 return false;
95 } 92 }
96 93
97 bool canUseSelfForInterceptor( 94 bool canUseSelfForInterceptor(
98 HInstruction receiver, Set<ClassEntity> interceptedClasses) { 95 HInstruction receiver, Set<ClassEntity> interceptedClasses) {
99 if (receiver.canBePrimitive(closedWorld)) { 96 if (receiver.canBePrimitive(closedWorld)) {
100 // Primitives always need interceptors. 97 // Primitives always need interceptors.
101 return false; 98 return false;
102 } 99 }
103 if (receiver.canBeNull() && 100 if (receiver.canBeNull() &&
104 interceptedClasses.contains(backendClasses.nullClass)) { 101 interceptedClasses.contains(_commonElements.jsNullClass)) {
105 // Need the JSNull interceptor. 102 // Need the JSNull interceptor.
106 return false; 103 return false;
107 } 104 }
108 105
109 // All intercepted classes extend `Interceptor`, so if the receiver can't be 106 // All intercepted classes extend `Interceptor`, so if the receiver can't be
110 // a class extending `Interceptor` then it can be called directly. 107 // a class extending `Interceptor` then it can be called directly.
111 return new TypeMask.nonNullSubclass( 108 return new TypeMask.nonNullSubclass(
112 _commonElements.jsInterceptorClass, closedWorld) 109 _commonElements.jsInterceptorClass, closedWorld)
113 .isDisjoint(receiver.instructionType, closedWorld); 110 .isDisjoint(receiver.instructionType, closedWorld);
114 } 111 }
(...skipping 20 matching lines...) Expand all
135 } 132 }
136 133
137 ConstantValue constant = new InterceptorConstantValue(constantInterceptor); 134 ConstantValue constant = new InterceptorConstantValue(constantInterceptor);
138 return graph.addConstant(constant, closedWorld); 135 return graph.addConstant(constant, closedWorld);
139 } 136 }
140 137
141 ClassEntity tryComputeConstantInterceptorFromType( 138 ClassEntity tryComputeConstantInterceptorFromType(
142 TypeMask type, Set<ClassEntity> interceptedClasses) { 139 TypeMask type, Set<ClassEntity> interceptedClasses) {
143 if (type.isNullable) { 140 if (type.isNullable) {
144 if (type.isNull) { 141 if (type.isNull) {
145 return backendClasses.nullClass; 142 return _commonElements.jsNullClass;
146 } 143 }
147 } else if (type.containsOnlyInt(closedWorld)) { 144 } else if (type.containsOnlyInt(closedWorld)) {
148 return backendClasses.intClass; 145 return _commonElements.jsIntClass;
149 } else if (type.containsOnlyDouble(closedWorld)) { 146 } else if (type.containsOnlyDouble(closedWorld)) {
150 return backendClasses.doubleClass; 147 return _commonElements.jsDoubleClass;
151 } else if (type.containsOnlyBool(closedWorld)) { 148 } else if (type.containsOnlyBool(closedWorld)) {
152 return backendClasses.boolClass; 149 return _commonElements.jsBoolClass;
153 } else if (type.containsOnlyString(closedWorld)) { 150 } else if (type.containsOnlyString(closedWorld)) {
154 return backendClasses.stringClass; 151 return _commonElements.jsStringClass;
155 } else if (type.satisfies(backendClasses.listClass, closedWorld)) { 152 } else if (type.satisfies(_commonElements.jsArrayClass, closedWorld)) {
156 return backendClasses.listClass; 153 return _commonElements.jsArrayClass;
157 } else if (type.containsOnlyNum(closedWorld) && 154 } else if (type.containsOnlyNum(closedWorld) &&
158 !interceptedClasses.contains(backendClasses.intClass) && 155 !interceptedClasses.contains(_commonElements.jsIntClass) &&
159 !interceptedClasses.contains(backendClasses.doubleClass)) { 156 !interceptedClasses.contains(_commonElements.jsDoubleClass)) {
160 // If the method being intercepted is not defined in [int] or [double] we 157 // If the method being intercepted is not defined in [int] or [double] we
161 // can safely use the number interceptor. This is because none of the 158 // can safely use the number interceptor. This is because none of the
162 // [int] or [double] methods are called from a method defined on [num]. 159 // [int] or [double] methods are called from a method defined on [num].
163 return backendClasses.numClass; 160 return _commonElements.jsNumberClass;
164 } else { 161 } else {
165 // Try to find constant interceptor for a native class. If the receiver 162 // Try to find constant interceptor for a native class. If the receiver
166 // is constrained to a leaf native class, we can use the class's 163 // is constrained to a leaf native class, we can use the class's
167 // interceptor directly. 164 // interceptor directly.
168 165
169 // TODO(sra): Key DOM classes like Node, Element and Event are not leaf 166 // TODO(sra): Key DOM classes like Node, Element and Event are not leaf
170 // classes. When the receiver type is not a leaf class, we might still be 167 // classes. When the receiver type is not a leaf class, we might still be
171 // able to use the receiver class as a constant interceptor. It is 168 // able to use the receiver class as a constant interceptor. It is
172 // usually the case that methods defined on a non-leaf class don't test 169 // usually the case that methods defined on a non-leaf class don't test
173 // for a subclass or call methods defined on a subclass. Provided the 170 // for a subclass or call methods defined on a subclass. Provided the
174 // code is completely insensitive to the specific instance subclasses, we 171 // code is completely insensitive to the specific instance subclasses, we
175 // can use the non-leaf class directly. 172 // can use the non-leaf class directly.
176 ClassEntity element = type.singleClass(closedWorld); 173 ClassEntity element = type.singleClass(closedWorld);
177 if (element != null && backendClasses.isNativeClass(element)) { 174 if (element != null && closedWorld.nativeData.isNativeClass(element)) {
178 return element; 175 return element;
179 } 176 }
180 } 177 }
181 178
182 return null; 179 return null;
183 } 180 }
184 181
185 HInstruction findDominator(Iterable<HInstruction> instructions) { 182 HInstruction findDominator(Iterable<HInstruction> instructions) {
186 HInstruction result; 183 HInstruction result;
187 L1: 184 L1:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 // selector of that instruction. 219 // selector of that instruction.
223 if (dominator is HInvokeDynamic && 220 if (dominator is HInvokeDynamic &&
224 dominator.isCallOnInterceptor(closedWorld) && 221 dominator.isCallOnInterceptor(closedWorld) &&
225 node == dominator.receiver && 222 node == dominator.receiver &&
226 useCount(dominator, node) == 1) { 223 useCount(dominator, node) == 1) {
227 interceptedClasses = 224 interceptedClasses =
228 interceptorData.getInterceptedClassesOn(dominator.selector.name); 225 interceptorData.getInterceptedClassesOn(dominator.selector.name);
229 226
230 // If we found that we need number, we must still go through all 227 // If we found that we need number, we must still go through all
231 // uses to check if they require int, or double. 228 // uses to check if they require int, or double.
232 if (interceptedClasses.contains(backendClasses.numClass) && 229 if (interceptedClasses.contains(_commonElements.jsNumberClass) &&
233 !(interceptedClasses.contains(backendClasses.doubleClass) || 230 !(interceptedClasses.contains(_commonElements.jsDoubleClass) ||
234 interceptedClasses.contains(backendClasses.intClass))) { 231 interceptedClasses.contains(_commonElements.jsIntClass))) {
235 Set<ClassEntity> required; 232 Set<ClassEntity> required;
236 for (HInstruction user in node.usedBy) { 233 for (HInstruction user in node.usedBy) {
237 if (user is! HInvoke) continue; 234 if (user is! HInvoke) continue;
238 Set<ClassEntity> intercepted = 235 Set<ClassEntity> intercepted =
239 interceptorData.getInterceptedClassesOn(user.selector.name); 236 interceptorData.getInterceptedClassesOn(user.selector.name);
240 if (intercepted.contains(backendClasses.intClass)) { 237 if (intercepted.contains(_commonElements.jsIntClass)) {
241 // TODO(johnniwinther): Use type argument when all uses of 238 // TODO(johnniwinther): Use type argument when all uses of
242 // intercepted classes expect entities instead of elements. 239 // intercepted classes expect entities instead of elements.
243 required ??= new Set/*<ClassEntity>*/(); 240 required ??= new Set/*<ClassEntity>*/();
244 required.add(backendClasses.intClass); 241 required.add(_commonElements.jsIntClass);
245 } 242 }
246 if (intercepted.contains(backendClasses.doubleClass)) { 243 if (intercepted.contains(_commonElements.jsDoubleClass)) {
247 // TODO(johnniwinther): Use type argument when all uses of 244 // TODO(johnniwinther): Use type argument when all uses of
248 // intercepted classes expect entities instead of elements. 245 // intercepted classes expect entities instead of elements.
249 required ??= new Set/*<ClassEntity>*/(); 246 required ??= new Set/*<ClassEntity>*/();
250 required.add(backendClasses.doubleClass); 247 required.add(_commonElements.jsDoubleClass);
251 } 248 }
252 } 249 }
253 // Don't modify the result of [interceptorData.getInterceptedClassesOn]. 250 // Don't modify the result of [interceptorData.getInterceptedClassesOn].
254 if (required != null) { 251 if (required != null) {
255 interceptedClasses = interceptedClasses.union(required); 252 interceptedClasses = interceptedClasses.union(required);
256 } 253 }
257 } 254 }
258 } else { 255 } else {
259 // TODO(johnniwinther): Use type argument when all uses of intercepted 256 // TODO(johnniwinther): Use type argument when all uses of intercepted
260 // classes expect entities instead of elements. 257 // classes expect entities instead of elements.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 // If it is a conditional constant interceptor and was not strengthened to a 305 // If it is a conditional constant interceptor and was not strengthened to a
309 // constant interceptor then there is nothing more we can do. 306 // constant interceptor then there is nothing more we can do.
310 if (node.isConditionalConstantInterceptor) return false; 307 if (node.isConditionalConstantInterceptor) return false;
311 308
312 // Do we have an 'almost constant' interceptor? The receiver could be 309 // Do we have an 'almost constant' interceptor? The receiver could be
313 // `null` but not any other JavaScript falsy value, `null` values cause 310 // `null` but not any other JavaScript falsy value, `null` values cause
314 // `NoSuchMethodError`s, and if the receiver was not null we would have a 311 // `NoSuchMethodError`s, and if the receiver was not null we would have a
315 // constant interceptor `C`. Then we can use `(receiver && C)` for the 312 // constant interceptor `C`. Then we can use `(receiver && C)` for the
316 // interceptor. 313 // interceptor.
317 if (receiver.canBeNull()) { 314 if (receiver.canBeNull()) {
318 if (!interceptedClasses.contains(backendClasses.nullClass)) { 315 if (!interceptedClasses.contains(_commonElements.jsNullClass)) {
319 // Can use `(receiver && C)` only if receiver is either null or truthy. 316 // Can use `(receiver && C)` only if receiver is either null or truthy.
320 if (!(receiver.canBePrimitiveNumber(closedWorld) || 317 if (!(receiver.canBePrimitiveNumber(closedWorld) ||
321 receiver.canBePrimitiveBoolean(closedWorld) || 318 receiver.canBePrimitiveBoolean(closedWorld) ||
322 receiver.canBePrimitiveString(closedWorld))) { 319 receiver.canBePrimitiveString(closedWorld))) {
323 ClassEntity interceptorClass = tryComputeConstantInterceptorFromType( 320 ClassEntity interceptorClass = tryComputeConstantInterceptorFromType(
324 receiver.instructionType.nonNullable(), interceptedClasses); 321 receiver.instructionType.nonNullable(), interceptedClasses);
325 if (interceptorClass != null) { 322 if (interceptorClass != null) {
326 HInstruction constantInstruction = graph.addConstant( 323 HInstruction constantInstruction = graph.addConstant(
327 new InterceptorConstantValue(interceptorClass), closedWorld); 324 new InterceptorConstantValue(interceptorClass), closedWorld);
328 node.conditionalConstantInterceptor = constantInstruction; 325 node.conditionalConstantInterceptor = constantInstruction;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 instruction = new HInvokeDynamicMethod( 419 instruction = new HInvokeDynamicMethod(
423 selector, mask, inputs, node.instructionType, true); 420 selector, mask, inputs, node.instructionType, true);
424 } 421 }
425 422
426 HBasicBlock block = node.block; 423 HBasicBlock block = node.block;
427 block.addAfter(node, instruction); 424 block.addAfter(node, instruction);
428 block.rewrite(node, instruction); 425 block.rewrite(node, instruction);
429 return true; 426 return true;
430 } 427 }
431 } 428 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/native/enqueue.dart ('k') | pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698