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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 SlotsBuffer* slots_buffer_; | 690 SlotsBuffer* slots_buffer_; |
679 SkipList* skip_list_; | 691 SkipList* skip_list_; |
680 intptr_t write_barrier_counter_; | 692 intptr_t write_barrier_counter_; |
681 // Used by the incremental marker to keep track of the scanning progress in | 693 // Used by the incremental marker to keep track of the scanning progress in |
682 // large objects that have a progress bar and are scanned in increments. | 694 // large objects that have a progress bar and are scanned in increments. |
683 int progress_bar_; | 695 int progress_bar_; |
684 // Assuming the initial allocation on a page is sequential, | 696 // Assuming the initial allocation on a page is sequential, |
685 // count highest number of bytes ever allocated on the page. | 697 // count highest number of bytes ever allocated on the page. |
686 int high_water_mark_; | 698 int high_water_mark_; |
687 | 699 |
| 700 intptr_t parallel_sweeping_; |
| 701 |
688 static MemoryChunk* Initialize(Heap* heap, | 702 static MemoryChunk* Initialize(Heap* heap, |
689 Address base, | 703 Address base, |
690 size_t size, | 704 size_t size, |
691 Address area_start, | 705 Address area_start, |
692 Address area_end, | 706 Address area_end, |
693 Executability executable, | 707 Executability executable, |
694 Space* owner); | 708 Space* owner); |
695 | 709 |
696 friend class MemoryAllocator; | 710 friend class MemoryAllocator; |
697 }; | 711 }; |
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1378 static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize); | 1392 static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize); |
1379 | 1393 |
1380 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListNode); | 1394 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListNode); |
1381 }; | 1395 }; |
1382 | 1396 |
1383 | 1397 |
1384 // The free list category holds a pointer to the top element and a pointer to | 1398 // The free list category holds a pointer to the top element and a pointer to |
1385 // the end element of the linked list of free memory blocks. | 1399 // the end element of the linked list of free memory blocks. |
1386 class FreeListCategory { | 1400 class FreeListCategory { |
1387 public: | 1401 public: |
1388 FreeListCategory() : top_(NULL), end_(NULL), available_(0) {} | 1402 FreeListCategory() : |
| 1403 top_(NULL), |
| 1404 end_(NULL), |
| 1405 mutex_(OS::CreateMutex()), |
| 1406 available_(0) {} |
| 1407 |
| 1408 ~FreeListCategory() { |
| 1409 delete mutex_; |
| 1410 } |
| 1411 |
| 1412 intptr_t Concatenate(FreeListCategory* category); |
1389 | 1413 |
1390 void Reset(); | 1414 void Reset(); |
1391 | 1415 |
1392 void Free(FreeListNode* node, int size_in_bytes); | 1416 void Free(FreeListNode* node, int size_in_bytes); |
1393 | 1417 |
1394 FreeListNode* PickNodeFromList(int *node_size); | 1418 FreeListNode* PickNodeFromList(int *node_size); |
1395 | 1419 |
1396 intptr_t CountFreeListItemsInList(Page* p); | 1420 intptr_t CountFreeListItemsInList(Page* p); |
1397 | 1421 |
1398 intptr_t EvictFreeListItemsInList(Page* p); | 1422 intptr_t EvictFreeListItemsInList(Page* p); |
1399 | 1423 |
1400 void RepairFreeList(Heap* heap); | 1424 void RepairFreeList(Heap* heap); |
1401 | 1425 |
1402 FreeListNode** GetTopAddress() { return &top_; } | 1426 FreeListNode** GetTopAddress() { return &top_; } |
1403 FreeListNode* top() const { return top_; } | 1427 FreeListNode* top() const { return top_; } |
1404 void set_top(FreeListNode* top) { top_ = top; } | 1428 void set_top(FreeListNode* top) { top_ = top; } |
1405 | 1429 |
1406 FreeListNode** GetEndAddress() { return &end_; } | 1430 FreeListNode** GetEndAddress() { return &end_; } |
1407 FreeListNode* end() const { return end_; } | 1431 FreeListNode* end() const { return end_; } |
1408 void set_end(FreeListNode* end) { end_ = end; } | 1432 void set_end(FreeListNode* end) { end_ = end; } |
1409 | 1433 |
1410 int* GetAvailableAddress() { return &available_; } | 1434 int* GetAvailableAddress() { return &available_; } |
1411 int available() const { return available_; } | 1435 int available() const { return available_; } |
1412 void set_available(int available) { available_ = available; } | 1436 void set_available(int available) { available_ = available; } |
1413 | 1437 |
| 1438 Mutex* mutex() { return mutex_; } |
| 1439 |
1414 #ifdef DEBUG | 1440 #ifdef DEBUG |
1415 intptr_t SumFreeList(); | 1441 intptr_t SumFreeList(); |
1416 int FreeListLength(); | 1442 int FreeListLength(); |
1417 #endif | 1443 #endif |
1418 | 1444 |
1419 private: | 1445 private: |
1420 FreeListNode* top_; | 1446 FreeListNode* top_; |
1421 FreeListNode* end_; | 1447 FreeListNode* end_; |
| 1448 Mutex* mutex_; |
1422 | 1449 |
1423 // Total available bytes in all blocks of this free list category. | 1450 // Total available bytes in all blocks of this free list category. |
1424 int available_; | 1451 int available_; |
1425 }; | 1452 }; |
1426 | 1453 |
1427 | 1454 |
1428 // The free list for the old space. The free list is organized in such a way | 1455 // The free list for the old space. The free list is organized in such a way |
1429 // as to encourage objects allocated around the same time to be near each | 1456 // as to encourage objects allocated around the same time to be near each |
1430 // other. The normal way to allocate is intended to be by bumping a 'top' | 1457 // other. The normal way to allocate is intended to be by bumping a 'top' |
1431 // pointer until it hits a 'limit' pointer. When the limit is hit we need to | 1458 // pointer until it hits a 'limit' pointer. When the limit is hit we need to |
(...skipping 13 matching lines...) Expand all Loading... |
1445 // spaces are called medium. | 1472 // spaces are called medium. |
1446 // 1048-16383 words: There is a list of spaces this large. It is used for top | 1473 // 1048-16383 words: There is a list of spaces this large. It is used for top |
1447 // and limit when the object we need to allocate is 256-2047 words in size. | 1474 // and limit when the object we need to allocate is 256-2047 words in size. |
1448 // These spaces are call large. | 1475 // These spaces are call large. |
1449 // At least 16384 words. This list is for objects of 2048 words or larger. | 1476 // At least 16384 words. This list is for objects of 2048 words or larger. |
1450 // Empty pages are added to this list. These spaces are called huge. | 1477 // Empty pages are added to this list. These spaces are called huge. |
1451 class FreeList BASE_EMBEDDED { | 1478 class FreeList BASE_EMBEDDED { |
1452 public: | 1479 public: |
1453 explicit FreeList(PagedSpace* owner); | 1480 explicit FreeList(PagedSpace* owner); |
1454 | 1481 |
| 1482 intptr_t Concatenate(FreeList* free_list); |
| 1483 |
1455 // Clear the free list. | 1484 // Clear the free list. |
1456 void Reset(); | 1485 void Reset(); |
1457 | 1486 |
1458 // Return the number of bytes available on the free list. | 1487 // Return the number of bytes available on the free list. |
1459 intptr_t available() { | 1488 intptr_t available() { |
1460 return small_list_.available() + medium_list_.available() + | 1489 return small_list_.available() + medium_list_.available() + |
1461 large_list_.available() + huge_list_.available(); | 1490 large_list_.available() + huge_list_.available(); |
1462 } | 1491 } |
1463 | 1492 |
1464 // Place a node on the free list. The block of size 'size_in_bytes' | 1493 // Place a node on the free list. The block of size 'size_in_bytes' |
(...skipping 27 matching lines...) Expand all Loading... |
1492 intptr_t small_size_; | 1521 intptr_t small_size_; |
1493 intptr_t medium_size_; | 1522 intptr_t medium_size_; |
1494 intptr_t large_size_; | 1523 intptr_t large_size_; |
1495 intptr_t huge_size_; | 1524 intptr_t huge_size_; |
1496 }; | 1525 }; |
1497 | 1526 |
1498 void CountFreeListItems(Page* p, SizeStats* sizes); | 1527 void CountFreeListItems(Page* p, SizeStats* sizes); |
1499 | 1528 |
1500 intptr_t EvictFreeListItems(Page* p); | 1529 intptr_t EvictFreeListItems(Page* p); |
1501 | 1530 |
| 1531 FreeListCategory* small_list() { return &small_list_; } |
| 1532 FreeListCategory* medium_list() { return &medium_list_; } |
| 1533 FreeListCategory* large_list() { return &large_list_; } |
| 1534 FreeListCategory* huge_list() { return &huge_list_; } |
| 1535 |
1502 private: | 1536 private: |
1503 // The size range of blocks, in bytes. | 1537 // The size range of blocks, in bytes. |
1504 static const int kMinBlockSize = 3 * kPointerSize; | 1538 static const int kMinBlockSize = 3 * kPointerSize; |
1505 static const int kMaxBlockSize = Page::kMaxNonCodeHeapObjectSize; | 1539 static const int kMaxBlockSize = Page::kMaxNonCodeHeapObjectSize; |
1506 | 1540 |
1507 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); | 1541 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); |
1508 | 1542 |
1509 PagedSpace* owner_; | 1543 PagedSpace* owner_; |
1510 Heap* heap_; | 1544 Heap* heap_; |
1511 | 1545 |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1706 unswept_free_bytes_ += (p->area_size() - p->LiveBytes()); | 1740 unswept_free_bytes_ += (p->area_size() - p->LiveBytes()); |
1707 } | 1741 } |
1708 | 1742 |
1709 void DecreaseUnsweptFreeBytes(Page* p) { | 1743 void DecreaseUnsweptFreeBytes(Page* p) { |
1710 ASSERT(ShouldBeSweptLazily(p)); | 1744 ASSERT(ShouldBeSweptLazily(p)); |
1711 unswept_free_bytes_ -= (p->area_size() - p->LiveBytes()); | 1745 unswept_free_bytes_ -= (p->area_size() - p->LiveBytes()); |
1712 } | 1746 } |
1713 | 1747 |
1714 bool AdvanceSweeper(intptr_t bytes_to_sweep); | 1748 bool AdvanceSweeper(intptr_t bytes_to_sweep); |
1715 | 1749 |
| 1750 // When parallel sweeper threads are active this function waits |
| 1751 // for them to complete, otherwise AdvanceSweeper with size_in_bytes |
| 1752 // is called. |
| 1753 bool EnsureSweeperProgress(intptr_t size_in_bytes); |
| 1754 |
1716 bool IsSweepingComplete() { | 1755 bool IsSweepingComplete() { |
1717 return !first_unswept_page_->is_valid(); | 1756 return !first_unswept_page_->is_valid(); |
1718 } | 1757 } |
1719 | 1758 |
1720 Page* FirstPage() { return anchor_.next_page(); } | 1759 Page* FirstPage() { return anchor_.next_page(); } |
1721 Page* LastPage() { return anchor_.prev_page(); } | 1760 Page* LastPage() { return anchor_.prev_page(); } |
1722 | 1761 |
1723 void CountFreeListItems(Page* p, FreeList::SizeStats* sizes) { | 1762 void CountFreeListItems(Page* p, FreeList::SizeStats* sizes) { |
1724 free_list_.CountFreeListItems(p, sizes); | 1763 free_list_.CountFreeListItems(p, sizes); |
1725 } | 1764 } |
1726 | 1765 |
1727 void EvictEvacuationCandidatesFromFreeLists(); | 1766 void EvictEvacuationCandidatesFromFreeLists(); |
1728 | 1767 |
1729 bool CanExpand(); | 1768 bool CanExpand(); |
1730 | 1769 |
1731 // Returns the number of total pages in this space. | 1770 // Returns the number of total pages in this space. |
1732 int CountTotalPages(); | 1771 int CountTotalPages(); |
1733 | 1772 |
1734 // Return size of allocatable area on a page in this space. | 1773 // Return size of allocatable area on a page in this space. |
1735 inline int AreaSize() { | 1774 inline int AreaSize() { |
1736 return area_size_; | 1775 return area_size_; |
1737 } | 1776 } |
1738 | 1777 |
1739 protected: | 1778 protected: |
| 1779 FreeList* free_list() { return &free_list_; } |
| 1780 |
| 1781 void AddToAccountingStats(intptr_t bytes) { |
| 1782 accounting_stats_.DeallocateBytes(bytes); |
| 1783 } |
| 1784 |
1740 int area_size_; | 1785 int area_size_; |
1741 | 1786 |
1742 // Maximum capacity of this space. | 1787 // Maximum capacity of this space. |
1743 intptr_t max_capacity_; | 1788 intptr_t max_capacity_; |
1744 | 1789 |
1745 intptr_t SizeOfFirstPage(); | 1790 intptr_t SizeOfFirstPage(); |
1746 | 1791 |
1747 // Accounting information for this space. | 1792 // Accounting information for this space. |
1748 AllocationStats accounting_stats_; | 1793 AllocationStats accounting_stats_; |
1749 | 1794 |
(...skipping 29 matching lines...) Expand all Loading... |
1779 bool Expand(); | 1824 bool Expand(); |
1780 | 1825 |
1781 // Generic fast case allocation function that tries linear allocation at the | 1826 // Generic fast case allocation function that tries linear allocation at the |
1782 // address denoted by top in allocation_info_. | 1827 // address denoted by top in allocation_info_. |
1783 inline HeapObject* AllocateLinearly(int size_in_bytes); | 1828 inline HeapObject* AllocateLinearly(int size_in_bytes); |
1784 | 1829 |
1785 // Slow path of AllocateRaw. This function is space-dependent. | 1830 // Slow path of AllocateRaw. This function is space-dependent. |
1786 MUST_USE_RESULT virtual HeapObject* SlowAllocateRaw(int size_in_bytes); | 1831 MUST_USE_RESULT virtual HeapObject* SlowAllocateRaw(int size_in_bytes); |
1787 | 1832 |
1788 friend class PageIterator; | 1833 friend class PageIterator; |
| 1834 friend class SweeperThread; |
1789 }; | 1835 }; |
1790 | 1836 |
1791 | 1837 |
1792 class NumberAndSizeInfo BASE_EMBEDDED { | 1838 class NumberAndSizeInfo BASE_EMBEDDED { |
1793 public: | 1839 public: |
1794 NumberAndSizeInfo() : number_(0), bytes_(0) {} | 1840 NumberAndSizeInfo() : number_(0), bytes_(0) {} |
1795 | 1841 |
1796 int number() const { return number_; } | 1842 int number() const { return number_; } |
1797 void increment_number(int num) { number_ += num; } | 1843 void increment_number(int num) { number_ += num; } |
1798 | 1844 |
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2763 } | 2809 } |
2764 // Must be small, since an iteration is used for lookup. | 2810 // Must be small, since an iteration is used for lookup. |
2765 static const int kMaxComments = 64; | 2811 static const int kMaxComments = 64; |
2766 }; | 2812 }; |
2767 #endif | 2813 #endif |
2768 | 2814 |
2769 | 2815 |
2770 } } // namespace v8::internal | 2816 } } // namespace v8::internal |
2771 | 2817 |
2772 #endif // V8_SPACES_H_ | 2818 #endif // V8_SPACES_H_ |
OLD | NEW |