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

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

Issue 11316354: Re-apply "Move the handling of operator[] into the new interceptors." (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 ssa; 5 part of ssa;
6 6
7 abstract class HVisitor<R> { 7 abstract class HVisitor<R> {
8 R visitAdd(HAdd node); 8 R visitAdd(HAdd node);
9 R visitBailoutTarget(HBailoutTarget node); 9 R visitBailoutTarget(HBailoutTarget node);
10 R visitBitAnd(HBitAnd node); 10 R visitBitAnd(HBitAnd node);
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 return new HBoundedType.exact(objectConstant.type); 173 return new HBoundedType.exact(objectConstant.type);
174 } 174 }
175 175
176 HConstant addConstant(Constant constant) { 176 HConstant addConstant(Constant constant) {
177 HConstant result = constants[constant]; 177 HConstant result = constants[constant];
178 if (result == null) { 178 if (result == null) {
179 HType type = mapConstantTypeToSsaType(constant); 179 HType type = mapConstantTypeToSsaType(constant);
180 result = new HConstant.internal(constant, type); 180 result = new HConstant.internal(constant, type);
181 entry.addAtExit(result); 181 entry.addAtExit(result);
182 constants[constant] = result; 182 constants[constant] = result;
183 } else if (result.block == null) {
ngeoffray 2012/12/12 16:14:14 This was the bug: we were adding a constant back i
kasperl 2012/12/13 08:49:24 So we would have a constant in the constant map th
184 // The constant was not used anymore.
185 entry.addAtExit(result);
183 } 186 }
184 return result; 187 return result;
185 } 188 }
186 189
187 HConstant addConstantInt(int i, ConstantSystem constantSystem) { 190 HConstant addConstantInt(int i, ConstantSystem constantSystem) {
188 return addConstant(constantSystem.createInt(i)); 191 return addConstant(constantSystem.createInt(i));
189 } 192 }
190 193
191 HConstant addConstantDouble(double d, ConstantSystem constantSystem) { 194 HConstant addConstantDouble(double d, ConstantSystem constantSystem) {
192 return addConstant(constantSystem.createDouble(d)); 195 return addConstant(constantSystem.createDouble(d));
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 visitExitTry(HExitTry node) => visitControlFlow(node); 285 visitExitTry(HExitTry node) => visitControlFlow(node);
283 visitFieldGet(HFieldGet node) => visitFieldAccess(node); 286 visitFieldGet(HFieldGet node) => visitFieldAccess(node);
284 visitFieldSet(HFieldSet node) => visitFieldAccess(node); 287 visitFieldSet(HFieldSet node) => visitFieldAccess(node);
285 visitForeign(HForeign node) => visitInstruction(node); 288 visitForeign(HForeign node) => visitInstruction(node);
286 visitForeignNew(HForeignNew node) => visitForeign(node); 289 visitForeignNew(HForeignNew node) => visitForeign(node);
287 visitGoto(HGoto node) => visitControlFlow(node); 290 visitGoto(HGoto node) => visitControlFlow(node);
288 visitGreater(HGreater node) => visitRelational(node); 291 visitGreater(HGreater node) => visitRelational(node);
289 visitGreaterEqual(HGreaterEqual node) => visitRelational(node); 292 visitGreaterEqual(HGreaterEqual node) => visitRelational(node);
290 visitIdentity(HIdentity node) => visitRelational(node); 293 visitIdentity(HIdentity node) => visitRelational(node);
291 visitIf(HIf node) => visitConditionalBranch(node); 294 visitIf(HIf node) => visitConditionalBranch(node);
292 visitIndex(HIndex node) => visitInvokeStatic(node); 295 visitIndex(HIndex node) => visitInstruction(node);
293 visitIndexAssign(HIndexAssign node) => visitInvokeStatic(node); 296 visitIndexAssign(HIndexAssign node) => visitInvokeStatic(node);
294 visitIntegerCheck(HIntegerCheck node) => visitCheck(node); 297 visitIntegerCheck(HIntegerCheck node) => visitCheck(node);
295 visitInterceptor(HInterceptor node) => visitInstruction(node); 298 visitInterceptor(HInterceptor node) => visitInstruction(node);
296 visitInvokeClosure(HInvokeClosure node) 299 visitInvokeClosure(HInvokeClosure node)
297 => visitInvokeDynamic(node); 300 => visitInvokeDynamic(node);
298 visitInvokeDynamicMethod(HInvokeDynamicMethod node) 301 visitInvokeDynamicMethod(HInvokeDynamicMethod node)
299 => visitInvokeDynamic(node); 302 => visitInvokeDynamic(node);
300 visitInvokeDynamicGetter(HInvokeDynamicGetter node) 303 visitInvokeDynamicGetter(HInvokeDynamicGetter node)
301 => visitInvokeDynamicField(node); 304 => visitInvokeDynamicField(node);
302 visitInvokeDynamicSetter(HInvokeDynamicSetter node) 305 visitInvokeDynamicSetter(HInvokeDynamicSetter node)
(...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after
1313 1316
1314 class HInvokeClosure extends HInvokeDynamic { 1317 class HInvokeClosure extends HInvokeDynamic {
1315 HInvokeClosure(Selector selector, List<HInstruction> inputs) 1318 HInvokeClosure(Selector selector, List<HInstruction> inputs)
1316 : super(selector, null, inputs); 1319 : super(selector, null, inputs);
1317 accept(HVisitor visitor) => visitor.visitInvokeClosure(this); 1320 accept(HVisitor visitor) => visitor.visitInvokeClosure(this);
1318 } 1321 }
1319 1322
1320 class HInvokeDynamicMethod extends HInvokeDynamic { 1323 class HInvokeDynamicMethod extends HInvokeDynamic {
1321 HInvokeDynamicMethod(Selector selector, List<HInstruction> inputs) 1324 HInvokeDynamicMethod(Selector selector, List<HInstruction> inputs)
1322 : super(selector, null, inputs); 1325 : super(selector, null, inputs);
1323 toString() => 'invoke dynamic method: $selector'; 1326 String toString() => 'invoke dynamic method: $selector';
1324 accept(HVisitor visitor) => visitor.visitInvokeDynamicMethod(this); 1327 accept(HVisitor visitor) => visitor.visitInvokeDynamicMethod(this);
1328
1329 bool isIndexOperatorOnIndexablePrimitive(HTypeMap types) {
1330 return isInterceptorCall
1331 && selector.kind == SelectorKind.INDEX
1332 && inputs[1].isIndexablePrimitive(types);
1333 }
1334
1335 HType computeDesiredTypeForInput(HInstruction input,
1336 HTypeMap types,
1337 Compiler compiler) {
1338 // TODO(ngeoffray): Move this logic into a different class that
1339 // will know what type it wants for a given selector.
1340 if (selector.kind != SelectorKind.INDEX) return HType.UNKNOWN;
1341 if (!isInterceptorCall) return HType.UNKNOWN;
1342
1343 HInstruction index = inputs[2];
1344 if (input == inputs[1] &&
1345 (index.isTypeUnknown(types) || index.isNumber(types))) {
1346 return HType.INDEXABLE_PRIMITIVE;
1347 }
1348 // The index should be an int when the receiver is a string or array.
1349 // However it turns out that inserting an integer check in the optimized
1350 // version is cheaper than having another bailout case. This is true,
1351 // because the integer check will simply throw if it fails.
1352 return HType.UNKNOWN;
1353 }
1325 } 1354 }
1326 1355
1327 abstract class HInvokeDynamicField extends HInvokeDynamic { 1356 abstract class HInvokeDynamicField extends HInvokeDynamic {
1328 final bool isSideEffectFree; 1357 final bool isSideEffectFree;
1329 HInvokeDynamicField( 1358 HInvokeDynamicField(
1330 Selector selector, Element element, List<HInstruction> inputs, 1359 Selector selector, Element element, List<HInstruction> inputs,
1331 this.isSideEffectFree) 1360 this.isSideEffectFree)
1332 : super(selector, element, inputs); 1361 : super(selector, element, inputs);
1333 toString() => 'invoke dynamic field: $selector'; 1362 toString() => 'invoke dynamic field: $selector';
1334 } 1363 }
(...skipping 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after
2432 toString() => 'literal list'; 2461 toString() => 'literal list';
2433 accept(HVisitor visitor) => visitor.visitLiteralList(this); 2462 accept(HVisitor visitor) => visitor.visitLiteralList(this);
2434 2463
2435 HType get guaranteedType => HType.EXTENDABLE_ARRAY; 2464 HType get guaranteedType => HType.EXTENDABLE_ARRAY;
2436 2465
2437 void prepareGvn(HTypeMap types) { 2466 void prepareGvn(HTypeMap types) {
2438 assert(!hasSideEffects(types)); 2467 assert(!hasSideEffects(types));
2439 } 2468 }
2440 } 2469 }
2441 2470
2442 class HIndex extends HInvokeStatic { 2471 class HIndex extends HInstruction {
2443 HIndex(HStatic target, HInstruction receiver, HInstruction index) 2472 HIndex(HInstruction receiver, HInstruction index)
2444 : super(<HInstruction>[target, receiver, index]); 2473 : super(<HInstruction>[receiver, index]);
2445 toString() => 'index operator'; 2474 String toString() => 'index operator';
2446 accept(HVisitor visitor) => visitor.visitIndex(this); 2475 accept(HVisitor visitor) => visitor.visitIndex(this);
2447 2476
2448 void prepareGvn(HTypeMap types) { 2477 void prepareGvn(HTypeMap types) {
2449 clearAllSideEffects(); 2478 clearAllSideEffects();
2450 if (isBuiltin(types)) { 2479 setDependsOnIndexStore();
2451 setDependsOnIndexStore(); 2480 setUseGvn();
2452 setUseGvn();
2453 } else {
2454 setAllSideEffects();
2455 }
2456 } 2481 }
2457 2482
2458 HInstruction get receiver => inputs[1]; 2483 HInstruction get receiver => inputs[0];
2459 HInstruction get index => inputs[2]; 2484 HInstruction get index => inputs[1];
2460
2461 HType computeDesiredTypeForNonTargetInput(HInstruction input,
2462 HTypeMap types,
2463 Compiler compiler) {
2464 if (input == receiver &&
2465 (index.isTypeUnknown(types) || index.isNumber(types))) {
2466 return HType.INDEXABLE_PRIMITIVE;
2467 }
2468 // The index should be an int when the receiver is a string or array.
2469 // However it turns out that inserting an integer check in the optimized
2470 // version is cheaper than having another bailout case. This is true,
2471 // because the integer check will simply throw if it fails.
2472 return HType.UNKNOWN;
2473 }
2474
2475 bool isBuiltin(HTypeMap types)
2476 => receiver.isIndexablePrimitive(types) && index.isInteger(types);
2477 2485
2478 int typeCode() => HInstruction.INDEX_TYPECODE; 2486 int typeCode() => HInstruction.INDEX_TYPECODE;
2479 bool typeEquals(HInstruction other) => other is HIndex; 2487 bool typeEquals(HInstruction other) => other is HIndex;
2480 bool dataEquals(HIndex other) => true; 2488 bool dataEquals(HIndex other) => true;
2481 } 2489 }
2482 2490
2483 class HIndexAssign extends HInvokeStatic { 2491 class HIndexAssign extends HInvokeStatic {
2484 HIndexAssign(HStatic target, 2492 HIndexAssign(HStatic target,
2485 HInstruction receiver, 2493 HInstruction receiver,
2486 HInstruction index, 2494 HInstruction index,
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
2942 HBasicBlock get start => expression.start; 2950 HBasicBlock get start => expression.start;
2943 HBasicBlock get end { 2951 HBasicBlock get end {
2944 // We don't create a switch block if there are no cases. 2952 // We don't create a switch block if there are no cases.
2945 assert(!statements.isEmpty); 2953 assert(!statements.isEmpty);
2946 return statements.last.end; 2954 return statements.last.end;
2947 } 2955 }
2948 2956
2949 bool accept(HStatementInformationVisitor visitor) => 2957 bool accept(HStatementInformationVisitor visitor) =>
2950 visitor.visitSwitchInfo(this); 2958 visitor.visitSwitchInfo(this);
2951 } 2959 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698