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

Side by Side Diff: Source/platform/heap/Heap.cpp

Issue 711053002: Prepare for incremental sweep by making the FreeList independent of the ThreadHeap (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 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
« no previous file with comments | « Source/platform/heap/Heap.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 template<typename Header> 641 template<typename Header>
642 ThreadHeap<Header>::ThreadHeap(ThreadState* state, int index) 642 ThreadHeap<Header>::ThreadHeap(ThreadState* state, int index)
643 : m_currentAllocationPoint(0) 643 : m_currentAllocationPoint(0)
644 , m_remainingAllocationSize(0) 644 , m_remainingAllocationSize(0)
645 , m_lastRemainingAllocationSize(0) 645 , m_lastRemainingAllocationSize(0)
646 , m_firstPage(0) 646 , m_firstPage(0)
647 , m_firstLargeHeapObject(0) 647 , m_firstLargeHeapObject(0)
648 , m_firstPageAllocatedDuringSweeping(0) 648 , m_firstPageAllocatedDuringSweeping(0)
649 , m_lastPageAllocatedDuringSweeping(0) 649 , m_lastPageAllocatedDuringSweeping(0)
650 , m_mergePoint(0) 650 , m_mergePoint(0)
651 , m_biggestFreeListIndex(0)
652 , m_threadState(state) 651 , m_threadState(state)
653 , m_index(index) 652 , m_index(index)
654 , m_numberOfNormalPages(0) 653 , m_numberOfNormalPages(0)
655 , m_promptlyFreedCount(0) 654 , m_promptlyFreedCount(0)
656 { 655 {
657 clearFreeLists(); 656 clearFreeLists();
658 } 657 }
659 658
660 template<typename Header> 659 template<typename Header>
660 FreeList<Header>::FreeList()
661 : m_biggestFreeListIndex(0)
662 {
663 }
664
665 template<typename Header>
661 ThreadHeap<Header>::~ThreadHeap() 666 ThreadHeap<Header>::~ThreadHeap()
662 { 667 {
663 ASSERT(!m_firstPage); 668 ASSERT(!m_firstPage);
664 ASSERT(!m_firstLargeHeapObject); 669 ASSERT(!m_firstLargeHeapObject);
665 } 670 }
666 671
667 template<typename Header> 672 template<typename Header>
668 void ThreadHeap<Header>::cleanupPages() 673 void ThreadHeap<Header>::cleanupPages()
669 { 674 {
670 clearFreeLists(); 675 clearFreeLists();
(...skipping 27 matching lines...) Expand all
698 return allocateLargeObject(allocationSize, gcInfo); 703 return allocateLargeObject(allocationSize, gcInfo);
699 704
700 updateRemainingAllocationSize(); 705 updateRemainingAllocationSize();
701 if (threadState()->shouldGC()) { 706 if (threadState()->shouldGC()) {
702 if (threadState()->shouldForceConservativeGC()) 707 if (threadState()->shouldForceConservativeGC())
703 Heap::collectGarbage(ThreadState::HeapPointersOnStack); 708 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
704 else 709 else
705 threadState()->setGCRequested(); 710 threadState()->setGCRequested();
706 } 711 }
707 if (remainingAllocationSize() > 0) { 712 if (remainingAllocationSize() > 0) {
708 addToFreeList(currentAllocationPoint(), remainingAllocationSize()); 713 m_freeList.addToFreeList(currentAllocationPoint(), remainingAllocationSi ze());
709 setAllocationPoint(0, 0); 714 setAllocationPoint(0, 0);
710 } 715 }
711 ensureCurrentAllocation(allocationSize, gcInfo); 716 ensureCurrentAllocation(allocationSize, gcInfo);
712 return allocate(size, gcInfo); 717 return allocate(size, gcInfo);
713 } 718 }
714 719
715 template<typename Header> 720 template<typename Header>
716 bool ThreadHeap<Header>::allocateFromFreeList(size_t minSize) 721 bool ThreadHeap<Header>::allocateFromFreeList(size_t minSize)
717 { 722 {
718 size_t bucketSize = 1 << m_biggestFreeListIndex; 723 size_t bucketSize = 1 << m_freeList.m_biggestFreeListIndex;
719 int i = m_biggestFreeListIndex; 724 int i = m_freeList.m_biggestFreeListIndex;
720 for (; i > 0; i--, bucketSize >>= 1) { 725 for (; i > 0; i--, bucketSize >>= 1) {
721 if (bucketSize < minSize) 726 if (bucketSize < minSize)
722 break; 727 break;
723 FreeListEntry* entry = m_freeLists[i]; 728 FreeListEntry* entry = m_freeList.m_freeLists[i];
724 if (entry) { 729 if (entry) {
725 m_biggestFreeListIndex = i; 730 m_freeList.m_biggestFreeListIndex = i;
726 entry->unlink(&m_freeLists[i]); 731 entry->unlink(&m_freeList.m_freeLists[i]);
727 setAllocationPoint(entry->address(), entry->size()); 732 setAllocationPoint(entry->address(), entry->size());
728 ASSERT(currentAllocationPoint() && remainingAllocationSize() >= minS ize); 733 ASSERT(currentAllocationPoint() && remainingAllocationSize() >= minS ize);
729 return true; 734 return true;
730 } 735 }
731 } 736 }
732 m_biggestFreeListIndex = i; 737 m_freeList.m_biggestFreeListIndex = i;
733 return false; 738 return false;
734 } 739 }
735 740
736 template<typename Header> 741 template<typename Header>
737 void ThreadHeap<Header>::ensureCurrentAllocation(size_t minSize, const GCInfo* g cInfo) 742 void ThreadHeap<Header>::ensureCurrentAllocation(size_t minSize, const GCInfo* g cInfo)
738 { 743 {
739 ASSERT(minSize >= allocationGranularity); 744 ASSERT(minSize >= allocationGranularity);
740 if (allocateFromFreeList(minSize)) 745 if (allocateFromFreeList(minSize))
741 return; 746 return;
742 if (coalesce(minSize) && allocateFromFreeList(minSize)) 747 if (coalesce(minSize) && allocateFromFreeList(minSize))
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 current->snapshot(json, info); 811 current->snapshot(json, info);
807 json->endDictionary(); 812 json->endDictionary();
808 } 813 }
809 json->endArray(); 814 json->endArray();
810 815
811 json->setInteger("pageCount", info->pageCount - previousPageCount); 816 json->setInteger("pageCount", info->pageCount - previousPageCount);
812 } 817 }
813 #endif 818 #endif
814 819
815 template<typename Header> 820 template<typename Header>
816 void ThreadHeap<Header>::addToFreeList(Address address, size_t size) 821 void FreeList<Header>::addToFreeList(Address address, size_t size)
817 { 822 {
818 ASSERT(heapPageFromAddress(address));
819 ASSERT(heapPageFromAddress(address + size - 1));
820 ASSERT(size < blinkPagePayloadSize()); 823 ASSERT(size < blinkPagePayloadSize());
821 // The free list entries are only pointer aligned (but when we allocate 824 // The free list entries are only pointer aligned (but when we allocate
822 // from them we are 8 byte aligned due to the header size). 825 // from them we are 8 byte aligned due to the header size).
823 ASSERT(!((reinterpret_cast<uintptr_t>(address) + sizeof(Header)) & allocatio nMask)); 826 ASSERT(!((reinterpret_cast<uintptr_t>(address) + sizeof(Header)) & allocatio nMask));
824 ASSERT(!(size & allocationMask)); 827 ASSERT(!(size & allocationMask));
825 ASAN_POISON_MEMORY_REGION(address, size); 828 ASAN_POISON_MEMORY_REGION(address, size);
826 FreeListEntry* entry; 829 FreeListEntry* entry;
827 if (size < sizeof(*entry)) { 830 if (size < sizeof(*entry)) {
828 // Create a dummy header with only a size and freelist bit set. 831 // Create a dummy header with only a size and freelist bit set.
829 ASSERT(size >= sizeof(BasicObjectHeader)); 832 ASSERT(size >= sizeof(BasicObjectHeader));
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 { 882 {
880 if (m_threadState->isSweepInProgress()) 883 if (m_threadState->isSweepInProgress())
881 return false; 884 return false;
882 885
883 if (m_promptlyFreedCount < 256) 886 if (m_promptlyFreedCount < 256)
884 return false; 887 return false;
885 888
886 // The smallest bucket able to satisfy an allocation request for minSize is 889 // The smallest bucket able to satisfy an allocation request for minSize is
887 // the bucket where all free-list entries are guarantied to be larger than 890 // the bucket where all free-list entries are guarantied to be larger than
888 // minSize. That bucket is one larger than the bucket minSize would go into. 891 // minSize. That bucket is one larger than the bucket minSize would go into.
889 size_t neededBucketIndex = bucketIndexForSize(minSize) + 1; 892 size_t neededBucketIndex = FreeList<Header>::bucketIndexForSize(minSize) + 1 ;
890 size_t neededFreeEntrySize = 1 << neededBucketIndex; 893 size_t neededFreeEntrySize = 1 << neededBucketIndex;
891 size_t neededPromptlyFreedSize = neededFreeEntrySize * 3; 894 size_t neededPromptlyFreedSize = neededFreeEntrySize * 3;
892 size_t foundFreeEntrySize = 0; 895 size_t foundFreeEntrySize = 0;
893 896
894 // Bailout early on large requests because it is unlikely we will find a fre e-list entry. 897 // Bailout early on large requests because it is unlikely we will find a fre e-list entry.
895 if (neededPromptlyFreedSize >= blinkPageSize) 898 if (neededPromptlyFreedSize >= blinkPageSize)
896 return false; 899 return false;
897 900
898 TRACE_EVENT_BEGIN2("blink_gc", "ThreadHeap::coalesce" , "requestedSize", (un signed)minSize , "neededSize", (unsigned)neededFreeEntrySize); 901 TRACE_EVENT_BEGIN2("blink_gc", "ThreadHeap::coalesce" , "requestedSize", (un signed)minSize , "neededSize", (unsigned)neededFreeEntrySize);
899 902
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
1423 } 1426 }
1424 1427
1425 #if ENABLE(ASSERT) 1428 #if ENABLE(ASSERT)
1426 template<typename Header> 1429 template<typename Header>
1427 bool ThreadHeap<Header>::isConsistentForSweeping() 1430 bool ThreadHeap<Header>::isConsistentForSweeping()
1428 { 1431 {
1429 // A thread heap is consistent for sweeping if none of the pages to 1432 // A thread heap is consistent for sweeping if none of the pages to
1430 // be swept contain a freelist block or the current allocation 1433 // be swept contain a freelist block or the current allocation
1431 // point. 1434 // point.
1432 for (size_t i = 0; i < blinkPageSizeLog2; i++) { 1435 for (size_t i = 0; i < blinkPageSizeLog2; i++) {
1433 for (FreeListEntry* freeListEntry = m_freeLists[i]; freeListEntry; freeL istEntry = freeListEntry->next()) { 1436 for (FreeListEntry* freeListEntry = m_freeList.m_freeLists[i]; freeListE ntry; freeListEntry = freeListEntry->next()) {
1434 if (pagesToBeSweptContains(freeListEntry->address())) { 1437 if (pagesToBeSweptContains(freeListEntry->address())) {
1435 return false; 1438 return false;
1436 } 1439 }
1437 ASSERT(pagesAllocatedDuringSweepingContains(freeListEntry->address() )); 1440 ASSERT(pagesAllocatedDuringSweepingContains(freeListEntry->address() ));
1438 } 1441 }
1439 } 1442 }
1440 if (ownsNonEmptyAllocationArea()) { 1443 if (ownsNonEmptyAllocationArea()) {
1441 ASSERT(pagesToBeSweptContains(currentAllocationPoint()) 1444 ASSERT(pagesToBeSweptContains(currentAllocationPoint())
1442 || pagesAllocatedDuringSweepingContains(currentAllocationPoint())); 1445 || pagesAllocatedDuringSweepingContains(currentAllocationPoint()));
1443 return !pagesToBeSweptContains(currentAllocationPoint()); 1446 return !pagesToBeSweptContains(currentAllocationPoint());
(...skipping 22 matching lines...) Expand all
1466 current->unmark(); 1469 current->unmark();
1467 else 1470 else
1468 current->setDeadMark(); 1471 current->setDeadMark();
1469 } 1472 }
1470 } 1473 }
1471 1474
1472 template<typename Header> 1475 template<typename Header>
1473 void ThreadHeap<Header>::clearFreeLists() 1476 void ThreadHeap<Header>::clearFreeLists()
1474 { 1477 {
1475 m_promptlyFreedCount = 0; 1478 m_promptlyFreedCount = 0;
1479 m_freeList.clear();
1480 }
1481
1482 template<typename Header>
1483 void FreeList<Header>::clear()
1484 {
1485 m_biggestFreeListIndex = 0;
1476 for (size_t i = 0; i < blinkPageSizeLog2; i++) { 1486 for (size_t i = 0; i < blinkPageSizeLog2; i++) {
1477 m_freeLists[i] = 0; 1487 m_freeLists[i] = 0;
1478 m_lastFreeListEntries[i] = 0; 1488 m_lastFreeListEntries[i] = 0;
1479 } 1489 }
1480 } 1490 }
1481 1491
1482 int BaseHeap::bucketIndexForSize(size_t size) 1492 template<typename Header>
1493 int FreeList<Header>::bucketIndexForSize(size_t size)
1483 { 1494 {
1484 ASSERT(size > 0); 1495 ASSERT(size > 0);
1485 int index = -1; 1496 int index = -1;
1486 while (size) { 1497 while (size) {
1487 size >>= 1; 1498 size >>= 1;
1488 index++; 1499 index++;
1489 } 1500 }
1490 return index; 1501 return index;
1491 } 1502 }
1492 1503
(...skipping 1243 matching lines...) Expand 10 before | Expand all | Expand 10 after
2736 // nothing on the freelists. 2747 // nothing on the freelists.
2737 ASSERT(splitOff->m_mergePoint || splitOff->m_numberOfNormalPages == 0); 2748 ASSERT(splitOff->m_mergePoint || splitOff->m_numberOfNormalPages == 0);
2738 if (splitOff->m_mergePoint) { 2749 if (splitOff->m_mergePoint) {
2739 // Link the split off pages into the beginning of the list again. 2750 // Link the split off pages into the beginning of the list again.
2740 splitOff->m_mergePoint->m_next = m_firstPage; 2751 splitOff->m_mergePoint->m_next = m_firstPage;
2741 m_firstPage = splitOff->m_firstPage; 2752 m_firstPage = splitOff->m_firstPage;
2742 m_numberOfNormalPages += splitOff->m_numberOfNormalPages; 2753 m_numberOfNormalPages += splitOff->m_numberOfNormalPages;
2743 splitOff->m_firstPage = 0; 2754 splitOff->m_firstPage = 0;
2744 // Merge free lists. 2755 // Merge free lists.
2745 for (size_t i = 0; i < blinkPageSizeLog2; i++) { 2756 for (size_t i = 0; i < blinkPageSizeLog2; i++) {
2746 if (!m_freeLists[i]) { 2757 if (!m_freeList.m_freeLists[i]) {
2747 m_freeLists[i] = splitOff->m_freeLists[i]; 2758 m_freeList.m_freeLists[i] = splitOff->m_freeList.m_freeLists[i];
2748 } else if (splitOff->m_freeLists[i]) { 2759 } else if (splitOff->m_freeList.m_freeLists[i]) {
2749 m_lastFreeListEntries[i]->append(splitOff->m_freeLists[i]); 2760 m_freeList.m_lastFreeListEntries[i]->append(splitOff->m_freeList .m_freeLists[i]);
2750 m_lastFreeListEntries[i] = splitOff->m_lastFreeListEntries[i]; 2761 m_freeList.m_lastFreeListEntries[i] = splitOff->m_freeList.m_las tFreeListEntries[i];
2751 } 2762 }
2752 } 2763 }
2753 } 2764 }
2754 } 2765 }
2755 2766
2756 void Heap::getHeapSpaceSize(uint64_t* objectSpaceSize, uint64_t* allocatedSpaceS ize) 2767 void Heap::getHeapSpaceSize(uint64_t* objectSpaceSize, uint64_t* allocatedSpaceS ize)
2757 { 2768 {
2758 *objectSpaceSize = 0; 2769 *objectSpaceSize = 0;
2759 *allocatedSpaceSize = 0; 2770 *allocatedSpaceSize = 0;
2760 ASSERT(ThreadState::isAnyThreadInGC()); 2771 ASSERT(ThreadState::isAnyThreadInGC());
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
2944 CallbackStack* Heap::s_weakCallbackStack; 2955 CallbackStack* Heap::s_weakCallbackStack;
2945 CallbackStack* Heap::s_ephemeronStack; 2956 CallbackStack* Heap::s_ephemeronStack;
2946 HeapDoesNotContainCache* Heap::s_heapDoesNotContainCache; 2957 HeapDoesNotContainCache* Heap::s_heapDoesNotContainCache;
2947 bool Heap::s_shutdownCalled = false; 2958 bool Heap::s_shutdownCalled = false;
2948 bool Heap::s_lastGCWasConservative = false; 2959 bool Heap::s_lastGCWasConservative = false;
2949 FreePagePool* Heap::s_freePagePool; 2960 FreePagePool* Heap::s_freePagePool;
2950 OrphanedPagePool* Heap::s_orphanedPagePool; 2961 OrphanedPagePool* Heap::s_orphanedPagePool;
2951 Heap::RegionTree* Heap::s_regionTree = 0; 2962 Heap::RegionTree* Heap::s_regionTree = 0;
2952 2963
2953 } 2964 }
OLDNEW
« no previous file with comments | « Source/platform/heap/Heap.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698