Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(266)

Side by Side Diff: src/spaces.h

Issue 11782028: Parallel and concurrent sweeping. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mark-compact.cc ('k') | src/spaces.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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(&parallel_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
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
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
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « src/mark-compact.cc ('k') | src/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698