| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_SPACES_H_ | 5 #ifndef V8_SPACES_H_ |
| 6 #define V8_SPACES_H_ | 6 #define V8_SPACES_H_ |
| 7 | 7 |
| 8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
| 9 #include "src/base/atomicops.h" |
| 9 #include "src/hashmap.h" | 10 #include "src/hashmap.h" |
| 10 #include "src/list.h" | 11 #include "src/list.h" |
| 11 #include "src/log.h" | 12 #include "src/log.h" |
| 12 #include "src/platform/mutex.h" | 13 #include "src/platform/mutex.h" |
| 13 #include "src/utils.h" | 14 #include "src/utils.h" |
| 14 | 15 |
| 15 namespace v8 { | 16 namespace v8 { |
| 16 namespace internal { | 17 namespace internal { |
| 17 | 18 |
| 18 class Isolate; | 19 class Isolate; |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 } | 285 } |
| 285 | 286 |
| 286 // Only works for addresses in pointer spaces, not data or code spaces. | 287 // Only works for addresses in pointer spaces, not data or code spaces. |
| 287 static inline MemoryChunk* FromAnyPointerAddress(Heap* heap, Address addr); | 288 static inline MemoryChunk* FromAnyPointerAddress(Heap* heap, Address addr); |
| 288 | 289 |
| 289 Address address() { return reinterpret_cast<Address>(this); } | 290 Address address() { return reinterpret_cast<Address>(this); } |
| 290 | 291 |
| 291 bool is_valid() { return address() != NULL; } | 292 bool is_valid() { return address() != NULL; } |
| 292 | 293 |
| 293 MemoryChunk* next_chunk() const { | 294 MemoryChunk* next_chunk() const { |
| 294 return reinterpret_cast<MemoryChunk*>(Acquire_Load(&next_chunk_)); | 295 return reinterpret_cast<MemoryChunk*>(base::Acquire_Load(&next_chunk_)); |
| 295 } | 296 } |
| 296 | 297 |
| 297 MemoryChunk* prev_chunk() const { | 298 MemoryChunk* prev_chunk() const { |
| 298 return reinterpret_cast<MemoryChunk*>(Acquire_Load(&prev_chunk_)); | 299 return reinterpret_cast<MemoryChunk*>(base::Acquire_Load(&prev_chunk_)); |
| 299 } | 300 } |
| 300 | 301 |
| 301 void set_next_chunk(MemoryChunk* next) { | 302 void set_next_chunk(MemoryChunk* next) { |
| 302 Release_Store(&next_chunk_, reinterpret_cast<AtomicWord>(next)); | 303 base::Release_Store(&next_chunk_, reinterpret_cast<base::AtomicWord>(next)); |
| 303 } | 304 } |
| 304 | 305 |
| 305 void set_prev_chunk(MemoryChunk* prev) { | 306 void set_prev_chunk(MemoryChunk* prev) { |
| 306 Release_Store(&prev_chunk_, reinterpret_cast<AtomicWord>(prev)); | 307 base::Release_Store(&prev_chunk_, reinterpret_cast<base::AtomicWord>(prev)); |
| 307 } | 308 } |
| 308 | 309 |
| 309 Space* owner() const { | 310 Space* owner() const { |
| 310 if ((reinterpret_cast<intptr_t>(owner_) & kFailureTagMask) == | 311 if ((reinterpret_cast<intptr_t>(owner_) & kFailureTagMask) == |
| 311 kFailureTag) { | 312 kFailureTag) { |
| 312 return reinterpret_cast<Space*>(reinterpret_cast<intptr_t>(owner_) - | 313 return reinterpret_cast<Space*>(reinterpret_cast<intptr_t>(owner_) - |
| 313 kFailureTag); | 314 kFailureTag); |
| 314 } else { | 315 } else { |
| 315 return NULL; | 316 return NULL; |
| 316 } | 317 } |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 // PARALLEL_SWEEPING_PENDING - This page is ready for parallel sweeping. | 455 // PARALLEL_SWEEPING_PENDING - This page is ready for parallel sweeping. |
| 455 enum ParallelSweepingState { | 456 enum ParallelSweepingState { |
| 456 PARALLEL_SWEEPING_DONE, | 457 PARALLEL_SWEEPING_DONE, |
| 457 PARALLEL_SWEEPING_FINALIZE, | 458 PARALLEL_SWEEPING_FINALIZE, |
| 458 PARALLEL_SWEEPING_IN_PROGRESS, | 459 PARALLEL_SWEEPING_IN_PROGRESS, |
| 459 PARALLEL_SWEEPING_PENDING | 460 PARALLEL_SWEEPING_PENDING |
| 460 }; | 461 }; |
| 461 | 462 |
| 462 ParallelSweepingState parallel_sweeping() { | 463 ParallelSweepingState parallel_sweeping() { |
| 463 return static_cast<ParallelSweepingState>( | 464 return static_cast<ParallelSweepingState>( |
| 464 Acquire_Load(¶llel_sweeping_)); | 465 base::Acquire_Load(¶llel_sweeping_)); |
| 465 } | 466 } |
| 466 | 467 |
| 467 void set_parallel_sweeping(ParallelSweepingState state) { | 468 void set_parallel_sweeping(ParallelSweepingState state) { |
| 468 Release_Store(¶llel_sweeping_, state); | 469 base::Release_Store(¶llel_sweeping_, state); |
| 469 } | 470 } |
| 470 | 471 |
| 471 bool TryParallelSweeping() { | 472 bool TryParallelSweeping() { |
| 472 return Acquire_CompareAndSwap(¶llel_sweeping_, | 473 return base::Acquire_CompareAndSwap( |
| 473 PARALLEL_SWEEPING_PENDING, | 474 ¶llel_sweeping_, PARALLEL_SWEEPING_PENDING, |
| 474 PARALLEL_SWEEPING_IN_PROGRESS) == | 475 PARALLEL_SWEEPING_IN_PROGRESS) == PARALLEL_SWEEPING_PENDING; |
| 475 PARALLEL_SWEEPING_PENDING; | |
| 476 } | 476 } |
| 477 | 477 |
| 478 // Manage live byte count (count of bytes known to be live, | 478 // Manage live byte count (count of bytes known to be live, |
| 479 // because they are marked black). | 479 // because they are marked black). |
| 480 void ResetLiveBytes() { | 480 void ResetLiveBytes() { |
| 481 if (FLAG_gc_verbose) { | 481 if (FLAG_gc_verbose) { |
| 482 PrintF("ResetLiveBytes:%p:%x->0\n", | 482 PrintF("ResetLiveBytes:%p:%x->0\n", |
| 483 static_cast<void*>(this), live_byte_count_); | 483 static_cast<void*>(this), live_byte_count_); |
| 484 } | 484 } |
| 485 live_byte_count_ = 0; | 485 live_byte_count_ = 0; |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 SlotsBuffer* slots_buffer_; | 700 SlotsBuffer* slots_buffer_; |
| 701 SkipList* skip_list_; | 701 SkipList* skip_list_; |
| 702 intptr_t write_barrier_counter_; | 702 intptr_t write_barrier_counter_; |
| 703 // Used by the incremental marker to keep track of the scanning progress in | 703 // Used by the incremental marker to keep track of the scanning progress in |
| 704 // large objects that have a progress bar and are scanned in increments. | 704 // large objects that have a progress bar and are scanned in increments. |
| 705 int progress_bar_; | 705 int progress_bar_; |
| 706 // Assuming the initial allocation on a page is sequential, | 706 // Assuming the initial allocation on a page is sequential, |
| 707 // count highest number of bytes ever allocated on the page. | 707 // count highest number of bytes ever allocated on the page. |
| 708 int high_water_mark_; | 708 int high_water_mark_; |
| 709 | 709 |
| 710 AtomicWord parallel_sweeping_; | 710 base::AtomicWord parallel_sweeping_; |
| 711 | 711 |
| 712 // PagedSpace free-list statistics. | 712 // PagedSpace free-list statistics. |
| 713 intptr_t available_in_small_free_list_; | 713 intptr_t available_in_small_free_list_; |
| 714 intptr_t available_in_medium_free_list_; | 714 intptr_t available_in_medium_free_list_; |
| 715 intptr_t available_in_large_free_list_; | 715 intptr_t available_in_large_free_list_; |
| 716 intptr_t available_in_huge_free_list_; | 716 intptr_t available_in_huge_free_list_; |
| 717 intptr_t non_available_small_blocks_; | 717 intptr_t non_available_small_blocks_; |
| 718 | 718 |
| 719 static MemoryChunk* Initialize(Heap* heap, | 719 static MemoryChunk* Initialize(Heap* heap, |
| 720 Address base, | 720 Address base, |
| 721 size_t size, | 721 size_t size, |
| 722 Address area_start, | 722 Address area_start, |
| 723 Address area_end, | 723 Address area_end, |
| 724 Executability executable, | 724 Executability executable, |
| 725 Space* owner); | 725 Space* owner); |
| 726 | 726 |
| 727 private: | 727 private: |
| 728 // next_chunk_ holds a pointer of type MemoryChunk | 728 // next_chunk_ holds a pointer of type MemoryChunk |
| 729 AtomicWord next_chunk_; | 729 base::AtomicWord next_chunk_; |
| 730 // prev_chunk_ holds a pointer of type MemoryChunk | 730 // prev_chunk_ holds a pointer of type MemoryChunk |
| 731 AtomicWord prev_chunk_; | 731 base::AtomicWord prev_chunk_; |
| 732 | 732 |
| 733 friend class MemoryAllocator; | 733 friend class MemoryAllocator; |
| 734 }; | 734 }; |
| 735 | 735 |
| 736 | 736 |
| 737 STATIC_ASSERT(sizeof(MemoryChunk) <= MemoryChunk::kHeaderSize); | 737 STATIC_ASSERT(sizeof(MemoryChunk) <= MemoryChunk::kHeaderSize); |
| 738 | 738 |
| 739 | 739 |
| 740 // ----------------------------------------------------------------------------- | 740 // ----------------------------------------------------------------------------- |
| 741 // A page is a memory chunk of a size 1MB. Large object pages may be larger. | 741 // A page is a memory chunk of a size 1MB. Large object pages may be larger. |
| (...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1525 | 1525 |
| 1526 FreeListNode* PickNodeFromList(int *node_size); | 1526 FreeListNode* PickNodeFromList(int *node_size); |
| 1527 FreeListNode* PickNodeFromList(int size_in_bytes, int *node_size); | 1527 FreeListNode* PickNodeFromList(int size_in_bytes, int *node_size); |
| 1528 | 1528 |
| 1529 intptr_t EvictFreeListItemsInList(Page* p); | 1529 intptr_t EvictFreeListItemsInList(Page* p); |
| 1530 bool ContainsPageFreeListItemsInList(Page* p); | 1530 bool ContainsPageFreeListItemsInList(Page* p); |
| 1531 | 1531 |
| 1532 void RepairFreeList(Heap* heap); | 1532 void RepairFreeList(Heap* heap); |
| 1533 | 1533 |
| 1534 FreeListNode* top() const { | 1534 FreeListNode* top() const { |
| 1535 return reinterpret_cast<FreeListNode*>(NoBarrier_Load(&top_)); | 1535 return reinterpret_cast<FreeListNode*>(base::NoBarrier_Load(&top_)); |
| 1536 } | 1536 } |
| 1537 | 1537 |
| 1538 void set_top(FreeListNode* top) { | 1538 void set_top(FreeListNode* top) { |
| 1539 NoBarrier_Store(&top_, reinterpret_cast<AtomicWord>(top)); | 1539 base::NoBarrier_Store(&top_, reinterpret_cast<base::AtomicWord>(top)); |
| 1540 } | 1540 } |
| 1541 | 1541 |
| 1542 FreeListNode** GetEndAddress() { return &end_; } | 1542 FreeListNode** GetEndAddress() { return &end_; } |
| 1543 FreeListNode* end() const { return end_; } | 1543 FreeListNode* end() const { return end_; } |
| 1544 void set_end(FreeListNode* end) { end_ = end; } | 1544 void set_end(FreeListNode* end) { end_ = end; } |
| 1545 | 1545 |
| 1546 int* GetAvailableAddress() { return &available_; } | 1546 int* GetAvailableAddress() { return &available_; } |
| 1547 int available() const { return available_; } | 1547 int available() const { return available_; } |
| 1548 void set_available(int available) { available_ = available; } | 1548 void set_available(int available) { available_ = available; } |
| 1549 | 1549 |
| 1550 Mutex* mutex() { return &mutex_; } | 1550 Mutex* mutex() { return &mutex_; } |
| 1551 | 1551 |
| 1552 bool IsEmpty() { | 1552 bool IsEmpty() { |
| 1553 return top() == 0; | 1553 return top() == 0; |
| 1554 } | 1554 } |
| 1555 | 1555 |
| 1556 #ifdef DEBUG | 1556 #ifdef DEBUG |
| 1557 intptr_t SumFreeList(); | 1557 intptr_t SumFreeList(); |
| 1558 int FreeListLength(); | 1558 int FreeListLength(); |
| 1559 #endif | 1559 #endif |
| 1560 | 1560 |
| 1561 private: | 1561 private: |
| 1562 // top_ points to the top FreeListNode* in the free list category. | 1562 // top_ points to the top FreeListNode* in the free list category. |
| 1563 AtomicWord top_; | 1563 base::AtomicWord top_; |
| 1564 FreeListNode* end_; | 1564 FreeListNode* end_; |
| 1565 Mutex mutex_; | 1565 Mutex mutex_; |
| 1566 | 1566 |
| 1567 // Total available bytes in all blocks of this free list category. | 1567 // Total available bytes in all blocks of this free list category. |
| 1568 int available_; | 1568 int available_; |
| 1569 }; | 1569 }; |
| 1570 | 1570 |
| 1571 | 1571 |
| 1572 // The free list for the old space. The free list is organized in such a way | 1572 // The free list for the old space. The free list is organized in such a way |
| 1573 // as to encourage objects allocated around the same time to be near each | 1573 // as to encourage objects allocated around the same time to be near each |
| (...skipping 1426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3000 } | 3000 } |
| 3001 // Must be small, since an iteration is used for lookup. | 3001 // Must be small, since an iteration is used for lookup. |
| 3002 static const int kMaxComments = 64; | 3002 static const int kMaxComments = 64; |
| 3003 }; | 3003 }; |
| 3004 #endif | 3004 #endif |
| 3005 | 3005 |
| 3006 | 3006 |
| 3007 } } // namespace v8::internal | 3007 } } // namespace v8::internal |
| 3008 | 3008 |
| 3009 #endif // V8_SPACES_H_ | 3009 #endif // V8_SPACES_H_ |
| OLD | NEW |