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