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

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: Correct update to co19 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)) {
1177 getOutputUnit(compiler.currentElement)) {
1178 return false; 1177 return false;
1179 } 1178 }
1180 if (compiler.disableInlining) return false; 1179 if (compiler.disableInlining) return false;
1181 1180
1182 assert(selector != null 1181 assert(selector != null
1183 || Elements.isStaticOrTopLevel(element) 1182 || Elements.isStaticOrTopLevel(element)
1184 || element.isGenerativeConstructorBody()); 1183 || element.isGenerativeConstructorBody());
1185 if (selector != null && !selector.applies(function, compiler)) { 1184 if (selector != null && !selector.applies(function, compiler)) {
1186 return false; 1185 return false;
1187 } 1186 }
(...skipping 1734 matching lines...) Expand 10 before | Expand all | Expand 10 after
2922 * [selector]. 2921 * [selector].
2923 */ 2922 */
2924 void generateInstanceGetterWithCompiledReceiver(ast.Send send, 2923 void generateInstanceGetterWithCompiledReceiver(ast.Send send,
2925 Selector selector, 2924 Selector selector,
2926 HInstruction receiver) { 2925 HInstruction receiver) {
2927 assert(Elements.isInstanceSend(send, elements)); 2926 assert(Elements.isInstanceSend(send, elements));
2928 assert(selector.isGetter()); 2927 assert(selector.isGetter());
2929 pushInvokeDynamic(send, selector, [receiver]); 2928 pushInvokeDynamic(send, selector, [receiver]);
2930 } 2929 }
2931 2930
2931 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that
2932 /// resolves to a deferred library.
2933 void generateIsDeferredLoadedCheckIfNeeded(ast.Send node) {
2934 DeferredLoadTask deferredTask = compiler.deferredLoadTask;
2935 PrefixElement prefixElement =
2936 deferredTask.deferredPrefixElement(node, elements);
2937 if (prefixElement != null) {
2938 String loadId =
2939 deferredTask.importDeferName[prefixElement.deferredImport];
2940 HInstruction loadIdConstant = addConstantString(loadId);
2941 String uri = prefixElement.deferredImport.uri.dartString.slowToString();
2942 HInstruction uriConstant = addConstantString(uri);
2943 Element helper = backend.getCheckDeferredIsLoaded();
2944 pushInvokeStatic(node, helper, [loadIdConstant, uriConstant]);
2945 pop();
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 972 matching lines...) Expand 10 before | Expand all | Expand 10 after
3914 // The new object will now be referenced through the 3931 // The new object will now be referenced through the
3915 // `setRuntimeTypeInfo` call. We therefore set the type of that 3932 // `setRuntimeTypeInfo` call. We therefore set the type of that
3916 // instruction to be of the object's type. 3933 // instruction to be of the object's type.
3917 assert(stack.last is HInvokeStatic || stack.last == newObject); 3934 assert(stack.last is HInvokeStatic || stack.last == newObject);
3918 stack.last.instructionType = newObject.instructionType; 3935 stack.last.instructionType = newObject.instructionType;
3919 return pop(); 3936 return pop();
3920 } 3937 }
3921 3938
3922 handleNewSend(ast.NewExpression node) { 3939 handleNewSend(ast.NewExpression node) {
3923 ast.Send send = node.send; 3940 ast.Send send = node.send;
3941 generateIsDeferredLoadedCheckIfNeeded(send);
3942
3924 bool isFixedList = false; 3943 bool isFixedList = false;
3925 bool isFixedListConstructorCall = 3944 bool isFixedListConstructorCall =
3926 Elements.isFixedListConstructorCall(elements[send], send, compiler); 3945 Elements.isFixedListConstructorCall(elements[send], send, compiler);
3927 bool isGrowableListConstructorCall = 3946 bool isGrowableListConstructorCall =
3928 Elements.isGrowableListConstructorCall(elements[send], send, compiler); 3947 Elements.isGrowableListConstructorCall(elements[send], send, compiler);
3929 3948
3930 TypeMask computeType(element) { 3949 TypeMask computeType(element) {
3931 Element originalElement = elements[send]; 3950 Element originalElement = elements[send];
3932 if (isFixedListConstructorCall 3951 if (isFixedListConstructorCall
3933 || Elements.isFilledListConstructorCall( 3952 || Elements.isFilledListConstructorCall(
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
4165 } 4184 }
4166 if (element.isErroneous()) { 4185 if (element.isErroneous()) {
4167 // An erroneous element indicates that the funciton could not be resolved 4186 // An erroneous element indicates that the funciton could not be resolved
4168 // (a warning has been issued). 4187 // (a warning has been issued).
4169 generateThrowNoSuchMethod(node, 4188 generateThrowNoSuchMethod(node,
4170 getTargetName(element), 4189 getTargetName(element),
4171 argumentNodes: node.arguments); 4190 argumentNodes: node.arguments);
4172 return; 4191 return;
4173 } 4192 }
4174 invariant(element, !element.isGenerativeConstructor()); 4193 invariant(element, !element.isGenerativeConstructor());
4194 generateIsDeferredLoadedCheckIfNeeded(node);
4175 if (element.isFunction()) { 4195 if (element.isFunction()) {
4176 var inputs = <HInstruction>[]; 4196 var inputs = <HInstruction>[];
4177 // TODO(5347): Try to avoid the need for calling [implementation] before 4197 // TODO(5347): Try to avoid the need for calling [implementation] before
4178 // calling [addStaticSendArgumentsToList]. 4198 // calling [addStaticSendArgumentsToList].
4179 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 4199 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
4180 element.implementation, 4200 element.implementation,
4181 inputs); 4201 inputs);
4182 if (!succeeded) { 4202 if (!succeeded) {
4183 generateWrongArgumentCountError(node, element, node.arguments); 4203 generateWrongArgumentCountError(node, element, node.arguments);
4184 return; 4204 return;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
4240 HInstruction target = pop(); 4260 HInstruction target = pop();
4241 Selector selector = elements.getSelector(node); 4261 Selector selector = elements.getSelector(node);
4242 List<HInstruction> inputs = <HInstruction>[target]; 4262 List<HInstruction> inputs = <HInstruction>[target];
4243 addDynamicSendArgumentsToList(node, inputs); 4263 addDynamicSendArgumentsToList(node, inputs);
4244 Selector closureSelector = new Selector.callClosureFrom(selector); 4264 Selector closureSelector = new Selector.callClosureFrom(selector);
4245 push(new HInvokeClosure(closureSelector, inputs, backend.dynamicType)); 4265 push(new HInvokeClosure(closureSelector, inputs, backend.dynamicType));
4246 } 4266 }
4247 } 4267 }
4248 4268
4249 visitGetterSend(ast.Send node) { 4269 visitGetterSend(ast.Send node) {
4270 generateIsDeferredLoadedCheckIfNeeded(node);
4250 generateGetter(node, elements[node]); 4271 generateGetter(node, elements[node]);
4251 } 4272 }
4252 4273
4253 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError. 4274 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError.
4254 internalError(String reason, {ast.Node node}) { 4275 internalError(String reason, {ast.Node node}) {
4255 compiler.internalError(node, reason); 4276 compiler.internalError(node, reason);
4256 } 4277 }
4257 4278
4258 void generateError(ast.Node node, String message, Element helper) { 4279 void generateError(ast.Node node, String message, Element helper) {
4259 HInstruction errorMessage = addConstantString(message); 4280 HInstruction errorMessage = addConstantString(message);
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
4508 } else { 4529 } else {
4509 visit(arguments.head); 4530 visit(arguments.head);
4510 assert(arguments.tail.isEmpty); 4531 assert(arguments.tail.isEmpty);
4511 rhs = pop(); 4532 rhs = pop();
4512 } 4533 }
4513 visitBinary(receiver, node.assignmentOperator, rhs, 4534 visitBinary(receiver, node.assignmentOperator, rhs,
4514 elements.getOperatorSelectorInComplexSendSet(node), node); 4535 elements.getOperatorSelectorInComplexSendSet(node), node);
4515 } 4536 }
4516 4537
4517 visitSendSet(ast.SendSet node) { 4538 visitSendSet(ast.SendSet node) {
4539 generateIsDeferredLoadedCheckIfNeeded(node);
4518 Element element = elements[node]; 4540 Element element = elements[node];
4519 if (!Elements.isUnresolved(element) && element.impliesType()) { 4541 if (!Elements.isUnresolved(element) && element.impliesType()) {
4520 ast.Identifier selector = node.selector; 4542 ast.Identifier selector = node.selector;
4521 generateThrowNoSuchMethod(node, selector.source, 4543 generateThrowNoSuchMethod(node, selector.source,
4522 argumentNodes: node.arguments); 4544 argumentNodes: node.arguments);
4523 return; 4545 return;
4524 } 4546 }
4525 ast.Operator op = node.assignmentOperator; 4547 ast.Operator op = node.assignmentOperator;
4526 if (node.isSuperCall) { 4548 if (node.isSuperCall) {
4527 HInstruction result; 4549 HInstruction result;
(...skipping 1742 matching lines...) Expand 10 before | Expand all | Expand 10 after
6270 DartType unaliased = type.unalias(builder.compiler); 6292 DartType unaliased = type.unalias(builder.compiler);
6271 if (unaliased is TypedefType) throw 'unable to unalias $type'; 6293 if (unaliased is TypedefType) throw 'unable to unalias $type';
6272 unaliased.accept(this, builder); 6294 unaliased.accept(this, builder);
6273 } 6295 }
6274 6296
6275 void visitDynamicType(DynamicType type, SsaBuilder builder) { 6297 void visitDynamicType(DynamicType type, SsaBuilder builder) {
6276 ClassElement cls = builder.compiler.findHelper('DynamicRuntimeType'); 6298 ClassElement cls = builder.compiler.findHelper('DynamicRuntimeType');
6277 builder.push(new HDynamicType(type, new TypeMask.exact(cls))); 6299 builder.push(new HDynamicType(type, new TypeMask.exact(cls)));
6278 } 6300 }
6279 } 6301 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698