| 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/compiler.h" | 7 #include "vm/compiler.h" |
| 8 #include "vm/isolate.h" | 8 #include "vm/isolate.h" |
| 9 #include "vm/log.h" | 9 #include "vm/log.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 pending_functions_(GrowableObjectArray::Handle(Z, | 57 pending_functions_(GrowableObjectArray::Handle(Z, |
| 58 GrowableObjectArray::New())), | 58 GrowableObjectArray::New())), |
| 59 collected_closures_(GrowableObjectArray::Handle(Z, I->collected_closures())), | 59 collected_closures_(GrowableObjectArray::Handle(Z, I->collected_closures())), |
| 60 sent_selectors_(Z), | 60 sent_selectors_(Z), |
| 61 error_(Error::Handle(Z)) { | 61 error_(Error::Handle(Z)) { |
| 62 } | 62 } |
| 63 | 63 |
| 64 | 64 |
| 65 void Precompiler::DoCompileAll( | 65 void Precompiler::DoCompileAll( |
| 66 Dart_QualifiedFunctionName embedder_entry_points[]) { | 66 Dart_QualifiedFunctionName embedder_entry_points[]) { |
| 67 LogBlock lb; | |
| 68 | |
| 69 // Drop all existing code so we can use the presence of code as an indicator | 67 // Drop all existing code so we can use the presence of code as an indicator |
| 70 // that we have already looked for the function's callees. | 68 // that we have already looked for the function's callees. |
| 71 ClearAllCode(); | 69 ClearAllCode(); |
| 72 | 70 |
| 73 // Start with the allocations and invocations that happen from C++. | 71 // Start with the allocations and invocations that happen from C++. |
| 74 AddRoots(embedder_entry_points); | 72 AddRoots(embedder_entry_points); |
| 75 | 73 |
| 76 // TODO(rmacnak): Eagerly add field-invocation functions to all signature | 74 // TODO(rmacnak): Eagerly add field-invocation functions to all signature |
| 77 // classes so closure calls don't go through the runtime. | 75 // classes so closure calls don't go through the runtime. |
| 78 | 76 |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 | 462 |
| 465 void Precompiler::AddFunction(const Function& function) { | 463 void Precompiler::AddFunction(const Function& function) { |
| 466 if (function.HasCode()) return; | 464 if (function.HasCode()) return; |
| 467 | 465 |
| 468 pending_functions_.Add(function); | 466 pending_functions_.Add(function); |
| 469 changed_ = true; | 467 changed_ = true; |
| 470 } | 468 } |
| 471 | 469 |
| 472 | 470 |
| 473 bool Precompiler::IsSent(const String& selector) { | 471 bool Precompiler::IsSent(const String& selector) { |
| 472 if (selector.IsNull()) { |
| 473 return false; |
| 474 } |
| 474 return sent_selectors_.Includes(selector); | 475 return sent_selectors_.Includes(selector); |
| 475 } | 476 } |
| 476 | 477 |
| 477 | 478 |
| 478 void Precompiler::AddSelector(const String& selector) { | 479 void Precompiler::AddSelector(const String& selector) { |
| 480 ASSERT(!selector.IsNull()); |
| 481 |
| 479 if (!IsSent(selector)) { | 482 if (!IsSent(selector)) { |
| 480 sent_selectors_.Add(selector); | 483 sent_selectors_.Add(selector); |
| 481 selector_count_++; | 484 selector_count_++; |
| 482 changed_ = true; | 485 changed_ = true; |
| 483 | 486 |
| 484 if (FLAG_trace_precompiler) { | 487 if (FLAG_trace_precompiler) { |
| 485 THR_Print("Enqueueing selector %" Pd " %s\n", | 488 THR_Print("Enqueueing selector %" Pd " %s\n", |
| 486 selector_count_, | 489 selector_count_, |
| 487 selector.ToCString()); | 490 selector.ToCString()); |
| 488 } | 491 } |
| 489 | |
| 490 if (!Field::IsGetterName(selector) && | |
| 491 !Field::IsSetterName(selector)) { | |
| 492 // Regular method may be call-through-getter. | |
| 493 const String& getter = String::Handle(Field::GetterSymbol(selector)); | |
| 494 AddSelector(getter); | |
| 495 } | |
| 496 } | 492 } |
| 497 } | 493 } |
| 498 | 494 |
| 499 | 495 |
| 500 void Precompiler::AddClass(const Class& cls) { | 496 void Precompiler::AddClass(const Class& cls) { |
| 501 if (cls.is_allocated()) return; | 497 if (cls.is_allocated()) return; |
| 502 | 498 |
| 503 class_count_++; | 499 class_count_++; |
| 504 cls.set_is_allocated(); | 500 cls.set_is_allocated(); |
| 505 changed_ = true; | 501 changed_ = true; |
| 506 | 502 |
| 507 if (FLAG_trace_precompiler) { | 503 if (FLAG_trace_precompiler) { |
| 508 THR_Print("Allocation %" Pd " %s\n", class_count_, cls.ToCString()); | 504 THR_Print("Allocation %" Pd " %s\n", class_count_, cls.ToCString()); |
| 509 } | 505 } |
| 510 | 506 |
| 511 const Class& superclass = Class::Handle(cls.SuperClass()); | 507 const Class& superclass = Class::Handle(cls.SuperClass()); |
| 512 if (!superclass.IsNull()) { | 508 if (!superclass.IsNull()) { |
| 513 AddClass(superclass); | 509 AddClass(superclass); |
| 514 } | 510 } |
| 515 } | 511 } |
| 516 | 512 |
| 517 | 513 |
| 518 void Precompiler::CheckForNewDynamicFunctions() { | 514 void Precompiler::CheckForNewDynamicFunctions() { |
| 519 Library& lib = Library::Handle(Z); | 515 Library& lib = Library::Handle(Z); |
| 520 Class& cls = Class::Handle(Z); | 516 Class& cls = Class::Handle(Z); |
| 521 Array& functions = Array::Handle(Z); | 517 Array& functions = Array::Handle(Z); |
| 522 Function& function = Function::Handle(Z); | 518 Function& function = Function::Handle(Z); |
| 519 Function& function2 = Function::Handle(Z); |
| 523 String& selector = String::Handle(Z); | 520 String& selector = String::Handle(Z); |
| 521 String& selector2 = String::Handle(Z); |
| 522 String& selector3 = String::Handle(Z); |
| 524 | 523 |
| 525 for (intptr_t i = 0; i < libraries_.Length(); i++) { | 524 for (intptr_t i = 0; i < libraries_.Length(); i++) { |
| 526 lib ^= libraries_.At(i); | 525 lib ^= libraries_.At(i); |
| 527 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); | 526 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); |
| 528 while (it.HasNext()) { | 527 while (it.HasNext()) { |
| 529 cls = it.GetNextClass(); | 528 cls = it.GetNextClass(); |
| 530 | 529 |
| 531 if (!cls.is_allocated()) { | 530 if (!cls.is_allocated()) { |
| 532 bool has_compiled_constructor = false; | 531 bool has_compiled_constructor = false; |
| 533 if (cls.allocation_stub() != Code::null()) { | 532 if (cls.allocation_stub() != Code::null()) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 | 573 |
| 575 // Don't bail out early if there is already code because we may discover | 574 // Don't bail out early if there is already code because we may discover |
| 576 // the corresponding getter selector is sent in some later iteration. | 575 // the corresponding getter selector is sent in some later iteration. |
| 577 // if (function.HasCode()) continue; | 576 // if (function.HasCode()) continue; |
| 578 | 577 |
| 579 selector = function.name(); | 578 selector = function.name(); |
| 580 if (IsSent(selector)) { | 579 if (IsSent(selector)) { |
| 581 AddFunction(function); | 580 AddFunction(function); |
| 582 } | 581 } |
| 583 | 582 |
| 584 if (function.kind() == RawFunction::kRegularFunction && | 583 // Handle the implicit call type conversions. |
| 585 !Field::IsGetterName(selector) && | 584 if (Field::IsGetterName(selector)) { |
| 586 !Field::IsSetterName(selector)) { | 585 selector2 = Field::NameFromGetter(selector); |
| 587 selector = Field::GetterSymbol(selector); | 586 selector3 = Symbols::Lookup(selector2); |
| 588 if (IsSent(selector)) { | 587 if (IsSent(selector2)) { |
| 589 function = function.ImplicitClosureFunction(); | 588 // Call-through-getter. |
| 589 // Function is get:foo and somewhere foo is called. |
| 590 AddFunction(function); | 590 AddFunction(function); |
| 591 } | 591 } |
| 592 selector3 = Symbols::LookupFromConcat(Symbols::ClosurizePrefix(), |
| 593 selector2); |
| 594 if (IsSent(selector3)) { |
| 595 // Hash-closurization. |
| 596 // Function is get:foo and somewhere get:#foo is called. |
| 597 AddFunction(function); |
| 598 |
| 599 function2 = function.ImplicitClosureFunction(); |
| 600 AddFunction(function2); |
| 601 } |
| 602 } else if (Field::IsSetterName(selector)) { |
| 603 selector2 = Symbols::LookupFromConcat(Symbols::ClosurizePrefix(), |
| 604 selector); |
| 605 if (IsSent(selector2)) { |
| 606 // Hash-closurization. |
| 607 // Function is set:foo and somewhere get:#set:foo is called. |
| 608 AddFunction(function); |
| 609 |
| 610 function2 = function.ImplicitClosureFunction(); |
| 611 AddFunction(function2); |
| 612 } |
| 613 } else if (function.kind() == RawFunction::kRegularFunction) { |
| 614 selector2 = Field::LookupGetterSymbol(selector); |
| 615 if (IsSent(selector2)) { |
| 616 // Closurization. |
| 617 // Function is foo and somewhere get:foo is called. |
| 618 function2 = function.ImplicitClosureFunction(); |
| 619 AddFunction(function2); |
| 620 } |
| 621 selector2 = Symbols::LookupFromConcat(Symbols::ClosurizePrefix(), |
| 622 selector); |
| 623 if (IsSent(selector2)) { |
| 624 // Hash-closurization. |
| 625 // Function is foo and somewhere get:#foo is called. |
| 626 function2 = function.ImplicitClosureFunction(); |
| 627 AddFunction(function2); |
| 628 } |
| 592 } | 629 } |
| 593 } | 630 } |
| 594 } | 631 } |
| 595 } | 632 } |
| 596 } | 633 } |
| 597 | 634 |
| 598 | 635 |
| 599 void Precompiler::DropUncompiledFunctions() { | 636 void Precompiler::DropUncompiledFunctions() { |
| 600 Library& lib = Library::Handle(Z); | 637 Library& lib = Library::Handle(Z); |
| 601 Class& cls = Class::Handle(Z); | 638 Class& cls = Class::Handle(Z); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 640 for (intptr_t j = 0; j < closures.Length(); j++) { | 677 for (intptr_t j = 0; j < closures.Length(); j++) { |
| 641 function ^= closures.At(j); | 678 function ^= closures.At(j); |
| 642 ASSERT(function.HasCode()); | 679 ASSERT(function.HasCode()); |
| 643 } | 680 } |
| 644 } | 681 } |
| 645 } | 682 } |
| 646 } | 683 } |
| 647 } | 684 } |
| 648 | 685 |
| 649 } // namespace dart | 686 } // namespace dart |
| OLD | NEW |