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_, 0, 1) == 0; | |
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_; } | |
Michael Starzinger
2013/01/28 16:30:18
Empty newline after the accessor.
Hannes Payer (out of office)
2013/01/30 10:11:27
Done.
| |
1414 #ifdef DEBUG | 1439 #ifdef DEBUG |
1415 intptr_t SumFreeList(); | 1440 intptr_t SumFreeList(); |
1416 int FreeListLength(); | 1441 int FreeListLength(); |
1417 #endif | 1442 #endif |
1418 | 1443 |
1419 private: | 1444 private: |
1420 FreeListNode* top_; | 1445 FreeListNode* top_; |
1421 FreeListNode* end_; | 1446 FreeListNode* end_; |
1447 Mutex* mutex_; | |
1422 | 1448 |
1423 // Total available bytes in all blocks of this free list category. | 1449 // Total available bytes in all blocks of this free list category. |
1424 int available_; | 1450 int available_; |
1425 }; | 1451 }; |
1426 | 1452 |
1427 | 1453 |
1428 // The free list for the old space. The free list is organized in such a way | 1454 // 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 | 1455 // 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' | 1456 // 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 | 1457 // 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. | 1471 // spaces are called medium. |
1446 // 1048-16383 words: There is a list of spaces this large. It is used for top | 1472 // 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. | 1473 // and limit when the object we need to allocate is 256-2047 words in size. |
1448 // These spaces are call large. | 1474 // These spaces are call large. |
1449 // At least 16384 words. This list is for objects of 2048 words or larger. | 1475 // 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. | 1476 // Empty pages are added to this list. These spaces are called huge. |
1451 class FreeList BASE_EMBEDDED { | 1477 class FreeList BASE_EMBEDDED { |
1452 public: | 1478 public: |
1453 explicit FreeList(PagedSpace* owner); | 1479 explicit FreeList(PagedSpace* owner); |
1454 | 1480 |
1481 intptr_t Concatenate(FreeList* free_list); | |
1482 | |
1455 // Clear the free list. | 1483 // Clear the free list. |
1456 void Reset(); | 1484 void Reset(); |
1457 | 1485 |
1458 // Return the number of bytes available on the free list. | 1486 // Return the number of bytes available on the free list. |
1459 intptr_t available() { | 1487 intptr_t available() { |
1460 return small_list_.available() + medium_list_.available() + | 1488 return small_list_.available() + medium_list_.available() + |
1461 large_list_.available() + huge_list_.available(); | 1489 large_list_.available() + huge_list_.available(); |
1462 } | 1490 } |
1463 | 1491 |
1464 // Place a node on the free list. The block of size 'size_in_bytes' | 1492 // 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_; | 1520 intptr_t small_size_; |
1493 intptr_t medium_size_; | 1521 intptr_t medium_size_; |
1494 intptr_t large_size_; | 1522 intptr_t large_size_; |
1495 intptr_t huge_size_; | 1523 intptr_t huge_size_; |
1496 }; | 1524 }; |
1497 | 1525 |
1498 void CountFreeListItems(Page* p, SizeStats* sizes); | 1526 void CountFreeListItems(Page* p, SizeStats* sizes); |
1499 | 1527 |
1500 intptr_t EvictFreeListItems(Page* p); | 1528 intptr_t EvictFreeListItems(Page* p); |
1501 | 1529 |
1530 FreeListCategory* small_list() { return &small_list_; } | |
1531 FreeListCategory* medium_list() { return &medium_list_; } | |
1532 FreeListCategory* large_list() { return &large_list_; } | |
1533 FreeListCategory* huge_list() { return &huge_list_; } | |
1534 | |
1502 private: | 1535 private: |
1503 // The size range of blocks, in bytes. | 1536 // The size range of blocks, in bytes. |
1504 static const int kMinBlockSize = 3 * kPointerSize; | 1537 static const int kMinBlockSize = 3 * kPointerSize; |
1505 static const int kMaxBlockSize = Page::kMaxNonCodeHeapObjectSize; | 1538 static const int kMaxBlockSize = Page::kMaxNonCodeHeapObjectSize; |
1506 | 1539 |
1507 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); | 1540 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); |
1508 | 1541 |
1509 PagedSpace* owner_; | 1542 PagedSpace* owner_; |
1510 Heap* heap_; | 1543 Heap* heap_; |
1511 | 1544 |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1625 int Free(Address start, int size_in_bytes) { | 1658 int Free(Address start, int size_in_bytes) { |
1626 int wasted = free_list_.Free(start, size_in_bytes); | 1659 int wasted = free_list_.Free(start, size_in_bytes); |
1627 accounting_stats_.DeallocateBytes(size_in_bytes - wasted); | 1660 accounting_stats_.DeallocateBytes(size_in_bytes - wasted); |
1628 return size_in_bytes - wasted; | 1661 return size_in_bytes - wasted; |
1629 } | 1662 } |
1630 | 1663 |
1631 void ResetFreeList() { | 1664 void ResetFreeList() { |
1632 free_list_.Reset(); | 1665 free_list_.Reset(); |
1633 } | 1666 } |
1634 | 1667 |
1668 FreeList* free_list() { return &free_list_; } | |
Michael Starzinger
2013/01/28 16:30:18
Remove this accessor, it is dangerous. Since the S
Hannes Payer (out of office)
2013/01/30 10:11:27
Done.
| |
1669 | |
1635 // Set space allocation info. | 1670 // Set space allocation info. |
1636 void SetTop(Address top, Address limit) { | 1671 void SetTop(Address top, Address limit) { |
1637 ASSERT(top == limit || | 1672 ASSERT(top == limit || |
1638 Page::FromAddress(top) == Page::FromAddress(limit - 1)); | 1673 Page::FromAddress(top) == Page::FromAddress(limit - 1)); |
1639 MemoryChunk::UpdateHighWaterMark(allocation_info_.top); | 1674 MemoryChunk::UpdateHighWaterMark(allocation_info_.top); |
1640 allocation_info_.top = top; | 1675 allocation_info_.top = top; |
1641 allocation_info_.limit = limit; | 1676 allocation_info_.limit = limit; |
1642 } | 1677 } |
1643 | 1678 |
1644 void Allocate(int bytes) { | 1679 void Allocate(int bytes) { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1729 bool CanExpand(); | 1764 bool CanExpand(); |
1730 | 1765 |
1731 // Returns the number of total pages in this space. | 1766 // Returns the number of total pages in this space. |
1732 int CountTotalPages(); | 1767 int CountTotalPages(); |
1733 | 1768 |
1734 // Return size of allocatable area on a page in this space. | 1769 // Return size of allocatable area on a page in this space. |
1735 inline int AreaSize() { | 1770 inline int AreaSize() { |
1736 return area_size_; | 1771 return area_size_; |
1737 } | 1772 } |
1738 | 1773 |
1774 void AddToAccountingStats(intptr_t bytes) { | |
Michael Starzinger
2013/01/28 16:30:18
Same comment as for free_list() apply to this func
Hannes Payer (out of office)
2013/01/30 10:11:27
Done.
| |
1775 accounting_stats_.DeallocateBytes(bytes); | |
1776 } | |
1777 | |
1739 protected: | 1778 protected: |
1740 int area_size_; | 1779 int area_size_; |
1741 | 1780 |
1742 // Maximum capacity of this space. | 1781 // Maximum capacity of this space. |
1743 intptr_t max_capacity_; | 1782 intptr_t max_capacity_; |
1744 | 1783 |
1745 intptr_t SizeOfFirstPage(); | 1784 intptr_t SizeOfFirstPage(); |
1746 | 1785 |
1747 // Accounting information for this space. | 1786 // Accounting information for this space. |
1748 AllocationStats accounting_stats_; | 1787 AllocationStats accounting_stats_; |
(...skipping 29 matching lines...) Expand all Loading... | |
1778 // size limit has been hit. | 1817 // size limit has been hit. |
1779 bool Expand(); | 1818 bool Expand(); |
1780 | 1819 |
1781 // Generic fast case allocation function that tries linear allocation at the | 1820 // Generic fast case allocation function that tries linear allocation at the |
1782 // address denoted by top in allocation_info_. | 1821 // address denoted by top in allocation_info_. |
1783 inline HeapObject* AllocateLinearly(int size_in_bytes); | 1822 inline HeapObject* AllocateLinearly(int size_in_bytes); |
1784 | 1823 |
1785 // Slow path of AllocateRaw. This function is space-dependent. | 1824 // Slow path of AllocateRaw. This function is space-dependent. |
1786 MUST_USE_RESULT virtual HeapObject* SlowAllocateRaw(int size_in_bytes); | 1825 MUST_USE_RESULT virtual HeapObject* SlowAllocateRaw(int size_in_bytes); |
1787 | 1826 |
1827 | |
Michael Starzinger
2013/01/28 16:30:18
Drop the second empty new-lined. Needs a short com
Hannes Payer (out of office)
2013/01/30 10:11:27
Done.
| |
1828 bool EnsureSweeperProgress(intptr_t size_in_bytes); | |
1829 | |
1788 friend class PageIterator; | 1830 friend class PageIterator; |
1789 }; | 1831 }; |
1790 | 1832 |
1791 | 1833 |
1792 class NumberAndSizeInfo BASE_EMBEDDED { | 1834 class NumberAndSizeInfo BASE_EMBEDDED { |
1793 public: | 1835 public: |
1794 NumberAndSizeInfo() : number_(0), bytes_(0) {} | 1836 NumberAndSizeInfo() : number_(0), bytes_(0) {} |
1795 | 1837 |
1796 int number() const { return number_; } | 1838 int number() const { return number_; } |
1797 void increment_number(int num) { number_ += num; } | 1839 void increment_number(int num) { number_ += num; } |
(...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2763 } | 2805 } |
2764 // Must be small, since an iteration is used for lookup. | 2806 // Must be small, since an iteration is used for lookup. |
2765 static const int kMaxComments = 64; | 2807 static const int kMaxComments = 64; |
2766 }; | 2808 }; |
2767 #endif | 2809 #endif |
2768 | 2810 |
2769 | 2811 |
2770 } } // namespace v8::internal | 2812 } } // namespace v8::internal |
2771 | 2813 |
2772 #endif // V8_SPACES_H_ | 2814 #endif // V8_SPACES_H_ |
OLD | NEW |