| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include <stdlib.h> | 28 #include <stdlib.h> |
| 29 | 29 |
| 30 #include "v8.h" | 30 #include "v8.h" |
| 31 | 31 |
| 32 #include "allocation-inl.h" | |
| 33 #include "ast.h" | 32 #include "ast.h" |
| 34 #include "bootstrapper.h" | 33 #include "bootstrapper.h" |
| 35 #include "codegen.h" | 34 #include "codegen.h" |
| 36 #include "compilation-cache.h" | 35 #include "compilation-cache.h" |
| 37 #include "cpu-profiler.h" | 36 #include "cpu-profiler.h" |
| 38 #include "debug.h" | 37 #include "debug.h" |
| 39 #include "deoptimizer.h" | 38 #include "deoptimizer.h" |
| 40 #include "heap-profiler.h" | 39 #include "heap-profiler.h" |
| 41 #include "hydrogen.h" | 40 #include "hydrogen.h" |
| 42 #include "isolate-inl.h" | 41 #include "isolate-inl.h" |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 #endif | 124 #endif |
| 126 thread_id_ = ThreadId::Current(); | 125 thread_id_ = ThreadId::Current(); |
| 127 } | 126 } |
| 128 | 127 |
| 129 | 128 |
| 130 v8::TryCatch* ThreadLocalTop::TryCatchHandler() { | 129 v8::TryCatch* ThreadLocalTop::TryCatchHandler() { |
| 131 return TRY_CATCH_FROM_ADDRESS(try_catch_handler_address()); | 130 return TRY_CATCH_FROM_ADDRESS(try_catch_handler_address()); |
| 132 } | 131 } |
| 133 | 132 |
| 134 | 133 |
| 135 int SystemThreadManager::NumberOfParallelSystemThreads( | |
| 136 ParallelSystemComponent type) { | |
| 137 int number_of_threads = Min(CPU::NumberOfProcessorsOnline(), kMaxThreads); | |
| 138 ASSERT(number_of_threads > 0); | |
| 139 if (number_of_threads == 1) { | |
| 140 return 0; | |
| 141 } | |
| 142 if (type == PARALLEL_SWEEPING) { | |
| 143 return number_of_threads; | |
| 144 } else if (type == CONCURRENT_SWEEPING) { | |
| 145 return number_of_threads - 1; | |
| 146 } | |
| 147 return 1; | |
| 148 } | |
| 149 | |
| 150 | |
| 151 // Create a dummy thread that will wait forever on a semaphore. The only | |
| 152 // purpose for this thread is to have some stack area to save essential data | |
| 153 // into for use by a stacks only core dump (aka minidump). | |
| 154 class PreallocatedMemoryThread: public Thread { | |
| 155 public: | |
| 156 char* data() { | |
| 157 if (data_ready_semaphore_ != NULL) { | |
| 158 // Initial access is guarded until the data has been published. | |
| 159 data_ready_semaphore_->Wait(); | |
| 160 delete data_ready_semaphore_; | |
| 161 data_ready_semaphore_ = NULL; | |
| 162 } | |
| 163 return data_; | |
| 164 } | |
| 165 | |
| 166 unsigned length() { | |
| 167 if (data_ready_semaphore_ != NULL) { | |
| 168 // Initial access is guarded until the data has been published. | |
| 169 data_ready_semaphore_->Wait(); | |
| 170 delete data_ready_semaphore_; | |
| 171 data_ready_semaphore_ = NULL; | |
| 172 } | |
| 173 return length_; | |
| 174 } | |
| 175 | |
| 176 // Stop the PreallocatedMemoryThread and release its resources. | |
| 177 void StopThread() { | |
| 178 keep_running_ = false; | |
| 179 wait_for_ever_semaphore_->Signal(); | |
| 180 | |
| 181 // Wait for the thread to terminate. | |
| 182 Join(); | |
| 183 | |
| 184 if (data_ready_semaphore_ != NULL) { | |
| 185 delete data_ready_semaphore_; | |
| 186 data_ready_semaphore_ = NULL; | |
| 187 } | |
| 188 | |
| 189 delete wait_for_ever_semaphore_; | |
| 190 wait_for_ever_semaphore_ = NULL; | |
| 191 } | |
| 192 | |
| 193 protected: | |
| 194 // When the thread starts running it will allocate a fixed number of bytes | |
| 195 // on the stack and publish the location of this memory for others to use. | |
| 196 void Run() { | |
| 197 EmbeddedVector<char, 15 * 1024> local_buffer; | |
| 198 | |
| 199 // Initialize the buffer with a known good value. | |
| 200 OS::StrNCpy(local_buffer, "Trace data was not generated.\n", | |
| 201 local_buffer.length()); | |
| 202 | |
| 203 // Publish the local buffer and signal its availability. | |
| 204 data_ = local_buffer.start(); | |
| 205 length_ = local_buffer.length(); | |
| 206 data_ready_semaphore_->Signal(); | |
| 207 | |
| 208 while (keep_running_) { | |
| 209 // This thread will wait here until the end of time. | |
| 210 wait_for_ever_semaphore_->Wait(); | |
| 211 } | |
| 212 | |
| 213 // Make sure we access the buffer after the wait to remove all possibility | |
| 214 // of it being optimized away. | |
| 215 OS::StrNCpy(local_buffer, "PreallocatedMemoryThread shutting down.\n", | |
| 216 local_buffer.length()); | |
| 217 } | |
| 218 | |
| 219 | |
| 220 private: | |
| 221 PreallocatedMemoryThread() | |
| 222 : Thread("v8:PreallocMem"), | |
| 223 keep_running_(true), | |
| 224 wait_for_ever_semaphore_(new Semaphore(0)), | |
| 225 data_ready_semaphore_(new Semaphore(0)), | |
| 226 data_(NULL), | |
| 227 length_(0) { | |
| 228 } | |
| 229 | |
| 230 // Used to make sure that the thread keeps looping even for spurious wakeups. | |
| 231 bool keep_running_; | |
| 232 | |
| 233 // This semaphore is used by the PreallocatedMemoryThread to wait for ever. | |
| 234 Semaphore* wait_for_ever_semaphore_; | |
| 235 // Semaphore to signal that the data has been initialized. | |
| 236 Semaphore* data_ready_semaphore_; | |
| 237 | |
| 238 // Location and size of the preallocated memory block. | |
| 239 char* data_; | |
| 240 unsigned length_; | |
| 241 | |
| 242 friend class Isolate; | |
| 243 | |
| 244 DISALLOW_COPY_AND_ASSIGN(PreallocatedMemoryThread); | |
| 245 }; | |
| 246 | |
| 247 | |
| 248 void Isolate::PreallocatedMemoryThreadStart() { | |
| 249 if (preallocated_memory_thread_ != NULL) return; | |
| 250 preallocated_memory_thread_ = new PreallocatedMemoryThread(); | |
| 251 preallocated_memory_thread_->Start(); | |
| 252 } | |
| 253 | |
| 254 | |
| 255 void Isolate::PreallocatedMemoryThreadStop() { | |
| 256 if (preallocated_memory_thread_ == NULL) return; | |
| 257 preallocated_memory_thread_->StopThread(); | |
| 258 // Done with the thread entirely. | |
| 259 delete preallocated_memory_thread_; | |
| 260 preallocated_memory_thread_ = NULL; | |
| 261 } | |
| 262 | |
| 263 | |
| 264 void Isolate::PreallocatedStorageInit(size_t size) { | |
| 265 ASSERT(free_list_.next_ == &free_list_); | |
| 266 ASSERT(free_list_.previous_ == &free_list_); | |
| 267 PreallocatedStorage* free_chunk = | |
| 268 reinterpret_cast<PreallocatedStorage*>(new char[size]); | |
| 269 free_list_.next_ = free_list_.previous_ = free_chunk; | |
| 270 free_chunk->next_ = free_chunk->previous_ = &free_list_; | |
| 271 free_chunk->size_ = size - sizeof(PreallocatedStorage); | |
| 272 preallocated_storage_preallocated_ = true; | |
| 273 } | |
| 274 | |
| 275 | |
| 276 void* Isolate::PreallocatedStorageNew(size_t size) { | |
| 277 if (!preallocated_storage_preallocated_) { | |
| 278 return FreeStoreAllocationPolicy().New(size); | |
| 279 } | |
| 280 ASSERT(free_list_.next_ != &free_list_); | |
| 281 ASSERT(free_list_.previous_ != &free_list_); | |
| 282 | |
| 283 size = (size + kPointerSize - 1) & ~(kPointerSize - 1); | |
| 284 // Search for exact fit. | |
| 285 for (PreallocatedStorage* storage = free_list_.next_; | |
| 286 storage != &free_list_; | |
| 287 storage = storage->next_) { | |
| 288 if (storage->size_ == size) { | |
| 289 storage->Unlink(); | |
| 290 storage->LinkTo(&in_use_list_); | |
| 291 return reinterpret_cast<void*>(storage + 1); | |
| 292 } | |
| 293 } | |
| 294 // Search for first fit. | |
| 295 for (PreallocatedStorage* storage = free_list_.next_; | |
| 296 storage != &free_list_; | |
| 297 storage = storage->next_) { | |
| 298 if (storage->size_ >= size + sizeof(PreallocatedStorage)) { | |
| 299 storage->Unlink(); | |
| 300 storage->LinkTo(&in_use_list_); | |
| 301 PreallocatedStorage* left_over = | |
| 302 reinterpret_cast<PreallocatedStorage*>( | |
| 303 reinterpret_cast<char*>(storage + 1) + size); | |
| 304 left_over->size_ = storage->size_ - size - sizeof(PreallocatedStorage); | |
| 305 ASSERT(size + left_over->size_ + sizeof(PreallocatedStorage) == | |
| 306 storage->size_); | |
| 307 storage->size_ = size; | |
| 308 left_over->LinkTo(&free_list_); | |
| 309 return reinterpret_cast<void*>(storage + 1); | |
| 310 } | |
| 311 } | |
| 312 // Allocation failure. | |
| 313 ASSERT(false); | |
| 314 return NULL; | |
| 315 } | |
| 316 | |
| 317 | |
| 318 // We don't attempt to coalesce. | |
| 319 void Isolate::PreallocatedStorageDelete(void* p) { | |
| 320 if (p == NULL) { | |
| 321 return; | |
| 322 } | |
| 323 if (!preallocated_storage_preallocated_) { | |
| 324 FreeStoreAllocationPolicy::Delete(p); | |
| 325 return; | |
| 326 } | |
| 327 PreallocatedStorage* storage = reinterpret_cast<PreallocatedStorage*>(p) - 1; | |
| 328 ASSERT(storage->next_->previous_ == storage); | |
| 329 ASSERT(storage->previous_->next_ == storage); | |
| 330 storage->Unlink(); | |
| 331 storage->LinkTo(&free_list_); | |
| 332 } | |
| 333 | |
| 334 Isolate* Isolate::default_isolate_ = NULL; | 134 Isolate* Isolate::default_isolate_ = NULL; |
| 335 Thread::LocalStorageKey Isolate::isolate_key_; | 135 Thread::LocalStorageKey Isolate::isolate_key_; |
| 336 Thread::LocalStorageKey Isolate::thread_id_key_; | 136 Thread::LocalStorageKey Isolate::thread_id_key_; |
| 337 Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_; | 137 Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_; |
| 338 #ifdef DEBUG | 138 #ifdef DEBUG |
| 339 Thread::LocalStorageKey PerThreadAssertScopeBase::thread_local_key; | 139 Thread::LocalStorageKey PerThreadAssertScopeBase::thread_local_key; |
| 340 #endif // DEBUG | 140 #endif // DEBUG |
| 341 Mutex Isolate::process_wide_mutex_; | 141 Mutex Isolate::process_wide_mutex_; |
| 342 // TODO(dcarney): Remove with default isolate. | 142 // TODO(dcarney): Remove with default isolate. |
| 343 enum DefaultIsolateStatus { | 143 enum DefaultIsolateStatus { |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 frames_seen++; | 647 frames_seen++; |
| 848 } | 648 } |
| 849 it.Advance(); | 649 it.Advance(); |
| 850 } | 650 } |
| 851 | 651 |
| 852 stack_trace->set_length(Smi::FromInt(frames_seen)); | 652 stack_trace->set_length(Smi::FromInt(frames_seen)); |
| 853 return stack_trace; | 653 return stack_trace; |
| 854 } | 654 } |
| 855 | 655 |
| 856 | 656 |
| 857 void Isolate::PrintStack() { | |
| 858 PrintStack(stdout); | |
| 859 } | |
| 860 | |
| 861 | |
| 862 void Isolate::PrintStack(FILE* out) { | 657 void Isolate::PrintStack(FILE* out) { |
| 863 if (stack_trace_nesting_level_ == 0) { | 658 if (stack_trace_nesting_level_ == 0) { |
| 864 stack_trace_nesting_level_++; | 659 stack_trace_nesting_level_++; |
| 865 | |
| 866 StringAllocator* allocator; | |
| 867 if (preallocated_message_space_ == NULL) { | |
| 868 allocator = new HeapStringAllocator(); | |
| 869 } else { | |
| 870 allocator = preallocated_message_space_; | |
| 871 } | |
| 872 | |
| 873 StringStream::ClearMentionedObjectCache(this); | 660 StringStream::ClearMentionedObjectCache(this); |
| 874 StringStream accumulator(allocator); | 661 HeapStringAllocator allocator; |
| 662 StringStream accumulator(&allocator); |
| 875 incomplete_message_ = &accumulator; | 663 incomplete_message_ = &accumulator; |
| 876 PrintStack(&accumulator); | 664 PrintStack(&accumulator); |
| 877 accumulator.OutputToFile(out); | 665 accumulator.OutputToFile(out); |
| 878 InitializeLoggingAndCounters(); | 666 InitializeLoggingAndCounters(); |
| 879 accumulator.Log(this); | 667 accumulator.Log(this); |
| 880 incomplete_message_ = NULL; | 668 incomplete_message_ = NULL; |
| 881 stack_trace_nesting_level_ = 0; | 669 stack_trace_nesting_level_ = 0; |
| 882 if (preallocated_message_space_ == NULL) { | |
| 883 // Remove the HeapStringAllocator created above. | |
| 884 delete allocator; | |
| 885 } | |
| 886 } else if (stack_trace_nesting_level_ == 1) { | 670 } else if (stack_trace_nesting_level_ == 1) { |
| 887 stack_trace_nesting_level_++; | 671 stack_trace_nesting_level_++; |
| 888 OS::PrintError( | 672 OS::PrintError( |
| 889 "\n\nAttempt to print stack while printing stack (double fault)\n"); | 673 "\n\nAttempt to print stack while printing stack (double fault)\n"); |
| 890 OS::PrintError( | 674 OS::PrintError( |
| 891 "If you are lucky you may find a partial stack dump on stdout.\n\n"); | 675 "If you are lucky you may find a partial stack dump on stdout.\n\n"); |
| 892 incomplete_message_->OutputToFile(out); | 676 incomplete_message_->OutputToFile(out); |
| 893 } | 677 } |
| 894 } | 678 } |
| 895 | 679 |
| (...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1745 PrintF("Isolate %p (id %d)" #tag "\n", \ | 1529 PrintF("Isolate %p (id %d)" #tag "\n", \ |
| 1746 reinterpret_cast<void*>(this), id()); \ | 1530 reinterpret_cast<void*>(this), id()); \ |
| 1747 } \ | 1531 } \ |
| 1748 } while (false) | 1532 } while (false) |
| 1749 #else | 1533 #else |
| 1750 #define TRACE_ISOLATE(tag) | 1534 #define TRACE_ISOLATE(tag) |
| 1751 #endif | 1535 #endif |
| 1752 | 1536 |
| 1753 | 1537 |
| 1754 Isolate::Isolate() | 1538 Isolate::Isolate() |
| 1755 : state_(UNINITIALIZED), | 1539 : embedder_data_(), |
| 1756 embedder_data_(NULL), | 1540 state_(UNINITIALIZED), |
| 1757 entry_stack_(NULL), | 1541 entry_stack_(NULL), |
| 1758 stack_trace_nesting_level_(0), | 1542 stack_trace_nesting_level_(0), |
| 1759 incomplete_message_(NULL), | 1543 incomplete_message_(NULL), |
| 1760 preallocated_memory_thread_(NULL), | |
| 1761 preallocated_message_space_(NULL), | |
| 1762 bootstrapper_(NULL), | 1544 bootstrapper_(NULL), |
| 1763 runtime_profiler_(NULL), | 1545 runtime_profiler_(NULL), |
| 1764 compilation_cache_(NULL), | 1546 compilation_cache_(NULL), |
| 1765 counters_(NULL), | 1547 counters_(NULL), |
| 1766 code_range_(NULL), | 1548 code_range_(NULL), |
| 1767 debugger_initialized_(false), | 1549 debugger_initialized_(false), |
| 1768 logger_(NULL), | 1550 logger_(NULL), |
| 1769 stats_table_(NULL), | 1551 stats_table_(NULL), |
| 1770 stub_cache_(NULL), | 1552 stub_cache_(NULL), |
| 1771 deoptimizer_data_(NULL), | 1553 deoptimizer_data_(NULL), |
| 1772 capture_stack_trace_for_uncaught_exceptions_(false), | 1554 capture_stack_trace_for_uncaught_exceptions_(false), |
| 1773 stack_trace_for_uncaught_exceptions_frame_limit_(0), | 1555 stack_trace_for_uncaught_exceptions_frame_limit_(0), |
| 1774 stack_trace_for_uncaught_exceptions_options_(StackTrace::kOverview), | 1556 stack_trace_for_uncaught_exceptions_options_(StackTrace::kOverview), |
| 1775 transcendental_cache_(NULL), | 1557 transcendental_cache_(NULL), |
| 1776 memory_allocator_(NULL), | 1558 memory_allocator_(NULL), |
| 1777 keyed_lookup_cache_(NULL), | 1559 keyed_lookup_cache_(NULL), |
| 1778 context_slot_cache_(NULL), | 1560 context_slot_cache_(NULL), |
| 1779 descriptor_lookup_cache_(NULL), | 1561 descriptor_lookup_cache_(NULL), |
| 1780 handle_scope_implementer_(NULL), | 1562 handle_scope_implementer_(NULL), |
| 1781 unicode_cache_(NULL), | 1563 unicode_cache_(NULL), |
| 1782 runtime_zone_(this), | 1564 runtime_zone_(this), |
| 1783 in_use_list_(0), | |
| 1784 free_list_(0), | |
| 1785 preallocated_storage_preallocated_(false), | |
| 1786 inner_pointer_to_code_cache_(NULL), | 1565 inner_pointer_to_code_cache_(NULL), |
| 1787 write_iterator_(NULL), | 1566 write_iterator_(NULL), |
| 1788 global_handles_(NULL), | 1567 global_handles_(NULL), |
| 1789 eternal_handles_(NULL), | 1568 eternal_handles_(NULL), |
| 1790 context_switcher_(NULL), | |
| 1791 thread_manager_(NULL), | 1569 thread_manager_(NULL), |
| 1792 fp_stubs_generated_(false), | 1570 fp_stubs_generated_(false), |
| 1793 has_installed_extensions_(false), | 1571 has_installed_extensions_(false), |
| 1794 string_tracker_(NULL), | 1572 string_tracker_(NULL), |
| 1795 regexp_stack_(NULL), | 1573 regexp_stack_(NULL), |
| 1796 date_cache_(NULL), | 1574 date_cache_(NULL), |
| 1797 code_stub_interface_descriptors_(NULL), | 1575 code_stub_interface_descriptors_(NULL), |
| 1798 // TODO(bmeurer) Initialized lazily because it depends on flags; can | 1576 // TODO(bmeurer) Initialized lazily because it depends on flags; can |
| 1799 // be fixed once the default isolate cleanup is done. | 1577 // be fixed once the default isolate cleanup is done. |
| 1800 random_number_generator_(NULL), | 1578 random_number_generator_(NULL), |
| 1801 has_fatal_error_(false), | 1579 has_fatal_error_(false), |
| 1802 use_crankshaft_(true), | 1580 use_crankshaft_(true), |
| 1803 initialized_from_snapshot_(false), | 1581 initialized_from_snapshot_(false), |
| 1804 cpu_profiler_(NULL), | 1582 cpu_profiler_(NULL), |
| 1805 heap_profiler_(NULL), | 1583 heap_profiler_(NULL), |
| 1806 function_entry_hook_(NULL), | 1584 function_entry_hook_(NULL), |
| 1807 deferred_handles_head_(NULL), | 1585 deferred_handles_head_(NULL), |
| 1808 optimizing_compiler_thread_(NULL), | 1586 optimizing_compiler_thread_(NULL), |
| 1809 sweeper_thread_(NULL), | 1587 sweeper_thread_(NULL), |
| 1588 num_sweeper_threads_(0), |
| 1589 max_available_threads_(0), |
| 1810 stress_deopt_count_(0) { | 1590 stress_deopt_count_(0) { |
| 1811 id_ = NoBarrier_AtomicIncrement(&isolate_counter_, 1); | 1591 id_ = NoBarrier_AtomicIncrement(&isolate_counter_, 1); |
| 1812 TRACE_ISOLATE(constructor); | 1592 TRACE_ISOLATE(constructor); |
| 1813 | 1593 |
| 1814 memset(isolate_addresses_, 0, | 1594 memset(isolate_addresses_, 0, |
| 1815 sizeof(isolate_addresses_[0]) * (kIsolateAddressCount + 1)); | 1595 sizeof(isolate_addresses_[0]) * (kIsolateAddressCount + 1)); |
| 1816 | 1596 |
| 1817 heap_.isolate_ = this; | 1597 heap_.isolate_ = this; |
| 1818 stack_guard_.isolate_ = this; | 1598 stack_guard_.isolate_ = this; |
| 1819 | 1599 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1892 | 1672 |
| 1893 | 1673 |
| 1894 void Isolate::Deinit() { | 1674 void Isolate::Deinit() { |
| 1895 if (state_ == INITIALIZED) { | 1675 if (state_ == INITIALIZED) { |
| 1896 TRACE_ISOLATE(deinit); | 1676 TRACE_ISOLATE(deinit); |
| 1897 | 1677 |
| 1898 #ifdef ENABLE_DEBUGGER_SUPPORT | 1678 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 1899 debugger()->UnloadDebugger(); | 1679 debugger()->UnloadDebugger(); |
| 1900 #endif | 1680 #endif |
| 1901 | 1681 |
| 1902 if (FLAG_concurrent_recompilation) { | 1682 if (concurrent_recompilation_enabled()) { |
| 1903 optimizing_compiler_thread_->Stop(); | 1683 optimizing_compiler_thread_->Stop(); |
| 1904 delete optimizing_compiler_thread_; | 1684 delete optimizing_compiler_thread_; |
| 1685 optimizing_compiler_thread_ = NULL; |
| 1905 } | 1686 } |
| 1906 | 1687 |
| 1907 if (FLAG_sweeper_threads > 0) { | 1688 for (int i = 0; i < num_sweeper_threads_; i++) { |
| 1908 for (int i = 0; i < FLAG_sweeper_threads; i++) { | 1689 sweeper_thread_[i]->Stop(); |
| 1909 sweeper_thread_[i]->Stop(); | 1690 delete sweeper_thread_[i]; |
| 1910 delete sweeper_thread_[i]; | 1691 sweeper_thread_[i] = NULL; |
| 1911 } | |
| 1912 delete[] sweeper_thread_; | |
| 1913 } | 1692 } |
| 1693 delete[] sweeper_thread_; |
| 1694 sweeper_thread_ = NULL; |
| 1695 |
| 1914 | 1696 |
| 1915 if (FLAG_hydrogen_stats) GetHStatistics()->Print(); | 1697 if (FLAG_hydrogen_stats) GetHStatistics()->Print(); |
| 1916 | 1698 |
| 1917 if (FLAG_print_deopt_stress) { | 1699 if (FLAG_print_deopt_stress) { |
| 1918 PrintF(stdout, "=== Stress deopt counter: %u\n", stress_deopt_count_); | 1700 PrintF(stdout, "=== Stress deopt counter: %u\n", stress_deopt_count_); |
| 1919 } | 1701 } |
| 1920 | 1702 |
| 1921 // We must stop the logger before we tear down other components. | 1703 // We must stop the logger before we tear down other components. |
| 1922 Sampler* sampler = logger_->sampler(); | 1704 Sampler* sampler = logger_->sampler(); |
| 1923 if (sampler && sampler->IsActive()) sampler->Stop(); | 1705 if (sampler && sampler->IsActive()) sampler->Stop(); |
| 1924 | 1706 |
| 1925 delete deoptimizer_data_; | 1707 delete deoptimizer_data_; |
| 1926 deoptimizer_data_ = NULL; | 1708 deoptimizer_data_ = NULL; |
| 1927 if (FLAG_preemption) { | |
| 1928 v8::Locker locker(reinterpret_cast<v8::Isolate*>(this)); | |
| 1929 v8::Locker::StopPreemption(reinterpret_cast<v8::Isolate*>(this)); | |
| 1930 } | |
| 1931 builtins_.TearDown(); | 1709 builtins_.TearDown(); |
| 1932 bootstrapper_->TearDown(); | 1710 bootstrapper_->TearDown(); |
| 1933 | 1711 |
| 1934 // Remove the external reference to the preallocated stack memory. | |
| 1935 delete preallocated_message_space_; | |
| 1936 preallocated_message_space_ = NULL; | |
| 1937 PreallocatedMemoryThreadStop(); | |
| 1938 | |
| 1939 if (runtime_profiler_ != NULL) { | 1712 if (runtime_profiler_ != NULL) { |
| 1940 runtime_profiler_->TearDown(); | 1713 runtime_profiler_->TearDown(); |
| 1941 delete runtime_profiler_; | 1714 delete runtime_profiler_; |
| 1942 runtime_profiler_ = NULL; | 1715 runtime_profiler_ = NULL; |
| 1943 } | 1716 } |
| 1944 heap_.TearDown(); | 1717 heap_.TearDown(); |
| 1945 logger_->TearDown(); | 1718 logger_->TearDown(); |
| 1946 | 1719 |
| 1947 delete heap_profiler_; | 1720 delete heap_profiler_; |
| 1948 heap_profiler_ = NULL; | 1721 heap_profiler_ = NULL; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2037 | 1810 |
| 2038 delete compilation_cache_; | 1811 delete compilation_cache_; |
| 2039 compilation_cache_ = NULL; | 1812 compilation_cache_ = NULL; |
| 2040 delete bootstrapper_; | 1813 delete bootstrapper_; |
| 2041 bootstrapper_ = NULL; | 1814 bootstrapper_ = NULL; |
| 2042 delete inner_pointer_to_code_cache_; | 1815 delete inner_pointer_to_code_cache_; |
| 2043 inner_pointer_to_code_cache_ = NULL; | 1816 inner_pointer_to_code_cache_ = NULL; |
| 2044 delete write_iterator_; | 1817 delete write_iterator_; |
| 2045 write_iterator_ = NULL; | 1818 write_iterator_ = NULL; |
| 2046 | 1819 |
| 2047 delete context_switcher_; | |
| 2048 context_switcher_ = NULL; | |
| 2049 delete thread_manager_; | 1820 delete thread_manager_; |
| 2050 thread_manager_ = NULL; | 1821 thread_manager_ = NULL; |
| 2051 | 1822 |
| 2052 delete string_tracker_; | 1823 delete string_tracker_; |
| 2053 string_tracker_ = NULL; | 1824 string_tracker_ = NULL; |
| 2054 | 1825 |
| 2055 delete memory_allocator_; | 1826 delete memory_allocator_; |
| 2056 memory_allocator_ = NULL; | 1827 memory_allocator_ = NULL; |
| 2057 delete code_range_; | 1828 delete code_range_; |
| 2058 code_range_ = NULL; | 1829 code_range_ = NULL; |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2227 | 1998 |
| 2228 // SetUp the object heap. | 1999 // SetUp the object heap. |
| 2229 ASSERT(!heap_.HasBeenSetUp()); | 2000 ASSERT(!heap_.HasBeenSetUp()); |
| 2230 if (!heap_.SetUp()) { | 2001 if (!heap_.SetUp()) { |
| 2231 V8::FatalProcessOutOfMemory("heap setup"); | 2002 V8::FatalProcessOutOfMemory("heap setup"); |
| 2232 return false; | 2003 return false; |
| 2233 } | 2004 } |
| 2234 | 2005 |
| 2235 deoptimizer_data_ = new DeoptimizerData(memory_allocator_); | 2006 deoptimizer_data_ = new DeoptimizerData(memory_allocator_); |
| 2236 | 2007 |
| 2237 if (FLAG_concurrent_recompilation) { | |
| 2238 optimizing_compiler_thread_ = new OptimizingCompilerThread(this); | |
| 2239 optimizing_compiler_thread_->Start(); | |
| 2240 } | |
| 2241 | |
| 2242 const bool create_heap_objects = (des == NULL); | 2008 const bool create_heap_objects = (des == NULL); |
| 2243 if (create_heap_objects && !heap_.CreateHeapObjects()) { | 2009 if (create_heap_objects && !heap_.CreateHeapObjects()) { |
| 2244 V8::FatalProcessOutOfMemory("heap object creation"); | 2010 V8::FatalProcessOutOfMemory("heap object creation"); |
| 2245 return false; | 2011 return false; |
| 2246 } | 2012 } |
| 2247 | 2013 |
| 2248 if (create_heap_objects) { | 2014 if (create_heap_objects) { |
| 2249 // Terminate the cache array with the sentinel so we can iterate. | 2015 // Terminate the cache array with the sentinel so we can iterate. |
| 2250 PushToPartialSnapshotCache(heap_.undefined_value()); | 2016 PushToPartialSnapshotCache(heap_.undefined_value()); |
| 2251 } | 2017 } |
| 2252 | 2018 |
| 2253 InitializeThreadLocal(); | 2019 InitializeThreadLocal(); |
| 2254 | 2020 |
| 2255 bootstrapper_->Initialize(create_heap_objects); | 2021 bootstrapper_->Initialize(create_heap_objects); |
| 2256 builtins_.SetUp(this, create_heap_objects); | 2022 builtins_.SetUp(this, create_heap_objects); |
| 2257 | 2023 |
| 2258 // Only preallocate on the first initialization. | 2024 if (create_heap_objects) heap_.CreateStubsRequiringBuiltins(); |
| 2259 if (FLAG_preallocate_message_memory && preallocated_message_space_ == NULL) { | 2025 |
| 2260 // Start the thread which will set aside some memory. | 2026 // Set default value if not yet set. |
| 2261 PreallocatedMemoryThreadStart(); | 2027 // TODO(yangguo): move this to ResourceConstraints::ConfigureDefaults |
| 2262 preallocated_message_space_ = | 2028 // once ResourceConstraints becomes an argument to the Isolate constructor. |
| 2263 new NoAllocationStringAllocator( | 2029 if (max_available_threads_ < 1) { |
| 2264 preallocated_memory_thread_->data(), | 2030 // Choose the default between 1 and 4. |
| 2265 preallocated_memory_thread_->length()); | 2031 max_available_threads_ = Max(Min(CPU::NumberOfProcessorsOnline(), 4), 1); |
| 2266 PreallocatedStorageInit(preallocated_memory_thread_->length() / 4); | |
| 2267 } | 2032 } |
| 2268 | 2033 |
| 2269 if (FLAG_preemption) { | 2034 num_sweeper_threads_ = SweeperThread::NumberOfThreads(max_available_threads_); |
| 2270 v8::Locker locker(reinterpret_cast<v8::Isolate*>(this)); | 2035 |
| 2271 v8::Locker::StartPreemption(reinterpret_cast<v8::Isolate*>(this), 100); | 2036 if (FLAG_trace_hydrogen || FLAG_trace_hydrogen_stubs) { |
| 2037 PrintF("Concurrent recompilation has been disabled for tracing.\n"); |
| 2038 } else if (OptimizingCompilerThread::Enabled(max_available_threads_)) { |
| 2039 optimizing_compiler_thread_ = new OptimizingCompilerThread(this); |
| 2040 optimizing_compiler_thread_->Start(); |
| 2041 } |
| 2042 |
| 2043 if (num_sweeper_threads_ > 0) { |
| 2044 sweeper_thread_ = new SweeperThread*[num_sweeper_threads_]; |
| 2045 for (int i = 0; i < num_sweeper_threads_; i++) { |
| 2046 sweeper_thread_[i] = new SweeperThread(this); |
| 2047 sweeper_thread_[i]->Start(); |
| 2048 } |
| 2272 } | 2049 } |
| 2273 | 2050 |
| 2274 #ifdef ENABLE_DEBUGGER_SUPPORT | 2051 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 2275 debug_->SetUp(create_heap_objects); | 2052 debug_->SetUp(create_heap_objects); |
| 2276 #endif | 2053 #endif |
| 2277 | 2054 |
| 2278 // If we are deserializing, read the state into the now-empty heap. | 2055 // If we are deserializing, read the state into the now-empty heap. |
| 2279 if (!create_heap_objects) { | 2056 if (!create_heap_objects) { |
| 2280 des->Deserialize(this); | 2057 des->Deserialize(this); |
| 2281 } | 2058 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2324 kDeoptTableSerializeEntryCount - 1); | 2101 kDeoptTableSerializeEntryCount - 1); |
| 2325 } | 2102 } |
| 2326 | 2103 |
| 2327 if (!Serializer::enabled()) { | 2104 if (!Serializer::enabled()) { |
| 2328 // Ensure that all stubs which need to be generated ahead of time, but | 2105 // Ensure that all stubs which need to be generated ahead of time, but |
| 2329 // cannot be serialized into the snapshot have been generated. | 2106 // cannot be serialized into the snapshot have been generated. |
| 2330 HandleScope scope(this); | 2107 HandleScope scope(this); |
| 2331 CodeStub::GenerateFPStubs(this); | 2108 CodeStub::GenerateFPStubs(this); |
| 2332 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(this); | 2109 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(this); |
| 2333 StubFailureTrampolineStub::GenerateAheadOfTime(this); | 2110 StubFailureTrampolineStub::GenerateAheadOfTime(this); |
| 2111 StubFailureTailCallTrampolineStub::GenerateAheadOfTime(this); |
| 2334 // TODO(mstarzinger): The following is an ugly hack to make sure the | 2112 // TODO(mstarzinger): The following is an ugly hack to make sure the |
| 2335 // interface descriptor is initialized even when stubs have been | 2113 // interface descriptor is initialized even when stubs have been |
| 2336 // deserialized out of the snapshot without the graph builder. | 2114 // deserialized out of the snapshot without the graph builder. |
| 2337 FastCloneShallowArrayStub stub(FastCloneShallowArrayStub::CLONE_ELEMENTS, | 2115 FastCloneShallowArrayStub stub(FastCloneShallowArrayStub::CLONE_ELEMENTS, |
| 2338 DONT_TRACK_ALLOCATION_SITE, 0); | 2116 DONT_TRACK_ALLOCATION_SITE, 0); |
| 2339 stub.InitializeInterfaceDescriptor( | 2117 stub.InitializeInterfaceDescriptor( |
| 2340 this, code_stub_interface_descriptor(CodeStub::FastCloneShallowArray)); | 2118 this, code_stub_interface_descriptor(CodeStub::FastCloneShallowArray)); |
| 2341 BinaryOpStub::InitializeForIsolate(this); | 2119 BinaryOpStub::InitializeForIsolate(this); |
| 2342 CompareNilICStub::InitializeForIsolate(this); | 2120 CompareNilICStub::InitializeForIsolate(this); |
| 2343 ToBooleanStub::InitializeForIsolate(this); | 2121 ToBooleanStub::InitializeForIsolate(this); |
| 2344 ArrayConstructorStubBase::InstallDescriptors(this); | 2122 ArrayConstructorStubBase::InstallDescriptors(this); |
| 2345 InternalArrayConstructorStubBase::InstallDescriptors(this); | 2123 InternalArrayConstructorStubBase::InstallDescriptors(this); |
| 2346 FastNewClosureStub::InstallDescriptors(this); | 2124 FastNewClosureStub::InstallDescriptors(this); |
| 2347 NumberToStringStub::InstallDescriptors(this); | 2125 NumberToStringStub::InstallDescriptors(this); |
| 2348 NewStringAddStub::InstallDescriptors(this); | 2126 NewStringAddStub::InstallDescriptors(this); |
| 2349 } | 2127 } |
| 2350 | 2128 |
| 2351 if (FLAG_sweeper_threads > 0) { | |
| 2352 sweeper_thread_ = new SweeperThread*[FLAG_sweeper_threads]; | |
| 2353 for (int i = 0; i < FLAG_sweeper_threads; i++) { | |
| 2354 sweeper_thread_[i] = new SweeperThread(this); | |
| 2355 sweeper_thread_[i]->Start(); | |
| 2356 } | |
| 2357 } | |
| 2358 | |
| 2359 initialized_from_snapshot_ = (des != NULL); | 2129 initialized_from_snapshot_ = (des != NULL); |
| 2360 | 2130 |
| 2361 return true; | 2131 return true; |
| 2362 } | 2132 } |
| 2363 | 2133 |
| 2364 | 2134 |
| 2365 // Initialized lazily to allow early | 2135 // Initialized lazily to allow early |
| 2366 // v8::V8::SetAddHistogramSampleFunction calls. | 2136 // v8::V8::SetAddHistogramSampleFunction calls. |
| 2367 StatsTable* Isolate::stats_table() { | 2137 StatsTable* Isolate::stats_table() { |
| 2368 if (stats_table_ == NULL) { | 2138 if (stats_table_ == NULL) { |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2557 | 2327 |
| 2558 #ifdef DEBUG | 2328 #ifdef DEBUG |
| 2559 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \ | 2329 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \ |
| 2560 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_); | 2330 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_); |
| 2561 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET) | 2331 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET) |
| 2562 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET) | 2332 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET) |
| 2563 #undef ISOLATE_FIELD_OFFSET | 2333 #undef ISOLATE_FIELD_OFFSET |
| 2564 #endif | 2334 #endif |
| 2565 | 2335 |
| 2566 } } // namespace v8::internal | 2336 } } // namespace v8::internal |
| OLD | NEW |