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

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

Issue 1157933002: Oilpan: introduce eager finalization. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: remove HeapIndexTrait + tidy up Created 5 years, 6 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 | Annotate | Revision Log
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 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 m_firstUnsweptPage = m_firstPage; 327 m_firstUnsweptPage = m_firstPage;
328 m_firstPage = nullptr; 328 m_firstPage = nullptr;
329 } 329 }
330 330
331 #if defined(ADDRESS_SANITIZER) 331 #if defined(ADDRESS_SANITIZER)
332 void BaseHeap::poisonUnmarkedObjects() 332 void BaseHeap::poisonUnmarkedObjects()
333 { 333 {
334 // This method is called just before starting sweeping. 334 // This method is called just before starting sweeping.
335 // Thus all dead objects are in the list of m_firstUnsweptPage. 335 // Thus all dead objects are in the list of m_firstUnsweptPage.
336 for (BasePage* page = m_firstUnsweptPage; page; page = page->next()) { 336 for (BasePage* page = m_firstUnsweptPage; page; page = page->next()) {
337 page->poisonUnmarkedObjects(); 337 page->poisonObjects(BasePage::UnmarkedOnly, BasePage::SetPoison);
338 }
339 }
340
341 void BaseHeap::poisonHeap(bool setPoison)
haraken 2015/05/28 12:30:04 poisonHeap => poisonEagerHeap I'd use SetPoison/C
sof 2015/05/29 21:25:07 Moved enums around to make that possible. Keeping
342 {
343 ASSERT(heapIndex() == EagerSweepHeapIndex);
344 // This method is called just before starting sweeping
345 // of eager heaps. Hence, all objects will be in
346 // m_firstUnsweptPage before start.
347 if (setPoison) {
348 for (BasePage* page = m_firstUnsweptPage; page; page = page->next()) {
haraken 2015/05/28 12:30:04 Add ASSERT(!m_firstPage).
sof 2015/05/29 21:25:07 Done.
349 page->poisonObjects(BasePage::UnmarkedOrMarked, BasePage::SetPoison) ;
haraken 2015/05/28 12:30:04 Why do we need to poison marked objects? I'm ok wi
sof 2015/05/29 21:25:07 You're not allowed to touch other eagerly finalize
350 }
351 return;
352 }
353 for (BasePage* page = m_firstPage; page; page = page->next()) {
354 page->poisonObjects(BasePage::UnmarkedOnly, BasePage::ClearPoison);
haraken 2015/05/28 12:30:04 Who unpoisons the marked objects that have been po
sof 2015/05/29 21:25:07 This very loop when poisonHeap() is called on the
338 } 355 }
339 } 356 }
340 #endif 357 #endif
341 358
342 Address BaseHeap::lazySweep(size_t allocationSize, size_t gcInfoIndex) 359 Address BaseHeap::lazySweep(size_t allocationSize, size_t gcInfoIndex)
343 { 360 {
344 // If there are no pages to be swept, return immediately. 361 // If there are no pages to be swept, return immediately.
345 if (!m_firstUnsweptPage) 362 if (!m_firstUnsweptPage)
346 return nullptr; 363 return nullptr;
347 364
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 { 779 {
763 ASSERT(allocationSize > remainingAllocationSize()); 780 ASSERT(allocationSize > remainingAllocationSize());
764 ASSERT(allocationSize >= allocationGranularity); 781 ASSERT(allocationSize >= allocationGranularity);
765 782
766 #if ENABLE(GC_PROFILING) 783 #if ENABLE(GC_PROFILING)
767 threadState()->snapshotFreeListIfNecessary(); 784 threadState()->snapshotFreeListIfNecessary();
768 #endif 785 #endif
769 786
770 // 1. If this allocation is big enough, allocate a large object. 787 // 1. If this allocation is big enough, allocate a large object.
771 if (allocationSize >= largeObjectSizeThreshold) { 788 if (allocationSize >= largeObjectSizeThreshold) {
789 // TODO(sof): support eagerly finalized large objects, if ever needed.
790 ASSERT(heapIndex() != EagerSweepHeapIndex);
772 LargeObjectHeap* largeObjectHeap = static_cast<LargeObjectHeap*>(threadS tate()->heap(LargeObjectHeapIndex)); 791 LargeObjectHeap* largeObjectHeap = static_cast<LargeObjectHeap*>(threadS tate()->heap(LargeObjectHeapIndex));
773 Address largeObject = largeObjectHeap->allocateLargeObjectPage(allocatio nSize, gcInfoIndex); 792 Address largeObject = largeObjectHeap->allocateLargeObjectPage(allocatio nSize, gcInfoIndex);
774 ASAN_MARK_LARGE_VECTOR_CONTAINER(this, largeObject); 793 ASAN_MARK_LARGE_VECTOR_CONTAINER(this, largeObject);
775 return largeObject; 794 return largeObject;
776 } 795 }
777 796
778 // 2. Check if we should trigger a GC. 797 // 2. Check if we should trigger a GC.
779 updateRemainingAllocationSize(); 798 updateRemainingAllocationSize();
780 threadState()->scheduleGCIfNeeded(); 799 threadState()->scheduleGCIfNeeded();
781 800
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 // touches any other on-heap object that die at the same GC cycle. 1151 // touches any other on-heap object that die at the same GC cycle.
1133 ASAN_UNPOISON_MEMORY_REGION(payload, payloadSize); 1152 ASAN_UNPOISON_MEMORY_REGION(payload, payloadSize);
1134 header->finalize(payload, payloadSize); 1153 header->finalize(payload, payloadSize);
1135 // This memory will be added to the freelist. Maintain the invariant 1154 // This memory will be added to the freelist. Maintain the invariant
1136 // that memory on the freelist is zero filled. 1155 // that memory on the freelist is zero filled.
1137 FILL_ZERO_IF_PRODUCTION(headerAddress, size); 1156 FILL_ZERO_IF_PRODUCTION(headerAddress, size);
1138 ASAN_POISON_MEMORY_REGION(payload, payloadSize); 1157 ASAN_POISON_MEMORY_REGION(payload, payloadSize);
1139 headerAddress += size; 1158 headerAddress += size;
1140 continue; 1159 continue;
1141 } 1160 }
1142
1143 if (startOfGap != headerAddress) 1161 if (startOfGap != headerAddress)
1144 heapForNormalPage()->addToFreeList(startOfGap, headerAddress - start OfGap); 1162 heapForNormalPage()->addToFreeList(startOfGap, headerAddress - start OfGap);
1145 header->unmark(); 1163 header->unmark();
1146 headerAddress += header->size(); 1164 headerAddress += header->size();
1147 markedObjectSize += header->size(); 1165 markedObjectSize += header->size();
1148 startOfGap = headerAddress; 1166 startOfGap = headerAddress;
1149 } 1167 }
1150 if (startOfGap != payloadEnd()) 1168 if (startOfGap != payloadEnd())
1151 heapForNormalPage()->addToFreeList(startOfGap, payloadEnd() - startOfGap ); 1169 heapForNormalPage()->addToFreeList(startOfGap, payloadEnd() - startOfGap );
1152 1170
(...skipping 20 matching lines...) Expand all
1173 } else { 1191 } else {
1174 header->markDead(); 1192 header->markDead();
1175 } 1193 }
1176 headerAddress += header->size(); 1194 headerAddress += header->size();
1177 } 1195 }
1178 if (markedObjectSize) 1196 if (markedObjectSize)
1179 Heap::increaseMarkedObjectSize(markedObjectSize); 1197 Heap::increaseMarkedObjectSize(markedObjectSize);
1180 } 1198 }
1181 1199
1182 #if defined(ADDRESS_SANITIZER) 1200 #if defined(ADDRESS_SANITIZER)
1183 void NormalPage::poisonUnmarkedObjects() 1201 void NormalPage::poisonObjects(ObjectsToPoison objectsToPoison, Poisoning poison ing)
1184 { 1202 {
1185 for (Address headerAddress = payload(); headerAddress < payloadEnd();) { 1203 for (Address headerAddress = payload(); headerAddress < payloadEnd();) {
1186 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress); 1204 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress);
1187 ASSERT(header->size() < blinkPagePayloadSize()); 1205 ASSERT(header->size() < blinkPagePayloadSize());
1188 // Check if a free list entry first since we cannot call 1206 // Check if a free list entry first since we cannot call
1189 // isMarked on a free list entry. 1207 // isMarked on a free list entry.
1190 if (header->isFree()) { 1208 if (header->isFree()) {
1191 headerAddress += header->size(); 1209 headerAddress += header->size();
1192 continue; 1210 continue;
1193 } 1211 }
1194 header->checkHeader(); 1212 header->checkHeader();
1195 if (!header->isMarked()) { 1213 if (objectsToPoison == UnmarkedOrMarked || !header->isMarked()) {
1196 ASAN_POISON_MEMORY_REGION(header->payload(), header->payloadSize()); 1214 if (poisoning == SetPoison)
1215 ASAN_POISON_MEMORY_REGION(header->payload(), header->payloadSize ());
1216 else
1217 ASAN_UNPOISON_MEMORY_REGION(header->payload(), header->payloadSi ze());
1197 } 1218 }
1198 headerAddress += header->size(); 1219 headerAddress += header->size();
1199 } 1220 }
1200 } 1221 }
1201 #endif 1222 #endif
1202 1223
1203 void NormalPage::populateObjectStartBitMap() 1224 void NormalPage::populateObjectStartBitMap()
1204 { 1225 {
1205 memset(&m_objectStartBitMap, 0, objectStartBitMapSize); 1226 memset(&m_objectStartBitMap, 0, objectStartBitMapSize);
1206 Address start = payload(); 1227 Address start = payload();
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
1462 HeapObjectHeader* header = heapObjectHeader(); 1483 HeapObjectHeader* header = heapObjectHeader();
1463 if (header->isMarked()) { 1484 if (header->isMarked()) {
1464 header->unmark(); 1485 header->unmark();
1465 Heap::increaseMarkedObjectSize(size()); 1486 Heap::increaseMarkedObjectSize(size());
1466 } else { 1487 } else {
1467 header->markDead(); 1488 header->markDead();
1468 } 1489 }
1469 } 1490 }
1470 1491
1471 #if defined(ADDRESS_SANITIZER) 1492 #if defined(ADDRESS_SANITIZER)
1472 void LargeObjectPage::poisonUnmarkedObjects() 1493 void LargeObjectPage::poisonObjects(ObjectsToPoison objectsToPoison, Poisoning p oisoning)
1473 { 1494 {
1474 HeapObjectHeader* header = heapObjectHeader(); 1495 HeapObjectHeader* header = heapObjectHeader();
1475 if (!header->isMarked()) 1496 if (objectsToPoison == UnmarkedOrMarked || !header->isMarked()) {
1476 ASAN_POISON_MEMORY_REGION(header->payload(), header->payloadSize()); 1497 if (poisoning == BasePage::SetPoison)
1498 ASAN_POISON_MEMORY_REGION(header->payload(), header->payloadSize());
1499 else
1500 ASAN_UNPOISON_MEMORY_REGION(header->payload(), header->payloadSize() );
1501 }
1477 } 1502 }
1478 #endif 1503 #endif
1479 1504
1480 void LargeObjectPage::checkAndMarkPointer(Visitor* visitor, Address address) 1505 void LargeObjectPage::checkAndMarkPointer(Visitor* visitor, Address address)
1481 { 1506 {
1482 ASSERT(contains(address)); 1507 ASSERT(contains(address));
1483 if (!containedInObjectPayload(address) || heapObjectHeader()->isDead()) 1508 if (!containedInObjectPayload(address) || heapObjectHeader()->isDead())
1484 return; 1509 return;
1485 #if ENABLE(GC_PROFILING) 1510 #if ENABLE(GC_PROFILING)
1486 visitor->setHostInfo(&address, "stack"); 1511 visitor->setHostInfo(&address, "stack");
(...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after
2223 size_t Heap::s_allocatedObjectSize = 0; 2248 size_t Heap::s_allocatedObjectSize = 0;
2224 size_t Heap::s_allocatedSpace = 0; 2249 size_t Heap::s_allocatedSpace = 0;
2225 size_t Heap::s_markedObjectSize = 0; 2250 size_t Heap::s_markedObjectSize = 0;
2226 // We don't want to use 0 KB for the initial value because it may end up 2251 // We don't want to use 0 KB for the initial value because it may end up
2227 // triggering the first GC of some thread too prematurely. 2252 // triggering the first GC of some thread too prematurely.
2228 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; 2253 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024;
2229 size_t Heap::s_externalObjectSizeAtLastGC = 0; 2254 size_t Heap::s_externalObjectSizeAtLastGC = 0;
2230 double Heap::s_estimatedMarkingTimePerByte = 0.0; 2255 double Heap::s_estimatedMarkingTimePerByte = 0.0;
2231 2256
2232 } // namespace blink 2257 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698