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 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1340 // ie, its contents will be destroyed. The start address should be word | 1340 // ie, its contents will be destroyed. The start address should be word |
1341 // aligned, and the size should be a non-zero multiple of the word size. | 1341 // aligned, and the size should be a non-zero multiple of the word size. |
1342 int Free(Address start, int size_in_bytes); | 1342 int Free(Address start, int size_in_bytes); |
1343 | 1343 |
1344 // Allocate a block of size 'size_in_bytes' from the free list. The block | 1344 // Allocate a block of size 'size_in_bytes' from the free list. The block |
1345 // is unitialized. A failure is returned if no block is available. The | 1345 // is unitialized. A failure is returned if no block is available. The |
1346 // number of bytes lost to fragmentation is returned in the output parameter | 1346 // number of bytes lost to fragmentation is returned in the output parameter |
1347 // 'wasted_bytes'. The size should be a non-zero multiple of the word size. | 1347 // 'wasted_bytes'. The size should be a non-zero multiple of the word size. |
1348 MUST_USE_RESULT HeapObject* Allocate(int size_in_bytes); | 1348 MUST_USE_RESULT HeapObject* Allocate(int size_in_bytes); |
1349 | 1349 |
1350 void MarkNodes(); | |
1351 | |
1352 #ifdef DEBUG | 1350 #ifdef DEBUG |
1353 void Zap(); | 1351 void Zap(); |
1354 static intptr_t SumFreeList(FreeListNode* node); | 1352 static intptr_t SumFreeList(FreeListNode* node); |
1355 static int FreeListLength(FreeListNode* cur); | 1353 static int FreeListLength(FreeListNode* cur); |
1356 intptr_t SumFreeLists(); | 1354 intptr_t SumFreeLists(); |
1357 bool IsVeryLong(); | 1355 bool IsVeryLong(); |
1358 #endif | 1356 #endif |
1359 | 1357 |
1360 void CountFreeListItems(Page* p, intptr_t* sizes); | 1358 struct SizeStats { |
| 1359 intptr_t Total() { |
| 1360 return small_size_ + medium_size_ + large_size_ + huge_size_; |
| 1361 } |
| 1362 |
| 1363 intptr_t small_size_; |
| 1364 intptr_t medium_size_; |
| 1365 intptr_t large_size_; |
| 1366 intptr_t huge_size_; |
| 1367 }; |
| 1368 |
| 1369 void CountFreeListItems(Page* p, SizeStats* sizes); |
| 1370 |
| 1371 intptr_t EvictFreeListItems(Page* p); |
1361 | 1372 |
1362 private: | 1373 private: |
1363 // The size range of blocks, in bytes. | 1374 // The size range of blocks, in bytes. |
1364 static const int kMinBlockSize = 3 * kPointerSize; | 1375 static const int kMinBlockSize = 3 * kPointerSize; |
1365 static const int kMaxBlockSize = Page::kMaxHeapObjectSize; | 1376 static const int kMaxBlockSize = Page::kMaxHeapObjectSize; |
1366 | 1377 |
1367 FreeListNode* PickNodeFromList(FreeListNode** list, int* node_size); | 1378 FreeListNode* PickNodeFromList(FreeListNode** list, int* node_size); |
1368 | 1379 |
1369 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); | 1380 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); |
1370 | 1381 |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1549 bool AdvanceSweeper(intptr_t bytes_to_sweep); | 1560 bool AdvanceSweeper(intptr_t bytes_to_sweep); |
1550 | 1561 |
1551 bool IsSweepingComplete() { | 1562 bool IsSweepingComplete() { |
1552 return !first_unswept_page_->is_valid(); | 1563 return !first_unswept_page_->is_valid(); |
1553 } | 1564 } |
1554 | 1565 |
1555 Page* FirstPage() { return anchor_.next_page(); } | 1566 Page* FirstPage() { return anchor_.next_page(); } |
1556 Page* LastPage() { return anchor_.prev_page(); } | 1567 Page* LastPage() { return anchor_.prev_page(); } |
1557 | 1568 |
1558 bool IsFragmented(Page* p) { | 1569 bool IsFragmented(Page* p) { |
1559 intptr_t sizes[4]; | 1570 FreeList::SizeStats sizes; |
1560 free_list_.CountFreeListItems(p, sizes); | 1571 free_list_.CountFreeListItems(p, &sizes); |
1561 | 1572 |
1562 intptr_t ratio; | 1573 intptr_t ratio; |
1563 intptr_t ratio_threshold; | 1574 intptr_t ratio_threshold; |
1564 if (identity() == CODE_SPACE) { | 1575 if (identity() == CODE_SPACE) { |
1565 ratio = (sizes[1] * 10 + sizes[2] * 2) * 100 / Page::kObjectAreaSize; | 1576 ratio = (sizes.medium_size_ * 10 + sizes.large_size_ * 2) * 100 / |
| 1577 Page::kObjectAreaSize; |
1566 ratio_threshold = 10; | 1578 ratio_threshold = 10; |
1567 } else { | 1579 } else { |
1568 ratio = (sizes[0] * 5 + sizes[1]) * 100 / Page::kObjectAreaSize; | 1580 ratio = (sizes.small_size_ * 5 + sizes.medium_size_) * 100 / |
| 1581 Page::kObjectAreaSize; |
1569 ratio_threshold = 15; | 1582 ratio_threshold = 15; |
1570 } | 1583 } |
1571 | 1584 |
1572 if (FLAG_trace_fragmentation) { | 1585 if (FLAG_trace_fragmentation) { |
1573 PrintF("%p [%d]: %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %s\n", | 1586 PrintF("%p [%d]: %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %s\n", |
1574 reinterpret_cast<void*>(p), | 1587 reinterpret_cast<void*>(p), |
1575 identity(), | 1588 identity(), |
1576 static_cast<int>(sizes[0]), | 1589 static_cast<int>(sizes.small_size_), |
1577 static_cast<double>(sizes[0] * 100) / Page::kObjectAreaSize, | 1590 static_cast<double>(sizes.small_size_ * 100) / |
1578 static_cast<int>(sizes[1]), | 1591 Page::kObjectAreaSize, |
1579 static_cast<double>(sizes[1] * 100) / Page::kObjectAreaSize, | 1592 static_cast<int>(sizes.medium_size_), |
1580 static_cast<int>(sizes[2]), | 1593 static_cast<double>(sizes.medium_size_ * 100) / |
1581 static_cast<double>(sizes[2] * 100) / Page::kObjectAreaSize, | 1594 Page::kObjectAreaSize, |
1582 static_cast<int>(sizes[3]), | 1595 static_cast<int>(sizes.large_size_), |
1583 static_cast<double>(sizes[3] * 100) / Page::kObjectAreaSize, | 1596 static_cast<double>(sizes.large_size_ * 100) / |
| 1597 Page::kObjectAreaSize, |
| 1598 static_cast<int>(sizes.huge_size_), |
| 1599 static_cast<double>(sizes.huge_size_ * 100) / |
| 1600 Page::kObjectAreaSize, |
1584 (ratio > ratio_threshold) ? "[fragmented]" : ""); | 1601 (ratio > ratio_threshold) ? "[fragmented]" : ""); |
1585 } | 1602 } |
1586 | 1603 |
1587 return (ratio > ratio_threshold) || | 1604 return (ratio > ratio_threshold) || |
1588 (FLAG_always_compact && sizes[3] != Page::kObjectAreaSize); | 1605 (FLAG_always_compact && sizes.Total() != Page::kObjectAreaSize); |
1589 } | 1606 } |
1590 | 1607 |
1591 void EvictEvacuationCandidatesFromFreeLists(); | 1608 void EvictEvacuationCandidatesFromFreeLists(); |
1592 | 1609 |
1593 bool CanExpand(); | 1610 bool CanExpand(); |
1594 | 1611 |
1595 protected: | 1612 protected: |
1596 // Maximum capacity of this space. | 1613 // Maximum capacity of this space. |
1597 intptr_t max_capacity_; | 1614 intptr_t max_capacity_; |
1598 | 1615 |
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2327 // The limit of allocation for a page in this space. | 2344 // The limit of allocation for a page in this space. |
2328 virtual Address PageAllocationLimit(Page* page) { | 2345 virtual Address PageAllocationLimit(Page* page) { |
2329 return page->ObjectAreaEnd() - page_extra_; | 2346 return page->ObjectAreaEnd() - page_extra_; |
2330 } | 2347 } |
2331 | 2348 |
2332 int object_size_in_bytes() { return object_size_in_bytes_; } | 2349 int object_size_in_bytes() { return object_size_in_bytes_; } |
2333 | 2350 |
2334 // Prepares for a mark-compact GC. | 2351 // Prepares for a mark-compact GC. |
2335 virtual void PrepareForMarkCompact(); | 2352 virtual void PrepareForMarkCompact(); |
2336 | 2353 |
2337 void MarkFreeListNodes() { free_list_.MarkNodes(); } | |
2338 | |
2339 protected: | 2354 protected: |
2340 void ResetFreeList() { | 2355 void ResetFreeList() { |
2341 free_list_.Reset(); | 2356 free_list_.Reset(); |
2342 } | 2357 } |
2343 | 2358 |
2344 private: | 2359 private: |
2345 // The size of objects in this space. | 2360 // The size of objects in this space. |
2346 int object_size_in_bytes_; | 2361 int object_size_in_bytes_; |
2347 | 2362 |
2348 // The name of this space. | 2363 // The name of this space. |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2606 } | 2621 } |
2607 // Must be small, since an iteration is used for lookup. | 2622 // Must be small, since an iteration is used for lookup. |
2608 static const int kMaxComments = 64; | 2623 static const int kMaxComments = 64; |
2609 }; | 2624 }; |
2610 #endif | 2625 #endif |
2611 | 2626 |
2612 | 2627 |
2613 } } // namespace v8::internal | 2628 } } // namespace v8::internal |
2614 | 2629 |
2615 #endif // V8_SPACES_H_ | 2630 #endif // V8_SPACES_H_ |
OLD | NEW |