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 |