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

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

Issue 12033056: Implement "one-shot" interceptors. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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) 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 R visitLess(HLess node); 43 R visitLess(HLess node);
44 R visitLessEqual(HLessEqual node); 44 R visitLessEqual(HLessEqual node);
45 R visitLiteralList(HLiteralList node); 45 R visitLiteralList(HLiteralList node);
46 R visitLocalGet(HLocalGet node); 46 R visitLocalGet(HLocalGet node);
47 R visitLocalSet(HLocalSet node); 47 R visitLocalSet(HLocalSet node);
48 R visitLocalValue(HLocalValue node); 48 R visitLocalValue(HLocalValue node);
49 R visitLoopBranch(HLoopBranch node); 49 R visitLoopBranch(HLoopBranch node);
50 R visitMultiply(HMultiply node); 50 R visitMultiply(HMultiply node);
51 R visitNegate(HNegate node); 51 R visitNegate(HNegate node);
52 R visitNot(HNot node); 52 R visitNot(HNot node);
53 R visitOneShotInterceptor(HOneShotInterceptor);
53 R visitParameterValue(HParameterValue node); 54 R visitParameterValue(HParameterValue node);
54 R visitPhi(HPhi node); 55 R visitPhi(HPhi node);
55 R visitRangeConversion(HRangeConversion node); 56 R visitRangeConversion(HRangeConversion node);
56 R visitReturn(HReturn node); 57 R visitReturn(HReturn node);
57 R visitShiftLeft(HShiftLeft node); 58 R visitShiftLeft(HShiftLeft node);
58 R visitStatic(HStatic node); 59 R visitStatic(HStatic node);
59 R visitStaticStore(HStaticStore node); 60 R visitStaticStore(HStaticStore node);
60 R visitStringConcat(HStringConcat node); 61 R visitStringConcat(HStringConcat node);
61 R visitSubtract(HSubtract node); 62 R visitSubtract(HSubtract node);
62 R visitSwitch(HSwitch node); 63 R visitSwitch(HSwitch node);
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 visitLazyStatic(HLazyStatic node) => visitInstruction(node); 307 visitLazyStatic(HLazyStatic node) => visitInstruction(node);
307 visitLess(HLess node) => visitRelational(node); 308 visitLess(HLess node) => visitRelational(node);
308 visitLessEqual(HLessEqual node) => visitRelational(node); 309 visitLessEqual(HLessEqual node) => visitRelational(node);
309 visitLiteralList(HLiteralList node) => visitInstruction(node); 310 visitLiteralList(HLiteralList node) => visitInstruction(node);
310 visitLocalGet(HLocalGet node) => visitFieldAccess(node); 311 visitLocalGet(HLocalGet node) => visitFieldAccess(node);
311 visitLocalSet(HLocalSet node) => visitFieldAccess(node); 312 visitLocalSet(HLocalSet node) => visitFieldAccess(node);
312 visitLocalValue(HLocalValue node) => visitInstruction(node); 313 visitLocalValue(HLocalValue node) => visitInstruction(node);
313 visitLoopBranch(HLoopBranch node) => visitConditionalBranch(node); 314 visitLoopBranch(HLoopBranch node) => visitConditionalBranch(node);
314 visitNegate(HNegate node) => visitInvokeUnary(node); 315 visitNegate(HNegate node) => visitInvokeUnary(node);
315 visitNot(HNot node) => visitInstruction(node); 316 visitNot(HNot node) => visitInstruction(node);
317 visitOneShotInterceptor(HOneShotInterceptor node)
318 => visitInvokeDynamic(node);
316 visitPhi(HPhi node) => visitInstruction(node); 319 visitPhi(HPhi node) => visitInstruction(node);
317 visitMultiply(HMultiply node) => visitBinaryArithmetic(node); 320 visitMultiply(HMultiply node) => visitBinaryArithmetic(node);
318 visitParameterValue(HParameterValue node) => visitLocalValue(node); 321 visitParameterValue(HParameterValue node) => visitLocalValue(node);
319 visitRangeConversion(HRangeConversion node) => visitCheck(node); 322 visitRangeConversion(HRangeConversion node) => visitCheck(node);
320 visitReturn(HReturn node) => visitControlFlow(node); 323 visitReturn(HReturn node) => visitControlFlow(node);
321 visitShiftLeft(HShiftLeft node) => visitBinaryBitOp(node); 324 visitShiftLeft(HShiftLeft node) => visitBinaryBitOp(node);
322 visitSubtract(HSubtract node) => visitBinaryArithmetic(node); 325 visitSubtract(HSubtract node) => visitBinaryArithmetic(node);
323 visitSwitch(HSwitch node) => visitControlFlow(node); 326 visitSwitch(HSwitch node) => visitControlFlow(node);
324 visitStatic(HStatic node) => visitInstruction(node); 327 visitStatic(HStatic node) => visitInstruction(node);
325 visitStaticStore(HStaticStore node) => visitInstruction(node); 328 visitStaticStore(HStaticStore node) => visitInstruction(node);
(...skipping 981 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 */ 1310 */
1308 HInvoke(List<HInstruction> inputs) : super(inputs) { 1311 HInvoke(List<HInstruction> inputs) : super(inputs) {
1309 setAllSideEffects(); 1312 setAllSideEffects();
1310 setDependsOnSomething(); 1313 setDependsOnSomething();
1311 } 1314 }
1312 static const int ARGUMENTS_OFFSET = 1; 1315 static const int ARGUMENTS_OFFSET = 1;
1313 bool canThrow() => true; 1316 bool canThrow() => true;
1314 } 1317 }
1315 1318
1316 abstract class HInvokeDynamic extends HInvoke { 1319 abstract class HInvokeDynamic extends HInvoke {
1320 final InvokeDynamicSpecializer specializer;
1317 final Selector selector; 1321 final Selector selector;
1318 Element element; 1322 Element element;
1319 1323
1320 HInvokeDynamic(this.selector, this.element, List<HInstruction> inputs) 1324 HInvokeDynamic(Selector selector,
1321 : super(inputs); 1325 this.element,
1326 List<HInstruction> inputs,
1327 [bool isIntercepted = false])
1328 : super(inputs),
1329 this.selector = selector,
1330 specializer = isIntercepted
1331 ? InvokeDynamicSpecializer.lookupSpecializer(selector)
1332 : const InvokeDynamicSpecializer();
1322 toString() => 'invoke dynamic: $selector'; 1333 toString() => 'invoke dynamic: $selector';
1323 HInstruction get receiver => inputs[0]; 1334 HInstruction get receiver => inputs[0];
1324 1335
1325 bool get isInterceptorCall { 1336 bool get isInterceptorCall {
1326 // We know it's a selector call if it follows the interceptor 1337 // We know it's a selector call if it follows the interceptor
1327 // calling convention, which adds the actual receiver as a 1338 // calling convention, which adds the actual receiver as a
1328 // parameter to the call. 1339 // parameter to the call.
1329 return inputs.length - 2 == selector.argumentCount; 1340 return inputs.length - 2 == selector.argumentCount;
1330 } 1341 }
1331 1342
1332 int typeCode() => HInstruction.INVOKE_DYNAMIC_TYPECODE; 1343 int typeCode() => HInstruction.INVOKE_DYNAMIC_TYPECODE;
1333 bool typeEquals(other) => other is HInvokeDynamic; 1344 bool typeEquals(other) => other is HInvokeDynamic;
1334 bool dataEquals(HInvokeDynamic other) { 1345 bool dataEquals(HInvokeDynamic other) {
1335 return selector == other.selector 1346 return selector == other.selector
1336 && element == other.element; 1347 && element == other.element;
1337 } 1348 }
1349
1350 HType computeDesiredTypeForInput(HInstruction input,
1351 HTypeMap types,
1352 Compiler compiler) {
1353 return specializer.computeDesiredTypeForInput(this, input, types, compiler);
1354 }
1355
1356 HType computeTypeFromInputTypes(HTypeMap types, Compiler compiler) {
1357 return specializer.computeTypeFromInputTypes(this, types, compiler);
1358 }
1338 } 1359 }
1339 1360
1340 class HInvokeClosure extends HInvokeDynamic { 1361 class HInvokeClosure extends HInvokeDynamic {
1341 HInvokeClosure(Selector selector, List<HInstruction> inputs) 1362 HInvokeClosure(Selector selector, List<HInstruction> inputs)
1342 : super(selector, null, inputs) { 1363 : super(selector, null, inputs) {
1343 assert(selector.isClosureCall()); 1364 assert(selector.isClosureCall());
1344 } 1365 }
1345 accept(HVisitor visitor) => visitor.visitInvokeClosure(this); 1366 accept(HVisitor visitor) => visitor.visitInvokeClosure(this);
1346 } 1367 }
1347 1368
1348 class HInvokeDynamicMethod extends HInvokeDynamic { 1369 class HInvokeDynamicMethod extends HInvokeDynamic {
1349 final InvokeDynamicSpecializer specializer;
1350 HInvokeDynamicMethod(Selector selector, 1370 HInvokeDynamicMethod(Selector selector,
1351 List<HInstruction> inputs, 1371 List<HInstruction> inputs,
1352 [bool isIntercepted = false]) 1372 [bool isIntercepted = false])
1353 : super(selector, null, inputs), 1373 : super(selector, null, inputs, isIntercepted);
1354 specializer = isIntercepted 1374
1355 ? InvokeDynamicSpecializer.lookupSpecializer(selector)
1356 : const InvokeDynamicSpecializer();
1357 String toString() => 'invoke dynamic method: $selector'; 1375 String toString() => 'invoke dynamic method: $selector';
1358 accept(HVisitor visitor) => visitor.visitInvokeDynamicMethod(this); 1376 accept(HVisitor visitor) => visitor.visitInvokeDynamicMethod(this);
1359 1377
1360 bool isIndexOperatorOnIndexablePrimitive(HTypeMap types) { 1378 bool isIndexOperatorOnIndexablePrimitive(HTypeMap types) {
1361 return isInterceptorCall 1379 return isInterceptorCall
1362 && selector.kind == SelectorKind.INDEX 1380 && selector.kind == SelectorKind.INDEX
1363 && selector.name == const SourceString('[]') 1381 && selector.name == const SourceString('[]')
1364 && inputs[1].isIndexablePrimitive(types); 1382 && inputs[1].isIndexablePrimitive(types);
1365 } 1383 }
1366
1367 HType computeDesiredTypeForInput(HInstruction input,
1368 HTypeMap types,
1369 Compiler compiler) {
1370 return specializer.computeDesiredTypeForInput(this, input, types, compiler);
1371 }
1372
1373 HType computeTypeFromInputTypes(HTypeMap types, Compiler compiler) {
1374 return specializer.computeTypeFromInputTypes(this, types, compiler);
1375 }
1376 } 1384 }
1377 1385
1378 abstract class HInvokeDynamicField extends HInvokeDynamic { 1386 abstract class HInvokeDynamicField extends HInvokeDynamic {
1379 final bool isSideEffectFree; 1387 final bool isSideEffectFree;
1380 HInvokeDynamicField( 1388 HInvokeDynamicField(
1381 Selector selector, Element element, List<HInstruction> inputs, 1389 Selector selector, Element element, List<HInstruction> inputs,
1382 this.isSideEffectFree) 1390 this.isSideEffectFree)
1383 : super(selector, element, inputs); 1391 : super(selector, element, inputs);
1384 toString() => 'invoke dynamic field: $selector'; 1392 toString() => 'invoke dynamic field: $selector';
1385 } 1393 }
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after
2128 2136
2129 int typeCode() => HInstruction.INTERCEPTOR_TYPECODE; 2137 int typeCode() => HInstruction.INTERCEPTOR_TYPECODE;
2130 bool typeEquals(other) => other is HInterceptor; 2138 bool typeEquals(other) => other is HInterceptor;
2131 bool dataEquals(HInterceptor other) { 2139 bool dataEquals(HInterceptor other) {
2132 return interceptedClasses == other.interceptedClasses 2140 return interceptedClasses == other.interceptedClasses
2133 || (interceptedClasses.length == other.interceptedClasses.length 2141 || (interceptedClasses.length == other.interceptedClasses.length
2134 && interceptedClasses.containsAll(other.interceptedClasses)); 2142 && interceptedClasses.containsAll(other.interceptedClasses));
2135 } 2143 }
2136 } 2144 }
2137 2145
2146 /**
2147 * A "one-shot" interceptor is a call to a synthetized method that
2148 * will fetch the interceptor of its first parameter, and make a call
2149 * on a given selector with the remaining parameters.
2150 *
2151 * In order to share the same optimizations with regular interceptor
2152 * calls, this class extends [HInvokeDynamic] and also has the null
2153 * constant as the first input.
2154 */
2155 class HOneShotInterceptor extends HInvokeDynamic {
2156 Set<ClassElement> interceptedClasses;
2157 HOneShotInterceptor(Selector selector,
2158 List<HInstruction> inputs,
2159 this.interceptedClasses)
2160 : super(selector, null, inputs, true) {
2161 assert(inputs[0] is HConstant);
2162 assert(inputs[0].guaranteedType == HType.NULL);
2163 }
2164
2165 String toString() => 'one short interceptor on $selector';
sra1 2013/01/23 21:21:30 short -> shot
ngeoffray 2013/01/24 08:39:15 Done.
2166 accept(HVisitor visitor) => visitor.visitOneShotInterceptor(this);
2167 }
2168
2138 /** An [HLazyStatic] is a static that is initialized lazily at first read. */ 2169 /** An [HLazyStatic] is a static that is initialized lazily at first read. */
2139 class HLazyStatic extends HInstruction { 2170 class HLazyStatic extends HInstruction {
2140 final Element element; 2171 final Element element;
2141 HLazyStatic(this.element) : super(<HInstruction>[]) { 2172 HLazyStatic(this.element) : super(<HInstruction>[]) {
2142 // TODO(4931): The first access has side-effects, but we afterwards we 2173 // TODO(4931): The first access has side-effects, but we afterwards we
2143 // should be able to GVN. 2174 // should be able to GVN.
2144 setAllSideEffects(); 2175 setAllSideEffects();
2145 setDependsOnSomething(); 2176 setDependsOnSomething();
2146 } 2177 }
2147 2178
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
2646 HBasicBlock get start => expression.start; 2677 HBasicBlock get start => expression.start;
2647 HBasicBlock get end { 2678 HBasicBlock get end {
2648 // We don't create a switch block if there are no cases. 2679 // We don't create a switch block if there are no cases.
2649 assert(!statements.isEmpty); 2680 assert(!statements.isEmpty);
2650 return statements.last.end; 2681 return statements.last.end;
2651 } 2682 }
2652 2683
2653 bool accept(HStatementInformationVisitor visitor) => 2684 bool accept(HStatementInformationVisitor visitor) =>
2654 visitor.visitSwitchInfo(this); 2685 visitor.visitSwitchInfo(this);
2655 } 2686 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698