| OLD | NEW |
| 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 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 } | 292 } |
| 293 if (previousPage) { | 293 if (previousPage) { |
| 294 ASSERT(m_firstUnsweptPage); | 294 ASSERT(m_firstUnsweptPage); |
| 295 previousPage->m_next = m_firstPage; | 295 previousPage->m_next = m_firstPage; |
| 296 m_firstPage = m_firstUnsweptPage; | 296 m_firstPage = m_firstUnsweptPage; |
| 297 m_firstUnsweptPage = nullptr; | 297 m_firstUnsweptPage = nullptr; |
| 298 } | 298 } |
| 299 ASSERT(!m_firstUnsweptPage); | 299 ASSERT(!m_firstUnsweptPage); |
| 300 } | 300 } |
| 301 | 301 |
| 302 void BaseHeap::makeConsistentForMutator() | |
| 303 { | |
| 304 clearFreeLists(); | |
| 305 ASSERT(isConsistentForGC()); | |
| 306 ASSERT(!m_firstPage); | |
| 307 | |
| 308 // Drop marks from marked objects and rebuild free lists in preparation for | |
| 309 // resuming the executions of mutators. | |
| 310 BasePage* previousPage = nullptr; | |
| 311 for (BasePage* page = m_firstUnsweptPage; page; previousPage = page, page =
page->next()) { | |
| 312 page->makeConsistentForMutator(); | |
| 313 page->markAsSwept(); | |
| 314 } | |
| 315 if (previousPage) { | |
| 316 ASSERT(m_firstUnsweptPage); | |
| 317 previousPage->m_next = m_firstPage; | |
| 318 m_firstPage = m_firstUnsweptPage; | |
| 319 m_firstUnsweptPage = nullptr; | |
| 320 } | |
| 321 ASSERT(!m_firstUnsweptPage); | |
| 322 } | |
| 323 | |
| 324 size_t BaseHeap::objectPayloadSizeForTesting() | 302 size_t BaseHeap::objectPayloadSizeForTesting() |
| 325 { | 303 { |
| 326 ASSERT(isConsistentForGC()); | 304 ASSERT(isConsistentForGC()); |
| 327 ASSERT(!m_firstUnsweptPage); | 305 ASSERT(!m_firstUnsweptPage); |
| 328 | 306 |
| 329 size_t objectPayloadSize = 0; | 307 size_t objectPayloadSize = 0; |
| 330 for (BasePage* page = m_firstPage; page; page = page->next()) | 308 for (BasePage* page = m_firstPage; page; page = page->next()) |
| 331 objectPayloadSize += page->objectPayloadSizeForTesting(); | 309 objectPayloadSize += page->objectPayloadSizeForTesting(); |
| 332 return objectPayloadSize; | 310 return objectPayloadSize; |
| 333 } | 311 } |
| 334 | 312 |
| 335 void BaseHeap::prepareHeapForTermination() | 313 void BaseHeap::prepareHeapForTermination() |
| 336 { | 314 { |
| 337 ASSERT(!m_firstUnsweptPage); | 315 ASSERT(!m_firstUnsweptPage); |
| 338 for (BasePage* page = m_firstPage; page; page = page->next()) { | 316 for (BasePage* page = m_firstPage; page; page = page->next()) { |
| 339 page->setTerminating(); | 317 page->setTerminating(); |
| 340 } | 318 } |
| 341 } | 319 } |
| 342 | 320 |
| 343 void BaseHeap::prepareForSweep() | 321 void BaseHeap::prepareForSweep() |
| 344 { | 322 { |
| 345 ASSERT(threadState()->isInGC()); | 323 ASSERT(!threadState()->isInGC()); |
| 346 ASSERT(!m_firstUnsweptPage); | 324 ASSERT(!m_firstUnsweptPage); |
| 347 | 325 |
| 348 // Move all pages to a list of unswept pages. | 326 // Move all pages to a list of unswept pages. |
| 349 m_firstUnsweptPage = m_firstPage; | 327 m_firstUnsweptPage = m_firstPage; |
| 350 m_firstPage = nullptr; | 328 m_firstPage = nullptr; |
| 351 } | 329 } |
| 352 | 330 |
| 353 #if defined(ADDRESS_SANITIZER) | 331 #if defined(ADDRESS_SANITIZER) |
| 354 void BaseHeap::poisonUnmarkedObjects() | 332 void BaseHeap::poisonUnmarkedObjects() |
| 355 { | 333 { |
| (...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1194 markedObjectSize += header->size(); | 1172 markedObjectSize += header->size(); |
| 1195 } else { | 1173 } else { |
| 1196 header->markDead(); | 1174 header->markDead(); |
| 1197 } | 1175 } |
| 1198 headerAddress += header->size(); | 1176 headerAddress += header->size(); |
| 1199 } | 1177 } |
| 1200 if (markedObjectSize) | 1178 if (markedObjectSize) |
| 1201 Heap::increaseMarkedObjectSize(markedObjectSize); | 1179 Heap::increaseMarkedObjectSize(markedObjectSize); |
| 1202 } | 1180 } |
| 1203 | 1181 |
| 1204 void NormalPage::makeConsistentForMutator() | |
| 1205 { | |
| 1206 size_t markedObjectSize = 0; | |
| 1207 Address startOfGap = payload(); | |
| 1208 for (Address headerAddress = payload(); headerAddress < payloadEnd();) { | |
| 1209 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd
ress); | |
| 1210 ASSERT(header->size() < blinkPagePayloadSize()); | |
| 1211 // Check if a free list entry first since we cannot call | |
| 1212 // isMarked on a free list entry. | |
| 1213 if (header->isFree()) { | |
| 1214 headerAddress += header->size(); | |
| 1215 continue; | |
| 1216 } | |
| 1217 header->checkHeader(); | |
| 1218 | |
| 1219 if (startOfGap != headerAddress) | |
| 1220 heapForNormalPage()->addToFreeList(startOfGap, headerAddress - start
OfGap); | |
| 1221 if (header->isMarked()) { | |
| 1222 header->unmark(); | |
| 1223 markedObjectSize += header->size(); | |
| 1224 } | |
| 1225 headerAddress += header->size(); | |
| 1226 startOfGap = headerAddress; | |
| 1227 } | |
| 1228 if (startOfGap != payloadEnd()) | |
| 1229 heapForNormalPage()->addToFreeList(startOfGap, payloadEnd() - startOfGap
); | |
| 1230 | |
| 1231 if (markedObjectSize) | |
| 1232 Heap::increaseMarkedObjectSize(markedObjectSize); | |
| 1233 } | |
| 1234 | |
| 1235 #if defined(ADDRESS_SANITIZER) | 1182 #if defined(ADDRESS_SANITIZER) |
| 1236 void NormalPage::poisonUnmarkedObjects() | 1183 void NormalPage::poisonUnmarkedObjects() |
| 1237 { | 1184 { |
| 1238 for (Address headerAddress = payload(); headerAddress < payloadEnd();) { | 1185 for (Address headerAddress = payload(); headerAddress < payloadEnd();) { |
| 1239 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd
ress); | 1186 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd
ress); |
| 1240 ASSERT(header->size() < blinkPagePayloadSize()); | 1187 ASSERT(header->size() < blinkPagePayloadSize()); |
| 1241 // Check if a free list entry first since we cannot call | 1188 // Check if a free list entry first since we cannot call |
| 1242 // isMarked on a free list entry. | 1189 // isMarked on a free list entry. |
| 1243 if (header->isFree()) { | 1190 if (header->isFree()) { |
| 1244 headerAddress += header->size(); | 1191 headerAddress += header->size(); |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1514 { | 1461 { |
| 1515 HeapObjectHeader* header = heapObjectHeader(); | 1462 HeapObjectHeader* header = heapObjectHeader(); |
| 1516 if (header->isMarked()) { | 1463 if (header->isMarked()) { |
| 1517 header->unmark(); | 1464 header->unmark(); |
| 1518 Heap::increaseMarkedObjectSize(size()); | 1465 Heap::increaseMarkedObjectSize(size()); |
| 1519 } else { | 1466 } else { |
| 1520 header->markDead(); | 1467 header->markDead(); |
| 1521 } | 1468 } |
| 1522 } | 1469 } |
| 1523 | 1470 |
| 1524 void LargeObjectPage::makeConsistentForMutator() | |
| 1525 { | |
| 1526 HeapObjectHeader* header = heapObjectHeader(); | |
| 1527 if (header->isMarked()) { | |
| 1528 header->unmark(); | |
| 1529 Heap::increaseMarkedObjectSize(size()); | |
| 1530 } | |
| 1531 } | |
| 1532 | |
| 1533 #if defined(ADDRESS_SANITIZER) | 1471 #if defined(ADDRESS_SANITIZER) |
| 1534 void LargeObjectPage::poisonUnmarkedObjects() | 1472 void LargeObjectPage::poisonUnmarkedObjects() |
| 1535 { | 1473 { |
| 1536 HeapObjectHeader* header = heapObjectHeader(); | 1474 HeapObjectHeader* header = heapObjectHeader(); |
| 1537 if (!header->isMarked()) | 1475 if (!header->isMarked()) |
| 1538 ASAN_POISON_MEMORY_REGION(header->payload(), header->payloadSize()); | 1476 ASAN_POISON_MEMORY_REGION(header->payload(), header->payloadSize()); |
| 1539 } | 1477 } |
| 1540 #endif | 1478 #endif |
| 1541 | 1479 |
| 1542 void LargeObjectPage::checkAndMarkPointer(Visitor* visitor, Address address) | 1480 void LargeObjectPage::checkAndMarkPointer(Visitor* visitor, Address address) |
| (...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2286 size_t Heap::s_allocatedObjectSize = 0; | 2224 size_t Heap::s_allocatedObjectSize = 0; |
| 2287 size_t Heap::s_allocatedSpace = 0; | 2225 size_t Heap::s_allocatedSpace = 0; |
| 2288 size_t Heap::s_markedObjectSize = 0; | 2226 size_t Heap::s_markedObjectSize = 0; |
| 2289 // We don't want to use 0 KB for the initial value because it may end up | 2227 // We don't want to use 0 KB for the initial value because it may end up |
| 2290 // triggering the first GC of some thread too prematurely. | 2228 // triggering the first GC of some thread too prematurely. |
| 2291 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; | 2229 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; |
| 2292 size_t Heap::s_externalObjectSizeAtLastGC = 0; | 2230 size_t Heap::s_externalObjectSizeAtLastGC = 0; |
| 2293 double Heap::s_estimatedMarkingTimePerByte = 0.0; | 2231 double Heap::s_estimatedMarkingTimePerByte = 0.0; |
| 2294 | 2232 |
| 2295 } // namespace blink | 2233 } // namespace blink |
| OLD | NEW |