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

Side by Side Diff: pkg/compiler/lib/src/ssa/builder.dart

Issue 2608273002: Reduce use of Element in optimize.dart (Closed)
Patch Set: Fix. Created 3 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
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 import 'dart:collection'; 5 import 'dart:collection';
6 6
7 import 'package:js_runtime/shared/embedded_names.dart'; 7 import 'package:js_runtime/shared/embedded_names.dart';
8 8
9 import '../closure.dart'; 9 import '../closure.dart';
10 import '../common.dart'; 10 import '../common.dart';
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 SsaBuilderTask(JavaScriptBackend backend, this.sourceInformationFactory) 61 SsaBuilderTask(JavaScriptBackend backend, this.sourceInformationFactory)
62 : emitter = backend.emitter, 62 : emitter = backend.emitter,
63 backend = backend, 63 backend = backend,
64 compiler = backend.compiler, 64 compiler = backend.compiler,
65 super(backend.compiler.measurer); 65 super(backend.compiler.measurer);
66 66
67 DiagnosticReporter get reporter => compiler.reporter; 67 DiagnosticReporter get reporter => compiler.reporter;
68 68
69 HGraph build(CodegenWorkItem work, ClosedWorld closedWorld) { 69 HGraph build(CodegenWorkItem work, ClosedWorld closedWorld) {
70 return measure(() { 70 return measure(() {
71 Element element = work.element.implementation; 71 MemberElement element = work.element.implementation;
72 return reporter.withCurrentElement(element, () { 72 return reporter.withCurrentElement(element, () {
73 SsaBuilder builder = new SsaBuilder( 73 SsaBuilder builder = new SsaBuilder(
74 work.element.implementation, 74 work.element.implementation,
75 work.resolvedAst, 75 work.resolvedAst,
76 work.registry, 76 work.registry,
77 backend, 77 backend,
78 closedWorld, 78 closedWorld,
79 emitter.nativeEmitter, 79 emitter.nativeEmitter,
80 sourceInformationFactory); 80 sourceInformationFactory);
81 HGraph graph = builder.build(); 81 HGraph graph = builder.build();
82 82
83 // Default arguments are handled elsewhere, but we must ensure 83 // Default arguments are handled elsewhere, but we must ensure
84 // that the default values are computed during codegen. 84 // that the default values are computed during codegen.
85 if (!identical(element.kind, ElementKind.FIELD)) { 85 if (!identical(element.kind, ElementKind.FIELD)) {
86 FunctionElement function = element; 86 MethodElement function = element;
87 FunctionSignature signature = function.functionSignature; 87 FunctionSignature signature = function.functionSignature;
88 signature.forEachOptionalParameter((ParameterElement parameter) { 88 signature.forEachOptionalParameter((ParameterElement parameter) {
89 // This ensures the default value will be computed. 89 // This ensures the default value will be computed.
90 ConstantValue constant = 90 ConstantValue constant =
91 backend.constants.getConstantValue(parameter.constant); 91 backend.constants.getConstantValue(parameter.constant);
92 work.registry.registerCompileTimeConstant(constant); 92 work.registry.registerCompileTimeConstant(constant);
93 }); 93 });
94 } 94 }
95 if (backend.tracer.isEnabled) { 95 if (backend.tracer.isEnabled) {
96 String name; 96 String name;
(...skipping 23 matching lines...) Expand all
120 with 120 with
121 BaseImplementationOfCompoundsMixin, 121 BaseImplementationOfCompoundsMixin,
122 BaseImplementationOfSetIfNullsMixin, 122 BaseImplementationOfSetIfNullsMixin,
123 BaseImplementationOfSuperIndexSetIfNullMixin, 123 BaseImplementationOfSuperIndexSetIfNullMixin,
124 SemanticSendResolvedMixin, 124 SemanticSendResolvedMixin,
125 NewBulkMixin, 125 NewBulkMixin,
126 ErrorBulkMixin, 126 ErrorBulkMixin,
127 GraphBuilder 127 GraphBuilder
128 implements SemanticSendVisitor { 128 implements SemanticSendVisitor {
129 /// The element for which this SSA builder is being used. 129 /// The element for which this SSA builder is being used.
130 final Element target; 130 final MemberElement target;
131 final ClosedWorld closedWorld; 131 final ClosedWorld closedWorld;
132 132
133 ResolvedAst resolvedAst; 133 ResolvedAst resolvedAst;
134 134
135 /// Used to report information about inlining (which occurs while building the 135 /// Used to report information about inlining (which occurs while building the
136 /// SSA graph), when dump-info is enabled. 136 /// SSA graph), when dump-info is enabled.
137 final InfoReporter infoReporter; 137 final InfoReporter infoReporter;
138 138
139 /// Registry used to enqueue work during codegen, may be null to avoid 139 /// Registry used to enqueue work during codegen, may be null to avoid
140 /// enqueing any work. 140 /// enqueing any work.
(...skipping 29 matching lines...) Expand all
170 /** 170 /**
171 * True if we are visiting the expression of a throw statement; we assume this 171 * True if we are visiting the expression of a throw statement; we assume this
172 * is a slow path. 172 * is a slow path.
173 */ 173 */
174 bool inExpressionOfThrow = false; 174 bool inExpressionOfThrow = false;
175 175
176 /** 176 /**
177 * This stack contains declaration elements of the functions being built 177 * This stack contains declaration elements of the functions being built
178 * or inlined by this builder. 178 * or inlined by this builder.
179 */ 179 */
180 final List<Element> sourceElementStack = <Element>[]; 180 final List<MemberElement> sourceElementStack = <MemberElement>[];
181 181
182 HInstruction rethrowableException; 182 HInstruction rethrowableException;
183 183
184 /// Returns `true` if the current element is an `async` function. 184 /// Returns `true` if the current element is an `async` function.
185 bool get isBuildingAsyncFunction { 185 bool get isBuildingAsyncFunction {
186 Element element = sourceElement; 186 Element element = sourceElement;
187 return (element is FunctionElement && 187 return (element is FunctionElement &&
188 element.asyncMarker == AsyncMarker.ASYNC); 188 element.asyncMarker == AsyncMarker.ASYNC);
189 } 189 }
190 190
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 void apply(ast.Node node, [_]) { 248 void apply(ast.Node node, [_]) {
249 node.accept(this); 249 node.accept(this);
250 } 250 }
251 251
252 /// Returns the current source element. 252 /// Returns the current source element.
253 /// 253 ///
254 /// The returned element is a declaration element. 254 /// The returned element is a declaration element.
255 // TODO(johnniwinther): Check that all usages of sourceElement agree on 255 // TODO(johnniwinther): Check that all usages of sourceElement agree on
256 // implementation/declaration distinction. 256 // implementation/declaration distinction.
257 @override 257 @override
258 Element get sourceElement => sourceElementStack.last; 258 MemberElement get sourceElement => sourceElementStack.last;
259 259
260 /// Helper to retrieve global inference results for [element] with special 260 /// Helper to retrieve global inference results for [element] with special
261 /// care for `ConstructorBodyElement`s which don't exist at the time the 261 /// care for `ConstructorBodyElement`s which don't exist at the time the
262 /// global analysis run. 262 /// global analysis run.
263 /// 263 ///
264 /// Note: this helper is used selectively. When we know that we are in a 264 /// Note: this helper is used selectively. When we know that we are in a
265 /// context were we don't expect to see a constructor body element, we 265 /// context were we don't expect to see a constructor body element, we
266 /// directly fetch the data from the global inference results. 266 /// directly fetch the data from the global inference results.
267 GlobalTypeInferenceElementResult _resultOf(AstElement element) => 267 GlobalTypeInferenceElementResult _resultOf(AstElement element) =>
268 inferenceResults.resultOf( 268 inferenceResults.resultOf(
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 // Bail out early if the inlining decision is in the cache and we can't 430 // Bail out early if the inlining decision is in the cache and we can't
431 // inline (no need to check the hard constraints). 431 // inline (no need to check the hard constraints).
432 bool cachedCanBeInlined = 432 bool cachedCanBeInlined =
433 backend.inlineCache.canInline(function, insideLoop: insideLoop); 433 backend.inlineCache.canInline(function, insideLoop: insideLoop);
434 if (cachedCanBeInlined == false) return false; 434 if (cachedCanBeInlined == false) return false;
435 435
436 bool meetsHardConstraints() { 436 bool meetsHardConstraints() {
437 if (compiler.options.disableInlining) return false; 437 if (compiler.options.disableInlining) return false;
438 438
439 assert(invariant( 439 assert(invariant(
440 currentNode != null ? currentNode : element, 440 currentNode != null ? currentNode : function,
441 selector != null || 441 selector != null ||
442 Elements.isStaticOrTopLevel(element) || 442 Elements.isStaticOrTopLevel(function) ||
443 element.isGenerativeConstructorBody, 443 function.isGenerativeConstructorBody,
444 message: "Missing selector for inlining of $element.")); 444 message: "Missing selector for inlining of $function."));
445 if (selector != null) { 445 if (selector != null) {
446 if (!selector.applies(function)) return false; 446 if (!selector.applies(function)) return false;
447 if (mask != null && !mask.canHit(function, selector, closedWorld)) { 447 if (mask != null && !mask.canHit(function, selector, closedWorld)) {
448 return false; 448 return false;
449 } 449 }
450 } 450 }
451 451
452 if (backend.isJsInterop(element)) return false; 452 if (backend.isJsInterop(function)) return false;
453 453
454 // Don't inline operator== methods if the parameter can be null. 454 // Don't inline operator== methods if the parameter can be null.
455 if (element.name == '==') { 455 if (function.name == '==') {
456 if (element.enclosingClass != commonElements.objectClass && 456 if (function.enclosingClass != commonElements.objectClass &&
457 providedArguments[1].canBeNull()) { 457 providedArguments[1].canBeNull()) {
458 return false; 458 return false;
459 } 459 }
460 } 460 }
461 461
462 // Generative constructors of native classes should not be called directly 462 // Generative constructors of native classes should not be called directly
463 // and have an extra argument that causes problems with inlining. 463 // and have an extra argument that causes problems with inlining.
464 if (element.isGenerativeConstructor && 464 if (function.isGenerativeConstructor &&
465 backend.isNativeOrExtendsNative(element.enclosingClass)) { 465 backend.isNativeOrExtendsNative(function.enclosingClass)) {
466 return false; 466 return false;
467 } 467 }
468 468
469 // A generative constructor body is not seen by global analysis, 469 // A generative constructor body is not seen by global analysis,
470 // so we should not query for its type. 470 // so we should not query for its type.
471 if (!element.isGenerativeConstructorBody) { 471 if (!function.isGenerativeConstructorBody) {
472 if (inferenceResults.resultOf(element).throwsAlways) { 472 if (inferenceResults.resultOf(function).throwsAlways) {
473 isReachable = false; 473 isReachable = false;
474 return false; 474 return false;
475 } 475 }
476 } 476 }
477 477
478 return true; 478 return true;
479 } 479 }
480 480
481 bool doesNotContainCode() { 481 bool doesNotContainCode() {
482 // A function with size 1 does not contain any code. 482 // A function with size 1 does not contain any code.
483 return InlineWeeder.canBeInlined(functionResolvedAst, 1, true, 483 return InlineWeeder.canBeInlined(functionResolvedAst, 1, true,
484 enableUserAssertions: compiler.options.enableUserAssertions); 484 enableUserAssertions: compiler.options.enableUserAssertions);
485 } 485 }
486 486
487 bool reductiveHeuristic() { 487 bool reductiveHeuristic() {
488 // The call is on a path which is executed rarely, so inline only if it 488 // The call is on a path which is executed rarely, so inline only if it
489 // does not make the program larger. 489 // does not make the program larger.
490 if (isCalledOnce(element)) { 490 if (isCalledOnce(function)) {
491 return InlineWeeder.canBeInlined(functionResolvedAst, -1, false, 491 return InlineWeeder.canBeInlined(functionResolvedAst, -1, false,
492 enableUserAssertions: compiler.options.enableUserAssertions); 492 enableUserAssertions: compiler.options.enableUserAssertions);
493 } 493 }
494 // TODO(sra): Measure if inlining would 'reduce' the size. One desirable 494 // TODO(sra): Measure if inlining would 'reduce' the size. One desirable
495 // case we miss by doing nothing is inlining very simple constructors 495 // case we miss by doing nothing is inlining very simple constructors
496 // where all fields are initialized with values from the arguments at this 496 // where all fields are initialized with values from the arguments at this
497 // call site. The code is slightly larger (`new Foo(1)` vs `Foo$(1)`) but 497 // call site. The code is slightly larger (`new Foo(1)` vs `Foo$(1)`) but
498 // that usually means the factory constructor is left unused and not 498 // that usually means the factory constructor is left unused and not
499 // emitted. 499 // emitted.
500 // We at least inline bodies that are empty (and thus have a size of 1). 500 // We at least inline bodies that are empty (and thus have a size of 1).
501 return doesNotContainCode(); 501 return doesNotContainCode();
502 } 502 }
503 503
504 bool heuristicSayGoodToGo() { 504 bool heuristicSayGoodToGo() {
505 // Don't inline recursively 505 // Don't inline recursively
506 if (inliningStack.any((entry) => entry.function == function)) { 506 if (inliningStack.any((entry) => entry.function == function)) {
507 return false; 507 return false;
508 } 508 }
509 509
510 if (element.isSynthesized) return true; 510 if (function.isSynthesized) return true;
511 511
512 // Don't inline across deferred import to prevent leaking code. The only 512 // Don't inline across deferred import to prevent leaking code. The only
513 // exception is an empty function (which does not contain code). 513 // exception is an empty function (which does not contain code).
514 bool hasOnlyNonDeferredImportPaths = compiler.deferredLoadTask 514 bool hasOnlyNonDeferredImportPaths = compiler.deferredLoadTask
515 .hasOnlyNonDeferredImportPaths(compiler.currentElement, element); 515 .hasOnlyNonDeferredImportPaths(compiler.currentElement, function);
516 516
517 if (!hasOnlyNonDeferredImportPaths) { 517 if (!hasOnlyNonDeferredImportPaths) {
518 return doesNotContainCode(); 518 return doesNotContainCode();
519 } 519 }
520 520
521 // Do not inline code that is rarely executed unless it reduces size. 521 // Do not inline code that is rarely executed unless it reduces size.
522 if (inExpressionOfThrow || inLazyInitializerExpression) { 522 if (inExpressionOfThrow || inLazyInitializerExpression) {
523 return reductiveHeuristic(); 523 return reductiveHeuristic();
524 } 524 }
525 525
(...skipping 13 matching lines...) Expand all
539 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP + 539 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP +
540 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters; 540 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters;
541 } else { 541 } else {
542 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP + 542 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP +
543 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters; 543 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters;
544 } 544 }
545 545
546 // If a method is called only once, and all the methods in the 546 // If a method is called only once, and all the methods in the
547 // inlining stack are called only once as well, we know we will 547 // inlining stack are called only once as well, we know we will
548 // save on output size by inlining this method. 548 // save on output size by inlining this method.
549 if (isCalledOnce(element)) { 549 if (isCalledOnce(function)) {
550 useMaxInliningNodes = false; 550 useMaxInliningNodes = false;
551 } 551 }
552 bool canInline; 552 bool canInline;
553 canInline = InlineWeeder.canBeInlined( 553 canInline = InlineWeeder.canBeInlined(
554 functionResolvedAst, maxInliningNodes, useMaxInliningNodes, 554 functionResolvedAst, maxInliningNodes, useMaxInliningNodes,
555 enableUserAssertions: compiler.options.enableUserAssertions); 555 enableUserAssertions: compiler.options.enableUserAssertions);
556 if (canInline) { 556 if (canInline) {
557 backend.inlineCache.markAsInlinable(element, insideLoop: insideLoop); 557 backend.inlineCache.markAsInlinable(function, insideLoop: insideLoop);
558 } else { 558 } else {
559 backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop); 559 backend.inlineCache
560 .markAsNonInlinable(function, insideLoop: insideLoop);
560 } 561 }
561 return canInline; 562 return canInline;
562 } 563 }
563 564
564 void doInlining() { 565 void doInlining() {
565 // Add an explicit null check on the receiver before doing the 566 // Add an explicit null check on the receiver before doing the
566 // inlining. We use [element] to get the same name in the 567 // inlining. We use [element] to get the same name in the
567 // NoSuchMethodError message as if we had called it. 568 // NoSuchMethodError message as if we had called it.
568 if (element.isInstanceMember && 569 if (function.isInstanceMember &&
569 !element.isGenerativeConstructorBody && 570 !function.isGenerativeConstructorBody &&
570 (mask == null || mask.isNullable)) { 571 (mask == null || mask.isNullable)) {
571 addWithPosition( 572 addWithPosition(
572 new HFieldGet(null, providedArguments[0], commonMasks.dynamicType, 573 new HFieldGet(null, providedArguments[0], commonMasks.dynamicType,
573 isAssignable: false), 574 isAssignable: false),
574 currentNode); 575 currentNode);
575 } 576 }
576 List<HInstruction> compiledArguments = completeSendArgumentsList( 577 List<HInstruction> compiledArguments = completeSendArgumentsList(
577 function, selector, providedArguments, currentNode); 578 function, selector, providedArguments, currentNode);
578 enterInlinedMethod(function, functionResolvedAst, compiledArguments, 579 enterInlinedMethod(function, functionResolvedAst, compiledArguments,
579 instanceType: instanceType); 580 instanceType: instanceType);
580 inlinedFrom(functionResolvedAst, () { 581 inlinedFrom(functionResolvedAst, () {
581 if (!isReachable) { 582 if (!isReachable) {
582 emitReturn(graph.addConstantNull(closedWorld), null); 583 emitReturn(graph.addConstantNull(closedWorld), null);
583 } else { 584 } else {
584 doInline(functionResolvedAst); 585 doInline(functionResolvedAst);
585 } 586 }
586 }); 587 });
587 leaveInlinedMethod(); 588 leaveInlinedMethod();
588 } 589 }
589 590
590 if (meetsHardConstraints() && heuristicSayGoodToGo()) { 591 if (meetsHardConstraints() && heuristicSayGoodToGo()) {
591 doInlining(); 592 doInlining();
592 infoReporter?.reportInlined(element, 593 infoReporter?.reportInlined(function,
593 inliningStack.isEmpty ? target : inliningStack.last.function); 594 inliningStack.isEmpty ? target : inliningStack.last.function);
594 return true; 595 return true;
595 } 596 }
596 597
597 return false; 598 return false;
598 } 599 }
599 600
600 bool get allInlinedFunctionsCalledOnce { 601 bool get allInlinedFunctionsCalledOnce {
601 return inliningStack.isEmpty || inliningStack.last.allFunctionsCalledOnce; 602 return inliningStack.isEmpty || inliningStack.last.allFunctionsCalledOnce;
602 } 603 }
603 604
604 bool isFunctionCalledOnce(element) { 605 bool isFunctionCalledOnce(MethodElement element) {
605 // ConstructorBodyElements are not in the type inference graph. 606 // ConstructorBodyElements are not in the type inference graph.
606 if (element is ConstructorBodyElement) return false; 607 if (element is ConstructorBodyElement) return false;
607 return inferenceResults.resultOf(element).isCalledOnce; 608 return inferenceResults.resultOf(element).isCalledOnce;
608 } 609 }
609 610
610 bool isCalledOnce(Element element) { 611 bool isCalledOnce(MethodElement element) {
611 return allInlinedFunctionsCalledOnce && isFunctionCalledOnce(element); 612 return allInlinedFunctionsCalledOnce && isFunctionCalledOnce(element);
612 } 613 }
613 614
614 inlinedFrom(ResolvedAst resolvedAst, f()) { 615 inlinedFrom(ResolvedAst resolvedAst, f()) {
615 Element element = resolvedAst.element; 616 MemberElement element = resolvedAst.element;
616 assert(element is FunctionElement || element is VariableElement); 617 assert(element is FunctionElement || element is VariableElement);
617 return reporter.withCurrentElement(element.implementation, () { 618 return reporter.withCurrentElement(element.implementation, () {
618 // The [sourceElementStack] contains declaration elements. 619 // The [sourceElementStack] contains declaration elements.
619 SourceInformationBuilder oldSourceInformationBuilder = 620 SourceInformationBuilder oldSourceInformationBuilder =
620 sourceInformationBuilder; 621 sourceInformationBuilder;
621 sourceInformationBuilder = 622 sourceInformationBuilder =
622 sourceInformationBuilder.forContext(resolvedAst); 623 sourceInformationBuilder.forContext(resolvedAst);
623 sourceElementStack.add(element.declaration); 624 sourceElementStack.add(element.declaration);
624 var result = f(); 625 var result = f();
625 sourceInformationBuilder = oldSourceInformationBuilder; 626 sourceInformationBuilder = oldSourceInformationBuilder;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 679
679 HInstruction addConstant(ast.Node node) { 680 HInstruction addConstant(ast.Node node) {
680 return graph.addConstant(getConstantForNode(node), closedWorld); 681 return graph.addConstant(getConstantForNode(node), closedWorld);
681 } 682 }
682 683
683 /** 684 /**
684 * Documentation wanted -- johnniwinther 685 * Documentation wanted -- johnniwinther
685 * 686 *
686 * Invariant: [functionElement] must be an implementation element. 687 * Invariant: [functionElement] must be an implementation element.
687 */ 688 */
688 HGraph buildMethod(FunctionElement functionElement) { 689 HGraph buildMethod(MethodElement functionElement) {
689 assert(invariant(functionElement, functionElement.isImplementation)); 690 assert(invariant(functionElement, functionElement.isImplementation));
690 graph.calledInLoop = closedWorld.isCalledInLoop(functionElement); 691 graph.calledInLoop = closedWorld.isCalledInLoop(functionElement);
691 ast.FunctionExpression function = resolvedAst.node; 692 ast.FunctionExpression function = resolvedAst.node;
692 assert(function != null); 693 assert(function != null);
693 assert(elements.getFunctionDefinition(function) != null); 694 assert(elements.getFunctionDefinition(function) != null);
694 openFunction(functionElement, function); 695 openFunction(functionElement, function);
695 String name = functionElement.name; 696 String name = functionElement.name;
696 if (backend.isJsInterop(functionElement)) { 697 if (backend.isJsInterop(functionElement)) {
697 push(invokeJsInteropFunction(functionElement, parameters.values.toList(), 698 push(invokeJsInteropFunction(functionElement, parameters.values.toList(),
698 sourceInformationBuilder.buildGeneric(function))); 699 sourceInformationBuilder.buildGeneric(function)));
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 // Add the parameter as the last instruction of the entry block. 762 // Add the parameter as the last instruction of the entry block.
762 // If the method is intercepted, we want the actual receiver 763 // If the method is intercepted, we want the actual receiver
763 // to be the first parameter. 764 // to be the first parameter.
764 graph.entry.addBefore(graph.entry.last, parameter); 765 graph.entry.addBefore(graph.entry.last, parameter);
765 HInstruction value = 766 HInstruction value =
766 typeBuilder.potentiallyCheckOrTrustType(parameter, field.type); 767 typeBuilder.potentiallyCheckOrTrustType(parameter, field.type);
767 add(new HFieldSet(field, thisInstruction, value)); 768 add(new HFieldSet(field, thisInstruction, value));
768 return closeFunction(); 769 return closeFunction();
769 } 770 }
770 771
771 HGraph buildLazyInitializer(VariableElement variable) { 772 HGraph buildLazyInitializer(FieldElement variable) {
772 assert(invariant(variable, resolvedAst.element == variable, 773 assert(invariant(variable, resolvedAst.element == variable,
773 message: "Unexpected variable $variable for $resolvedAst.")); 774 message: "Unexpected variable $variable for $resolvedAst."));
774 inLazyInitializerExpression = true; 775 inLazyInitializerExpression = true;
775 ast.VariableDefinitions node = resolvedAst.node; 776 ast.VariableDefinitions node = resolvedAst.node;
776 ast.Node initializer = resolvedAst.body; 777 ast.Node initializer = resolvedAst.body;
777 assert(invariant(variable, initializer != null, 778 assert(invariant(variable, initializer != null,
778 message: "Non-constant variable $variable has no initializer.")); 779 message: "Non-constant variable $variable has no initializer."));
779 openFunction(variable, node); 780 openFunction(variable, node);
780 visit(initializer); 781 visit(initializer);
781 HInstruction value = pop(); 782 HInstruction value = pop();
(...skipping 5623 matching lines...) Expand 10 before | Expand all | Expand 10 after
6405 } 6406 }
6406 6407
6407 visitTypeVariable(ast.TypeVariable node) { 6408 visitTypeVariable(ast.TypeVariable node) {
6408 reporter.internalError(node, 'SsaFromAstMixin.visitTypeVariable.'); 6409 reporter.internalError(node, 'SsaFromAstMixin.visitTypeVariable.');
6409 } 6410 }
6410 6411
6411 /** 6412 /**
6412 * This method is invoked before inlining the body of [function] into this 6413 * This method is invoked before inlining the body of [function] into this
6413 * [SsaBuilder]. 6414 * [SsaBuilder].
6414 */ 6415 */
6415 void enterInlinedMethod(FunctionElement function, 6416 void enterInlinedMethod(MethodElement function,
6416 ResolvedAst functionResolvedAst, List<HInstruction> compiledArguments, 6417 ResolvedAst functionResolvedAst, List<HInstruction> compiledArguments,
6417 {InterfaceType instanceType}) { 6418 {InterfaceType instanceType}) {
6418 AstInliningState state = new AstInliningState( 6419 AstInliningState state = new AstInliningState(
6419 function, 6420 function,
6420 returnLocal, 6421 returnLocal,
6421 returnType, 6422 returnType,
6422 resolvedAst, 6423 resolvedAst,
6423 stack, 6424 stack,
6424 localsHandler, 6425 localsHandler,
6425 inTryStatement, 6426 inTryStatement,
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
6754 this.oldReturnLocal, 6755 this.oldReturnLocal,
6755 this.oldReturnType, 6756 this.oldReturnType,
6756 this.oldResolvedAst, 6757 this.oldResolvedAst,
6757 this.oldStack, 6758 this.oldStack,
6758 this.oldLocalsHandler, 6759 this.oldLocalsHandler,
6759 this.inTryStatement, 6760 this.inTryStatement,
6760 this.allFunctionsCalledOnce, 6761 this.allFunctionsCalledOnce,
6761 this.oldElementInferenceResults) 6762 this.oldElementInferenceResults)
6762 : super(function); 6763 : super(function);
6763 } 6764 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698