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

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

Issue 10377166: Prepare to have more than one universe. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
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 | dart/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
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 int hashCode() => element.hashCode(); 15 int hashCode() => element.hashCode();
16 16
17 String run(Compiler compiler) { 17 String run(Compiler compiler) {
18 String code = compiler.universe.generatedCode[element]; 18 String code = compiler.codegenWorld.generatedCode[element];
19 if (code !== null) return code; 19 if (code !== null) return code;
20 try { 20 try {
21 if (!isAnalyzed()) compiler.analyze(this); 21 if (!isAnalyzed()) compiler.analyze(this);
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 }
(...skipping 23 matching lines...) Expand all
52 optimizer = new SsaOptimizerTask(this); 52 optimizer = new SsaOptimizerTask(this);
53 generator = new SsaCodeGeneratorTask(this); 53 generator = new SsaCodeGeneratorTask(this);
54 } 54 }
55 55
56 String codegen(WorkItem work) { 56 String codegen(WorkItem work) {
57 HGraph graph = builder.build(work); 57 HGraph graph = builder.build(work);
58 optimizer.optimize(work, graph); 58 optimizer.optimize(work, graph);
59 if (work.allowSpeculativeOptimization 59 if (work.allowSpeculativeOptimization
60 && optimizer.trySpeculativeOptimizations(work, graph)) { 60 && optimizer.trySpeculativeOptimizations(work, graph)) {
61 String code = generator.generateBailoutMethod(work, graph); 61 String code = generator.generateBailoutMethod(work, graph);
62 compiler.universe.addBailoutCode(work, code); 62 compiler.codegenWorld.addBailoutCode(work, code);
63 optimizer.prepareForSpeculativeOptimizations(work, graph); 63 optimizer.prepareForSpeculativeOptimizations(work, graph);
64 optimizer.optimize(work, graph); 64 optimizer.optimize(work, graph);
65 } 65 }
66 return generator.generateMethod(work, graph); 66 return generator.generateMethod(work, graph);
67 } 67 }
68 68
69 void processNativeClasses(libraries) { 69 void processNativeClasses(libraries) {
70 native.processNativeClasses(emitter, libraries); 70 native.processNativeClasses(emitter, libraries);
71 } 71 }
72 72
73 void assembleProgram() => emitter.assembleProgram(); 73 void assembleProgram() => emitter.assembleProgram();
74 } 74 }
75 75
76 class Compiler implements DiagnosticListener { 76 class Compiler implements DiagnosticListener {
77 Queue<WorkItem> codegenQueue; 77 final Map<String, LibraryElement> libraries;
78 Universe universe; 78 int nextFreeClassId = 0;
79 World world; 79 World world;
80 String assembledCode; 80 String assembledCode;
81 Namer namer; 81 Namer namer;
82 Types types; 82 Types types;
83 bool enableTypeAssertions = false; 83 bool enableTypeAssertions = false;
84 84
85 final Tracer tracer; 85 final Tracer tracer;
86 86
87 CompilerTask measuredTask; 87 CompilerTask measuredTask;
88 Element _currentElement; 88 Element _currentElement;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 EnqueueTask enqueuer; 128 EnqueueTask enqueuer;
129 129
130 static final SourceString MAIN = const SourceString('main'); 130 static final SourceString MAIN = const SourceString('main');
131 static final SourceString NO_SUCH_METHOD = const SourceString('noSuchMethod'); 131 static final SourceString NO_SUCH_METHOD = const SourceString('noSuchMethod');
132 static final SourceString NO_SUCH_METHOD_EXCEPTION = 132 static final SourceString NO_SUCH_METHOD_EXCEPTION =
133 const SourceString('NoSuchMethodException'); 133 const SourceString('NoSuchMethodException');
134 static final SourceString START_ROOT_ISOLATE = 134 static final SourceString START_ROOT_ISOLATE =
135 const SourceString('startRootIsolate'); 135 const SourceString('startRootIsolate');
136 bool enabledNoSuchMethod = false; 136 bool enabledNoSuchMethod = false;
137 137
138 bool codegenQueueIsClosed = false;
139
140 Stopwatch codegenProgress; 138 Stopwatch codegenProgress;
141 139
142 Compiler([this.tracer = const Tracer()]) 140 Compiler([this.tracer = const Tracer()])
143 : universe = new Universe(), 141 : libraries = new Map<String, LibraryElement>(),
144 world = new World(), 142 world = new World(),
145 codegenQueue = new Queue<WorkItem>(),
146 codegenProgress = new Stopwatch.start() { 143 codegenProgress = new Stopwatch.start() {
147 namer = new Namer(this); 144 namer = new Namer(this);
148 constantHandler = new ConstantHandler(this); 145 constantHandler = new ConstantHandler(this);
149 scanner = new ScannerTask(this); 146 scanner = new ScannerTask(this);
150 dietParser = new DietParserTask(this); 147 dietParser = new DietParserTask(this);
151 parser = new ParserTask(this); 148 parser = new ParserTask(this);
152 validator = new TreeValidatorTask(this); 149 validator = new TreeValidatorTask(this);
153 resolver = new ResolverTask(this); 150 resolver = new ResolverTask(this);
154 checker = new TypeCheckerTask(this); 151 checker = new TypeCheckerTask(this);
155 backend = new JavaScriptBackend(this); 152 backend = new JavaScriptBackend(this);
156 enqueuer = new EnqueueTask(this); 153 enqueuer = new EnqueueTask(this);
157 tasks = [scanner, dietParser, parser, resolver, checker, 154 tasks = [scanner, dietParser, parser, resolver, checker,
158 constantHandler, enqueuer]; 155 constantHandler, enqueuer];
159 } 156 }
160 157
158 Universe get codegenWorld() => enqueuer.codegen.universe;
159
160 int getNextFreeClassId() => nextFreeClassId++;
161
161 void ensure(bool condition) { 162 void ensure(bool condition) {
162 if (!condition) cancel('failed assertion in leg'); 163 if (!condition) cancel('failed assertion in leg');
163 } 164 }
164 165
165 void unimplemented(String methodName, 166 void unimplemented(String methodName,
166 [Node node, Token token, HInstruction instruction, 167 [Node node, Token token, HInstruction instruction,
167 Element element]) { 168 Element element]) {
168 internalError("$methodName not implemented", 169 internalError("$methodName not implemented",
169 node, token, instruction, element); 170 node, token, instruction, element);
170 } 171 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 } 228 }
228 tracer.close(); 229 tracer.close();
229 log('compilation succeeded'); 230 log('compilation succeeded');
230 return true; 231 return true;
231 } 232 }
232 233
233 void enableNoSuchMethod(Element element) { 234 void enableNoSuchMethod(Element element) {
234 if (enabledNoSuchMethod) return; 235 if (enabledNoSuchMethod) return;
235 if (element.enclosingElement == objectClass) return; 236 if (element.enclosingElement == objectClass) return;
236 enabledNoSuchMethod = true; 237 enabledNoSuchMethod = true;
237 enqueuer.registerInvocation(NO_SUCH_METHOD, new Selector.invocation(2)); 238 enqueuer.codegen.registerInvocation(NO_SUCH_METHOD,
239 new Selector.invocation(2));
238 } 240 }
239 241
240 void enableIsolateSupport(LibraryElement element) { 242 void enableIsolateSupport(LibraryElement element) {
241 isolateLibrary = element; 243 isolateLibrary = element;
242 addToWorkList(element.find(START_ROOT_ISOLATE)); 244 enqueuer.codegen.addToWorkList(element.find(START_ROOT_ISOLATE));
243 } 245 }
244 246
245 bool hasIsolateSupport() => isolateLibrary !== null; 247 bool hasIsolateSupport() => isolateLibrary !== null;
246 248
247 void onLibraryLoaded(LibraryElement library, Uri uri) { 249 void onLibraryLoaded(LibraryElement library, Uri uri) {
248 if (uri.toString() == 'dart:isolate') { 250 if (uri.toString() == 'dart:isolate') {
249 enableIsolateSupport(library); 251 enableIsolateSupport(library);
250 } 252 }
251 if (dynamicClass !== null) { 253 if (dynamicClass !== null) {
252 // When loading the built-in libraries, dynamicClass is null. We 254 // When loading the built-in libraries, dynamicClass is null. We
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 // built. So we add the implicit import of coreLibrary now. This 300 // built. So we add the implicit import of coreLibrary now. This
299 // can be cleaned up when we have proper support for "dart:core" 301 // can be cleaned up when we have proper support for "dart:core"
300 // and don't need to access it through the field "coreLibrary". 302 // and don't need to access it through the field "coreLibrary".
301 // TODO(ahe): Clean this up as described above. 303 // TODO(ahe): Clean this up as described above.
302 scanner.importLibrary(coreImplLibrary, coreLibrary, null); 304 scanner.importLibrary(coreImplLibrary, coreLibrary, null);
303 scanner.importLibrary(jsHelperLibrary, coreLibrary, null); 305 scanner.importLibrary(jsHelperLibrary, coreLibrary, null);
304 scanner.importLibrary(interceptorsLibrary, coreLibrary, null); 306 scanner.importLibrary(interceptorsLibrary, coreLibrary, null);
305 addForeignFunctions(jsHelperLibrary); 307 addForeignFunctions(jsHelperLibrary);
306 addForeignFunctions(interceptorsLibrary); 308 addForeignFunctions(interceptorsLibrary);
307 309
308 universe.libraries['dart:core'] = coreLibrary; 310 libraries['dart:core'] = coreLibrary;
309 universe.libraries['dart:coreimpl'] = coreImplLibrary; 311 libraries['dart:coreimpl'] = coreImplLibrary;
310 312
311 initializeSpecialClasses(); 313 initializeSpecialClasses();
312 } 314 }
313 315
314 /** Define the JS helper functions in the given library. */ 316 /** Define the JS helper functions in the given library. */
315 void addForeignFunctions(LibraryElement library) { 317 void addForeignFunctions(LibraryElement library) {
316 library.define(new ForeignElement( 318 library.define(new ForeignElement(
317 const SourceString('JS'), library), this); 319 const SourceString('JS'), library), this);
318 library.define(new ForeignElement( 320 library.define(new ForeignElement(
319 const SourceString('UNINTERCEPTED'), library), this); 321 const SourceString('UNINTERCEPTED'), library), this);
(...skipping 14 matching lines...) Expand all
334 if (main === null) { 336 if (main === null) {
335 reportFatalError('Could not find $MAIN', mainApp); 337 reportFatalError('Could not find $MAIN', mainApp);
336 } else { 338 } else {
337 if (!main.isFunction()) reportFatalError('main is not a function', main); 339 if (!main.isFunction()) reportFatalError('main is not a function', main);
338 FunctionElement mainMethod = main; 340 FunctionElement mainMethod = main;
339 FunctionSignature parameters = mainMethod.computeSignature(this); 341 FunctionSignature parameters = mainMethod.computeSignature(this);
340 parameters.forEachParameter((Element parameter) { 342 parameters.forEachParameter((Element parameter) {
341 reportFatalError('main cannot have parameters', parameter); 343 reportFatalError('main cannot have parameters', parameter);
342 }); 344 });
343 } 345 }
344 Collection<LibraryElement> libraries = universe.libraries.getValues(); 346 Collection<LibraryElement> libraries = libraries.getValues();
345 backend.processNativeClasses(libraries); 347 backend.processNativeClasses(libraries);
346 world.populate(this, libraries); 348 world.populate(this, libraries);
347 addToWorkList(main); 349 enqueuer.codegen.addToWorkList(main);
348 codegenProgress.reset(); 350 codegenProgress.reset();
349 while (!codegenQueue.isEmpty()) { 351 while (!enqueuer.codegen.queue.isEmpty()) {
350 WorkItem work = codegenQueue.removeLast(); 352 WorkItem work = enqueuer.codegen.queue.removeLast();
351 withCurrentElement(work.element, () => work.run(this)); 353 withCurrentElement(work.element, () => work.run(this));
352 } 354 }
353 codegenQueueIsClosed = true; 355 enqueuer.codegen.queueIsClosed = true;
354 assert(enqueuer.checkNoEnqueuedInvokedInstanceMethods()); 356 assert(enqueuer.codegen.checkNoEnqueuedInvokedInstanceMethods());
355 enqueuer.registerFieldClosureInvocations(); 357 enqueuer.codegen.registerFieldClosureInvocations();
356 backend.assembleProgram(); 358 backend.assembleProgram();
357 if (!codegenQueue.isEmpty()) { 359 if (!enqueuer.codegen.queue.isEmpty()) {
358 internalErrorOnElement(codegenQueue.first().element, 360 internalErrorOnElement(enqueuer.codegen.queue.first().element,
359 "work list is not empty"); 361 "work list is not empty");
360 } 362 }
361 } 363 }
362 364
363 TreeElements analyzeElement(Element element) { 365 TreeElements analyzeElement(Element element) {
364 assert(parser !== null); 366 assert(parser !== null);
365 Node tree = parser.parse(element); 367 Node tree = parser.parse(element);
366 validator.validate(tree); 368 validator.validate(tree);
367 TreeElements elements = resolver.resolve(element); 369 TreeElements elements = resolver.resolve(element);
368 checker.check(tree, elements); 370 checker.check(tree, elements);
369 return elements; 371 return elements;
370 } 372 }
371 373
372 TreeElements analyze(WorkItem work) { 374 TreeElements analyze(WorkItem work) {
373 work.resolutionTree = analyzeElement(work.element); 375 work.resolutionTree = analyzeElement(work.element);
374 return work.resolutionTree; 376 return work.resolutionTree;
375 } 377 }
376 378
377 String codegen(WorkItem work) { 379 String codegen(WorkItem work) {
378 if (codegenProgress.elapsedInMs() > 500) { 380 if (codegenProgress.elapsedInMs() > 500) {
379 // TODO(ahe): Add structured diagnostics to the compiler API and 381 // TODO(ahe): Add structured diagnostics to the compiler API and
380 // use it to separate this from the --verbose option. 382 // use it to separate this from the --verbose option.
381 log('compiled ${universe.generatedCode.length} methods'); 383 log('compiled ${codegenWorld.generatedCode.length} methods');
382 codegenProgress.reset(); 384 codegenProgress.reset();
383 } 385 }
384 if (work.element.kind.category == ElementCategory.VARIABLE) { 386 if (work.element.kind.category == ElementCategory.VARIABLE) {
385 constantHandler.compileWorkItem(work); 387 constantHandler.compileWorkItem(work);
386 return null; 388 return null;
387 } else { 389 } else {
388 String code = backend.codegen(work); 390 String code = backend.codegen(work);
389 universe.addGeneratedCode(work, code); 391 codegenWorld.addGeneratedCode(work, code);
390 return code; 392 return code;
391 } 393 }
392 } 394 }
393 395
394 void addToWorkList(Element element, [TreeElements elements]) {
395 if (codegenQueueIsClosed) {
396 internalErrorOnElement(element, "work list is closed");
397 }
398 if (element.kind === ElementKind.GENERATIVE_CONSTRUCTOR) {
399 registerInstantiatedClass(element.enclosingElement);
400 }
401 codegenQueue.add(new WorkItem(element, elements));
402 }
403
404 void registerStaticUse(Element element) { 396 void registerStaticUse(Element element) {
405 addToWorkList(element); 397 enqueuer.codegen.addToWorkList(element);
406 } 398 }
407 399
408 void registerGetOfStaticFunction(FunctionElement element) { 400 void registerGetOfStaticFunction(FunctionElement element) {
409 registerStaticUse(element); 401 registerStaticUse(element);
410 universe.staticFunctionsNeedingGetter.add(element); 402 codegenWorld.staticFunctionsNeedingGetter.add(element);
411 } 403 }
412 404
413 void registerDynamicInvocation(SourceString methodName, Selector selector) { 405 void registerDynamicInvocation(SourceString methodName, Selector selector) {
414 assert(selector !== null); 406 assert(selector !== null);
415 enqueuer.registerInvocation(methodName, selector); 407 enqueuer.codegen.registerInvocation(methodName, selector);
416 } 408 }
417 409
418 void registerDynamicInvocationOf(Element element) { 410 void registerDynamicInvocationOf(Element element) {
419 addToWorkList(element); 411 enqueuer.codegen.addToWorkList(element);
420 } 412 }
421 413
422 void registerDynamicGetter(SourceString methodName, Selector selector) { 414 void registerDynamicGetter(SourceString methodName, Selector selector) {
423 enqueuer.registerGetter(methodName, selector); 415 enqueuer.codegen.registerGetter(methodName, selector);
424 } 416 }
425 417
426 void registerDynamicSetter(SourceString methodName, Selector selector) { 418 void registerDynamicSetter(SourceString methodName, Selector selector) {
427 enqueuer.registerSetter(methodName, selector); 419 enqueuer.codegen.registerSetter(methodName, selector);
428 } 420 }
429 421
430 void registerInstantiatedClass(ClassElement element) { 422 void registerInstantiatedClass(ClassElement cls) {
431 universe.instantiatedClasses.add(element); 423 enqueuer.codegen.registerInstantiatedClass(cls);
432 enqueuer.onRegisterInstantiatedClass(element);
433 } 424 }
434 425
435 // TODO(ngeoffray): This should get a type. 426 // TODO(ngeoffray): This should get a type.
436 void registerIsCheck(Element element) { 427 void registerIsCheck(Element element) {
437 universe.isChecks.add(element); 428 codegenWorld.isChecks.add(element);
438 } 429 }
439 430
440 void resolveClass(ClassElement element) { 431 void resolveClass(ClassElement element) {
441 withCurrentElement(element, () => resolver.resolveClass(element)); 432 withCurrentElement(element, () => resolver.resolveClass(element));
442 } 433 }
443 434
444 Type resolveTypeAnnotation(Element element, TypeAnnotation annotation) { 435 Type resolveTypeAnnotation(Element element, TypeAnnotation annotation) {
445 return resolver.resolveTypeAnnotation(element, annotation); 436 return resolver.resolveTypeAnnotation(element, annotation);
446 } 437 }
447 438
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 } 578 }
588 } 579 }
589 580
590 class SourceSpan { 581 class SourceSpan {
591 final Uri uri; 582 final Uri uri;
592 final int begin; 583 final int begin;
593 final int end; 584 final int end;
594 585
595 const SourceSpan(this.uri, this.begin, this.end); 586 const SourceSpan(this.uri, this.begin, this.end);
596 } 587 }
OLDNEW
« no previous file with comments | « no previous file | dart/lib/compiler/implementation/emitter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698