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

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

Issue 12299006: Start tracking all registered elements in one big full function set (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 10 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 /** 7 /**
8 * A special element for the extra parameter taken by intercepted 8 * A special element for the extra parameter taken by intercepted
9 * methods. We need to override [Element.computeType] because our 9 * methods. We need to override [Element.computeType] because our
10 * optimizers may look at its declared type. 10 * optimizers may look at its declared type.
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 updateLocal(boxElement, oldBox); 243 updateLocal(boxElement, oldBox);
244 HInstruction oldValue = readLocal(boxedVariable); 244 HInstruction oldValue = readLocal(boxedVariable);
245 updateLocal(boxElement, newBox); 245 updateLocal(boxElement, newBox);
246 updateLocal(boxedVariable, oldValue); 246 updateLocal(boxedVariable, oldValue);
247 } 247 }
248 updateLocal(boxElement, newBox); 248 updateLocal(boxElement, newBox);
249 } 249 }
250 250
251 HType cachedTypeOfThis; 251 HType cachedTypeOfThis;
252 252
253 HType computeTypeOfThis() { 253 HType getTypeOfThis() {
254 Element element = closureData.thisElement; 254 HType result = cachedTypeOfThis;
255 ClassElement cls = element.enclosingElement.getEnclosingClass(); 255 if (result == null) {
256 Compiler compiler = builder.compiler; 256 Element element = closureData.thisElement;
257 DartType type = cls.computeType(compiler); 257 ClassElement cls = element.enclosingElement.getEnclosingClass();
258 if (compiler.world.isUsedAsMixin(cls)) { 258 Compiler compiler = builder.compiler;
259 // If the enclosing class is used as a mixin, [:this:] can be 259 DartType type = cls.computeType(compiler);
260 // of the class that mixins the enclosing class. These two 260 if (compiler.world.isUsedAsMixin(cls)) {
261 // classes do not have a subclass relationship, so, for 261 // If the enclosing class is used as a mixin, [:this:] can be
262 // simplicity, we mark the type as an interface type. 262 // of the class that mixins the enclosing class. These two
263 cachedTypeOfThis = new HType.nonNullSubtype(type, compiler); 263 // classes do not have a subclass relationship, so, for
264 } else { 264 // simplicity, we mark the type as an interface type.
265 cachedTypeOfThis = new HType.nonNullSubclass(type, compiler); 265 result = new HType.nonNullSubtype(type, compiler);
266 } else {
267 result = new HType.nonNullSubclass(type, compiler);
268 }
269 cachedTypeOfThis = result;
266 } 270 }
267 return cachedTypeOfThis; 271 return result;
268 } 272 }
269 273
270 /** 274 /**
271 * Documentation wanted -- johnniwinther 275 * Documentation wanted -- johnniwinther
272 * 276 *
273 * Invariant: [function] must be an implementation element. 277 * Invariant: [function] must be an implementation element.
274 */ 278 */
275 void startFunction(Element element, Expression node) { 279 void startFunction(Element element, Expression node) {
276 assert(invariant(node, element.isImplementation)); 280 assert(invariant(node, element.isImplementation));
277 Compiler compiler = builder.compiler; 281 Compiler compiler = builder.compiler;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 HThis thisInstruction = new HThis(closureData.thisElement); 317 HThis thisInstruction = new HThis(closureData.thisElement);
314 builder.graph.thisInstruction = thisInstruction; 318 builder.graph.thisInstruction = thisInstruction;
315 builder.graph.entry.addAtEntry(thisInstruction); 319 builder.graph.entry.addAtEntry(thisInstruction);
316 updateLocal(closureData.closureElement, thisInstruction); 320 updateLocal(closureData.closureElement, thisInstruction);
317 } else if (element.isInstanceMember() 321 } else if (element.isInstanceMember()
318 || element.isGenerativeConstructor()) { 322 || element.isGenerativeConstructor()) {
319 // Once closures have been mapped to classes their instance members might 323 // Once closures have been mapped to classes their instance members might
320 // not have any thisElement if the closure was created inside a static 324 // not have any thisElement if the closure was created inside a static
321 // context. 325 // context.
322 HThis thisInstruction = new HThis( 326 HThis thisInstruction = new HThis(
323 closureData.thisElement, computeTypeOfThis()); 327 closureData.thisElement, getTypeOfThis());
324 builder.graph.thisInstruction = thisInstruction; 328 builder.graph.thisInstruction = thisInstruction;
325 builder.graph.entry.addAtEntry(thisInstruction); 329 builder.graph.entry.addAtEntry(thisInstruction);
326 directLocals[closureData.thisElement] = thisInstruction; 330 directLocals[closureData.thisElement] = thisInstruction;
327 } 331 }
328 332
329 // If this method is an intercepted method, add the extra 333 // If this method is an intercepted method, add the extra
330 // parameter to it, that is the actual receiver. 334 // parameter to it, that is the actual receiver.
331 ClassElement cls = element.getEnclosingClass(); 335 ClassElement cls = element.getEnclosingClass();
332 if (builder.backend.isInterceptorClass(cls)) { 336 if (builder.backend.isInterceptorClass(cls)) {
333 HType type = HType.UNKNOWN; 337 HType type = HType.UNKNOWN;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 HLocalValue local = getLocal(element); 432 HLocalValue local = getLocal(element);
429 HInstruction variable = new HLocalGet(element, local); 433 HInstruction variable = new HLocalGet(element, local);
430 builder.add(variable); 434 builder.add(variable);
431 return variable; 435 return variable;
432 } 436 }
433 } 437 }
434 438
435 HInstruction readThis() { 439 HInstruction readThis() {
436 HInstruction res = readLocal(closureData.thisElement); 440 HInstruction res = readLocal(closureData.thisElement);
437 if (res.guaranteedType == null) { 441 if (res.guaranteedType == null) {
438 if (cachedTypeOfThis == null) { 442 res.guaranteedType = getTypeOfThis();
439 computeTypeOfThis();
440 }
441 res.guaranteedType = cachedTypeOfThis;
442 } 443 }
443 return res; 444 return res;
444 } 445 }
445 446
446 HLocalValue getLocal(Element element) { 447 HLocalValue getLocal(Element element) {
447 // If the element is a parameter, we already have a 448 // If the element is a parameter, we already have a
448 // HParameterValue for it. We cannot create another one because 449 // HParameterValue for it. We cannot create another one because
449 // it could then have another name than the real parameter. And 450 // it could then have another name than the real parameter. And
450 // the other one would not know it is just a copy of the real 451 // the other one would not know it is just a copy of the real
451 // parameter. 452 // parameter.
(...skipping 2330 matching lines...) Expand 10 before | Expand all | Expand 10 after
2782 compiler); 2783 compiler);
2783 } 2784 }
2784 2785
2785 void addGenericSendArgumentsToList(Link<Node> link, List<HInstruction> list) { 2786 void addGenericSendArgumentsToList(Link<Node> link, List<HInstruction> list) {
2786 for (; !link.isEmpty; link = link.tail) { 2787 for (; !link.isEmpty; link = link.tail) {
2787 visit(link.head); 2788 visit(link.head);
2788 list.add(pop()); 2789 list.add(pop());
2789 } 2790 }
2790 } 2791 }
2791 2792
2793 bool isThisSend(Send send) {
2794 Node receiver = send.receiver;
2795 if (receiver == null) return true;
2796 Identifier identifier = receiver.asIdentifier();
2797 return identifier != null && identifier.isThis();
2798 }
2799
2792 visitDynamicSend(Send node) { 2800 visitDynamicSend(Send node) {
2793 Selector selector = elements.getSelector(node); 2801 Selector selector = elements.getSelector(node);
2794 2802
2803 // TODO(kasperl): It would be much better to try to get the
2804 // guaranteed type of the receiver after we've evaluated it, but
2805 // because of the way inlining currently works that is hard to do
2806 // with re-evaluating the receiver.
2807 if (isThisSend(node)) {
2808 HType receiverType = localsHandler.getTypeOfThis();
2809 selector = receiverType.refine(selector, compiler);
2810 }
2811
2795 SourceString dartMethodName; 2812 SourceString dartMethodName;
2796 bool isNotEquals = false; 2813 bool isNotEquals = false;
2797 if (node.isIndex && !node.arguments.tail.isEmpty) { 2814 if (node.isIndex && !node.arguments.tail.isEmpty) {
2798 dartMethodName = Elements.constructOperatorName( 2815 dartMethodName = Elements.constructOperatorName(
2799 const SourceString('[]='), false); 2816 const SourceString('[]='), false);
2800 } else if (node.selector.asOperator() != null) { 2817 } else if (node.selector.asOperator() != null) {
2801 SourceString name = node.selector.asIdentifier().source; 2818 SourceString name = node.selector.asIdentifier().source;
2802 isNotEquals = identical(name.stringValue, '!='); 2819 isNotEquals = identical(name.stringValue, '!=');
2803 dartMethodName = Elements.constructOperatorName( 2820 dartMethodName = Elements.constructOperatorName(
2804 name, node.argumentsNode is Prefix); 2821 name, node.argumentsNode is Prefix);
2805 } else { 2822 } else {
2806 dartMethodName = node.selector.asIdentifier().source; 2823 dartMethodName = node.selector.asIdentifier().source;
2807 } 2824 }
2808 2825
2809 Element element = elements[node]; 2826 Element element = compiler.world.locateSingleElement(selector);
2810 bool isClosureCall = false; 2827 bool isClosureCall = false;
2811 if (element != null && compiler.world.hasNoOverridingMember(element)) { 2828 if (element != null) {
2812 if (tryInlineMethod(element, selector, node.arguments, node)) { 2829 if (tryInlineMethod(element, selector, node.arguments, node)) {
2813 if (element.isGetter()) { 2830 if (element.isGetter()) {
2814 // If the element is a getter, we are doing a closure call 2831 // If the element is a getter, we are doing a closure call
2815 // on what this getter returns. 2832 // on what this getter returns.
2816 assert(selector.isCall()); 2833 assert(selector.isCall());
2817 isClosureCall = true; 2834 isClosureCall = true;
2818 } else { 2835 } else {
2819 return; 2836 return;
2820 } 2837 }
2821 } 2838 }
(...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after
3925 void buildInitializer() { 3942 void buildInitializer() {
3926 SourceString iteratorName = const SourceString("iterator"); 3943 SourceString iteratorName = const SourceString("iterator");
3927 Selector selector = 3944 Selector selector =
3928 new Selector.getter(iteratorName, currentElement.getLibrary()); 3945 new Selector.getter(iteratorName, currentElement.getLibrary());
3929 Set<ClassElement> interceptedClasses = getInterceptedClassesOn(selector); 3946 Set<ClassElement> interceptedClasses = getInterceptedClassesOn(selector);
3930 visit(node.expression); 3947 visit(node.expression);
3931 HInstruction receiver = pop(); 3948 HInstruction receiver = pop();
3932 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); 3949 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector);
3933 if (interceptedClasses == null) { 3950 if (interceptedClasses == null) {
3934 iterator = 3951 iterator =
3935 new HInvokeDynamicGetter(selector, null, receiver, hasGetter); 3952 new HInvokeDynamicGetter(selector, null, receiver, !hasGetter);
ngeoffray 2013/02/18 08:35:34 change the constructor to have a named argument? T
3936 } else { 3953 } else {
3937 HInterceptor interceptor = 3954 HInterceptor interceptor =
3938 invokeInterceptor(interceptedClasses, receiver, null); 3955 invokeInterceptor(interceptedClasses, receiver, null);
3939 iterator = 3956 iterator =
3940 new HInvokeDynamicGetter(selector, null, interceptor, hasGetter); 3957 new HInvokeDynamicGetter(selector, null, interceptor, !hasGetter);
3941 // Add the receiver as an argument to the getter call on the 3958 // Add the receiver as an argument to the getter call on the
3942 // interceptor. 3959 // interceptor.
3943 iterator.inputs.add(receiver); 3960 iterator.inputs.add(receiver);
3944 } 3961 }
3945 add(iterator); 3962 add(iterator);
3946 } 3963 }
3947 HInstruction buildCondition() { 3964 HInstruction buildCondition() {
3948 SourceString name = const SourceString('moveNext'); 3965 SourceString name = const SourceString('moveNext');
3949 Selector selector = new Selector.call( 3966 Selector selector = new Selector.call(
3950 name, currentElement.getLibrary(), 0); 3967 name, currentElement.getLibrary(), 0);
3951 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); 3968 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector);
ngeoffray 2013/02/18 08:35:34 You can remove this hasGetter.
3952 push(new HInvokeDynamicMethod(selector, <HInstruction>[iterator])); 3969 push(new HInvokeDynamicMethod(selector, <HInstruction>[iterator]));
3953 return popBoolified(); 3970 return popBoolified();
3954 } 3971 }
3955 void buildBody() { 3972 void buildBody() {
3956 SourceString name = const SourceString('current'); 3973 SourceString name = const SourceString('current');
3957 Selector call = new Selector.getter(name, currentElement.getLibrary()); 3974 Selector call = new Selector.getter(name, currentElement.getLibrary());
3958 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(call); 3975 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(call);
3959 push(new HInvokeDynamicGetter(call, null, iterator, hasGetter)); 3976 push(new HInvokeDynamicGetter(call, null, iterator, !hasGetter));
3960 3977
3961 Element variable; 3978 Element variable;
3962 if (node.declaredIdentifier.asSend() != null) { 3979 if (node.declaredIdentifier.asSend() != null) {
3963 variable = elements[node.declaredIdentifier]; 3980 variable = elements[node.declaredIdentifier];
3964 } else { 3981 } else {
3965 assert(node.declaredIdentifier.asVariableDefinitions() != null); 3982 assert(node.declaredIdentifier.asVariableDefinitions() != null);
3966 VariableDefinitions variableDefinitions = node.declaredIdentifier; 3983 VariableDefinitions variableDefinitions = node.declaredIdentifier;
3967 variable = elements[variableDefinitions.definitions.nodes.head]; 3984 variable = elements[variableDefinitions.definitions.nodes.head];
3968 } 3985 }
3969 HInstruction oldVariable = pop(); 3986 HInstruction oldVariable = pop();
(...skipping 1106 matching lines...) Expand 10 before | Expand all | Expand 10 after
5076 new HSubGraphBlockInformation(elseBranch.graph)); 5093 new HSubGraphBlockInformation(elseBranch.graph));
5077 5094
5078 HBasicBlock conditionStartBlock = conditionBranch.block; 5095 HBasicBlock conditionStartBlock = conditionBranch.block;
5079 conditionStartBlock.setBlockFlow(info, joinBlock); 5096 conditionStartBlock.setBlockFlow(info, joinBlock);
5080 SubGraph conditionGraph = conditionBranch.graph; 5097 SubGraph conditionGraph = conditionBranch.graph;
5081 HIf branch = conditionGraph.end.last; 5098 HIf branch = conditionGraph.end.last;
5082 assert(branch is HIf); 5099 assert(branch is HIf);
5083 branch.blockInformation = conditionStartBlock.blockFlow; 5100 branch.blockInformation = conditionStartBlock.blockFlow;
5084 } 5101 }
5085 } 5102 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698