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 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1534 void set_was_swept_conservatively(bool b) { was_swept_conservatively_ = b; } | 1545 void set_was_swept_conservatively(bool b) { was_swept_conservatively_ = b; } |
1535 | 1546 |
1536 // Evacuation candidates are swept by evacuator. Needs to return a valid | 1547 // Evacuation candidates are swept by evacuator. Needs to return a valid |
1537 // result before _and_ after evacuation has finished. | 1548 // result before _and_ after evacuation has finished. |
1538 static bool ShouldBeSweptLazily(Page* p) { | 1549 static bool ShouldBeSweptLazily(Page* p) { |
1539 return !p->IsEvacuationCandidate() && | 1550 return !p->IsEvacuationCandidate() && |
1540 !p->IsFlagSet(Page::RESCAN_ON_EVACUATION) && | 1551 !p->IsFlagSet(Page::RESCAN_ON_EVACUATION) && |
1541 !p->WasSweptPrecisely(); | 1552 !p->WasSweptPrecisely(); |
1542 } | 1553 } |
1543 | 1554 |
1544 void SetPagesToSweep(Page* first, Page* last) { | 1555 void SetPagesToSweep(Page* first) { |
1545 first_unswept_page_ = first; | 1556 first_unswept_page_ = first; |
1546 last_unswept_page_ = last; | |
1547 } | 1557 } |
1548 | 1558 |
1549 bool AdvanceSweeper(intptr_t bytes_to_sweep); | 1559 bool AdvanceSweeper(intptr_t bytes_to_sweep); |
1550 | 1560 |
1551 bool IsSweepingComplete() { | 1561 bool IsSweepingComplete() { |
1552 return !first_unswept_page_->is_valid(); | 1562 return !first_unswept_page_->is_valid(); |
1553 } | 1563 } |
1554 | 1564 |
1555 Page* FirstPage() { return anchor_.next_page(); } | 1565 Page* FirstPage() { return anchor_.next_page(); } |
1556 Page* LastPage() { return anchor_.prev_page(); } | 1566 Page* LastPage() { return anchor_.prev_page(); } |
1557 | 1567 |
1558 bool IsFragmented(Page* p) { | 1568 bool IsFragmented(Page* p) { |
1559 intptr_t sizes[4]; | 1569 FreeList::SizeStats sizes; |
1560 free_list_.CountFreeListItems(p, sizes); | 1570 free_list_.CountFreeListItems(p, &sizes); |
1561 | 1571 |
1562 intptr_t ratio; | 1572 intptr_t ratio; |
1563 intptr_t ratio_threshold; | 1573 intptr_t ratio_threshold; |
1564 if (identity() == CODE_SPACE) { | 1574 if (identity() == CODE_SPACE) { |
1565 ratio = (sizes[1] * 10 + sizes[2] * 2) * 100 / Page::kObjectAreaSize; | 1575 ratio = (sizes.medium_size_ * 10 + sizes.large_size_ * 2) * 100 / |
| 1576 Page::kObjectAreaSize; |
1566 ratio_threshold = 10; | 1577 ratio_threshold = 10; |
1567 } else { | 1578 } else { |
1568 ratio = (sizes[0] * 5 + sizes[1]) * 100 / Page::kObjectAreaSize; | 1579 ratio = (sizes.small_size_ * 5 + sizes.medium_size_) * 100 / |
| 1580 Page::kObjectAreaSize; |
1569 ratio_threshold = 15; | 1581 ratio_threshold = 15; |
1570 } | 1582 } |
1571 | 1583 |
1572 if (FLAG_trace_fragmentation) { | 1584 if (FLAG_trace_fragmentation) { |
1573 PrintF("%p [%d]: %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %s\n", | 1585 PrintF("%p [%d]: %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %s\n", |
1574 reinterpret_cast<void*>(p), | 1586 reinterpret_cast<void*>(p), |
1575 identity(), | 1587 identity(), |
1576 static_cast<int>(sizes[0]), | 1588 static_cast<int>(sizes.small_size_), |
1577 static_cast<double>(sizes[0] * 100) / Page::kObjectAreaSize, | 1589 static_cast<double>(sizes.small_size_ * 100) / |
1578 static_cast<int>(sizes[1]), | 1590 Page::kObjectAreaSize, |
1579 static_cast<double>(sizes[1] * 100) / Page::kObjectAreaSize, | 1591 static_cast<int>(sizes.medium_size_), |
1580 static_cast<int>(sizes[2]), | 1592 static_cast<double>(sizes.medium_size_ * 100) / |
1581 static_cast<double>(sizes[2] * 100) / Page::kObjectAreaSize, | 1593 Page::kObjectAreaSize, |
1582 static_cast<int>(sizes[3]), | 1594 static_cast<int>(sizes.large_size_), |
1583 static_cast<double>(sizes[3] * 100) / Page::kObjectAreaSize, | 1595 static_cast<double>(sizes.large_size_ * 100) / |
| 1596 Page::kObjectAreaSize, |
| 1597 static_cast<int>(sizes.huge_size_), |
| 1598 static_cast<double>(sizes.huge_size_ * 100) / |
| 1599 Page::kObjectAreaSize, |
1584 (ratio > ratio_threshold) ? "[fragmented]" : ""); | 1600 (ratio > ratio_threshold) ? "[fragmented]" : ""); |
1585 } | 1601 } |
1586 | 1602 |
1587 return (ratio > ratio_threshold) || | 1603 return (ratio > ratio_threshold) || |
1588 (FLAG_always_compact && sizes[3] != Page::kObjectAreaSize); | 1604 (FLAG_always_compact && sizes.Total() != Page::kObjectAreaSize); |
1589 } | 1605 } |
1590 | 1606 |
1591 void EvictEvacuationCandidatesFromFreeLists(); | 1607 void EvictEvacuationCandidatesFromFreeLists(); |
1592 | 1608 |
1593 bool CanExpand(); | 1609 bool CanExpand(); |
1594 | 1610 |
1595 protected: | 1611 protected: |
1596 // Maximum capacity of this space. | 1612 // Maximum capacity of this space. |
1597 intptr_t max_capacity_; | 1613 intptr_t max_capacity_; |
1598 | 1614 |
(...skipping 11 matching lines...) Expand all Loading... |
1610 | 1626 |
1611 // Bytes of each page that cannot be allocated. Possibly non-zero | 1627 // Bytes of each page that cannot be allocated. Possibly non-zero |
1612 // for pages in spaces with only fixed-size objects. Always zero | 1628 // for pages in spaces with only fixed-size objects. Always zero |
1613 // for pages in spaces with variable sized objects (those pages are | 1629 // for pages in spaces with variable sized objects (those pages are |
1614 // padded with free-list nodes). | 1630 // padded with free-list nodes). |
1615 int page_extra_; | 1631 int page_extra_; |
1616 | 1632 |
1617 bool was_swept_conservatively_; | 1633 bool was_swept_conservatively_; |
1618 | 1634 |
1619 Page* first_unswept_page_; | 1635 Page* first_unswept_page_; |
1620 Page* last_unswept_page_; | |
1621 | 1636 |
1622 // Expands the space by allocating a fixed number of pages. Returns false if | 1637 // Expands the space by allocating a fixed number of pages. Returns false if |
1623 // it cannot allocate requested number of pages from OS. | 1638 // it cannot allocate requested number of pages from OS. |
1624 bool Expand(); | 1639 bool Expand(); |
1625 | 1640 |
1626 // Generic fast case allocation function that tries linear allocation at the | 1641 // Generic fast case allocation function that tries linear allocation at the |
1627 // address denoted by top in allocation_info_. | 1642 // address denoted by top in allocation_info_. |
1628 inline HeapObject* AllocateLinearly(int size_in_bytes); | 1643 inline HeapObject* AllocateLinearly(int size_in_bytes); |
1629 | 1644 |
1630 // Slow path of AllocateRaw. This function is space-dependent. | 1645 // Slow path of AllocateRaw. This function is space-dependent. |
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2327 // The limit of allocation for a page in this space. | 2342 // The limit of allocation for a page in this space. |
2328 virtual Address PageAllocationLimit(Page* page) { | 2343 virtual Address PageAllocationLimit(Page* page) { |
2329 return page->ObjectAreaEnd() - page_extra_; | 2344 return page->ObjectAreaEnd() - page_extra_; |
2330 } | 2345 } |
2331 | 2346 |
2332 int object_size_in_bytes() { return object_size_in_bytes_; } | 2347 int object_size_in_bytes() { return object_size_in_bytes_; } |
2333 | 2348 |
2334 // Prepares for a mark-compact GC. | 2349 // Prepares for a mark-compact GC. |
2335 virtual void PrepareForMarkCompact(); | 2350 virtual void PrepareForMarkCompact(); |
2336 | 2351 |
2337 void MarkFreeListNodes() { free_list_.MarkNodes(); } | |
2338 | |
2339 protected: | 2352 protected: |
2340 void ResetFreeList() { | 2353 void ResetFreeList() { |
2341 free_list_.Reset(); | 2354 free_list_.Reset(); |
2342 } | 2355 } |
2343 | 2356 |
2344 private: | 2357 private: |
2345 // The size of objects in this space. | 2358 // The size of objects in this space. |
2346 int object_size_in_bytes_; | 2359 int object_size_in_bytes_; |
2347 | 2360 |
2348 // The name of this space. | 2361 // The name of this space. |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2606 } | 2619 } |
2607 // Must be small, since an iteration is used for lookup. | 2620 // Must be small, since an iteration is used for lookup. |
2608 static const int kMaxComments = 64; | 2621 static const int kMaxComments = 64; |
2609 }; | 2622 }; |
2610 #endif | 2623 #endif |
2611 | 2624 |
2612 | 2625 |
2613 } } // namespace v8::internal | 2626 } } // namespace v8::internal |
2614 | 2627 |
2615 #endif // V8_SPACES_H_ | 2628 #endif // V8_SPACES_H_ |
OLD | NEW |