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