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

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

Issue 23003031: Extract interceptor calls from raw is-checks. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments. Created 7 years, 3 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 13 matching lines...) Expand all
24 String get name => 'SSA builder'; 24 String get name => 'SSA builder';
25 25
26 SsaBuilderTask(JavaScriptBackend backend) 26 SsaBuilderTask(JavaScriptBackend backend)
27 : emitter = backend.emitter, 27 : emitter = backend.emitter,
28 backend = backend, 28 backend = backend,
29 super(backend.compiler); 29 super(backend.compiler);
30 30
31 HGraph build(CodegenWorkItem work) { 31 HGraph build(CodegenWorkItem work) {
32 return measure(() { 32 return measure(() {
33 Element element = work.element.implementation; 33 Element element = work.element.implementation;
34 HInstruction.idCounter = 0; 34 return compiler.withCurrentElement(element, () {
35 ConstantSystem constantSystem = compiler.backend.constantSystem; 35 HInstruction.idCounter = 0;
36 SsaBuilder builder = new SsaBuilder(constantSystem, this, work); 36 ConstantSystem constantSystem = compiler.backend.constantSystem;
37 HGraph graph; 37 SsaBuilder builder = new SsaBuilder(constantSystem, this, work);
38 ElementKind kind = element.kind; 38 HGraph graph;
39 if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) { 39 ElementKind kind = element.kind;
40 graph = compileConstructor(builder, work); 40 if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
41 } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY || 41 graph = compileConstructor(builder, work);
42 kind == ElementKind.FUNCTION || 42 } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
43 kind == ElementKind.GETTER || 43 kind == ElementKind.FUNCTION ||
44 kind == ElementKind.SETTER) { 44 kind == ElementKind.GETTER ||
45 graph = builder.buildMethod(element); 45 kind == ElementKind.SETTER) {
46 } else if (kind == ElementKind.FIELD) { 46 graph = builder.buildMethod(element);
47 assert(!element.isInstanceMember()); 47 } else if (kind == ElementKind.FIELD) {
48 graph = builder.buildLazyInitializer(element); 48 assert(!element.isInstanceMember());
49 } else { 49 graph = builder.buildLazyInitializer(element);
50 compiler.internalErrorOnElement(element, 50 } else {
51 'unexpected element kind $kind'); 51 compiler.internalErrorOnElement(element,
52 } 52 'unexpected element kind $kind');
53 assert(graph.isValid()); 53 }
54 if (!identical(kind, ElementKind.FIELD)) { 54 assert(graph.isValid());
55 FunctionElement function = element; 55 if (!identical(kind, ElementKind.FIELD)) {
56 FunctionSignature signature = function.computeSignature(compiler); 56 FunctionElement function = element;
57 signature.forEachOptionalParameter((Element parameter) { 57 FunctionSignature signature = function.computeSignature(compiler);
58 // This ensures the default value will be computed. 58 signature.forEachOptionalParameter((Element parameter) {
59 builder.compileVariable(parameter); 59 // This ensures the default value will be computed.
60 }); 60 builder.compileVariable(parameter);
61 } 61 });
62 }
62 63
63 if (compiler.tracer.enabled) { 64 if (compiler.tracer.enabled) {
64 String name; 65 String name;
65 if (element.isMember()) { 66 if (element.isMember()) {
66 String className = element.getEnclosingClass().name.slowToString(); 67 String className = element.getEnclosingClass().name.slowToString();
67 String memberName = element.name.slowToString(); 68 String memberName = element.name.slowToString();
68 name = "$className.$memberName"; 69 name = "$className.$memberName";
69 if (element.isGenerativeConstructorBody()) { 70 if (element.isGenerativeConstructorBody()) {
70 name = "$name (body)"; 71 name = "$name (body)";
72 }
73 } else {
74 name = "${element.name.slowToString()}";
71 } 75 }
72 } else { 76 compiler.tracer.traceCompilation(
73 name = "${element.name.slowToString()}"; 77 name, work.compilationContext, compiler);
78 compiler.tracer.traceGraph('builder', graph);
74 } 79 }
75 compiler.tracer.traceCompilation( 80 return graph;
76 name, work.compilationContext, compiler); 81 });
77 compiler.tracer.traceGraph('builder', graph);
78 }
79 return graph;
80 }); 82 });
81 } 83 }
82 84
83 HGraph compileConstructor(SsaBuilder builder, CodegenWorkItem work) { 85 HGraph compileConstructor(SsaBuilder builder, CodegenWorkItem work) {
84 return builder.buildFactory(work.element); 86 return builder.buildFactory(work.element);
85 } 87 }
86 } 88 }
87 89
88 90
89 /** 91 /**
(...skipping 2701 matching lines...) Expand 10 before | Expand all | Expand 10 after
2791 link = link.tail) { 2793 link = link.tail) {
2792 inputs.add(addTypeVariableReference(link.head)); 2794 inputs.add(addTypeVariableReference(link.head));
2793 } 2795 }
2794 return buildLiteralList(inputs); 2796 return buildLiteralList(inputs);
2795 } 2797 }
2796 2798
2797 HInstruction buildIsNode(Node node, DartType type, HInstruction expression) { 2799 HInstruction buildIsNode(Node node, DartType type, HInstruction expression) {
2798 type = type.unalias(compiler); 2800 type = type.unalias(compiler);
2799 if (type.kind == TypeKind.FUNCTION) { 2801 if (type.kind == TypeKind.FUNCTION) {
2800 if (backend.rti.isSimpleFunctionType(type)) { 2802 if (backend.rti.isSimpleFunctionType(type)) {
2801 return new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK); 2803 // TODO(johnniwinther): Avoid interceptor if unneeded.
2804 return new HIs.raw(type, expression, invokeInterceptor(expression));
2802 } 2805 }
2803 Element checkFunctionSubtype = backend.getCheckFunctionSubtype(); 2806 Element checkFunctionSubtype = backend.getCheckFunctionSubtype();
2804 2807
2805 HInstruction signatureName = graph.addConstantString( 2808 HInstruction signatureName = graph.addConstantString(
2806 new DartString.literal(backend.namer.getFunctionTypeName(type)), 2809 new DartString.literal(backend.namer.getFunctionTypeName(type)),
2807 node, compiler); 2810 node, compiler);
2808 2811
2809 HInstruction contextName; 2812 HInstruction contextName;
2810 HInstruction context; 2813 HInstruction context;
2811 HInstruction typeArguments; 2814 HInstruction typeArguments;
(...skipping 16 matching lines...) Expand all
2828 typeArguments = graph.addConstantNull(compiler); 2831 typeArguments = graph.addConstantNull(compiler);
2829 } 2832 }
2830 2833
2831 List<HInstruction> inputs = <HInstruction>[expression, 2834 List<HInstruction> inputs = <HInstruction>[expression,
2832 signatureName, 2835 signatureName,
2833 contextName, 2836 contextName,
2834 context, 2837 context,
2835 typeArguments]; 2838 typeArguments];
2836 pushInvokeStatic(node, checkFunctionSubtype, inputs, HType.BOOLEAN); 2839 pushInvokeStatic(node, checkFunctionSubtype, inputs, HType.BOOLEAN);
2837 HInstruction call = pop(); 2840 HInstruction call = pop();
2838 return new HIs(type, <HInstruction>[expression, call], 2841 return new HIs.compound(type, expression, call);
2839 HIs.COMPOUND_CHECK);
2840 } else if (type.kind == TypeKind.TYPE_VARIABLE) { 2842 } else if (type.kind == TypeKind.TYPE_VARIABLE) {
2841 HInstruction runtimeType = addTypeVariableReference(type); 2843 HInstruction runtimeType = addTypeVariableReference(type);
2842 Element helper = backend.getCheckSubtypeOfRuntimeType(); 2844 Element helper = backend.getCheckSubtypeOfRuntimeType();
2843 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; 2845 List<HInstruction> inputs = <HInstruction>[expression, runtimeType];
2844 pushInvokeStatic(null, helper, inputs, HType.BOOLEAN); 2846 pushInvokeStatic(null, helper, inputs, HType.BOOLEAN);
2845 HInstruction call = pop(); 2847 HInstruction call = pop();
2846 return new HIs(type, <HInstruction>[expression, call], 2848 return new HIs.variable(type, expression, call);
2847 HIs.VARIABLE_CHECK);
2848 } else if (RuntimeTypes.hasTypeArguments(type)) { 2849 } else if (RuntimeTypes.hasTypeArguments(type)) {
2849 ClassElement element = type.element; 2850 ClassElement element = type.element;
2850 Element helper = backend.getCheckSubtype(); 2851 Element helper = backend.getCheckSubtype();
2851 HInstruction representations = 2852 HInstruction representations =
2852 buildTypeArgumentRepresentations(type); 2853 buildTypeArgumentRepresentations(type);
2853 add(representations); 2854 add(representations);
2854 String operator = 2855 String operator =
2855 backend.namer.operatorIs(backend.getImplementationClass(element)); 2856 backend.namer.operatorIs(backend.getImplementationClass(element));
2856 HInstruction isFieldName = addConstantString(node, operator); 2857 HInstruction isFieldName = addConstantString(node, operator);
2857 HInstruction asFieldName = compiler.world.hasAnySubtype(element) 2858 HInstruction asFieldName = compiler.world.hasAnySubtype(element)
2858 ? addConstantString(node, backend.namer.substitutionName(element)) 2859 ? addConstantString(node, backend.namer.substitutionName(element))
2859 : graph.addConstantNull(compiler); 2860 : graph.addConstantNull(compiler);
2860 List<HInstruction> inputs = <HInstruction>[expression, 2861 List<HInstruction> inputs = <HInstruction>[expression,
2861 isFieldName, 2862 isFieldName,
2862 representations, 2863 representations,
2863 asFieldName]; 2864 asFieldName];
2864 pushInvokeStatic(node, helper, inputs, HType.BOOLEAN); 2865 pushInvokeStatic(node, helper, inputs, HType.BOOLEAN);
2865 HInstruction call = pop(); 2866 HInstruction call = pop();
2866 return 2867 return new HIs.compound(type, expression, call);
2867 new HIs(type, <HInstruction>[expression, call], HIs.COMPOUND_CHECK);
2868 } else { 2868 } else {
2869 return new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK); 2869 if (backend.hasDirectCheckFor(type)) {
2870 return new HIs.direct(type, expression);
2871 }
2872 // TODO(johnniwinther): Avoid interceptor if unneeded.
2873 return new HIs.raw(type, expression, invokeInterceptor(expression));
2870 } 2874 }
2871 } 2875 }
2872 2876
2873 void addDynamicSendArgumentsToList(Send node, List<HInstruction> list) { 2877 void addDynamicSendArgumentsToList(Send node, List<HInstruction> list) {
2874 Selector selector = elements.getSelector(node); 2878 Selector selector = elements.getSelector(node);
2875 if (selector.namedArgumentCount == 0) { 2879 if (selector.namedArgumentCount == 0) {
2876 addGenericSendArgumentsToList(node.arguments, list); 2880 addGenericSendArgumentsToList(node.arguments, list);
2877 } else { 2881 } else {
2878 // Visit positional arguments and add them to the list. 2882 // Visit positional arguments and add them to the list.
2879 Link<Node> arguments = node.arguments; 2883 Link<Node> arguments = node.arguments;
(...skipping 2015 matching lines...) Expand 10 before | Expand all | Expand 10 after
4895 HInvokeStatic unwrappedException = pop(); 4899 HInvokeStatic unwrappedException = pop();
4896 tryInstruction.exception = exception; 4900 tryInstruction.exception = exception;
4897 Link<Node> link = node.catchBlocks.nodes; 4901 Link<Node> link = node.catchBlocks.nodes;
4898 4902
4899 void pushCondition(CatchBlock catchBlock) { 4903 void pushCondition(CatchBlock catchBlock) {
4900 if (catchBlock.onKeyword != null) { 4904 if (catchBlock.onKeyword != null) {
4901 DartType type = elements.getType(catchBlock.type); 4905 DartType type = elements.getType(catchBlock.type);
4902 if (type == null) { 4906 if (type == null) {
4903 compiler.internalError('On with no type', node: catchBlock.type); 4907 compiler.internalError('On with no type', node: catchBlock.type);
4904 } 4908 }
4905 // TODO(karlkose): support type arguments here. 4909 HInstruction condition =
4906 HInstruction condition = new HIs(type, 4910 buildIsNode(catchBlock.type, type, unwrappedException);
4907 <HInstruction>[unwrappedException],
4908 HIs.RAW_CHECK);
4909 push(condition); 4911 push(condition);
4910 } else { 4912 } else {
4911 VariableDefinitions declaration = catchBlock.formals.nodes.head; 4913 VariableDefinitions declaration = catchBlock.formals.nodes.head;
4912 HInstruction condition = null; 4914 HInstruction condition = null;
4913 if (declaration.type == null) { 4915 if (declaration.type == null) {
4914 condition = graph.addConstantBool(true, compiler); 4916 condition = graph.addConstantBool(true, compiler);
4915 stack.add(condition); 4917 stack.add(condition);
4916 } else { 4918 } else {
4917 // TODO(aprelev@gmail.com): Once old catch syntax is removed 4919 // TODO(aprelev@gmail.com): Once old catch syntax is removed
4918 // "if" condition above and this "else" branch should be deleted as 4920 // "if" condition above and this "else" branch should be deleted as
4919 // type of declared variable won't matter for the catch 4921 // type of declared variable won't matter for the catch
4920 // condition. 4922 // condition.
4921 DartType type = elements.getType(declaration.type); 4923 DartType type = elements.getType(declaration.type);
4922 if (type == null) { 4924 if (type == null) {
4923 compiler.cancel('Catch with unresolved type', node: catchBlock); 4925 compiler.cancel('Catch with unresolved type', node: catchBlock);
4924 } 4926 }
4925 // TODO(karlkose): support type arguments here. 4927 condition = buildIsNode(declaration.type, type, unwrappedException);
4926 condition = new HIs(type, <HInstruction>[unwrappedException],
4927 HIs.RAW_CHECK);
4928 push(condition); 4928 push(condition);
4929 } 4929 }
4930 } 4930 }
4931 } 4931 }
4932 4932
4933 void visitThen() { 4933 void visitThen() {
4934 CatchBlock catchBlock = link.head; 4934 CatchBlock catchBlock = link.head;
4935 link = link.tail; 4935 link = link.tail;
4936 if (catchBlock.exception != null) { 4936 if (catchBlock.exception != null) {
4937 localsHandler.updateLocal(elements[catchBlock.exception], 4937 localsHandler.updateLocal(elements[catchBlock.exception],
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
5469 new HSubGraphBlockInformation(elseBranch.graph)); 5469 new HSubGraphBlockInformation(elseBranch.graph));
5470 5470
5471 HBasicBlock conditionStartBlock = conditionBranch.block; 5471 HBasicBlock conditionStartBlock = conditionBranch.block;
5472 conditionStartBlock.setBlockFlow(info, joinBlock); 5472 conditionStartBlock.setBlockFlow(info, joinBlock);
5473 SubGraph conditionGraph = conditionBranch.graph; 5473 SubGraph conditionGraph = conditionBranch.graph;
5474 HIf branch = conditionGraph.end.last; 5474 HIf branch = conditionGraph.end.last;
5475 assert(branch is HIf); 5475 assert(branch is HIf);
5476 branch.blockInformation = conditionStartBlock.blockFlow; 5476 branch.blockInformation = conditionStartBlock.blockFlow;
5477 } 5477 }
5478 } 5478 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698