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

Side by Side Diff: lib/compiler/implementation/compiler.dart

Issue 10386086: RFC: Start refactoring to provide more than a single backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 7 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
« no previous file with comments | « no previous file | lib/compiler/implementation/emitter.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 class WorkItem { 5 class WorkItem {
6 final Element element; 6 final Element element;
7 TreeElements resolutionTree; 7 TreeElements resolutionTree;
8 Function run; 8 Function run;
9 bool allowSpeculativeOptimization = true; 9 bool allowSpeculativeOptimization = true;
10 List<HTypeGuard> guards = const <HTypeGuard>[]; 10 List<HTypeGuard> guards = const <HTypeGuard>[];
11 11
12 WorkItem.toCompile(this.element) : resolutionTree = null { 12 WorkItem.toCompile(this.element) : resolutionTree = null {
13 run = (Compiler compiler) => compiler.compile(this); 13 run = (Compiler compiler) => compiler.compile(this);
14 } 14 }
15 15
16 WorkItem.toCodegen(this.element, this.resolutionTree) { 16 WorkItem.toCodegen(this.element, this.resolutionTree) {
17 run = (Compiler compiler) => compiler.codegen(this); 17 run = (Compiler compiler) => compiler.codegen(this);
18 } 18 }
19 19
20 bool isAnalyzed() => resolutionTree != null; 20 bool isAnalyzed() => resolutionTree != null;
21 21
22 int hashCode() => element.hashCode(); 22 int hashCode() => element.hashCode();
23 } 23 }
24 24
25 interface Backend {
26 String codegen(WorkItem work);
27 void assembleProgram();
28 }
29
30 class JavaScriptBackend implements Backend {
ahe 2012/05/14 08:14:30 Consider creating a separate library for this clas
Anton Muhin 2012/05/14 14:36:45 What would be your recommendation where to place i
31 Compiler compiler;
32 SsaBuilderTask builder;
33 SsaOptimizerTask optimizer;
34 SsaCodeGeneratorTask generator;
35 CodeEmitterTask emitter;
36
37 JavaScriptBackend(Compiler compiler)
38 : this.compiler = compiler,
39 builder = new SsaBuilderTask(compiler),
40 optimizer = new SsaOptimizerTask(compiler),
41 generator = new SsaCodeGeneratorTask(compiler),
42 emitter = new CodeEmitterTask(compiler);
43
44 String codegen(WorkItem work) {
45 HGraph graph = builder.build(work);
46 optimizer.optimize(work, graph);
47 if (work.allowSpeculativeOptimization
48 && optimizer.trySpeculativeOptimizations(work, graph)) {
49 String code = generator.generateBailoutMethod(work, graph);
50 compiler.universe.addBailoutCode(work, code);
51 optimizer.prepareForSpeculativeOptimizations(work, graph);
52 optimizer.optimize(work, graph);
53 }
54 return generator.generateMethod(work, graph);
55 }
56
57 void assembleProgram() => emitter.assembleProgram();
58 }
59
25 class Compiler implements DiagnosticListener { 60 class Compiler implements DiagnosticListener {
26 Queue<WorkItem> worklist; 61 Queue<WorkItem> worklist;
27 Universe universe; 62 Universe universe;
28 World world; 63 World world;
29 String assembledCode; 64 String assembledCode;
30 Namer namer; 65 Namer namer;
31 Types types; 66 Types types;
32 bool enableTypeAssertions = false; 67 bool enableTypeAssertions = false;
33 68
34 final Tracer tracer; 69 final Tracer tracer;
(...skipping 30 matching lines...) Expand all
65 } 100 }
66 } 101 }
67 102
68 List<CompilerTask> tasks; 103 List<CompilerTask> tasks;
69 ScannerTask scanner; 104 ScannerTask scanner;
70 DietParserTask dietParser; 105 DietParserTask dietParser;
71 ParserTask parser; 106 ParserTask parser;
72 TreeValidatorTask validator; 107 TreeValidatorTask validator;
73 ResolverTask resolver; 108 ResolverTask resolver;
74 TypeCheckerTask checker; 109 TypeCheckerTask checker;
75 SsaBuilderTask builder; 110 Backend backend;
76 SsaOptimizerTask optimizer;
77 SsaCodeGeneratorTask generator;
78 CodeEmitterTask emitter;
79 ConstantHandler constantHandler; 111 ConstantHandler constantHandler;
80 EnqueueTask enqueuer; 112 EnqueueTask enqueuer;
81 113
82 static final SourceString MAIN = const SourceString('main'); 114 static final SourceString MAIN = const SourceString('main');
83 static final SourceString NO_SUCH_METHOD = const SourceString('noSuchMethod'); 115 static final SourceString NO_SUCH_METHOD = const SourceString('noSuchMethod');
84 static final SourceString NO_SUCH_METHOD_EXCEPTION = 116 static final SourceString NO_SUCH_METHOD_EXCEPTION =
85 const SourceString('NoSuchMethodException'); 117 const SourceString('NoSuchMethodException');
86 static final SourceString START_ROOT_ISOLATE = 118 static final SourceString START_ROOT_ISOLATE =
87 const SourceString('startRootIsolate'); 119 const SourceString('startRootIsolate');
88 bool enabledNoSuchMethod = false; 120 bool enabledNoSuchMethod = false;
89 121
90 bool workListIsClosed = false; 122 bool workListIsClosed = false;
91 123
92 Stopwatch codegenProgress; 124 Stopwatch codegenProgress;
93 125
94 Compiler([this.tracer = const Tracer()]) 126 Compiler([this.tracer = const Tracer()])
95 : universe = new Universe(), 127 : universe = new Universe(),
96 world = new World(), 128 world = new World(),
97 worklist = new Queue<WorkItem>(), 129 worklist = new Queue<WorkItem>(),
98 codegenProgress = new Stopwatch.start() { 130 codegenProgress = new Stopwatch.start() {
99 namer = new Namer(this); 131 namer = new Namer(this);
100 constantHandler = new ConstantHandler(this); 132 constantHandler = new ConstantHandler(this);
101 scanner = new ScannerTask(this); 133 scanner = new ScannerTask(this);
102 dietParser = new DietParserTask(this); 134 dietParser = new DietParserTask(this);
103 parser = new ParserTask(this); 135 parser = new ParserTask(this);
104 validator = new TreeValidatorTask(this); 136 validator = new TreeValidatorTask(this);
105 resolver = new ResolverTask(this); 137 resolver = new ResolverTask(this);
106 checker = new TypeCheckerTask(this); 138 checker = new TypeCheckerTask(this);
107 builder = new SsaBuilderTask(this); 139 backend = new JavaScriptBackend(this);
108 optimizer = new SsaOptimizerTask(this);
109 generator = new SsaCodeGeneratorTask(this);
110 emitter = new CodeEmitterTask(this);
111 enqueuer = new EnqueueTask(this); 140 enqueuer = new EnqueueTask(this);
112 tasks = [scanner, dietParser, parser, resolver, checker, 141 tasks = [scanner, dietParser, parser, resolver, checker,
113 builder, optimizer, generator, 142 constantHandler, enqueuer];
114 emitter, constantHandler, enqueuer];
115 } 143 }
116 144
117 void ensure(bool condition) { 145 void ensure(bool condition) {
118 if (!condition) cancel('failed assertion in leg'); 146 if (!condition) cancel('failed assertion in leg');
119 } 147 }
120 148
121 void unimplemented(String methodName, 149 void unimplemented(String methodName,
122 [Node node, Token token, HInstruction instruction, 150 [Node node, Token token, HInstruction instruction,
123 Element element]) { 151 Element element]) {
124 internalError("$methodName not implemented", 152 internalError("$methodName not implemented",
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 world.populate(this, libraries); 326 world.populate(this, libraries);
299 enqueue(new WorkItem.toCompile(main)); 327 enqueue(new WorkItem.toCompile(main));
300 codegenProgress.reset(); 328 codegenProgress.reset();
301 while (!worklist.isEmpty()) { 329 while (!worklist.isEmpty()) {
302 WorkItem work = worklist.removeLast(); 330 WorkItem work = worklist.removeLast();
303 withCurrentElement(work.element, () => (work.run)(this)); 331 withCurrentElement(work.element, () => (work.run)(this));
304 } 332 }
305 workListIsClosed = true; 333 workListIsClosed = true;
306 assert(enqueuer.checkNoEnqueuedInvokedInstanceMethods()); 334 assert(enqueuer.checkNoEnqueuedInvokedInstanceMethods());
307 enqueuer.registerFieldClosureInvocations(); 335 enqueuer.registerFieldClosureInvocations();
308 emitter.assembleProgram(); 336 backend.assembleProgram();
309 if (!worklist.isEmpty()) { 337 if (!worklist.isEmpty()) {
310 internalErrorOnElement(worklist.first().element, 338 internalErrorOnElement(worklist.first().element,
311 "work list is not empty"); 339 "work list is not empty");
312 } 340 }
313 } 341 }
314 342
315 TreeElements analyzeElement(Element element) { 343 TreeElements analyzeElement(Element element) {
316 assert(parser !== null); 344 assert(parser !== null);
317 Node tree = parser.parse(element); 345 Node tree = parser.parse(element);
318 validator.validate(tree); 346 validator.validate(tree);
(...skipping 11 matching lines...) Expand all
330 if (codegenProgress.elapsedInMs() > 500) { 358 if (codegenProgress.elapsedInMs() > 500) {
331 // TODO(ahe): Add structured diagnostics to the compiler API and 359 // TODO(ahe): Add structured diagnostics to the compiler API and
332 // use it to separate this from the --verbose option. 360 // use it to separate this from the --verbose option.
333 log('compiled ${universe.generatedCode.length} methods'); 361 log('compiled ${universe.generatedCode.length} methods');
334 codegenProgress.reset(); 362 codegenProgress.reset();
335 } 363 }
336 if (work.element.kind.category == ElementCategory.VARIABLE) { 364 if (work.element.kind.category == ElementCategory.VARIABLE) {
337 constantHandler.compileWorkItem(work); 365 constantHandler.compileWorkItem(work);
338 return null; 366 return null;
339 } else { 367 } else {
340 HGraph graph = builder.build(work); 368 String code = backend.codegen(work);
341 optimizer.optimize(work, graph); 369 universe.addGeneratedCode(work, code);
342 if (work.allowSpeculativeOptimization 370 return code;
343 && optimizer.trySpeculativeOptimizations(work, graph)) {
344 String code = generator.generateBailoutMethod(work, graph);
345 universe.addBailoutCode(work, code);
346 optimizer.prepareForSpeculativeOptimizations(work, graph);
347 optimizer.optimize(work, graph);
348 code = generator.generateMethod(work, graph);
349 universe.addGeneratedCode(work, code);
350 return code;
351 } else {
352 String code = generator.generateMethod(work, graph);
353 universe.addGeneratedCode(work, code);
354 return code;
355 }
356 } 371 }
357 } 372 }
358 373
359 String compile(WorkItem work) { 374 String compile(WorkItem work) {
360 String code = universe.generatedCode[work.element]; 375 String code = universe.generatedCode[work.element];
361 if (code !== null) return code; 376 if (code !== null) return code;
362 analyze(work); 377 analyze(work);
363 return codegen(work); 378 return codegen(work);
364 } 379 }
365 380
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 } 574 }
560 } 575 }
561 576
562 class SourceSpan { 577 class SourceSpan {
563 final Uri uri; 578 final Uri uri;
564 final int begin; 579 final int begin;
565 final int end; 580 final int end;
566 581
567 const SourceSpan(this.uri, this.begin, this.end); 582 const SourceSpan(this.uri, this.begin, this.end);
568 } 583 }
OLDNEW
« no previous file with comments | « no previous file | lib/compiler/implementation/emitter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698