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

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

Issue 10386161: Start compiler refactoring to support 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 bool allowSpeculativeOptimization = true; 8 bool allowSpeculativeOptimization = true;
9 List<HTypeGuard> guards = const <HTypeGuard>[]; 9 List<HTypeGuard> guards = const <HTypeGuard>[];
10 10
(...skipping 11 matching lines...) Expand all
22 return compiler.codegen(this); 22 return compiler.codegen(this);
23 } catch (CompilerCancelledException ex) { 23 } catch (CompilerCancelledException ex) {
24 throw; 24 throw;
25 } catch (var ex) { 25 } catch (var ex) {
26 compiler.unhandledExceptionOnElement(element); 26 compiler.unhandledExceptionOnElement(element);
27 throw; 27 throw;
28 } 28 }
29 } 29 }
30 } 30 }
31 31
32 class Backend {
33 final Compiler compiler;
34
35 Backend(this.compiler);
36
37 abstract String codegen(WorkItem work);
38 abstract void processNativeClasses(libraries);
39 abstract void assembleProgram();
40 }
41
42 class JavaScriptBackend extends Backend {
43 SsaBuilderTask builder;
44 SsaOptimizerTask optimizer;
45 SsaCodeGeneratorTask generator;
46 CodeEmitterTask emitter;
47
48 JavaScriptBackend(Compiler compiler)
49 : emitter = new CodeEmitterTask(compiler),
50 super(compiler) {
51 builder = new SsaBuilderTask(this);
52 optimizer = new SsaOptimizerTask(this);
53 generator = new SsaCodeGeneratorTask(this);
54 }
55
56 String codegen(WorkItem work) {
57 HGraph graph = builder.build(work);
58 optimizer.optimize(work, graph);
59 if (work.allowSpeculativeOptimization
60 && optimizer.trySpeculativeOptimizations(work, graph)) {
61 String code = generator.generateBailoutMethod(work, graph);
62 compiler.universe.addBailoutCode(work, code);
63 optimizer.prepareForSpeculativeOptimizations(work, graph);
64 optimizer.optimize(work, graph);
65 }
66 return generator.generateMethod(work, graph);
67 }
68
69 void processNativeClasses(libraries) {
70 native.processNativeClasses(emitter, libraries);
71 }
72
73 void assembleProgram() => emitter.assembleProgram();
74 }
75
32 class Compiler implements DiagnosticListener { 76 class Compiler implements DiagnosticListener {
33 Queue<WorkItem> codegenQueue; 77 Queue<WorkItem> codegenQueue;
34 Universe universe; 78 Universe universe;
35 World world; 79 World world;
36 String assembledCode; 80 String assembledCode;
37 Namer namer; 81 Namer namer;
38 Types types; 82 Types types;
39 bool enableTypeAssertions = false; 83 bool enableTypeAssertions = false;
40 84
41 final Tracer tracer; 85 final Tracer tracer;
(...skipping 30 matching lines...) Expand all
72 } 116 }
73 } 117 }
74 118
75 List<CompilerTask> tasks; 119 List<CompilerTask> tasks;
76 ScannerTask scanner; 120 ScannerTask scanner;
77 DietParserTask dietParser; 121 DietParserTask dietParser;
78 ParserTask parser; 122 ParserTask parser;
79 TreeValidatorTask validator; 123 TreeValidatorTask validator;
80 ResolverTask resolver; 124 ResolverTask resolver;
81 TypeCheckerTask checker; 125 TypeCheckerTask checker;
82 SsaBuilderTask builder; 126 Backend backend;
83 SsaOptimizerTask optimizer;
84 SsaCodeGeneratorTask generator;
85 CodeEmitterTask emitter;
86 ConstantHandler constantHandler; 127 ConstantHandler constantHandler;
87 EnqueueTask enqueuer; 128 EnqueueTask enqueuer;
88 129
89 static final SourceString MAIN = const SourceString('main'); 130 static final SourceString MAIN = const SourceString('main');
90 static final SourceString NO_SUCH_METHOD = const SourceString('noSuchMethod'); 131 static final SourceString NO_SUCH_METHOD = const SourceString('noSuchMethod');
91 static final SourceString NO_SUCH_METHOD_EXCEPTION = 132 static final SourceString NO_SUCH_METHOD_EXCEPTION =
92 const SourceString('NoSuchMethodException'); 133 const SourceString('NoSuchMethodException');
93 static final SourceString START_ROOT_ISOLATE = 134 static final SourceString START_ROOT_ISOLATE =
94 const SourceString('startRootIsolate'); 135 const SourceString('startRootIsolate');
95 bool enabledNoSuchMethod = false; 136 bool enabledNoSuchMethod = false;
96 137
97 bool codegenQueueIsClosed = false; 138 bool codegenQueueIsClosed = false;
98 139
99 Stopwatch codegenProgress; 140 Stopwatch codegenProgress;
100 141
101 Compiler([this.tracer = const Tracer()]) 142 Compiler([this.tracer = const Tracer()])
102 : universe = new Universe(), 143 : universe = new Universe(),
103 world = new World(), 144 world = new World(),
104 codegenQueue = new Queue<WorkItem>(), 145 codegenQueue = new Queue<WorkItem>(),
105 codegenProgress = new Stopwatch.start() { 146 codegenProgress = new Stopwatch.start() {
106 namer = new Namer(this); 147 namer = new Namer(this);
107 constantHandler = new ConstantHandler(this); 148 constantHandler = new ConstantHandler(this);
108 scanner = new ScannerTask(this); 149 scanner = new ScannerTask(this);
109 dietParser = new DietParserTask(this); 150 dietParser = new DietParserTask(this);
110 parser = new ParserTask(this); 151 parser = new ParserTask(this);
111 validator = new TreeValidatorTask(this); 152 validator = new TreeValidatorTask(this);
112 resolver = new ResolverTask(this); 153 resolver = new ResolverTask(this);
113 checker = new TypeCheckerTask(this); 154 checker = new TypeCheckerTask(this);
114 builder = new SsaBuilderTask(this); 155 backend = new JavaScriptBackend(this);
115 optimizer = new SsaOptimizerTask(this);
116 generator = new SsaCodeGeneratorTask(this);
117 emitter = new CodeEmitterTask(this);
118 enqueuer = new EnqueueTask(this); 156 enqueuer = new EnqueueTask(this);
119 tasks = [scanner, dietParser, parser, resolver, checker, 157 tasks = [scanner, dietParser, parser, resolver, checker,
120 builder, optimizer, generator, 158 constantHandler, enqueuer];
121 emitter, constantHandler, enqueuer];
122 } 159 }
123 160
124 void ensure(bool condition) { 161 void ensure(bool condition) {
125 if (!condition) cancel('failed assertion in leg'); 162 if (!condition) cancel('failed assertion in leg');
126 } 163 }
127 164
128 void unimplemented(String methodName, 165 void unimplemented(String methodName,
129 [Node node, Token token, HInstruction instruction, 166 [Node node, Token token, HInstruction instruction,
130 Element element]) { 167 Element element]) {
131 internalError("$methodName not implemented", 168 internalError("$methodName not implemented",
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 reportFatalError('Could not find $MAIN', mainApp); 335 reportFatalError('Could not find $MAIN', mainApp);
299 } else { 336 } else {
300 if (!main.isFunction()) reportFatalError('main is not a function', main); 337 if (!main.isFunction()) reportFatalError('main is not a function', main);
301 FunctionElement mainMethod = main; 338 FunctionElement mainMethod = main;
302 FunctionSignature parameters = mainMethod.computeSignature(this); 339 FunctionSignature parameters = mainMethod.computeSignature(this);
303 parameters.forEachParameter((Element parameter) { 340 parameters.forEachParameter((Element parameter) {
304 reportFatalError('main cannot have parameters', parameter); 341 reportFatalError('main cannot have parameters', parameter);
305 }); 342 });
306 } 343 }
307 Collection<LibraryElement> libraries = universe.libraries.getValues(); 344 Collection<LibraryElement> libraries = universe.libraries.getValues();
308 native.processNativeClasses(this, libraries); 345 backend.processNativeClasses(libraries);
309 world.populate(this, libraries); 346 world.populate(this, libraries);
310 addToWorkList(main); 347 addToWorkList(main);
311 codegenProgress.reset(); 348 codegenProgress.reset();
312 while (!codegenQueue.isEmpty()) { 349 while (!codegenQueue.isEmpty()) {
313 WorkItem work = codegenQueue.removeLast(); 350 WorkItem work = codegenQueue.removeLast();
314 withCurrentElement(work.element, () => work.run(this)); 351 withCurrentElement(work.element, () => work.run(this));
315 } 352 }
316 codegenQueueIsClosed = true; 353 codegenQueueIsClosed = true;
317 assert(enqueuer.checkNoEnqueuedInvokedInstanceMethods()); 354 assert(enqueuer.checkNoEnqueuedInvokedInstanceMethods());
318 enqueuer.registerFieldClosureInvocations(); 355 enqueuer.registerFieldClosureInvocations();
319 emitter.assembleProgram(); 356 backend.assembleProgram();
320 if (!codegenQueue.isEmpty()) { 357 if (!codegenQueue.isEmpty()) {
321 internalErrorOnElement(codegenQueue.first().element, 358 internalErrorOnElement(codegenQueue.first().element,
322 "work list is not empty"); 359 "work list is not empty");
323 } 360 }
324 } 361 }
325 362
326 TreeElements analyzeElement(Element element) { 363 TreeElements analyzeElement(Element element) {
327 assert(parser !== null); 364 assert(parser !== null);
328 Node tree = parser.parse(element); 365 Node tree = parser.parse(element);
329 validator.validate(tree); 366 validator.validate(tree);
(...skipping 11 matching lines...) Expand all
341 if (codegenProgress.elapsedInMs() > 500) { 378 if (codegenProgress.elapsedInMs() > 500) {
342 // TODO(ahe): Add structured diagnostics to the compiler API and 379 // TODO(ahe): Add structured diagnostics to the compiler API and
343 // use it to separate this from the --verbose option. 380 // use it to separate this from the --verbose option.
344 log('compiled ${universe.generatedCode.length} methods'); 381 log('compiled ${universe.generatedCode.length} methods');
345 codegenProgress.reset(); 382 codegenProgress.reset();
346 } 383 }
347 if (work.element.kind.category == ElementCategory.VARIABLE) { 384 if (work.element.kind.category == ElementCategory.VARIABLE) {
348 constantHandler.compileWorkItem(work); 385 constantHandler.compileWorkItem(work);
349 return null; 386 return null;
350 } else { 387 } else {
351 HGraph graph = builder.build(work); 388 String code = backend.codegen(work);
352 optimizer.optimize(work, graph); 389 universe.addGeneratedCode(work, code);
353 if (work.allowSpeculativeOptimization 390 return code;
354 && optimizer.trySpeculativeOptimizations(work, graph)) {
355 String code = generator.generateBailoutMethod(work, graph);
356 universe.addBailoutCode(work, code);
357 optimizer.prepareForSpeculativeOptimizations(work, graph);
358 optimizer.optimize(work, graph);
359 code = generator.generateMethod(work, graph);
360 universe.addGeneratedCode(work, code);
361 return code;
362 } else {
363 String code = generator.generateMethod(work, graph);
364 universe.addGeneratedCode(work, code);
365 return code;
366 }
367 } 391 }
368 } 392 }
369 393
370 void addToWorkList(Element element, [TreeElements elements]) { 394 void addToWorkList(Element element, [TreeElements elements]) {
371 if (codegenQueueIsClosed) { 395 if (codegenQueueIsClosed) {
372 internalErrorOnElement(element, "work list is closed"); 396 internalErrorOnElement(element, "work list is closed");
373 } 397 }
374 if (element.kind === ElementKind.GENERATIVE_CONSTRUCTOR) { 398 if (element.kind === ElementKind.GENERATIVE_CONSTRUCTOR) {
375 registerInstantiatedClass(element.enclosingElement); 399 registerInstantiatedClass(element.enclosingElement);
376 } 400 }
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 } 587 }
564 } 588 }
565 589
566 class SourceSpan { 590 class SourceSpan {
567 final Uri uri; 591 final Uri uri;
568 final int begin; 592 final int begin;
569 final int end; 593 final int end;
570 594
571 const SourceSpan(this.uri, this.begin, this.end); 595 const SourceSpan(this.uri, this.begin, this.end);
572 } 596 }
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