| 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 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 537 | 537 |
| 538 Heap::increaseAllocatedSpace(page->size()); | 538 Heap::increaseAllocatedSpace(page->size()); |
| 539 addToFreeList(page->payload(), page->payloadSize()); | 539 addToFreeList(page->payload(), page->payloadSize()); |
| 540 } | 540 } |
| 541 | 541 |
| 542 void NormalPageHeap::freePage(NormalPage* page) | 542 void NormalPageHeap::freePage(NormalPage* page) |
| 543 { | 543 { |
| 544 Heap::decreaseAllocatedSpace(page->size()); | 544 Heap::decreaseAllocatedSpace(page->size()); |
| 545 | 545 |
| 546 if (page->terminating()) { | 546 if (page->terminating()) { |
| 547 ASSERT(ThreadState::current()->isTerminating()); |
| 547 // The thread is shutting down and this page is being removed as a part | 548 // The thread is shutting down and this page is being removed as a part |
| 548 // of the thread local GC. In that case the object could be traced in | 549 // of the thread local GC. In that case the object could be traced in |
| 549 // the next global GC if there is a dangling pointer from a live thread | 550 // the next global GC if there is a dangling pointer from a live thread |
| 550 // heap to this dead thread heap. To guard against this, we put the | 551 // heap to this dead thread heap. To guard against this, we put the |
| 551 // page into the orphaned page pool and zap the page memory. This | 552 // page into the orphaned page pool and zap the page memory. This |
| 552 // ensures that tracing the dangling pointer in the next global GC just | 553 // ensures that tracing the dangling pointer in the next global GC just |
| 553 // crashes instead of causing use-after-frees. After the next global | 554 // crashes instead of causing use-after-frees. After the next global |
| 554 // GC, the orphaned pages are removed. | 555 // GC, the orphaned pages are removed. |
| 555 Heap::orphanedPagePool()->addOrphanedPage(heapIndex(), page); | 556 Heap::orphanedPagePool()->addOrphanedPage(heapIndex(), page); |
| 557 ASSERT(!page->terminating()); |
| 556 } else { | 558 } else { |
| 559 ASSERT(!ThreadState::current()->isTerminating()); |
| 557 PageMemory* memory = page->storage(); | 560 PageMemory* memory = page->storage(); |
| 558 page->~NormalPage(); | 561 page->~NormalPage(); |
| 559 Heap::freePagePool()->addFreePage(heapIndex(), memory); | 562 Heap::freePagePool()->addFreePage(heapIndex(), memory); |
| 560 } | 563 } |
| 561 } | 564 } |
| 562 | 565 |
| 563 bool NormalPageHeap::coalesce() | 566 bool NormalPageHeap::coalesce() |
| 564 { | 567 { |
| 565 // Don't coalesce heaps if there are not enough promptly freed entries | 568 // Don't coalesce heaps if there are not enough promptly freed entries |
| 566 // to be coalesced. | 569 // to be coalesced. |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 919 ASSERT(ThreadState::current()->isTerminating()); | 922 ASSERT(ThreadState::current()->isTerminating()); |
| 920 // The thread is shutting down and this page is being removed as a part | 923 // The thread is shutting down and this page is being removed as a part |
| 921 // of the thread local GC. In that case the object could be traced in | 924 // of the thread local GC. In that case the object could be traced in |
| 922 // the next global GC if there is a dangling pointer from a live thread | 925 // the next global GC if there is a dangling pointer from a live thread |
| 923 // heap to this dead thread heap. To guard against this, we put the | 926 // heap to this dead thread heap. To guard against this, we put the |
| 924 // page into the orphaned page pool and zap the page memory. This | 927 // page into the orphaned page pool and zap the page memory. This |
| 925 // ensures that tracing the dangling pointer in the next global GC just | 928 // ensures that tracing the dangling pointer in the next global GC just |
| 926 // crashes instead of causing use-after-frees. After the next global | 929 // crashes instead of causing use-after-frees. After the next global |
| 927 // GC, the orphaned pages are removed. | 930 // GC, the orphaned pages are removed. |
| 928 Heap::orphanedPagePool()->addOrphanedPage(heapIndex(), object); | 931 Heap::orphanedPagePool()->addOrphanedPage(heapIndex(), object); |
| 932 ASSERT(!object->terminating()); |
| 929 } else { | 933 } else { |
| 930 ASSERT(!ThreadState::current()->isTerminating()); | 934 ASSERT(!ThreadState::current()->isTerminating()); |
| 931 PageMemory* memory = object->storage(); | 935 PageMemory* memory = object->storage(); |
| 932 object->~LargeObjectPage(); | 936 object->~LargeObjectPage(); |
| 933 delete memory; | 937 delete memory; |
| 934 } | 938 } |
| 935 } | 939 } |
| 936 | 940 |
| 937 Address LargeObjectHeap::lazySweepPages(size_t allocationSize, size_t gcInfoInde
x) | 941 Address LargeObjectHeap::lazySweepPages(size_t allocationSize, size_t gcInfoInde
x) |
| 938 { | 942 { |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1305 ASSERT(contains(address)); | 1309 ASSERT(contains(address)); |
| 1306 HeapObjectHeader* header = findHeaderFromAddress(address); | 1310 HeapObjectHeader* header = findHeaderFromAddress(address); |
| 1307 if (!header || header->isDead()) | 1311 if (!header || header->isDead()) |
| 1308 return; | 1312 return; |
| 1309 #if ENABLE(GC_PROFILING) | 1313 #if ENABLE(GC_PROFILING) |
| 1310 visitor->setHostInfo(&address, "stack"); | 1314 visitor->setHostInfo(&address, "stack"); |
| 1311 #endif | 1315 #endif |
| 1312 markPointer(visitor, header); | 1316 markPointer(visitor, header); |
| 1313 } | 1317 } |
| 1314 | 1318 |
| 1319 static void zapOrphanedPage(void* payload, size_t payloadSize) |
| 1320 { |
| 1321 #if defined(ADDRESS_SANITIZER) |
| 1322 // Unpoison memory before memset. |
| 1323 ASAN_UNPOISON_MEMORY_REGION(payload(), payloadSize()); |
| 1324 #endif |
| 1325 // Zap the payload with a recognizable value to detect any incorrect |
| 1326 // cross thread pointer usage. |
| 1327 memset(payload, orphanedZapValue, payloadSize); |
| 1328 #if defined(ADDRESS_SANITIZER) |
| 1329 // Poison the memory again. |
| 1330 ASAN_UNPOISON_MEMORY_REGION(payload(), payloadSize()); |
| 1331 #endif |
| 1332 } |
| 1333 |
| 1315 void NormalPage::markOrphaned() | 1334 void NormalPage::markOrphaned() |
| 1316 { | 1335 { |
| 1317 // Zap the payload with a recognizable value to detect any incorrect | 1336 zapOrphanedPage(payload(), payloadSize()); |
| 1318 // cross thread pointer usage. | |
| 1319 #if defined(ADDRESS_SANITIZER) | |
| 1320 // This needs to zap poisoned memory as well. | |
| 1321 // Force unpoison memory before memset. | |
| 1322 ASAN_UNPOISON_MEMORY_REGION(payload(), payloadSize()); | |
| 1323 #endif | |
| 1324 memset(payload(), orphanedZapValue, payloadSize()); | |
| 1325 BasePage::markOrphaned(); | 1337 BasePage::markOrphaned(); |
| 1326 } | 1338 } |
| 1327 | 1339 |
| 1328 #if ENABLE(GC_PROFILING) | 1340 #if ENABLE(GC_PROFILING) |
| 1329 const GCInfo* NormalPage::findGCInfo(Address address) | 1341 const GCInfo* NormalPage::findGCInfo(Address address) |
| 1330 { | 1342 { |
| 1331 if (address < payload()) | 1343 if (address < payload()) |
| 1332 return nullptr; | 1344 return nullptr; |
| 1333 | 1345 |
| 1334 HeapObjectHeader* header = findHeaderFromAddress(address); | 1346 HeapObjectHeader* header = findHeaderFromAddress(address); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1478 if (!containedInObjectPayload(address) || heapObjectHeader()->isDead()) | 1490 if (!containedInObjectPayload(address) || heapObjectHeader()->isDead()) |
| 1479 return; | 1491 return; |
| 1480 #if ENABLE(GC_PROFILING) | 1492 #if ENABLE(GC_PROFILING) |
| 1481 visitor->setHostInfo(&address, "stack"); | 1493 visitor->setHostInfo(&address, "stack"); |
| 1482 #endif | 1494 #endif |
| 1483 markPointer(visitor, heapObjectHeader()); | 1495 markPointer(visitor, heapObjectHeader()); |
| 1484 } | 1496 } |
| 1485 | 1497 |
| 1486 void LargeObjectPage::markOrphaned() | 1498 void LargeObjectPage::markOrphaned() |
| 1487 { | 1499 { |
| 1488 // Zap the payload with a recognizable value to detect any incorrect | 1500 zapOrphanedPage(payload(), payloadSize()); |
| 1489 // cross thread pointer usage. | |
| 1490 memset(payload(), orphanedZapValue, payloadSize()); | |
| 1491 BasePage::markOrphaned(); | 1501 BasePage::markOrphaned(); |
| 1492 } | 1502 } |
| 1493 | 1503 |
| 1494 #if ENABLE(GC_PROFILING) | 1504 #if ENABLE(GC_PROFILING) |
| 1495 const GCInfo* LargeObjectPage::findGCInfo(Address address) | 1505 const GCInfo* LargeObjectPage::findGCInfo(Address address) |
| 1496 { | 1506 { |
| 1497 if (!containedInObjectPayload(address)) | 1507 if (!containedInObjectPayload(address)) |
| 1498 return nullptr; | 1508 return nullptr; |
| 1499 HeapObjectHeader* header = heapObjectHeader(); | 1509 HeapObjectHeader* header = heapObjectHeader(); |
| 1500 return Heap::gcInfo(header->gcInfoIndex()); | 1510 return Heap::gcInfo(header->gcInfoIndex()); |
| (...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2235 size_t Heap::s_allocatedObjectSize = 0; | 2245 size_t Heap::s_allocatedObjectSize = 0; |
| 2236 size_t Heap::s_allocatedSpace = 0; | 2246 size_t Heap::s_allocatedSpace = 0; |
| 2237 size_t Heap::s_markedObjectSize = 0; | 2247 size_t Heap::s_markedObjectSize = 0; |
| 2238 // We don't want to use 0 KB for the initial value because it may end up | 2248 // We don't want to use 0 KB for the initial value because it may end up |
| 2239 // triggering the first GC of some thread too prematurely. | 2249 // triggering the first GC of some thread too prematurely. |
| 2240 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; | 2250 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; |
| 2241 size_t Heap::s_externalObjectSizeAtLastGC = 0; | 2251 size_t Heap::s_externalObjectSizeAtLastGC = 0; |
| 2242 double Heap::s_estimatedMarkingTimePerByte = 0.0; | 2252 double Heap::s_estimatedMarkingTimePerByte = 0.0; |
| 2243 | 2253 |
| 2244 } // namespace blink | 2254 } // namespace blink |
| OLD | NEW |