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 |