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

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

Issue 10542073: RFC: Resolution based tree-shaking. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 6 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 | dart/lib/compiler/implementation/elements/elements.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
11 WorkItem(this.element, this.resolutionTree); 11 WorkItem(this.element, this.resolutionTree);
12 12
13 bool isAnalyzed() => resolutionTree !== null; 13 bool isAnalyzed() => resolutionTree !== null;
14 14
15 String run(Compiler compiler, Enqueuer world) { 15 String run(Compiler compiler, Enqueuer world) {
16 String code = world.universe.generatedCode[element]; 16 String code = world.universe.generatedCode[element];
17 if (code !== null) return code; 17 if (code !== null) return code;
18 if (!isAnalyzed()) compiler.analyze(this); 18 if (!isAnalyzed()) {
19 resolutionTree = world.getCachedElements(element);
kasperl 2012/06/12 05:50:12 So getCachedElements has the side-effect that this
ahe 2012/06/12 06:22:48 getCachedElements does not have side-effects. Assi
20 if (!isAnalyzed()) compiler.analyze(this);
21 }
22 if (world.isFirstQueue) {
23 world.resolvedElements[element] = resolutionTree;
24 return null;
25 }
26 if (resolutionTree === null) {
27 compiler.internalError('Error: unresolved element', element: element);
28 }
19 return compiler.codegen(this); 29 return compiler.codegen(this);
20 } 30 }
21 } 31 }
22 32
23 class Backend { 33 class Backend {
24 final Compiler compiler; 34 final Compiler compiler;
25 35
26 Backend(this.compiler); 36 Backend(this.compiler);
27 37
28 abstract String codegen(WorkItem work); 38 abstract String codegen(WorkItem work);
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 FunctionSignature parameters = mainMethod.computeSignature(this); 369 FunctionSignature parameters = mainMethod.computeSignature(this);
360 parameters.forEachParameter((Element parameter) { 370 parameters.forEachParameter((Element parameter) {
361 reportFatalError('main cannot have parameters', parameter); 371 reportFatalError('main cannot have parameters', parameter);
362 }); 372 });
363 } 373 }
364 374
365 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution 375 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution
366 // should know this. 376 // should know this.
367 world.populate(this, libraries.getValues()); 377 world.populate(this, libraries.getValues());
368 378
369 // Not yet ready to process the enqueuer.resolution queue... 379 log('Resolving');
370 // processQueue(enqueuer.resolution); 380 processQueue(enqueuer.resolution, main);
381 log('Resolved ${enqueuer.resolution.resolvedElements.length} elements.');
382
383 log('Compiling');
371 processQueue(enqueuer.codegen, main); 384 processQueue(enqueuer.codegen, main);
372 385
373 backend.assembleProgram(); 386 backend.assembleProgram();
374 if (!enqueuer.codegen.queue.isEmpty()) { 387 enqueuer.codegen.forEach((WorkItem work) {
375 internalErrorOnElement(enqueuer.codegen.queue.first().element, 388 internalErrorOnElement(work.element, "work list is not empty");
376 "work list is not empty"); 389 });
377 }
378 } 390 }
379 391
380 processQueue(Enqueuer world, Element main) { 392 processQueue(Enqueuer world, Element main) {
381 backend.processNativeClasses(world, libraries.getValues()); 393 backend.processNativeClasses(world, libraries.getValues());
382 world.addToWorkList(main); 394 world.addToWorkList(main);
383 codegenProgress.reset(); 395 codegenProgress.reset();
384 while (!world.queue.isEmpty()) { 396 world.forEach((WorkItem work) {
385 WorkItem work = world.queue.removeLast();
386 withCurrentElement(work.element, () => work.run(this, world)); 397 withCurrentElement(work.element, () => work.run(this, world));
387 } 398 });
388 world.queueIsClosed = true; 399 world.queueIsClosed = true;
389 assert(world.checkNoEnqueuedInvokedInstanceMethods()); 400 assert(world.checkNoEnqueuedInvokedInstanceMethods());
390 world.registerFieldClosureInvocations(); 401 world.registerFieldClosureInvocations();
391 } 402 }
392 403
393 TreeElements analyzeElement(Element element) { 404 TreeElements analyzeElement(Element element) {
405 if (element is AbstractFieldElement) {
406 return null;
407 }
408 final int allowed = ElementCategory.VARIABLE | ElementCategory.FUNCTION
409 | ElementCategory.FACTORY;
410 if (!element.isAccessor() && (element.kind.category & allowed) == 0) {
411 return null;
412 }
394 assert(parser !== null); 413 assert(parser !== null);
395 Node tree = parser.parse(element); 414 Node tree = parser.parse(element);
396 validator.validate(tree); 415 validator.validate(tree);
397 unparseValidator.check(element); 416 unparseValidator.check(element);
398 TreeElements elements = resolver.resolve(element); 417 TreeElements elements = resolver.resolve(element);
399 checker.check(tree, elements); 418 checker.check(tree, elements);
400 return elements; 419 return elements;
401 } 420 }
402 421
403 TreeElements analyze(WorkItem work) { 422 TreeElements analyze(WorkItem work) {
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 // not a good error location, but cancel really is "internal 521 // not a good error location, but cancel really is "internal
503 // error" or "not implemented yet", so the vicinity is good 522 // error" or "not implemented yet", so the vicinity is good
504 // enough for now. 523 // enough for now.
505 element = element.enclosingElement; 524 element = element.enclosingElement;
506 // TODO(ahe): I plan to overhaul this infrastructure anyways. 525 // TODO(ahe): I plan to overhaul this infrastructure anyways.
507 } 526 }
508 if (element === null) { 527 if (element === null) {
509 element = currentElement; 528 element = currentElement;
510 } 529 }
511 Token position = element.position(); 530 Token position = element.position();
531 Uri uri = element.getCompilationUnit().script.uri;
512 if (position === null) { 532 if (position === null) {
513 Uri uri = element.getCompilationUnit().script.uri;
514 return new SourceSpan(uri, 0, 0); 533 return new SourceSpan(uri, 0, 0);
534 } else {
535 return SourceSpan.withOffsets(
536 position, position,
537 (beginOffset, endOffset) {
538 return new SourceSpan(uri, beginOffset, endOffset);
539 });
515 } 540 }
516 return spanFromTokens(position, position);
517 } 541 }
518 542
519 Script readScript(Uri uri, [ScriptTag node]) { 543 Script readScript(Uri uri, [ScriptTag node]) {
520 unimplemented('Compiler.readScript'); 544 unimplemented('Compiler.readScript');
521 } 545 }
522 546
523 String get legDirectory() { 547 String get legDirectory() {
524 unimplemented('Compiler.legDirectory'); 548 unimplemented('Compiler.legDirectory');
525 } 549 }
526 550
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 // invariant that endOffset > beginOffset, but for EOF the 619 // invariant that endOffset > beginOffset, but for EOF the
596 // charoffset of the next token may be [beginOffset]. This can 620 // charoffset of the next token may be [beginOffset]. This can
597 // also happen for synthetized tokens that are produced during 621 // also happen for synthetized tokens that are produced during
598 // error handling. 622 // error handling.
599 final endOffset = 623 final endOffset =
600 Math.max((end.next !== null) ? end.next.charOffset : 0, beginOffset + 1); 624 Math.max((end.next !== null) ? end.next.charOffset : 0, beginOffset + 1);
601 assert(endOffset > beginOffset); 625 assert(endOffset > beginOffset);
602 return f(beginOffset, endOffset); 626 return f(beginOffset, endOffset);
603 } 627 }
604 } 628 }
OLDNEW
« no previous file with comments | « no previous file | dart/lib/compiler/implementation/elements/elements.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698