OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 // Set or clear multiple flags at a time. The flags in the mask | 447 // Set or clear multiple flags at a time. The flags in the mask |
448 // are set to the value in "flags", the rest retain the current value | 448 // are set to the value in "flags", the rest retain the current value |
449 // in flags_. | 449 // in flags_. |
450 void SetFlags(intptr_t flags, intptr_t mask) { | 450 void SetFlags(intptr_t flags, intptr_t mask) { |
451 flags_ = (flags_ & ~mask) | (flags & mask); | 451 flags_ = (flags_ & ~mask) | (flags & mask); |
452 } | 452 } |
453 | 453 |
454 // Return all current flags. | 454 // Return all current flags. |
455 intptr_t GetFlags() { return flags_; } | 455 intptr_t GetFlags() { return flags_; } |
456 | 456 |
| 457 intptr_t parallel_sweeping() const { |
| 458 return parallel_sweeping_; |
| 459 } |
| 460 |
| 461 void set_parallel_sweeping(intptr_t state) { |
| 462 parallel_sweeping_ = state; |
| 463 } |
| 464 |
| 465 bool TryParallelSweeping() { |
| 466 return NoBarrier_CompareAndSwap(¶llel_sweeping_, 1, 0) == 1; |
| 467 } |
| 468 |
457 // Manage live byte count (count of bytes known to be live, | 469 // Manage live byte count (count of bytes known to be live, |
458 // because they are marked black). | 470 // because they are marked black). |
459 void ResetLiveBytes() { | 471 void ResetLiveBytes() { |
460 if (FLAG_gc_verbose) { | 472 if (FLAG_gc_verbose) { |
461 PrintF("ResetLiveBytes:%p:%x->0\n", | 473 PrintF("ResetLiveBytes:%p:%x->0\n", |
462 static_cast<void*>(this), live_byte_count_); | 474 static_cast<void*>(this), live_byte_count_); |
463 } | 475 } |
464 live_byte_count_ = 0; | 476 live_byte_count_ = 0; |
465 } | 477 } |
466 void IncrementLiveBytes(int by) { | 478 void IncrementLiveBytes(int by) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 static const intptr_t kLiveBytesOffset = | 538 static const intptr_t kLiveBytesOffset = |
527 kSizeOffset + kPointerSize + kPointerSize + kPointerSize + | 539 kSizeOffset + kPointerSize + kPointerSize + kPointerSize + |
528 kPointerSize + kPointerSize + | 540 kPointerSize + kPointerSize + |
529 kPointerSize + kPointerSize + kPointerSize + kIntSize; | 541 kPointerSize + kPointerSize + kPointerSize + kIntSize; |
530 | 542 |
531 static const size_t kSlotsBufferOffset = kLiveBytesOffset + kIntSize; | 543 static const size_t kSlotsBufferOffset = kLiveBytesOffset + kIntSize; |
532 | 544 |
533 static const size_t kWriteBarrierCounterOffset = | 545 static const size_t kWriteBarrierCounterOffset = |
534 kSlotsBufferOffset + kPointerSize + kPointerSize; | 546 kSlotsBufferOffset + kPointerSize + kPointerSize; |
535 | 547 |
536 static const size_t kHeaderSize = | 548 static const size_t kHeaderSize = kWriteBarrierCounterOffset + kPointerSize + |
537 kWriteBarrierCounterOffset + kPointerSize + kIntSize + kIntSize; | 549 kIntSize + kIntSize + kPointerSize; |
538 | 550 |
539 static const int kBodyOffset = | 551 static const int kBodyOffset = |
540 CODE_POINTER_ALIGN(kHeaderSize + Bitmap::kSize); | 552 CODE_POINTER_ALIGN(kHeaderSize + Bitmap::kSize); |
541 | 553 |
542 // The start offset of the object area in a page. Aligned to both maps and | 554 // The start offset of the object area in a page. Aligned to both maps and |
543 // code alignment to be suitable for both. Also aligned to 32 words because | 555 // code alignment to be suitable for both. Also aligned to 32 words because |
544 // the marking bitmap is arranged in 32 bit chunks. | 556 // the marking bitmap is arranged in 32 bit chunks. |
545 static const int kObjectStartAlignment = 32 * kPointerSize; | 557 static const int kObjectStartAlignment = 32 * kPointerSize; |
546 static const int kObjectStartOffset = kBodyOffset - 1 + | 558 static const int kObjectStartOffset = kBodyOffset - 1 + |
547 (kObjectStartAlignment - (kBodyOffset - 1) % kObjectStartAlignment); | 559 (kObjectStartAlignment - (kBodyOffset - 1) % kObjectStartAlignment); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 SlotsBuffer* slots_buffer_; | 691 SlotsBuffer* slots_buffer_; |
680 SkipList* skip_list_; | 692 SkipList* skip_list_; |
681 intptr_t write_barrier_counter_; | 693 intptr_t write_barrier_counter_; |
682 // Used by the incremental marker to keep track of the scanning progress in | 694 // Used by the incremental marker to keep track of the scanning progress in |
683 // large objects that have a progress bar and are scanned in increments. | 695 // large objects that have a progress bar and are scanned in increments. |
684 int progress_bar_; | 696 int progress_bar_; |
685 // Assuming the initial allocation on a page is sequential, | 697 // Assuming the initial allocation on a page is sequential, |
686 // count highest number of bytes ever allocated on the page. | 698 // count highest number of bytes ever allocated on the page. |
687 int high_water_mark_; | 699 int high_water_mark_; |
688 | 700 |
| 701 intptr_t parallel_sweeping_; |
| 702 |
689 static MemoryChunk* Initialize(Heap* heap, | 703 static MemoryChunk* Initialize(Heap* heap, |
690 Address base, | 704 Address base, |
691 size_t size, | 705 size_t size, |
692 Address area_start, | 706 Address area_start, |
693 Address area_end, | 707 Address area_end, |
694 Executability executable, | 708 Executability executable, |
695 Space* owner); | 709 Space* owner); |
696 | 710 |
697 friend class MemoryAllocator; | 711 friend class MemoryAllocator; |
698 }; | 712 }; |
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1388 static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize); | 1402 static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize); |
1389 | 1403 |
1390 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListNode); | 1404 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListNode); |
1391 }; | 1405 }; |
1392 | 1406 |
1393 | 1407 |
1394 // The free list category holds a pointer to the top element and a pointer to | 1408 // The free list category holds a pointer to the top element and a pointer to |
1395 // the end element of the linked list of free memory blocks. | 1409 // the end element of the linked list of free memory blocks. |
1396 class FreeListCategory { | 1410 class FreeListCategory { |
1397 public: | 1411 public: |
1398 FreeListCategory() : top_(NULL), end_(NULL), available_(0) {} | 1412 FreeListCategory() : |
| 1413 top_(NULL), |
| 1414 end_(NULL), |
| 1415 mutex_(OS::CreateMutex()), |
| 1416 available_(0) {} |
| 1417 |
| 1418 ~FreeListCategory() { |
| 1419 delete mutex_; |
| 1420 } |
| 1421 |
| 1422 intptr_t Concatenate(FreeListCategory* category); |
1399 | 1423 |
1400 void Reset(); | 1424 void Reset(); |
1401 | 1425 |
1402 void Free(FreeListNode* node, int size_in_bytes); | 1426 void Free(FreeListNode* node, int size_in_bytes); |
1403 | 1427 |
1404 FreeListNode* PickNodeFromList(int *node_size); | 1428 FreeListNode* PickNodeFromList(int *node_size); |
1405 | 1429 |
1406 intptr_t CountFreeListItemsInList(Page* p); | 1430 intptr_t CountFreeListItemsInList(Page* p); |
1407 | 1431 |
1408 intptr_t EvictFreeListItemsInList(Page* p); | 1432 intptr_t EvictFreeListItemsInList(Page* p); |
1409 | 1433 |
1410 void RepairFreeList(Heap* heap); | 1434 void RepairFreeList(Heap* heap); |
1411 | 1435 |
1412 FreeListNode** GetTopAddress() { return &top_; } | 1436 FreeListNode** GetTopAddress() { return &top_; } |
1413 FreeListNode* top() const { return top_; } | 1437 FreeListNode* top() const { return top_; } |
1414 void set_top(FreeListNode* top) { top_ = top; } | 1438 void set_top(FreeListNode* top) { top_ = top; } |
1415 | 1439 |
1416 FreeListNode** GetEndAddress() { return &end_; } | 1440 FreeListNode** GetEndAddress() { return &end_; } |
1417 FreeListNode* end() const { return end_; } | 1441 FreeListNode* end() const { return end_; } |
1418 void set_end(FreeListNode* end) { end_ = end; } | 1442 void set_end(FreeListNode* end) { end_ = end; } |
1419 | 1443 |
1420 int* GetAvailableAddress() { return &available_; } | 1444 int* GetAvailableAddress() { return &available_; } |
1421 int available() const { return available_; } | 1445 int available() const { return available_; } |
1422 void set_available(int available) { available_ = available; } | 1446 void set_available(int available) { available_ = available; } |
1423 | 1447 |
| 1448 Mutex* mutex() { return mutex_; } |
| 1449 |
1424 #ifdef DEBUG | 1450 #ifdef DEBUG |
1425 intptr_t SumFreeList(); | 1451 intptr_t SumFreeList(); |
1426 int FreeListLength(); | 1452 int FreeListLength(); |
1427 #endif | 1453 #endif |
1428 | 1454 |
1429 private: | 1455 private: |
1430 FreeListNode* top_; | 1456 FreeListNode* top_; |
1431 FreeListNode* end_; | 1457 FreeListNode* end_; |
| 1458 Mutex* mutex_; |
1432 | 1459 |
1433 // Total available bytes in all blocks of this free list category. | 1460 // Total available bytes in all blocks of this free list category. |
1434 int available_; | 1461 int available_; |
1435 }; | 1462 }; |
1436 | 1463 |
1437 | 1464 |
1438 // The free list for the old space. The free list is organized in such a way | 1465 // The free list for the old space. The free list is organized in such a way |
1439 // as to encourage objects allocated around the same time to be near each | 1466 // as to encourage objects allocated around the same time to be near each |
1440 // other. The normal way to allocate is intended to be by bumping a 'top' | 1467 // other. The normal way to allocate is intended to be by bumping a 'top' |
1441 // pointer until it hits a 'limit' pointer. When the limit is hit we need to | 1468 // pointer until it hits a 'limit' pointer. When the limit is hit we need to |
(...skipping 13 matching lines...) Expand all Loading... |
1455 // spaces are called medium. | 1482 // spaces are called medium. |
1456 // 1048-16383 words: There is a list of spaces this large. It is used for top | 1483 // 1048-16383 words: There is a list of spaces this large. It is used for top |
1457 // and limit when the object we need to allocate is 256-2047 words in size. | 1484 // and limit when the object we need to allocate is 256-2047 words in size. |
1458 // These spaces are call large. | 1485 // These spaces are call large. |
1459 // At least 16384 words. This list is for objects of 2048 words or larger. | 1486 // At least 16384 words. This list is for objects of 2048 words or larger. |
1460 // Empty pages are added to this list. These spaces are called huge. | 1487 // Empty pages are added to this list. These spaces are called huge. |
1461 class FreeList BASE_EMBEDDED { | 1488 class FreeList BASE_EMBEDDED { |
1462 public: | 1489 public: |
1463 explicit FreeList(PagedSpace* owner); | 1490 explicit FreeList(PagedSpace* owner); |
1464 | 1491 |
| 1492 intptr_t Concatenate(FreeList* free_list); |
| 1493 |
1465 // Clear the free list. | 1494 // Clear the free list. |
1466 void Reset(); | 1495 void Reset(); |
1467 | 1496 |
1468 // Return the number of bytes available on the free list. | 1497 // Return the number of bytes available on the free list. |
1469 intptr_t available() { | 1498 intptr_t available() { |
1470 return small_list_.available() + medium_list_.available() + | 1499 return small_list_.available() + medium_list_.available() + |
1471 large_list_.available() + huge_list_.available(); | 1500 large_list_.available() + huge_list_.available(); |
1472 } | 1501 } |
1473 | 1502 |
1474 // Place a node on the free list. The block of size 'size_in_bytes' | 1503 // Place a node on the free list. The block of size 'size_in_bytes' |
(...skipping 27 matching lines...) Expand all Loading... |
1502 intptr_t small_size_; | 1531 intptr_t small_size_; |
1503 intptr_t medium_size_; | 1532 intptr_t medium_size_; |
1504 intptr_t large_size_; | 1533 intptr_t large_size_; |
1505 intptr_t huge_size_; | 1534 intptr_t huge_size_; |
1506 }; | 1535 }; |
1507 | 1536 |
1508 void CountFreeListItems(Page* p, SizeStats* sizes); | 1537 void CountFreeListItems(Page* p, SizeStats* sizes); |
1509 | 1538 |
1510 intptr_t EvictFreeListItems(Page* p); | 1539 intptr_t EvictFreeListItems(Page* p); |
1511 | 1540 |
| 1541 FreeListCategory* small_list() { return &small_list_; } |
| 1542 FreeListCategory* medium_list() { return &medium_list_; } |
| 1543 FreeListCategory* large_list() { return &large_list_; } |
| 1544 FreeListCategory* huge_list() { return &huge_list_; } |
| 1545 |
1512 private: | 1546 private: |
1513 // The size range of blocks, in bytes. | 1547 // The size range of blocks, in bytes. |
1514 static const int kMinBlockSize = 3 * kPointerSize; | 1548 static const int kMinBlockSize = 3 * kPointerSize; |
1515 static const int kMaxBlockSize = Page::kMaxNonCodeHeapObjectSize; | 1549 static const int kMaxBlockSize = Page::kMaxNonCodeHeapObjectSize; |
1516 | 1550 |
1517 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); | 1551 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); |
1518 | 1552 |
1519 PagedSpace* owner_; | 1553 PagedSpace* owner_; |
1520 Heap* heap_; | 1554 Heap* heap_; |
1521 | 1555 |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1716 unswept_free_bytes_ += (p->area_size() - p->LiveBytes()); | 1750 unswept_free_bytes_ += (p->area_size() - p->LiveBytes()); |
1717 } | 1751 } |
1718 | 1752 |
1719 void DecreaseUnsweptFreeBytes(Page* p) { | 1753 void DecreaseUnsweptFreeBytes(Page* p) { |
1720 ASSERT(ShouldBeSweptLazily(p)); | 1754 ASSERT(ShouldBeSweptLazily(p)); |
1721 unswept_free_bytes_ -= (p->area_size() - p->LiveBytes()); | 1755 unswept_free_bytes_ -= (p->area_size() - p->LiveBytes()); |
1722 } | 1756 } |
1723 | 1757 |
1724 bool AdvanceSweeper(intptr_t bytes_to_sweep); | 1758 bool AdvanceSweeper(intptr_t bytes_to_sweep); |
1725 | 1759 |
| 1760 // When parallel sweeper threads are active this function waits |
| 1761 // for them to complete, otherwise AdvanceSweeper with size_in_bytes |
| 1762 // is called. |
| 1763 bool EnsureSweeperProgress(intptr_t size_in_bytes); |
| 1764 |
1726 bool IsSweepingComplete() { | 1765 bool IsSweepingComplete() { |
1727 return !first_unswept_page_->is_valid(); | 1766 return !first_unswept_page_->is_valid(); |
1728 } | 1767 } |
1729 | 1768 |
1730 Page* FirstPage() { return anchor_.next_page(); } | 1769 Page* FirstPage() { return anchor_.next_page(); } |
1731 Page* LastPage() { return anchor_.prev_page(); } | 1770 Page* LastPage() { return anchor_.prev_page(); } |
1732 | 1771 |
1733 void CountFreeListItems(Page* p, FreeList::SizeStats* sizes) { | 1772 void CountFreeListItems(Page* p, FreeList::SizeStats* sizes) { |
1734 free_list_.CountFreeListItems(p, sizes); | 1773 free_list_.CountFreeListItems(p, sizes); |
1735 } | 1774 } |
1736 | 1775 |
1737 void EvictEvacuationCandidatesFromFreeLists(); | 1776 void EvictEvacuationCandidatesFromFreeLists(); |
1738 | 1777 |
1739 bool CanExpand(); | 1778 bool CanExpand(); |
1740 | 1779 |
1741 // Returns the number of total pages in this space. | 1780 // Returns the number of total pages in this space. |
1742 int CountTotalPages(); | 1781 int CountTotalPages(); |
1743 | 1782 |
1744 // Return size of allocatable area on a page in this space. | 1783 // Return size of allocatable area on a page in this space. |
1745 inline int AreaSize() { | 1784 inline int AreaSize() { |
1746 return area_size_; | 1785 return area_size_; |
1747 } | 1786 } |
1748 | 1787 |
1749 protected: | 1788 protected: |
| 1789 FreeList* free_list() { return &free_list_; } |
| 1790 |
| 1791 void AddToAccountingStats(intptr_t bytes) { |
| 1792 accounting_stats_.DeallocateBytes(bytes); |
| 1793 } |
| 1794 |
1750 int area_size_; | 1795 int area_size_; |
1751 | 1796 |
1752 // Maximum capacity of this space. | 1797 // Maximum capacity of this space. |
1753 intptr_t max_capacity_; | 1798 intptr_t max_capacity_; |
1754 | 1799 |
1755 intptr_t SizeOfFirstPage(); | 1800 intptr_t SizeOfFirstPage(); |
1756 | 1801 |
1757 // Accounting information for this space. | 1802 // Accounting information for this space. |
1758 AllocationStats accounting_stats_; | 1803 AllocationStats accounting_stats_; |
1759 | 1804 |
(...skipping 29 matching lines...) Expand all Loading... |
1789 bool Expand(); | 1834 bool Expand(); |
1790 | 1835 |
1791 // Generic fast case allocation function that tries linear allocation at the | 1836 // Generic fast case allocation function that tries linear allocation at the |
1792 // address denoted by top in allocation_info_. | 1837 // address denoted by top in allocation_info_. |
1793 inline HeapObject* AllocateLinearly(int size_in_bytes); | 1838 inline HeapObject* AllocateLinearly(int size_in_bytes); |
1794 | 1839 |
1795 // Slow path of AllocateRaw. This function is space-dependent. | 1840 // Slow path of AllocateRaw. This function is space-dependent. |
1796 MUST_USE_RESULT virtual HeapObject* SlowAllocateRaw(int size_in_bytes); | 1841 MUST_USE_RESULT virtual HeapObject* SlowAllocateRaw(int size_in_bytes); |
1797 | 1842 |
1798 friend class PageIterator; | 1843 friend class PageIterator; |
| 1844 friend class SweeperThread; |
1799 }; | 1845 }; |
1800 | 1846 |
1801 | 1847 |
1802 class NumberAndSizeInfo BASE_EMBEDDED { | 1848 class NumberAndSizeInfo BASE_EMBEDDED { |
1803 public: | 1849 public: |
1804 NumberAndSizeInfo() : number_(0), bytes_(0) {} | 1850 NumberAndSizeInfo() : number_(0), bytes_(0) {} |
1805 | 1851 |
1806 int number() const { return number_; } | 1852 int number() const { return number_; } |
1807 void increment_number(int num) { number_ += num; } | 1853 void increment_number(int num) { number_ += num; } |
1808 | 1854 |
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2773 } | 2819 } |
2774 // Must be small, since an iteration is used for lookup. | 2820 // Must be small, since an iteration is used for lookup. |
2775 static const int kMaxComments = 64; | 2821 static const int kMaxComments = 64; |
2776 }; | 2822 }; |
2777 #endif | 2823 #endif |
2778 | 2824 |
2779 | 2825 |
2780 } } // namespace v8::internal | 2826 } } // namespace v8::internal |
2781 | 2827 |
2782 #endif // V8_SPACES_H_ | 2828 #endif // V8_SPACES_H_ |
OLD | NEW |