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

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

Issue 850063002: Do not fire timers for finalizing objects. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Reset sweep status on pages before sweeping instead Created 5 years, 11 months 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
« Source/platform/heap/Heap.h ('K') | « 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 525 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 { 536 {
537 HeapObjectHeader* header = heapObjectHeader(); 537 HeapObjectHeader* header = heapObjectHeader();
538 if (header->isMarked()) 538 if (header->isMarked())
539 header->unmark(); 539 header->unmark();
540 else 540 else
541 header->markDead(); 541 header->markDead();
542 } 542 }
543 543
544 void LargeObject::removeFromHeap(ThreadHeap* heap) 544 void LargeObject::removeFromHeap(ThreadHeap* heap)
545 { 545 {
546 markAsUnswept();
haraken 2015/01/16 17:29:49 Isn't it guaranteed that the page is already marke
sof 2015/01/16 19:30:17 Removed.
546 heap->freeLargeObject(this); 547 heap->freeLargeObject(this);
547 } 548 }
548 549
549 ThreadHeap::ThreadHeap(ThreadState* state, int index) 550 ThreadHeap::ThreadHeap(ThreadState* state, int index)
550 : m_currentAllocationPoint(nullptr) 551 : m_currentAllocationPoint(nullptr)
551 , m_remainingAllocationSize(0) 552 , m_remainingAllocationSize(0)
552 , m_lastRemainingAllocationSize(0) 553 , m_lastRemainingAllocationSize(0)
553 , m_firstPage(nullptr) 554 , m_firstPage(nullptr)
554 , m_firstLargeObject(nullptr) 555 , m_firstLargeObject(nullptr)
555 , m_firstUnsweptPage(nullptr) 556 , m_firstUnsweptPage(nullptr)
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 HeapPage* page = m_firstUnsweptPage; 741 HeapPage* page = m_firstUnsweptPage;
741 if (page->isEmpty()) { 742 if (page->isEmpty()) {
742 page->unlink(&m_firstUnsweptPage); 743 page->unlink(&m_firstUnsweptPage);
743 page->removeFromHeap(this); 744 page->removeFromHeap(this);
744 } else { 745 } else {
745 // Sweep a page and move the page from m_firstUnsweptPages to 746 // Sweep a page and move the page from m_firstUnsweptPages to
746 // m_firstPages. 747 // m_firstPages.
747 page->sweep(); 748 page->sweep();
748 page->unlink(&m_firstUnsweptPage); 749 page->unlink(&m_firstUnsweptPage);
749 page->link(&m_firstPage); 750 page->link(&m_firstPage);
751 page->markAsSwept();
750 752
751 result = allocateFromFreeList(allocationSize, gcInfoIndex); 753 result = allocateFromFreeList(allocationSize, gcInfoIndex);
752 if (result) { 754 if (result)
753 break; 755 break;
754 }
755 } 756 }
756 } 757 }
757 758
758 if (threadState()->isMainThread()) 759 if (threadState()->isMainThread())
759 ScriptForbiddenScope::exit(); 760 ScriptForbiddenScope::exit();
760 return result; 761 return result;
761 } 762 }
762 763
763 bool ThreadHeap::lazySweepLargeObjects(size_t allocationSize) 764 bool ThreadHeap::lazySweepLargeObjects(size_t allocationSize)
764 { 765 {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 if (sweptSize >= allocationSize) { 798 if (sweptSize >= allocationSize) {
798 result = true; 799 result = true;
799 break; 800 break;
800 } 801 }
801 } else { 802 } else {
802 // Sweep a large object and move the large object from 803 // Sweep a large object and move the large object from
803 // m_firstUnsweptLargeObjects to m_firstLargeObjects. 804 // m_firstUnsweptLargeObjects to m_firstLargeObjects.
804 largeObject->sweep(); 805 largeObject->sweep();
805 largeObject->unlink(&m_firstUnsweptLargeObject); 806 largeObject->unlink(&m_firstUnsweptLargeObject);
806 largeObject->link(&m_firstLargeObject); 807 largeObject->link(&m_firstLargeObject);
808 largeObject->markAsSwept();
807 } 809 }
808 } 810 }
809 811
810 if (threadState()->isMainThread()) 812 if (threadState()->isMainThread())
811 ScriptForbiddenScope::exit(); 813 ScriptForbiddenScope::exit();
812 return result; 814 return result;
813 } 815 }
814 816
815 void ThreadHeap::completeSweep() 817 void ThreadHeap::completeSweep()
816 { 818 {
817 RELEASE_ASSERT(threadState()->isSweepingInProgress()); 819 RELEASE_ASSERT(threadState()->isSweepingInProgress());
818 ASSERT(threadState()->sweepForbidden()); 820 ASSERT(threadState()->sweepForbidden());
819 821
820 if (threadState()->isMainThread()) 822 if (threadState()->isMainThread())
821 ScriptForbiddenScope::enter(); 823 ScriptForbiddenScope::enter();
822 824
823 // Sweep normal pages. 825 // Sweep normal pages.
824 while (m_firstUnsweptPage) { 826 while (m_firstUnsweptPage) {
825 HeapPage* page = m_firstUnsweptPage; 827 HeapPage* page = m_firstUnsweptPage;
826 if (page->isEmpty()) { 828 if (page->isEmpty()) {
827 page->unlink(&m_firstUnsweptPage); 829 page->unlink(&m_firstUnsweptPage);
828 page->removeFromHeap(this); 830 page->removeFromHeap(this);
829 } else { 831 } else {
830 // Sweep a page and move the page from m_firstUnsweptPages to 832 // Sweep a page and move the page from m_firstUnsweptPages to
831 // m_firstPages. 833 // m_firstPages.
832 page->sweep(); 834 page->sweep();
833 page->unlink(&m_firstUnsweptPage); 835 page->unlink(&m_firstUnsweptPage);
834 page->link(&m_firstPage); 836 page->link(&m_firstPage);
837 page->markAsSwept();
835 } 838 }
836 } 839 }
837 840
838 // Sweep large objects. 841 // Sweep large objects.
839 while (m_firstUnsweptLargeObject) { 842 while (m_firstUnsweptLargeObject) {
840 LargeObject* largeObject = m_firstUnsweptLargeObject; 843 LargeObject* largeObject = m_firstUnsweptLargeObject;
841 if (largeObject->isEmpty()) { 844 if (largeObject->isEmpty()) {
842 largeObject->unlink(&m_firstUnsweptLargeObject); 845 largeObject->unlink(&m_firstUnsweptLargeObject);
843 largeObject->removeFromHeap(this); 846 largeObject->removeFromHeap(this);
844 } else { 847 } else {
845 // Sweep a large object and move the large object from 848 // Sweep a large object and move the large object from
846 // m_firstUnsweptLargeObjects to m_firstLargeObjects. 849 // m_firstUnsweptLargeObjects to m_firstLargeObjects.
847 largeObject->sweep(); 850 largeObject->sweep();
848 largeObject->unlink(&m_firstUnsweptLargeObject); 851 largeObject->unlink(&m_firstUnsweptLargeObject);
849 largeObject->link(&m_firstLargeObject); 852 largeObject->link(&m_firstLargeObject);
853 largeObject->markAsSwept();
850 } 854 }
851 } 855 }
852 856
853 if (threadState()->isMainThread()) 857 if (threadState()->isMainThread())
854 ScriptForbiddenScope::exit(); 858 ScriptForbiddenScope::exit();
855 } 859 }
856 860
857 #if ENABLE(ASSERT) 861 #if ENABLE(ASSERT)
858 static bool isLargeObjectAligned(LargeObject* largeObject, Address address) 862 static bool isLargeObjectAligned(LargeObject* largeObject, Address address)
859 { 863 {
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 Address result = headerAddress + sizeof(*header); 1143 Address result = headerAddress + sizeof(*header);
1140 ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask)); 1144 ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask));
1141 LargeObject* largeObject = new (largeObjectAddress) LargeObject(pageMemory, this, size); 1145 LargeObject* largeObject = new (largeObjectAddress) LargeObject(pageMemory, this, size);
1142 header->checkHeader(); 1146 header->checkHeader();
1143 1147
1144 // Poison the object header and allocationGranularity bytes after the object 1148 // Poison the object header and allocationGranularity bytes after the object
1145 ASAN_POISON_MEMORY_REGION(header, sizeof(*header)); 1149 ASAN_POISON_MEMORY_REGION(header, sizeof(*header));
1146 ASAN_POISON_MEMORY_REGION(largeObject->address() + largeObject->size(), allo cationGranularity); 1150 ASAN_POISON_MEMORY_REGION(largeObject->address() + largeObject->size(), allo cationGranularity);
1147 1151
1148 largeObject->link(&m_firstLargeObject); 1152 largeObject->link(&m_firstLargeObject);
1153 if (threadState()->isSweepingInProgress())
1154 largeObject->markAsSwept();
haraken 2015/01/16 17:29:49 It's a bit inconsistent that a page allocated duri
sof 2015/01/16 19:30:17 We can flip defaults that way.
1149 1155
1150 Heap::increaseAllocatedSpace(largeObject->size()); 1156 Heap::increaseAllocatedSpace(largeObject->size());
1151 Heap::increaseAllocatedObjectSize(largeObject->size()); 1157 Heap::increaseAllocatedObjectSize(largeObject->size());
1152 return result; 1158 return result;
1153 } 1159 }
1154 1160
1155 void ThreadHeap::freeLargeObject(LargeObject* object) 1161 void ThreadHeap::freeLargeObject(LargeObject* object)
1156 { 1162 {
1157 object->heapObjectHeader()->finalize(object->payload(), object->payloadSize( )); 1163 object->heapObjectHeader()->finalize(object->payload(), object->payloadSize( ));
1158 Heap::decreaseAllocatedSpace(object->size()); 1164 Heap::decreaseAllocatedSpace(object->size());
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 // We got some memory, but failed to commit it, try again. 1233 // We got some memory, but failed to commit it, try again.
1228 delete memory; 1234 delete memory;
1229 } 1235 }
1230 return nullptr; 1236 return nullptr;
1231 } 1237 }
1232 1238
1233 BaseHeapPage::BaseHeapPage(PageMemory* storage, ThreadHeap* heap) 1239 BaseHeapPage::BaseHeapPage(PageMemory* storage, ThreadHeap* heap)
1234 : m_storage(storage) 1240 : m_storage(storage)
1235 , m_heap(heap) 1241 , m_heap(heap)
1236 , m_terminating(false) 1242 , m_terminating(false)
1243 , m_swept(false)
haraken 2015/01/16 17:29:49 As commented above, m_swept(true) will make the co
sof 2015/01/16 19:30:17 Done.
1237 { 1244 {
1238 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this))); 1245 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this)));
1239 } 1246 }
1240 1247
1241 void BaseHeapPage::markOrphaned() 1248 void BaseHeapPage::markOrphaned()
1242 { 1249 {
1243 m_heap = nullptr; 1250 m_heap = nullptr;
1244 m_terminating = false; 1251 m_terminating = false;
1245 // Since we zap the page payload for orphaned pages we need to mark it as 1252 // Since we zap the page payload for orphaned pages we need to mark it as
1246 // unused so a conservative pointer won't interpret the object headers. 1253 // unused so a conservative pointer won't interpret the object headers.
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1385 delete memory; 1392 delete memory;
1386 } else { 1393 } else {
1387 Heap::freePagePool()->addFreePage(m_index, memory); 1394 Heap::freePagePool()->addFreePage(m_index, memory);
1388 } 1395 }
1389 offset += blinkPageSize; 1396 offset += blinkPageSize;
1390 } 1397 }
1391 } 1398 }
1392 HeapPage* page = new (pageMemory->writableStart()) HeapPage(pageMemory, this ); 1399 HeapPage* page = new (pageMemory->writableStart()) HeapPage(pageMemory, this );
1393 1400
1394 page->link(&m_firstPage); 1401 page->link(&m_firstPage);
1402 if (threadState()->isSweepingInProgress())
1403 page->markAsSwept();
haraken 2015/01/16 17:29:49 Ditto. I think we can remove this code.
sof 2015/01/16 19:30:17 Done.
1395 1404
1396 Heap::increaseAllocatedSpace(blinkPageSize); 1405 Heap::increaseAllocatedSpace(blinkPageSize);
1397 addToFreeList(page->payload(), page->payloadSize()); 1406 addToFreeList(page->payload(), page->payloadSize());
1398 } 1407 }
1399 1408
1400 #if ENABLE(ASSERT) 1409 #if ENABLE(ASSERT)
1401 bool ThreadHeap::pagesToBeSweptContains(Address address) 1410 bool ThreadHeap::pagesToBeSweptContains(Address address)
1402 { 1411 {
1403 for (HeapPage* page = m_firstUnsweptPage; page; page = page->next()) { 1412 for (HeapPage* page = m_firstUnsweptPage; page; page = page->next()) {
1404 if (page->contains(address)) 1413 if (page->contains(address))
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1436 if (hasCurrentAllocationArea()) { 1445 if (hasCurrentAllocationArea()) {
1437 if (pagesToBeSweptContains(currentAllocationPoint())) 1446 if (pagesToBeSweptContains(currentAllocationPoint()))
1438 return false; 1447 return false;
1439 } 1448 }
1440 return true; 1449 return true;
1441 } 1450 }
1442 #endif 1451 #endif
1443 1452
1444 void ThreadHeap::makeConsistentForSweeping() 1453 void ThreadHeap::makeConsistentForSweeping()
1445 { 1454 {
1446 markUnmarkedObjectsDead(); 1455 preparePagesForSweeping();
1447 setAllocationPoint(nullptr, 0); 1456 setAllocationPoint(nullptr, 0);
1448 clearFreeLists(); 1457 clearFreeLists();
1449 } 1458 }
1450 1459
1451 void ThreadHeap::markUnmarkedObjectsDead() 1460 void ThreadHeap::preparePagesForSweeping()
1452 { 1461 {
1453 ASSERT(isConsistentForSweeping()); 1462 ASSERT(isConsistentForSweeping());
1463 for (HeapPage* page = m_firstPage; page; page = page->next())
haraken 2015/01/16 17:29:49 You can move this loop to after line 1484.
sof 2015/01/16 19:30:17 It's preferable to have this loop here & over thes
1464 page->markAsUnswept();
1465
1454 // If a new GC is requested before this thread got around to sweep, 1466 // If a new GC is requested before this thread got around to sweep,
1455 // ie. due to the thread doing a long running operation, we clear 1467 // ie. due to the thread doing a long running operation, we clear
1456 // the mark bits and mark any of the dead objects as dead. The latter 1468 // the mark bits and mark any of the dead objects as dead. The latter
1457 // is used to ensure the next GC marking does not trace already dead 1469 // is used to ensure the next GC marking does not trace already dead
1458 // objects. If we trace a dead object we could end up tracing into 1470 // objects. If we trace a dead object we could end up tracing into
1459 // garbage or the middle of another object via the newly conservatively 1471 // garbage or the middle of another object via the newly conservatively
1460 // found object. 1472 // found object.
1461 HeapPage* previousPage = nullptr; 1473 HeapPage* previousPage = nullptr;
1462 for (HeapPage* page = m_firstUnsweptPage; page; previousPage = page, page = page->next()) { 1474 for (HeapPage* page = m_firstUnsweptPage; page; previousPage = page, page = page->next()) {
1463 page->markUnmarkedObjectsDead(); 1475 page->markUnmarkedObjectsDead();
1476 page->markAsUnswept();
haraken 2015/01/16 17:29:49 Then you won't need this.
1464 } 1477 }
1465 if (previousPage) { 1478 if (previousPage) {
1466 ASSERT(m_firstUnsweptPage); 1479 ASSERT(m_firstUnsweptPage);
1467 previousPage->m_next = m_firstPage; 1480 previousPage->m_next = m_firstPage;
1468 m_firstPage = m_firstUnsweptPage; 1481 m_firstPage = m_firstUnsweptPage;
1469 m_firstUnsweptPage = nullptr; 1482 m_firstUnsweptPage = nullptr;
1470 } 1483 }
1471 ASSERT(!m_firstUnsweptPage); 1484 ASSERT(!m_firstUnsweptPage);
1472 1485
1486 for (LargeObject* largeObject = m_firstLargeObject; largeObject; largeObject = largeObject->next())
haraken 2015/01/16 17:29:49 Ditto.
sof 2015/01/16 19:30:17 See above.
1487 largeObject->markAsUnswept();
1488
1473 LargeObject* previousLargeObject = nullptr; 1489 LargeObject* previousLargeObject = nullptr;
1474 for (LargeObject* largeObject = m_firstUnsweptLargeObject; largeObject; prev iousLargeObject = largeObject, largeObject = largeObject->next()) { 1490 for (LargeObject* largeObject = m_firstUnsweptLargeObject; largeObject; prev iousLargeObject = largeObject, largeObject = largeObject->next()) {
1475 largeObject->markUnmarkedObjectsDead(); 1491 largeObject->markUnmarkedObjectsDead();
1492 largeObject->markAsUnswept();
1476 } 1493 }
1477 if (previousLargeObject) { 1494 if (previousLargeObject) {
1478 ASSERT(m_firstUnsweptLargeObject); 1495 ASSERT(m_firstUnsweptLargeObject);
1479 previousLargeObject->m_next = m_firstLargeObject; 1496 previousLargeObject->m_next = m_firstLargeObject;
1480 m_firstLargeObject = m_firstUnsweptLargeObject; 1497 m_firstLargeObject = m_firstUnsweptLargeObject;
1481 m_firstUnsweptLargeObject = nullptr; 1498 m_firstUnsweptLargeObject = nullptr;
1482 } 1499 }
1483 ASSERT(!m_firstUnsweptLargeObject); 1500 ASSERT(!m_firstUnsweptLargeObject);
1484 } 1501 }
1485 1502
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1611 if (header->isMarked()) 1628 if (header->isMarked())
1612 header->unmark(); 1629 header->unmark();
1613 else 1630 else
1614 header->markDead(); 1631 header->markDead();
1615 headerAddress += header->size(); 1632 headerAddress += header->size();
1616 } 1633 }
1617 } 1634 }
1618 1635
1619 void HeapPage::removeFromHeap(ThreadHeap* heap) 1636 void HeapPage::removeFromHeap(ThreadHeap* heap)
1620 { 1637 {
1638 markAsUnswept();
haraken 2015/01/16 17:29:49 I think the page is already marked as unswept. ASS
sof 2015/01/16 19:30:17 Removed.
1621 heap->freePage(this); 1639 heap->freePage(this);
1622 } 1640 }
1623 1641
1624 void HeapPage::populateObjectStartBitMap() 1642 void HeapPage::populateObjectStartBitMap()
1625 { 1643 {
1626 memset(&m_objectStartBitMap, 0, objectStartBitMapSize); 1644 memset(&m_objectStartBitMap, 0, objectStartBitMapSize);
1627 Address start = payload(); 1645 Address start = payload();
1628 for (Address headerAddress = start; headerAddress < payloadEnd();) { 1646 for (Address headerAddress = start; headerAddress < payloadEnd();) {
1629 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress); 1647 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress);
1630 size_t objectOffset = headerAddress - start; 1648 size_t objectOffset = headerAddress - start;
(...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after
2694 bool Heap::s_shutdownCalled = false; 2712 bool Heap::s_shutdownCalled = false;
2695 bool Heap::s_lastGCWasConservative = false; 2713 bool Heap::s_lastGCWasConservative = false;
2696 FreePagePool* Heap::s_freePagePool; 2714 FreePagePool* Heap::s_freePagePool;
2697 OrphanedPagePool* Heap::s_orphanedPagePool; 2715 OrphanedPagePool* Heap::s_orphanedPagePool;
2698 Heap::RegionTree* Heap::s_regionTree = nullptr; 2716 Heap::RegionTree* Heap::s_regionTree = nullptr;
2699 size_t Heap::s_allocatedObjectSize = 0; 2717 size_t Heap::s_allocatedObjectSize = 0;
2700 size_t Heap::s_allocatedSpace = 0; 2718 size_t Heap::s_allocatedSpace = 0;
2701 size_t Heap::s_markedObjectSize = 0; 2719 size_t Heap::s_markedObjectSize = 0;
2702 2720
2703 } // namespace blink 2721 } // namespace blink
OLDNEW
« Source/platform/heap/Heap.h ('K') | « Source/platform/heap/Heap.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698