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

Side by Side Diff: src/spaces.h

Issue 8507038: Fix Heap::Shrink to ensure that it does not free pages that are still in use. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: get rid of last_unswept_page_, add comment about Heap::ReserveSpace Created 9 years, 1 month 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
« no previous file with comments | « src/mark-compact.cc ('k') | src/spaces.cc » ('j') | src/spaces.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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_
OLDNEW
« no previous file with comments | « src/mark-compact.cc ('k') | src/spaces.cc » ('j') | src/spaces.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698