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

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 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 visitExitTry(HExitTry node) => visitControlFlow(node); 285 visitExitTry(HExitTry node) => visitControlFlow(node);
286 visitFieldGet(HFieldGet node) => visitFieldAccess(node); 286 visitFieldGet(HFieldGet node) => visitFieldAccess(node);
287 visitFieldSet(HFieldSet node) => visitFieldAccess(node); 287 visitFieldSet(HFieldSet node) => visitFieldAccess(node);
288 visitForeign(HForeign node) => visitInstruction(node); 288 visitForeign(HForeign node) => visitInstruction(node);
289 visitForeignNew(HForeignNew node) => visitForeign(node); 289 visitForeignNew(HForeignNew node) => visitForeign(node);
290 visitGoto(HGoto node) => visitControlFlow(node); 290 visitGoto(HGoto node) => visitControlFlow(node);
291 visitGreater(HGreater node) => visitRelational(node); 291 visitGreater(HGreater node) => visitRelational(node);
292 visitGreaterEqual(HGreaterEqual node) => visitRelational(node); 292 visitGreaterEqual(HGreaterEqual node) => visitRelational(node);
293 visitIdentity(HIdentity node) => visitRelational(node); 293 visitIdentity(HIdentity node) => visitRelational(node);
294 visitIf(HIf node) => visitConditionalBranch(node); 294 visitIf(HIf node) => visitConditionalBranch(node);
295 visitIndex(HIndex node) => visitInvokeStatic(node); 295 visitIndex(HIndex node) => visitInstruction(node);
296 visitIndexAssign(HIndexAssign node) => visitInvokeStatic(node); 296 visitIndexAssign(HIndexAssign node) => visitInvokeStatic(node);
297 visitIntegerCheck(HIntegerCheck node) => visitCheck(node); 297 visitIntegerCheck(HIntegerCheck node) => visitCheck(node);
298 visitInterceptor(HInterceptor node) => visitInstruction(node); 298 visitInterceptor(HInterceptor node) => visitInstruction(node);
299 visitInvokeClosure(HInvokeClosure node) 299 visitInvokeClosure(HInvokeClosure node)
300 => visitInvokeDynamic(node); 300 => visitInvokeDynamic(node);
301 visitInvokeDynamicMethod(HInvokeDynamicMethod node) 301 visitInvokeDynamicMethod(HInvokeDynamicMethod node)
302 => visitInvokeDynamic(node); 302 => visitInvokeDynamic(node);
303 visitInvokeDynamicGetter(HInvokeDynamicGetter node) 303 visitInvokeDynamicGetter(HInvokeDynamicGetter node)
304 => visitInvokeDynamicField(node); 304 => visitInvokeDynamicField(node);
305 visitInvokeDynamicSetter(HInvokeDynamicSetter node) 305 visitInvokeDynamicSetter(HInvokeDynamicSetter node)
(...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after
1316 1316
1317 class HInvokeClosure extends HInvokeDynamic { 1317 class HInvokeClosure extends HInvokeDynamic {
1318 HInvokeClosure(Selector selector, List<HInstruction> inputs) 1318 HInvokeClosure(Selector selector, List<HInstruction> inputs)
1319 : super(selector, null, inputs); 1319 : super(selector, null, inputs);
1320 accept(HVisitor visitor) => visitor.visitInvokeClosure(this); 1320 accept(HVisitor visitor) => visitor.visitInvokeClosure(this);
1321 } 1321 }
1322 1322
1323 class HInvokeDynamicMethod extends HInvokeDynamic { 1323 class HInvokeDynamicMethod extends HInvokeDynamic {
1324 HInvokeDynamicMethod(Selector selector, List<HInstruction> inputs) 1324 HInvokeDynamicMethod(Selector selector, List<HInstruction> inputs)
1325 : super(selector, null, inputs); 1325 : super(selector, null, inputs);
1326 toString() => 'invoke dynamic method: $selector'; 1326 String toString() => 'invoke dynamic method: $selector';
1327 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 }
1328 } 1354 }
1329 1355
1330 abstract class HInvokeDynamicField extends HInvokeDynamic { 1356 abstract class HInvokeDynamicField extends HInvokeDynamic {
1331 final bool isSideEffectFree; 1357 final bool isSideEffectFree;
1332 HInvokeDynamicField( 1358 HInvokeDynamicField(
1333 Selector selector, Element element, List<HInstruction> inputs, 1359 Selector selector, Element element, List<HInstruction> inputs,
1334 this.isSideEffectFree) 1360 this.isSideEffectFree)
1335 : super(selector, element, inputs); 1361 : super(selector, element, inputs);
1336 toString() => 'invoke dynamic field: $selector'; 1362 toString() => 'invoke dynamic field: $selector';
1337 } 1363 }
(...skipping 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after
2435 toString() => 'literal list'; 2461 toString() => 'literal list';
2436 accept(HVisitor visitor) => visitor.visitLiteralList(this); 2462 accept(HVisitor visitor) => visitor.visitLiteralList(this);
2437 2463
2438 HType get guaranteedType => HType.EXTENDABLE_ARRAY; 2464 HType get guaranteedType => HType.EXTENDABLE_ARRAY;
2439 2465
2440 void prepareGvn(HTypeMap types) { 2466 void prepareGvn(HTypeMap types) {
2441 assert(!hasSideEffects(types)); 2467 assert(!hasSideEffects(types));
2442 } 2468 }
2443 } 2469 }
2444 2470
2445 class HIndex extends HInvokeStatic { 2471 class HIndex extends HInstruction {
2446 HIndex(HStatic target, HInstruction receiver, HInstruction index) 2472 HIndex(HInstruction receiver, HInstruction index)
2447 : super(<HInstruction>[target, receiver, index]); 2473 : super(<HInstruction>[receiver, index]);
2448 toString() => 'index operator'; 2474 String toString() => 'index operator';
2449 accept(HVisitor visitor) => visitor.visitIndex(this); 2475 accept(HVisitor visitor) => visitor.visitIndex(this);
2450 2476
2451 void prepareGvn(HTypeMap types) { 2477 void prepareGvn(HTypeMap types) {
2452 clearAllSideEffects(); 2478 clearAllSideEffects();
2453 if (isBuiltin(types)) { 2479 setDependsOnIndexStore();
2454 setDependsOnIndexStore(); 2480 setUseGvn();
2455 setUseGvn();
2456 } else {
2457 setAllSideEffects();
2458 }
2459 } 2481 }
2460 2482
2461 HInstruction get receiver => inputs[1]; 2483 HInstruction get receiver => inputs[0];
2462 HInstruction get index => inputs[2]; 2484 HInstruction get index => inputs[1];
2463
2464 HType computeDesiredTypeForNonTargetInput(HInstruction input,
2465 HTypeMap types,
2466 Compiler compiler) {
2467 if (input == receiver &&
2468 (index.isTypeUnknown(types) || index.isNumber(types))) {
2469 return HType.INDEXABLE_PRIMITIVE;
2470 }
2471 // The index should be an int when the receiver is a string or array.
2472 // However it turns out that inserting an integer check in the optimized
2473 // version is cheaper than having another bailout case. This is true,
2474 // because the integer check will simply throw if it fails.
2475 return HType.UNKNOWN;
2476 }
2477
2478 bool isBuiltin(HTypeMap types)
2479 => receiver.isIndexablePrimitive(types) && index.isInteger(types);
2480 2485
2481 int typeCode() => HInstruction.INDEX_TYPECODE; 2486 int typeCode() => HInstruction.INDEX_TYPECODE;
2482 bool typeEquals(HInstruction other) => other is HIndex; 2487 bool typeEquals(HInstruction other) => other is HIndex;
2483 bool dataEquals(HIndex other) => true; 2488 bool dataEquals(HIndex other) => true;
2484 } 2489 }
2485 2490
2486 class HIndexAssign extends HInvokeStatic { 2491 class HIndexAssign extends HInvokeStatic {
2487 HIndexAssign(HStatic target, 2492 HIndexAssign(HStatic target,
2488 HInstruction receiver, 2493 HInstruction receiver,
2489 HInstruction index, 2494 HInstruction index,
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
2945 HBasicBlock get start => expression.start; 2950 HBasicBlock get start => expression.start;
2946 HBasicBlock get end { 2951 HBasicBlock get end {
2947 // 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.
2948 assert(!statements.isEmpty); 2953 assert(!statements.isEmpty);
2949 return statements.last.end; 2954 return statements.last.end;
2950 } 2955 }
2951 2956
2952 bool accept(HStatementInformationVisitor visitor) => 2957 bool accept(HStatementInformationVisitor visitor) =>
2953 visitor.visitSwitchInfo(this); 2958 visitor.visitSwitchInfo(this);
2954 } 2959 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698