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

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
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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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_
OLDNEW
« src/mark-compact.cc ('K') | « src/mark-compact.cc ('k') | src/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698