Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 #include "vm/compiler.h" | 5 #include "vm/compiler.h" |
| 6 | 6 |
| 7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
| 8 | 8 |
| 9 #include "vm/ast_printer.h" | 9 #include "vm/ast_printer.h" |
| 10 #include "vm/block_scheduler.h" | 10 #include "vm/block_scheduler.h" |
| (...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 778 // Do not install code, but return it instead. | 778 // Do not install code, but return it instead. |
| 779 // Since code dependencies (CHA, fields) are defined eagerly, | 779 // Since code dependencies (CHA, fields) are defined eagerly, |
| 780 // the code may be disabled before installing it. | 780 // the code may be disabled before installing it. |
| 781 code.set_owner(function); | 781 code.set_owner(function); |
| 782 result->set_result_code(code); | 782 result->set_result_code(code); |
| 783 // Disable invalidation counters that are not relevant. | 783 // Disable invalidation counters that are not relevant. |
| 784 if (thread->cha()->leaf_classes().is_empty()) { | 784 if (thread->cha()->leaf_classes().is_empty()) { |
| 785 result->ClearCHAInvalidationGen(); | 785 result->ClearCHAInvalidationGen(); |
| 786 } | 786 } |
| 787 if (flow_graph->guarded_fields()->is_empty()) { | 787 if (flow_graph->guarded_fields()->is_empty()) { |
| 788 result->ClearFieldInnvalidationGen(); | 788 result->ClearFieldInvalidationGen(); |
| 789 } | 789 } |
| 790 if (!parsed_function->HasDeferredPrefixes()) { | 790 if (!parsed_function->HasDeferredPrefixes()) { |
| 791 result->ClearPrefixInnvalidationGen(); | 791 result->ClearPrefixInvalidationGen(); |
| 792 } | 792 } |
| 793 } else { | 793 } else { |
| 794 const bool is_osr = osr_id != Compiler::kNoOSRDeoptId; | 794 const bool is_osr = osr_id != Compiler::kNoOSRDeoptId; |
| 795 function.InstallOptimizedCode(code, is_osr); | 795 function.InstallOptimizedCode(code, is_osr); |
| 796 } | 796 } |
| 797 | 797 |
| 798 // TODO(srdjan): In background compilation, verify that CHA and field | 798 // TODO(srdjan): In background compilation, verify that CHA and field |
| 799 // guards have not been invalidated in the meantime. | 799 // guards have not been invalidated in the meantime. |
| 800 // Register code with the classes it depends on because of CHA and | 800 // Register code with the classes it depends on because of CHA and |
| 801 // fields it depends on because of store guards, unless we cannot | 801 // fields it depends on because of store guards, unless we cannot |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1131 #endif | 1131 #endif |
| 1132 return Error::null(); | 1132 return Error::null(); |
| 1133 } else { | 1133 } else { |
| 1134 Thread* const thread = Thread::Current(); | 1134 Thread* const thread = Thread::Current(); |
| 1135 Isolate* const isolate = thread->isolate(); | 1135 Isolate* const isolate = thread->isolate(); |
| 1136 StackZone stack_zone(thread); | 1136 StackZone stack_zone(thread); |
| 1137 Error& error = Error::Handle(); | 1137 Error& error = Error::Handle(); |
| 1138 // We got an error during compilation. | 1138 // We got an error during compilation. |
| 1139 error = isolate->object_store()->sticky_error(); | 1139 error = isolate->object_store()->sticky_error(); |
| 1140 isolate->object_store()->clear_sticky_error(); | 1140 isolate->object_store()->clear_sticky_error(); |
| 1141 ASSERT(!optimized); | |
| 1142 // Do not attempt to optimize functions that can cause errors. | |
| 1143 function.set_is_optimizable(false); | |
| 1141 return error.raw(); | 1144 return error.raw(); |
| 1142 } | 1145 } |
| 1143 UNREACHABLE(); | 1146 UNREACHABLE(); |
| 1144 return Error::null(); | 1147 return Error::null(); |
| 1145 } | 1148 } |
| 1146 | 1149 |
| 1147 | 1150 |
| 1148 RawError* Compiler::CompileFunction(Thread* thread, | 1151 RawError* Compiler::CompileFunction(Thread* thread, |
| 1149 const Function& function) { | 1152 const Function& function) { |
| 1150 Isolate* isolate = thread->isolate(); | 1153 Isolate* isolate = thread->isolate(); |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1485 ASSERT(Thread::Current()->IsMutatorThread()); | 1488 ASSERT(Thread::Current()->IsMutatorThread()); |
| 1486 obj_ = Object::null(); | 1489 obj_ = Object::null(); |
| 1487 } | 1490 } |
| 1488 | 1491 |
| 1489 void Clear() { | 1492 void Clear() { |
| 1490 next_ = NULL; | 1493 next_ = NULL; |
| 1491 obj_ = Object::null(); | 1494 obj_ = Object::null(); |
| 1492 cha_invalidation_gen_ = Isolate::kInvalidGen; | 1495 cha_invalidation_gen_ = Isolate::kInvalidGen; |
| 1493 field_invalidation_gen_ = Isolate::kInvalidGen; | 1496 field_invalidation_gen_ = Isolate::kInvalidGen; |
| 1494 prefix_invalidation_gen_ = Isolate::kInvalidGen; | 1497 prefix_invalidation_gen_ = Isolate::kInvalidGen; |
| 1495 } | 1498 } |
|
siva
2015/11/06 23:12:54
This is not used anymore, can be removed?
srdjan
2015/12/09 22:43:17
Done.
| |
| 1496 | 1499 |
| 1497 RawFunction* Function() const { return Function::RawCast(obj_); } | 1500 RawFunction* Function() const { return Function::RawCast(obj_); } |
| 1498 RawCode* Code() const { | 1501 RawCode* Code() const { return Code::RawCast(obj_); } |
| 1499 return (obj_ == Object::null()) ? Code::null() : Code::RawCast(obj_); | |
| 1500 } | |
| 1501 | 1502 |
| 1502 uint32_t cha_invalidation_gen() const { return cha_invalidation_gen_; } | 1503 uint32_t cha_invalidation_gen() const { return cha_invalidation_gen_; } |
| 1503 uint32_t field_invalidation_gen() const { return field_invalidation_gen_; } | 1504 uint32_t field_invalidation_gen() const { return field_invalidation_gen_; } |
| 1504 uint32_t prefix_invalidation_gen() const { return prefix_invalidation_gen_; } | 1505 uint32_t prefix_invalidation_gen() const { return prefix_invalidation_gen_; } |
| 1505 | 1506 |
| 1506 void set_next(QueueElement* elem) { next_ = elem; } | 1507 void set_next(QueueElement* elem) { next_ = elem; } |
| 1507 QueueElement* next() const { return next_; } | 1508 QueueElement* next() const { return next_; } |
| 1508 | 1509 |
| 1509 RawObject** obj_ptr() { return &obj_; } | 1510 RawObject** obj_ptr() { return &obj_; } |
| 1510 RawObject* obj() const { return obj_; } | 1511 RawObject* obj() const { return obj_; } |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1699 BackgroundCompilationResult result; | 1700 BackgroundCompilationResult result; |
| 1700 while (running_ && !function.IsNull()) { | 1701 while (running_ && !function.IsNull()) { |
| 1701 result.Init(); | 1702 result.Init(); |
| 1702 const Error& error = Error::Handle(zone, | 1703 const Error& error = Error::Handle(zone, |
| 1703 Compiler::CompileOptimizedFunction(thread, | 1704 Compiler::CompileOptimizedFunction(thread, |
| 1704 function, | 1705 function, |
| 1705 Compiler::kNoOSRDeoptId, | 1706 Compiler::kNoOSRDeoptId, |
| 1706 &result)); | 1707 &result)); |
| 1707 // TODO(srdjan): We do not expect errors while compiling optimized | 1708 // TODO(srdjan): We do not expect errors while compiling optimized |
| 1708 // code, any errors should have been caught when compiling | 1709 // code, any errors should have been caught when compiling |
| 1709 // unoptimized code. | 1710 // unoptimized code. Any issues while optimizing are flagged by |
| 1710 // If it still happens mark function as not optimizable. | 1711 // making the result invalid. |
| 1711 ASSERT(error.IsNull()); | 1712 ASSERT(error.IsNull()); |
| 1712 // Reuse the input QueueElement to return the result. | 1713 AddResult(result); |
| 1713 QueueElement* qelem = function_queue()->Remove(); | |
| 1714 qelem->Clear(); | |
| 1715 result_queue()->Add(qelem); | |
| 1716 // Add 'qelem' to the queue first so that it gets visited by GC. | |
| 1717 qelem->SetFromResult(result); | |
| 1718 function = function_queue()->PeekFunction(); | 1714 function = function_queue()->PeekFunction(); |
| 1719 } | 1715 } |
| 1720 } | 1716 } |
| 1721 Thread::ExitIsolateAsHelper(); | 1717 Thread::ExitIsolateAsHelper(); |
| 1722 { | 1718 { |
| 1723 // Wait to be notified when the work queue is not empty. | 1719 // Wait to be notified when the work queue is not empty. |
| 1724 MonitorLocker ml(queue_monitor_); | 1720 MonitorLocker ml(queue_monitor_); |
| 1725 while (function_queue()->IsEmpty() && running_) { | 1721 while (function_queue()->IsEmpty() && running_) { |
| 1726 ml.Wait(); | 1722 ml.Wait(); |
| 1727 } | 1723 } |
| 1728 } | 1724 } |
| 1729 } // while running | 1725 } // while running |
| 1730 | 1726 |
| 1731 { | 1727 { |
| 1732 // Notify that the thread is done. | 1728 // Notify that the thread is done. |
| 1733 MonitorLocker ml_done(done_monitor_); | 1729 MonitorLocker ml_done(done_monitor_); |
| 1734 *done_ = true; | 1730 *done_ = true; |
| 1735 ml_done.Notify(); | 1731 ml_done.Notify(); |
| 1736 } | 1732 } |
| 1737 } | 1733 } |
| 1738 | 1734 |
| 1739 | 1735 |
| 1736 // Use to first queue element to form the result element. | |
| 1737 void BackgroundCompiler::AddResult(const BackgroundCompilationResult& result) { | |
| 1738 ASSERT(!Thread::Current()->IsMutatorThread()); | |
| 1739 MonitorLocker ml(queue_monitor_); | |
| 1740 // Reuse the input QueueElement to return the result. | |
| 1741 QueueElement* qelem = function_queue()->Remove(); | |
| 1742 if (result.IsValid()) { | |
| 1743 qelem->SetFromResult(result); | |
| 1744 result_queue()->Add(qelem); | |
| 1745 } | |
| 1746 } | |
| 1747 | |
| 1748 | |
| 1740 void BackgroundCompiler::CompileOptimized(const Function& function) { | 1749 void BackgroundCompiler::CompileOptimized(const Function& function) { |
| 1741 ASSERT(Thread::Current()->IsMutatorThread()); | 1750 ASSERT(Thread::Current()->IsMutatorThread()); |
| 1742 MonitorLocker ml(queue_monitor_); | 1751 MonitorLocker ml(queue_monitor_); |
| 1743 if (function_queue()->ContainsObj(function)) { | 1752 if (function_queue()->ContainsObj(function)) { |
| 1744 return; | 1753 return; |
| 1745 } | 1754 } |
| 1746 QueueElement* elem = new QueueElement(function); | 1755 QueueElement* elem = new QueueElement(function); |
| 1747 function_queue()->Add(elem); | 1756 function_queue()->Add(elem); |
| 1748 ml.Notify(); | 1757 ml.Notify(); |
| 1749 } | 1758 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1827 isolate->set_background_compiler(task); | 1836 isolate->set_background_compiler(task); |
| 1828 start_task = true; | 1837 start_task = true; |
| 1829 } | 1838 } |
| 1830 } | 1839 } |
| 1831 if (start_task) { | 1840 if (start_task) { |
| 1832 Dart::thread_pool()->Run(isolate->background_compiler()); | 1841 Dart::thread_pool()->Run(isolate->background_compiler()); |
| 1833 } | 1842 } |
| 1834 } | 1843 } |
| 1835 | 1844 |
| 1836 } // namespace dart | 1845 } // namespace dart |
| OLD | NEW |