OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 #include "vm/precompiler.h" | 5 #include "vm/precompiler.h" |
6 | 6 |
7 #include "vm/code_patcher.h" | 7 #include "vm/code_patcher.h" |
8 #include "vm/compiler.h" | 8 #include "vm/compiler.h" |
9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
10 #include "vm/log.h" | 10 #include "vm/log.h" |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 pending_functions_( | 61 pending_functions_( |
62 GrowableObjectArray::Handle(Z, GrowableObjectArray::New())), | 62 GrowableObjectArray::Handle(Z, GrowableObjectArray::New())), |
63 sent_selectors_(), | 63 sent_selectors_(), |
64 enqueued_functions_(), | 64 enqueued_functions_(), |
65 error_(Error::Handle(Z)) { | 65 error_(Error::Handle(Z)) { |
66 } | 66 } |
67 | 67 |
68 | 68 |
69 void Precompiler::DoCompileAll( | 69 void Precompiler::DoCompileAll( |
70 Dart_QualifiedFunctionName embedder_entry_points[]) { | 70 Dart_QualifiedFunctionName embedder_entry_points[]) { |
71 ClearAllCode(); | 71 ASSERT(I->compilation_allowed()); |
72 | 72 |
73 // Make sure class hierarchy is stable before compilation so that CHA | 73 // Make sure class hierarchy is stable before compilation so that CHA |
74 // can be used. Also ensures lookup of entry points won't miss functions | 74 // can be used. Also ensures lookup of entry points won't miss functions |
75 // because their class hasn't been finalized yet. | 75 // because their class hasn't been finalized yet. |
76 FinalizeAllClasses(); | 76 FinalizeAllClasses(); |
77 | 77 |
78 // Start with the allocations and invocations that happen from C++. | 78 const intptr_t kPrecompilerRounds = 1; |
79 AddRoots(embedder_entry_points); | 79 for (intptr_t round = 0; round < kPrecompilerRounds; round++) { |
| 80 if (FLAG_trace_precompiler) { |
| 81 OS::Print("Precompiler round %" Pd "\n", round); |
| 82 } |
80 | 83 |
81 // Compile newly found targets and add their callees until we reach a fixed | 84 if (round > 0) { |
82 // point. | 85 ResetPrecompilerState(); |
83 Iterate(); | 86 } |
| 87 |
| 88 // TODO(rmacnak): We should be able to do a more thorough job and drop some |
| 89 // - implicit static closures |
| 90 // - field initializers |
| 91 // - invoke-field-dispatchers |
| 92 // - method-extractors |
| 93 // that are needed in early iterations but optimized away in later |
| 94 // iterations. |
| 95 ClearAllCode(); |
| 96 |
| 97 // Start with the allocations and invocations that happen from C++. |
| 98 AddRoots(embedder_entry_points); |
| 99 |
| 100 // Compile newly found targets and add their callees until we reach a fixed |
| 101 // point. |
| 102 Iterate(); |
| 103 } |
84 | 104 |
85 DropUncompiledFunctions(); | 105 DropUncompiledFunctions(); |
86 | 106 |
87 // TODO(rmacnak): DropEmptyClasses(); | 107 // TODO(rmacnak): DropEmptyClasses(); |
88 | 108 |
89 BindStaticCalls(); | 109 BindStaticCalls(); |
90 | 110 |
91 DedupStackmaps(); | 111 DedupStackmaps(); |
92 | 112 |
93 if (FLAG_trace_precompiler) { | 113 if (FLAG_trace_precompiler) { |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 Function::KindToCString(function.kind())); | 351 Function::KindToCString(function.kind())); |
332 } | 352 } |
333 | 353 |
334 ASSERT(!function.is_abstract()); | 354 ASSERT(!function.is_abstract()); |
335 ASSERT(!function.IsRedirectingFactory()); | 355 ASSERT(!function.IsRedirectingFactory()); |
336 | 356 |
337 error_ = Compiler::CompileFunction(thread_, function); | 357 error_ = Compiler::CompileFunction(thread_, function); |
338 if (!error_.IsNull()) { | 358 if (!error_.IsNull()) { |
339 Jump(error_); | 359 Jump(error_); |
340 } | 360 } |
| 361 } else { |
| 362 if (FLAG_trace_precompiler) { |
| 363 // This function was compiled from somewhere other than Precompiler, |
| 364 // such as const constructors compiled by the parser. |
| 365 THR_Print("Already has code: %s (%" Pd ", %s)\n", |
| 366 function.ToLibNamePrefixedQualifiedCString(), |
| 367 function.token_pos(), |
| 368 Function::KindToCString(function.kind())); |
| 369 } |
341 } | 370 } |
342 | 371 |
343 ASSERT(function.HasCode()); | 372 ASSERT(function.HasCode()); |
344 AddCalleesOf(function); | 373 AddCalleesOf(function); |
345 } | 374 } |
346 | 375 |
347 | 376 |
348 void Precompiler::AddCalleesOf(const Function& function) { | 377 void Precompiler::AddCalleesOf(const Function& function) { |
349 ASSERT(function.HasCode()); | 378 ASSERT(function.HasCode()); |
350 | 379 |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 AddConstObject(Instance::Cast(value)); | 524 AddConstObject(Instance::Cast(value)); |
496 } | 525 } |
497 | 526 |
498 if (field.has_initializer()) { | 527 if (field.has_initializer()) { |
499 // Should not be in the middle of initialization while precompiling. | 528 // Should not be in the middle of initialization while precompiling. |
500 ASSERT(value.raw() != Object::transition_sentinel().raw()); | 529 ASSERT(value.raw() != Object::transition_sentinel().raw()); |
501 | 530 |
502 const bool is_initialized = value.raw() != Object::sentinel().raw(); | 531 const bool is_initialized = value.raw() != Object::sentinel().raw(); |
503 if (is_initialized && !reset_fields_) return; | 532 if (is_initialized && !reset_fields_) return; |
504 | 533 |
505 if (field.HasPrecompiledInitializer()) return; | 534 if (!field.HasPrecompiledInitializer()) { |
506 | 535 if (FLAG_trace_precompiler) { |
507 if (FLAG_trace_precompiler) { | 536 THR_Print("Precompiling initializer for %s\n", field.ToCString()); |
508 THR_Print("Precompiling initializer for %s\n", field.ToCString()); | 537 } |
| 538 ASSERT(!Dart::IsRunningPrecompiledCode()); |
| 539 field.SetStaticValue(Instance::Handle(field.SavedInitialStaticValue())); |
| 540 Compiler::CompileStaticInitializer(field); |
509 } | 541 } |
510 ASSERT(!Dart::IsRunningPrecompiledCode()); | |
511 field.SetStaticValue(Instance::Handle(field.SavedInitialStaticValue())); | |
512 Compiler::CompileStaticInitializer(field); | |
513 | 542 |
514 const Function& function = | 543 const Function& function = |
515 Function::Handle(Z, field.PrecompiledInitializer()); | 544 Function::Handle(Z, field.PrecompiledInitializer()); |
516 AddCalleesOf(function); | 545 AddCalleesOf(function); |
517 } | 546 } |
518 } | 547 } |
519 } | 548 } |
520 | 549 |
521 | 550 |
522 void Precompiler::AddFunction(const Function& function) { | 551 void Precompiler::AddFunction(const Function& function) { |
(...skipping 27 matching lines...) Expand all Loading... |
550 selector.ToCString()); | 579 selector.ToCString()); |
551 } | 580 } |
552 } | 581 } |
553 } | 582 } |
554 | 583 |
555 | 584 |
556 void Precompiler::AddInstantiatedClass(const Class& cls) { | 585 void Precompiler::AddInstantiatedClass(const Class& cls) { |
557 if (cls.is_allocated()) return; | 586 if (cls.is_allocated()) return; |
558 | 587 |
559 class_count_++; | 588 class_count_++; |
560 cls.set_is_allocated(); | 589 cls.set_is_allocated(true); |
561 changed_ = true; | 590 changed_ = true; |
562 | 591 |
563 if (FLAG_trace_precompiler) { | 592 if (FLAG_trace_precompiler) { |
564 THR_Print("Allocation %" Pd " %s\n", class_count_, cls.ToCString()); | 593 THR_Print("Allocation %" Pd " %s\n", class_count_, cls.ToCString()); |
565 } | 594 } |
566 | 595 |
567 const Class& superclass = Class::Handle(cls.SuperClass()); | 596 const Class& superclass = Class::Handle(cls.SuperClass()); |
568 if (!superclass.IsNull()) { | 597 if (!superclass.IsNull()) { |
569 AddInstantiatedClass(superclass); | 598 AddInstantiatedClass(superclass); |
570 } | 599 } |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
897 if (cls.IsDynamicClass()) { | 926 if (cls.IsDynamicClass()) { |
898 continue; // class 'dynamic' is in the read-only VM isolate. | 927 continue; // class 'dynamic' is in the read-only VM isolate. |
899 } | 928 } |
900 cls.EnsureIsFinalized(T); | 929 cls.EnsureIsFinalized(T); |
901 } | 930 } |
902 } | 931 } |
903 I->set_all_classes_finalized(true); | 932 I->set_all_classes_finalized(true); |
904 } | 933 } |
905 | 934 |
906 | 935 |
| 936 void Precompiler::ResetPrecompilerState() { |
| 937 changed_ = false; |
| 938 function_count_ = 0; |
| 939 class_count_ = 0; |
| 940 selector_count_ = 0; |
| 941 dropped_function_count_ = 0; |
| 942 ASSERT(pending_functions_.Length() == 0); |
| 943 sent_selectors_.Clear(); |
| 944 enqueued_functions_.Clear(); |
| 945 |
| 946 Library& lib = Library::Handle(Z); |
| 947 Class& cls = Class::Handle(Z); |
| 948 |
| 949 for (intptr_t i = 0; i < libraries_.Length(); i++) { |
| 950 lib ^= libraries_.At(i); |
| 951 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); |
| 952 while (it.HasNext()) { |
| 953 cls = it.GetNextClass(); |
| 954 if (cls.IsDynamicClass()) { |
| 955 continue; // class 'dynamic' is in the read-only VM isolate. |
| 956 } |
| 957 cls.set_is_allocated(false); |
| 958 } |
| 959 } |
| 960 } |
| 961 |
907 } // namespace dart | 962 } // namespace dart |
OLD | NEW |