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 |