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

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: Avoid generating an interceptor when unused. Created 7 years, 4 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, () {
ngeoffray 2013/08/24 11:16:26 Since the build method is the entry point of the b
Johnni Winther 2013/08/26 07:34:00 The current element was the declaration and not th
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 return new HIs.raw(type, expression ,invokeInterceptor(expression));
ngeoffray 2013/08/24 11:16:26 move space around last comma.
Johnni Winther 2013/08/26 07:34:00 Done.
2802 } 2804 }
2803 Element checkFunctionSubtype = backend.getCheckFunctionSubtype(); 2805 Element checkFunctionSubtype = backend.getCheckFunctionSubtype();
2804 2806
2805 HInstruction signatureName = graph.addConstantString( 2807 HInstruction signatureName = graph.addConstantString(
2806 new DartString.literal(backend.namer.getFunctionTypeName(type)), 2808 new DartString.literal(backend.namer.getFunctionTypeName(type)),
2807 node, compiler); 2809 node, compiler);
2808 2810
2809 HInstruction contextName; 2811 HInstruction contextName;
2810 HInstruction context; 2812 HInstruction context;
2811 HInstruction typeArguments; 2813 HInstruction typeArguments;
(...skipping 16 matching lines...) Expand all
2828 typeArguments = graph.addConstantNull(compiler); 2830 typeArguments = graph.addConstantNull(compiler);
2829 } 2831 }
2830 2832
2831 List<HInstruction> inputs = <HInstruction>[expression, 2833 List<HInstruction> inputs = <HInstruction>[expression,
2832 signatureName, 2834 signatureName,
2833 contextName, 2835 contextName,
2834 context, 2836 context,
2835 typeArguments]; 2837 typeArguments];
2836 pushInvokeStatic(node, checkFunctionSubtype, inputs, HType.BOOLEAN); 2838 pushInvokeStatic(node, checkFunctionSubtype, inputs, HType.BOOLEAN);
2837 HInstruction call = pop(); 2839 HInstruction call = pop();
2838 return new HIs(type, <HInstruction>[expression, call], 2840 return new HIs.compound(type, expression, call);
2839 HIs.COMPOUND_CHECK);
2840 } else if (type.kind == TypeKind.TYPE_VARIABLE) { 2841 } else if (type.kind == TypeKind.TYPE_VARIABLE) {
2841 HInstruction runtimeType = addTypeVariableReference(type); 2842 HInstruction runtimeType = addTypeVariableReference(type);
2842 Element helper = backend.getCheckSubtypeOfRuntimeType(); 2843 Element helper = backend.getCheckSubtypeOfRuntimeType();
2843 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; 2844 List<HInstruction> inputs = <HInstruction>[expression, runtimeType];
2844 pushInvokeStatic(null, helper, inputs, HType.BOOLEAN); 2845 pushInvokeStatic(null, helper, inputs, HType.BOOLEAN);
2845 HInstruction call = pop(); 2846 HInstruction call = pop();
2846 return new HIs(type, <HInstruction>[expression, call], 2847 return new HIs.variable(type, expression, call);
2847 HIs.VARIABLE_CHECK);
2848 } else if (RuntimeTypes.hasTypeArguments(type)) { 2848 } else if (RuntimeTypes.hasTypeArguments(type)) {
2849 ClassElement element = type.element; 2849 ClassElement element = type.element;
2850 Element helper = backend.getCheckSubtype(); 2850 Element helper = backend.getCheckSubtype();
2851 HInstruction representations = 2851 HInstruction representations =
2852 buildTypeArgumentRepresentations(type); 2852 buildTypeArgumentRepresentations(type);
2853 add(representations); 2853 add(representations);
2854 String operator = 2854 String operator =
2855 backend.namer.operatorIs(backend.getImplementationClass(element)); 2855 backend.namer.operatorIs(backend.getImplementationClass(element));
2856 HInstruction isFieldName = addConstantString(node, operator); 2856 HInstruction isFieldName = addConstantString(node, operator);
2857 HInstruction asFieldName = compiler.world.hasAnySubtype(element) 2857 HInstruction asFieldName = compiler.world.hasAnySubtype(element)
2858 ? addConstantString(node, backend.namer.substitutionName(element)) 2858 ? addConstantString(node, backend.namer.substitutionName(element))
2859 : graph.addConstantNull(compiler); 2859 : graph.addConstantNull(compiler);
2860 List<HInstruction> inputs = <HInstruction>[expression, 2860 List<HInstruction> inputs = <HInstruction>[expression,
2861 isFieldName, 2861 isFieldName,
2862 representations, 2862 representations,
2863 asFieldName]; 2863 asFieldName];
2864 pushInvokeStatic(node, helper, inputs, HType.BOOLEAN); 2864 pushInvokeStatic(node, helper, inputs, HType.BOOLEAN);
2865 HInstruction call = pop(); 2865 HInstruction call = pop();
2866 return 2866 return new HIs.compound(type, expression, call);
2867 new HIs(type, <HInstruction>[expression, call], HIs.COMPOUND_CHECK);
2868 } else { 2867 } else {
2869 return new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK); 2868 Element element = type.element;
2869 if (element == compiler.stringClass ||
ngeoffray 2013/08/24 11:16:26 Maybe add a "backend.hasDirectCheckFor(element)" i
Johnni Winther 2013/08/26 07:34:00 Done.
2870 element == compiler.boolClass ||
2871 element == compiler.numClass ||
2872 element == compiler.intClass ||
2873 element == compiler.doubleClass ||
2874 element == backend.jsArrayClass ||
2875 element == backend.jsMutableArrayClass ||
2876 element == backend.jsExtendableArrayClass ||
2877 element == backend.jsFixedArrayClass) {
2878 return new HIs.direct(type, expression);
2879 }
2880 return new HIs.raw(type, expression, invokeInterceptor(expression));
2870 } 2881 }
2871 } 2882 }
2872 2883
2873 void addDynamicSendArgumentsToList(Send node, List<HInstruction> list) { 2884 void addDynamicSendArgumentsToList(Send node, List<HInstruction> list) {
2874 Selector selector = elements.getSelector(node); 2885 Selector selector = elements.getSelector(node);
2875 if (selector.namedArgumentCount == 0) { 2886 if (selector.namedArgumentCount == 0) {
2876 addGenericSendArgumentsToList(node.arguments, list); 2887 addGenericSendArgumentsToList(node.arguments, list);
2877 } else { 2888 } else {
2878 // Visit positional arguments and add them to the list. 2889 // Visit positional arguments and add them to the list.
2879 Link<Node> arguments = node.arguments; 2890 Link<Node> arguments = node.arguments;
(...skipping 2015 matching lines...) Expand 10 before | Expand all | Expand 10 after
4895 HInvokeStatic unwrappedException = pop(); 4906 HInvokeStatic unwrappedException = pop();
4896 tryInstruction.exception = exception; 4907 tryInstruction.exception = exception;
4897 Link<Node> link = node.catchBlocks.nodes; 4908 Link<Node> link = node.catchBlocks.nodes;
4898 4909
4899 void pushCondition(CatchBlock catchBlock) { 4910 void pushCondition(CatchBlock catchBlock) {
4900 if (catchBlock.onKeyword != null) { 4911 if (catchBlock.onKeyword != null) {
4901 DartType type = elements.getType(catchBlock.type); 4912 DartType type = elements.getType(catchBlock.type);
4902 if (type == null) { 4913 if (type == null) {
4903 compiler.internalError('On with no type', node: catchBlock.type); 4914 compiler.internalError('On with no type', node: catchBlock.type);
4904 } 4915 }
4905 // TODO(karlkose): support type arguments here. 4916 HInstruction condition =
4906 HInstruction condition = new HIs(type, 4917 buildIsNode(catchBlock.type, type, unwrappedException);
4907 <HInstruction>[unwrappedException],
4908 HIs.RAW_CHECK);
4909 push(condition); 4918 push(condition);
4910 } else { 4919 } else {
4911 VariableDefinitions declaration = catchBlock.formals.nodes.head; 4920 VariableDefinitions declaration = catchBlock.formals.nodes.head;
4912 HInstruction condition = null; 4921 HInstruction condition = null;
4913 if (declaration.type == null) { 4922 if (declaration.type == null) {
4914 condition = graph.addConstantBool(true, compiler); 4923 condition = graph.addConstantBool(true, compiler);
4915 stack.add(condition); 4924 stack.add(condition);
4916 } else { 4925 } else {
4917 // TODO(aprelev@gmail.com): Once old catch syntax is removed 4926 // TODO(aprelev@gmail.com): Once old catch syntax is removed
4918 // "if" condition above and this "else" branch should be deleted as 4927 // "if" condition above and this "else" branch should be deleted as
4919 // type of declared variable won't matter for the catch 4928 // type of declared variable won't matter for the catch
4920 // condition. 4929 // condition.
4921 DartType type = elements.getType(declaration.type); 4930 DartType type = elements.getType(declaration.type);
4922 if (type == null) { 4931 if (type == null) {
4923 compiler.cancel('Catch with unresolved type', node: catchBlock); 4932 compiler.cancel('Catch with unresolved type', node: catchBlock);
4924 } 4933 }
4925 // TODO(karlkose): support type arguments here. 4934 condition = buildIsNode(declaration.type, type, unwrappedException);
4926 condition = new HIs(type, <HInstruction>[unwrappedException],
4927 HIs.RAW_CHECK);
4928 push(condition); 4935 push(condition);
4929 } 4936 }
4930 } 4937 }
4931 } 4938 }
4932 4939
4933 void visitThen() { 4940 void visitThen() {
4934 CatchBlock catchBlock = link.head; 4941 CatchBlock catchBlock = link.head;
4935 link = link.tail; 4942 link = link.tail;
4936 if (catchBlock.exception != null) { 4943 if (catchBlock.exception != null) {
4937 localsHandler.updateLocal(elements[catchBlock.exception], 4944 localsHandler.updateLocal(elements[catchBlock.exception],
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
5469 new HSubGraphBlockInformation(elseBranch.graph)); 5476 new HSubGraphBlockInformation(elseBranch.graph));
5470 5477
5471 HBasicBlock conditionStartBlock = conditionBranch.block; 5478 HBasicBlock conditionStartBlock = conditionBranch.block;
5472 conditionStartBlock.setBlockFlow(info, joinBlock); 5479 conditionStartBlock.setBlockFlow(info, joinBlock);
5473 SubGraph conditionGraph = conditionBranch.graph; 5480 SubGraph conditionGraph = conditionBranch.graph;
5474 HIf branch = conditionGraph.end.last; 5481 HIf branch = conditionGraph.end.last;
5475 assert(branch is HIf); 5482 assert(branch is HIf);
5476 branch.blockInformation = conditionStartBlock.blockFlow; 5483 branch.blockInformation = conditionStartBlock.blockFlow;
5477 } 5484 }
5478 } 5485 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698