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

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

Issue 232563006: Insert checks before deferred calls and accesses. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 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 | 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 implement [TypedElement.type] because our 9 * methods. We need to implement [TypedElement.type] because our
10 * optimizers may look at its declared type. 10 * optimizers may look at its declared type.
(...skipping 1154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 1165
1166 // Bail out early if the inlining decision is in the cache and we can't 1166 // Bail out early if the inlining decision is in the cache and we can't
1167 // inline (no need to check the hard constraints). 1167 // inline (no need to check the hard constraints).
1168 bool cachedCanBeInlined = 1168 bool cachedCanBeInlined =
1169 backend.inlineCache.canInline(function, insideLoop: insideLoop); 1169 backend.inlineCache.canInline(function, insideLoop: insideLoop);
1170 if (cachedCanBeInlined == false) return false; 1170 if (cachedCanBeInlined == false) return false;
1171 1171
1172 bool meetsHardConstraints() { 1172 bool meetsHardConstraints() {
1173 // Don't inline from one output unit to another. If something is deferred 1173 // Don't inline from one output unit to another. If something is deferred
1174 // it is to save space in the loading code. 1174 // it is to save space in the loading code.
1175 var getOutputUnit = compiler.deferredLoadTask.outputUnitForElement; 1175 if (!compiler.deferredLoadTask
1176 if (getOutputUnit(element) != 1176 .inSameOutputUnit(element,compiler.currentElement)) return false;
Johnni Winther 2014/04/11 07:34:54 Add { } around `return false;`.
sigurdm 2014/04/11 09:11:38 Done.
1177 getOutputUnit(compiler.currentElement)) {
1178 return false;
1179 }
1180 if (compiler.disableInlining) return false; 1177 if (compiler.disableInlining) return false;
1181 1178
1182 assert(selector != null 1179 assert(selector != null
1183 || Elements.isStaticOrTopLevel(element) 1180 || Elements.isStaticOrTopLevel(element)
1184 || element.isGenerativeConstructorBody()); 1181 || element.isGenerativeConstructorBody());
1185 if (selector != null && !selector.applies(function, compiler)) { 1182 if (selector != null && !selector.applies(function, compiler)) {
1186 return false; 1183 return false;
1187 } 1184 }
1188 1185
1189 // Don't inline operator== methods if the parameter can be null. 1186 // Don't inline operator== methods if the parameter can be null.
(...skipping 1732 matching lines...) Expand 10 before | Expand all | Expand 10 after
2922 * [selector]. 2919 * [selector].
2923 */ 2920 */
2924 void generateInstanceGetterWithCompiledReceiver(ast.Send send, 2921 void generateInstanceGetterWithCompiledReceiver(ast.Send send,
2925 Selector selector, 2922 Selector selector,
2926 HInstruction receiver) { 2923 HInstruction receiver) {
2927 assert(Elements.isInstanceSend(send, elements)); 2924 assert(Elements.isInstanceSend(send, elements));
2928 assert(selector.isGetter()); 2925 assert(selector.isGetter());
2929 pushInvokeDynamic(send, selector, [receiver]); 2926 pushInvokeDynamic(send, selector, [receiver]);
2930 } 2927 }
2931 2928
2929 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that
2930 /// resolves to a deferred library.
2931 void generateIsDeferredLoadedCheckIfNeeded(ast.Send node){
2932 if (elements[node] != null) {
Johnni Winther 2014/04/11 07:34:54 Is this needed or just an optimization?
sigurdm 2014/04/11 09:11:38 Not needed - I think it was a temporary fix I forg
2933 var deferredTask = compiler.deferredLoadTask;
2934 PrefixElement prefixElement =
2935 deferredTask.deferredPrefixElement(node, elements);
2936 if (prefixElement != null) {
2937 String loadId =
2938 deferredTask.importDeferName[prefixElement.deferredImport];
2939 HInstruction loadIdConstant = addConstantString(loadId);
2940 String uri = prefixElement.deferredImport.uri.dartString.slowToString();
2941 HInstruction uriConstant = addConstantString(uri);
2942 Element helper = backend.getCheckDeferredIsLoaded();
2943 pushInvokeStatic(node, helper, [loadIdConstant, uriConstant]);
2944 pop();
2945 }
2946 }
2947 }
2948
2932 void generateGetter(ast.Send send, Element element) { 2949 void generateGetter(ast.Send send, Element element) {
2933 if (element != null && element.isForeign(compiler)) { 2950 if (element != null && element.isForeign(compiler)) {
2934 visitForeignGetter(send); 2951 visitForeignGetter(send);
2935 } else if (Elements.isStaticOrTopLevelField(element)) { 2952 } else if (Elements.isStaticOrTopLevelField(element)) {
2936 Constant value; 2953 Constant value;
2937 if (element.isField() && !element.isAssignable()) { 2954 if (element.isField() && !element.isAssignable()) {
2938 // A static final or const. Get its constant value and inline it if 2955 // A static final or const. Get its constant value and inline it if
2939 // the value can be compiled eagerly. 2956 // the value can be compiled eagerly.
2940 value = backend.constants.getConstantForVariable(element); 2957 value = backend.constants.getConstantForVariable(element);
2941 } 2958 }
(...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after
3902 // The new object will now be referenced through the 3919 // The new object will now be referenced through the
3903 // `setRuntimeTypeInfo` call. We therefore set the type of that 3920 // `setRuntimeTypeInfo` call. We therefore set the type of that
3904 // instruction to be of the object's type. 3921 // instruction to be of the object's type.
3905 assert(stack.last is HInvokeStatic || stack.last == newObject); 3922 assert(stack.last is HInvokeStatic || stack.last == newObject);
3906 stack.last.instructionType = newObject.instructionType; 3923 stack.last.instructionType = newObject.instructionType;
3907 return pop(); 3924 return pop();
3908 } 3925 }
3909 3926
3910 handleNewSend(ast.NewExpression node) { 3927 handleNewSend(ast.NewExpression node) {
3911 ast.Send send = node.send; 3928 ast.Send send = node.send;
3929 generateIsDeferredLoadedCheckIfNeeded(send);
3930
3912 bool isFixedList = false; 3931 bool isFixedList = false;
3913 bool isFixedListConstructorCall = 3932 bool isFixedListConstructorCall =
3914 Elements.isFixedListConstructorCall(elements[send], send, compiler); 3933 Elements.isFixedListConstructorCall(elements[send], send, compiler);
3915 bool isGrowableListConstructorCall = 3934 bool isGrowableListConstructorCall =
3916 Elements.isGrowableListConstructorCall(elements[send], send, compiler); 3935 Elements.isGrowableListConstructorCall(elements[send], send, compiler);
3917 3936
3918 TypeMask computeType(element) { 3937 TypeMask computeType(element) {
3919 Element originalElement = elements[send]; 3938 Element originalElement = elements[send];
3920 if (isFixedListConstructorCall 3939 if (isFixedListConstructorCall
3921 || Elements.isFilledListConstructorCall( 3940 || Elements.isFilledListConstructorCall(
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
4153 } 4172 }
4154 if (element.isErroneous()) { 4173 if (element.isErroneous()) {
4155 // An erroneous element indicates that the funciton could not be resolved 4174 // An erroneous element indicates that the funciton could not be resolved
4156 // (a warning has been issued). 4175 // (a warning has been issued).
4157 generateThrowNoSuchMethod(node, 4176 generateThrowNoSuchMethod(node,
4158 getTargetName(element), 4177 getTargetName(element),
4159 argumentNodes: node.arguments); 4178 argumentNodes: node.arguments);
4160 return; 4179 return;
4161 } 4180 }
4162 invariant(element, !element.isGenerativeConstructor()); 4181 invariant(element, !element.isGenerativeConstructor());
4182 generateIsDeferredLoadedCheckIfNeeded(node);
4163 if (element.isFunction()) { 4183 if (element.isFunction()) {
4164 var inputs = <HInstruction>[]; 4184 var inputs = <HInstruction>[];
4165 // TODO(5347): Try to avoid the need for calling [implementation] before 4185 // TODO(5347): Try to avoid the need for calling [implementation] before
4166 // calling [addStaticSendArgumentsToList]. 4186 // calling [addStaticSendArgumentsToList].
4167 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 4187 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
4168 element.implementation, 4188 element.implementation,
4169 inputs); 4189 inputs);
4170 if (!succeeded) { 4190 if (!succeeded) {
4171 generateWrongArgumentCountError(node, element, node.arguments); 4191 generateWrongArgumentCountError(node, element, node.arguments);
4172 return; 4192 return;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
4228 HInstruction target = pop(); 4248 HInstruction target = pop();
4229 Selector selector = elements.getSelector(node); 4249 Selector selector = elements.getSelector(node);
4230 List<HInstruction> inputs = <HInstruction>[target]; 4250 List<HInstruction> inputs = <HInstruction>[target];
4231 addDynamicSendArgumentsToList(node, inputs); 4251 addDynamicSendArgumentsToList(node, inputs);
4232 Selector closureSelector = new Selector.callClosureFrom(selector); 4252 Selector closureSelector = new Selector.callClosureFrom(selector);
4233 push(new HInvokeClosure(closureSelector, inputs, backend.dynamicType)); 4253 push(new HInvokeClosure(closureSelector, inputs, backend.dynamicType));
4234 } 4254 }
4235 } 4255 }
4236 4256
4237 visitGetterSend(ast.Send node) { 4257 visitGetterSend(ast.Send node) {
4258 generateIsDeferredLoadedCheckIfNeeded(node);
4238 generateGetter(node, elements[node]); 4259 generateGetter(node, elements[node]);
4239 } 4260 }
4240 4261
4241 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError. 4262 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError.
4242 internalError(String reason, {ast.Node node}) { 4263 internalError(String reason, {ast.Node node}) {
4243 compiler.internalError(node, reason); 4264 compiler.internalError(node, reason);
4244 } 4265 }
4245 4266
4246 void generateError(ast.Node node, String message, Element helper) { 4267 void generateError(ast.Node node, String message, Element helper) {
4247 HInstruction errorMessage = addConstantString(message); 4268 HInstruction errorMessage = addConstantString(message);
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
4496 } else { 4517 } else {
4497 visit(arguments.head); 4518 visit(arguments.head);
4498 assert(arguments.tail.isEmpty); 4519 assert(arguments.tail.isEmpty);
4499 rhs = pop(); 4520 rhs = pop();
4500 } 4521 }
4501 visitBinary(receiver, node.assignmentOperator, rhs, 4522 visitBinary(receiver, node.assignmentOperator, rhs,
4502 elements.getOperatorSelectorInComplexSendSet(node), node); 4523 elements.getOperatorSelectorInComplexSendSet(node), node);
4503 } 4524 }
4504 4525
4505 visitSendSet(ast.SendSet node) { 4526 visitSendSet(ast.SendSet node) {
4527 generateIsDeferredLoadedCheckIfNeeded(node);
4506 Element element = elements[node]; 4528 Element element = elements[node];
4507 if (!Elements.isUnresolved(element) && element.impliesType()) { 4529 if (!Elements.isUnresolved(element) && element.impliesType()) {
4508 ast.Identifier selector = node.selector; 4530 ast.Identifier selector = node.selector;
4509 generateThrowNoSuchMethod(node, selector.source, 4531 generateThrowNoSuchMethod(node, selector.source,
4510 argumentNodes: node.arguments); 4532 argumentNodes: node.arguments);
4511 return; 4533 return;
4512 } 4534 }
4513 ast.Operator op = node.assignmentOperator; 4535 ast.Operator op = node.assignmentOperator;
4514 if (node.isSuperCall) { 4536 if (node.isSuperCall) {
4515 HInstruction result; 4537 HInstruction result;
(...skipping 1742 matching lines...) Expand 10 before | Expand all | Expand 10 after
6258 DartType unaliased = type.unalias(builder.compiler); 6280 DartType unaliased = type.unalias(builder.compiler);
6259 if (unaliased is TypedefType) throw 'unable to unalias $type'; 6281 if (unaliased is TypedefType) throw 'unable to unalias $type';
6260 unaliased.accept(this, builder); 6282 unaliased.accept(this, builder);
6261 } 6283 }
6262 6284
6263 void visitDynamicType(DynamicType type, SsaBuilder builder) { 6285 void visitDynamicType(DynamicType type, SsaBuilder builder) {
6264 ClassElement cls = builder.compiler.findHelper('DynamicRuntimeType'); 6286 ClassElement cls = builder.compiler.findHelper('DynamicRuntimeType');
6265 builder.push(new HDynamicType(type, new TypeMask.exact(cls))); 6287 builder.push(new HDynamicType(type, new TypeMask.exact(cls)));
6266 } 6288 }
6267 } 6289 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698