Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: third_party/WebKit/Source/platform/heap/HeapPage.cpp

Issue 1477023003: Refactor the Heap into ThreadHeap to prepare for per thread heaps Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 void HeapObjectHeader::zapMagic() 92 void HeapObjectHeader::zapMagic()
93 { 93 {
94 ASSERT(checkHeader()); 94 ASSERT(checkHeader());
95 m_magic = zappedMagic; 95 m_magic = zappedMagic;
96 } 96 }
97 #endif 97 #endif
98 98
99 void HeapObjectHeader::finalize(Address object, size_t objectSize) 99 void HeapObjectHeader::finalize(Address object, size_t objectSize)
100 { 100 {
101 HeapAllocHooks::freeHookIfEnabled(object); 101 HeapAllocHooks::freeHookIfEnabled(object);
102 const GCInfo* gcInfo = Heap::gcInfo(gcInfoIndex()); 102 const GCInfo* gcInfo = ThreadHeap::gcInfo(gcInfoIndex());
103 if (gcInfo->hasFinalizer()) 103 if (gcInfo->hasFinalizer())
104 gcInfo->m_finalize(object); 104 gcInfo->m_finalize(object);
105 105
106 ASAN_RETIRE_CONTAINER_ANNOTATION(object, objectSize); 106 ASAN_RETIRE_CONTAINER_ANNOTATION(object, objectSize);
107 } 107 }
108 108
109 BaseArena::BaseArena(ThreadState* state, int index) 109 BaseArena::BaseArena(ThreadState* state, int index)
110 : m_firstPage(nullptr) 110 : m_firstPage(nullptr)
111 , m_firstUnsweptPage(nullptr) 111 , m_firstUnsweptPage(nullptr)
112 , m_threadState(state) 112 , m_threadState(state)
113 , m_index(index) 113 , m_index(index)
114 { 114 {
115 } 115 }
116 116
117 BaseArena::~BaseArena() 117 BaseArena::~BaseArena()
118 { 118 {
119 ASSERT(!m_firstPage); 119 ASSERT(!m_firstPage);
120 ASSERT(!m_firstUnsweptPage); 120 ASSERT(!m_firstUnsweptPage);
121 } 121 }
122 122
123 void BaseArena::cleanupPages() 123 void BaseArena::cleanupPages()
124 { 124 {
125 clearFreeLists(); 125 clearFreeLists();
126 126
127 ASSERT(!m_firstUnsweptPage); 127 ASSERT(!m_firstUnsweptPage);
128 // Add the BaseArena's pages to the orphanedPagePool. 128 // Add the BaseArena's pages to the orphanedPagePool.
129 for (BasePage* page = m_firstPage; page; page = page->next()) { 129 for (BasePage* page = m_firstPage; page; page = page->next()) {
130 Heap::decreaseAllocatedSpace(page->size()); 130 getThreadState()->heap().heapStats().decreaseAllocatedSpace(page->size() );
131 Heap::getOrphanedPagePool()->addOrphanedPage(arenaIndex(), page); 131 getThreadState()->heap().getOrphanedPagePool()->addOrphanedPage(arenaInd ex(), page);
132 } 132 }
133 m_firstPage = nullptr; 133 m_firstPage = nullptr;
134 } 134 }
135 135
136 void BaseArena::takeSnapshot(const String& dumpBaseName, ThreadState::GCSnapshot Info& info) 136 void BaseArena::takeSnapshot(const String& dumpBaseName, ThreadState::GCSnapshot Info& info)
137 { 137 {
138 // |dumpBaseName| at this point is "blink_gc/thread_X/heaps/HeapName" 138 // |dumpBaseName| at this point is "blink_gc/thread_X/heaps/HeapName"
139 WebMemoryAllocatorDump* allocatorDump = BlinkGCMemoryDumpProvider::instance( )->createMemoryAllocatorDumpForCurrentGC(dumpBaseName); 139 WebMemoryAllocatorDump* allocatorDump = BlinkGCMemoryDumpProvider::instance( )->createMemoryAllocatorDumpForCurrentGC(dumpBaseName);
140 size_t pageCount = 0; 140 size_t pageCount = 0;
141 BasePage::HeapSnapshotInfo heapInfo; 141 BasePage::HeapSnapshotInfo heapInfo;
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 if (getThreadState()->sweepForbidden()) 276 if (getThreadState()->sweepForbidden())
277 return nullptr; 277 return nullptr;
278 278
279 TRACE_EVENT0("blink_gc", "BaseArena::lazySweepPages"); 279 TRACE_EVENT0("blink_gc", "BaseArena::lazySweepPages");
280 ThreadState::SweepForbiddenScope sweepForbidden(getThreadState()); 280 ThreadState::SweepForbiddenScope sweepForbidden(getThreadState());
281 ScriptForbiddenIfMainThreadScope scriptForbidden; 281 ScriptForbiddenIfMainThreadScope scriptForbidden;
282 282
283 double startTime = WTF::currentTimeMS(); 283 double startTime = WTF::currentTimeMS();
284 Address result = lazySweepPages(allocationSize, gcInfoIndex); 284 Address result = lazySweepPages(allocationSize, gcInfoIndex);
285 getThreadState()->accumulateSweepingTime(WTF::currentTimeMS() - startTime); 285 getThreadState()->accumulateSweepingTime(WTF::currentTimeMS() - startTime);
286 Heap::reportMemoryUsageForTracing(); 286 ThreadHeap::reportMemoryUsageForTracing();
287 287
288 return result; 288 return result;
289 } 289 }
290 290
291 void BaseArena::sweepUnsweptPage() 291 void BaseArena::sweepUnsweptPage()
292 { 292 {
293 BasePage* page = m_firstUnsweptPage; 293 BasePage* page = m_firstUnsweptPage;
294 if (page->isEmpty()) { 294 if (page->isEmpty()) {
295 page->unlink(&m_firstUnsweptPage); 295 page->unlink(&m_firstUnsweptPage);
296 page->removeFromHeap(); 296 page->removeFromHeap();
(...skipping 17 matching lines...) Expand all
314 RELEASE_ASSERT(getThreadState()->isSweepingInProgress()); 314 RELEASE_ASSERT(getThreadState()->isSweepingInProgress());
315 ASSERT(getThreadState()->sweepForbidden()); 315 ASSERT(getThreadState()->sweepForbidden());
316 ASSERT(!getThreadState()->isMainThread() || ScriptForbiddenScope::isScriptFo rbidden()); 316 ASSERT(!getThreadState()->isMainThread() || ScriptForbiddenScope::isScriptFo rbidden());
317 317
318 int pageCount = 1; 318 int pageCount = 1;
319 while (m_firstUnsweptPage) { 319 while (m_firstUnsweptPage) {
320 sweepUnsweptPage(); 320 sweepUnsweptPage();
321 if (pageCount % deadlineCheckInterval == 0) { 321 if (pageCount % deadlineCheckInterval == 0) {
322 if (deadlineSeconds <= monotonicallyIncreasingTime()) { 322 if (deadlineSeconds <= monotonicallyIncreasingTime()) {
323 // Deadline has come. 323 // Deadline has come.
324 Heap::reportMemoryUsageForTracing(); 324 ThreadHeap::reportMemoryUsageForTracing();
325 return !m_firstUnsweptPage; 325 return !m_firstUnsweptPage;
326 } 326 }
327 } 327 }
328 pageCount++; 328 pageCount++;
329 } 329 }
330 Heap::reportMemoryUsageForTracing(); 330 ThreadHeap::reportMemoryUsageForTracing();
331 return true; 331 return true;
332 } 332 }
333 333
334 void BaseArena::completeSweep() 334 void BaseArena::completeSweep()
335 { 335 {
336 RELEASE_ASSERT(getThreadState()->isSweepingInProgress()); 336 RELEASE_ASSERT(getThreadState()->isSweepingInProgress());
337 ASSERT(getThreadState()->sweepForbidden()); 337 ASSERT(getThreadState()->sweepForbidden());
338 ASSERT(!getThreadState()->isMainThread() || ScriptForbiddenScope::isScriptFo rbidden()); 338 ASSERT(!getThreadState()->isMainThread() || ScriptForbiddenScope::isScriptFo rbidden());
339 339
340 while (m_firstUnsweptPage) { 340 while (m_firstUnsweptPage) {
341 sweepUnsweptPage(); 341 sweepUnsweptPage();
342 } 342 }
343 Heap::reportMemoryUsageForTracing(); 343 ThreadHeap::reportMemoryUsageForTracing();
344 } 344 }
345 345
346 NormalPageArena::NormalPageArena(ThreadState* state, int index) 346 NormalPageArena::NormalPageArena(ThreadState* state, int index)
347 : BaseArena(state, index) 347 : BaseArena(state, index)
348 , m_currentAllocationPoint(nullptr) 348 , m_currentAllocationPoint(nullptr)
349 , m_remainingAllocationSize(0) 349 , m_remainingAllocationSize(0)
350 , m_lastRemainingAllocationSize(0) 350 , m_lastRemainingAllocationSize(0)
351 , m_promptlyFreedSize(0) 351 , m_promptlyFreedSize(0)
352 { 352 {
353 clearFreeLists(); 353 clearFreeLists();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 if (m_freeList.takeSnapshot(dumpName)) { 392 if (m_freeList.takeSnapshot(dumpName)) {
393 WebMemoryAllocatorDump* bucketsDump = BlinkGCMemoryDumpProvider::instanc e()->createMemoryAllocatorDumpForCurrentGC(dumpName + "/buckets"); 393 WebMemoryAllocatorDump* bucketsDump = BlinkGCMemoryDumpProvider::instanc e()->createMemoryAllocatorDumpForCurrentGC(dumpName + "/buckets");
394 WebMemoryAllocatorDump* pagesDump = BlinkGCMemoryDumpProvider::instance( )->createMemoryAllocatorDumpForCurrentGC(dumpName + "/pages"); 394 WebMemoryAllocatorDump* pagesDump = BlinkGCMemoryDumpProvider::instance( )->createMemoryAllocatorDumpForCurrentGC(dumpName + "/pages");
395 BlinkGCMemoryDumpProvider::instance()->currentProcessMemoryDump()->addOw nershipEdge(pagesDump->guid(), bucketsDump->guid()); 395 BlinkGCMemoryDumpProvider::instance()->currentProcessMemoryDump()->addOw nershipEdge(pagesDump->guid(), bucketsDump->guid());
396 } 396 }
397 } 397 }
398 398
399 void NormalPageArena::allocatePage() 399 void NormalPageArena::allocatePage()
400 { 400 {
401 getThreadState()->shouldFlushHeapDoesNotContainCache(); 401 getThreadState()->shouldFlushHeapDoesNotContainCache();
402 PageMemory* pageMemory = Heap::getFreePagePool()->takeFreePage(arenaIndex()) ; 402 PageMemory* pageMemory = getThreadState()->heap().getFreePagePool()->takeFre ePage(arenaIndex());
403 403
404 if (!pageMemory) { 404 if (!pageMemory) {
405 // Allocate a memory region for blinkPagesPerRegion pages that 405 // Allocate a memory region for blinkPagesPerRegion pages that
406 // will each have the following layout. 406 // will each have the following layout.
407 // 407 //
408 // [ guard os page | ... payload ... | guard os page ] 408 // [ guard os page | ... payload ... | guard os page ]
409 // ^---{ aligned to blink page size } 409 // ^---{ aligned to blink page size }
410 PageMemoryRegion* region = PageMemoryRegion::allocateNormalPages(Heap::g etRegionTree()); 410 PageMemoryRegion* region = PageMemoryRegion::allocateNormalPages(getThre adState()->heap().getRegionTree());
411 411
412 // Setup the PageMemory object for each of the pages in the region. 412 // Setup the PageMemory object for each of the pages in the region.
413 for (size_t i = 0; i < blinkPagesPerRegion; ++i) { 413 for (size_t i = 0; i < blinkPagesPerRegion; ++i) {
414 PageMemory* memory = PageMemory::setupPageMemoryInRegion(region, i * blinkPageSize, blinkPagePayloadSize()); 414 PageMemory* memory = PageMemory::setupPageMemoryInRegion(region, i * blinkPageSize, blinkPagePayloadSize());
415 // Take the first possible page ensuring that this thread actually 415 // Take the first possible page ensuring that this thread actually
416 // gets a page and add the rest to the page pool. 416 // gets a page and add the rest to the page pool.
417 if (!pageMemory) { 417 if (!pageMemory) {
418 bool result = memory->commit(); 418 bool result = memory->commit();
419 // If you hit the ASSERT, it will mean that you're hitting 419 // If you hit the ASSERT, it will mean that you're hitting
420 // the limit of the number of mmapped regions OS can support 420 // the limit of the number of mmapped regions OS can support
421 // (e.g., /proc/sys/vm/max_map_count in Linux). 421 // (e.g., /proc/sys/vm/max_map_count in Linux).
422 RELEASE_ASSERT(result); 422 RELEASE_ASSERT(result);
423 pageMemory = memory; 423 pageMemory = memory;
424 } else { 424 } else {
425 Heap::getFreePagePool()->addFreePage(arenaIndex(), memory); 425 getThreadState()->heap().getFreePagePool()->addFreePage(arenaInd ex(), memory);
426 } 426 }
427 } 427 }
428 } 428 }
429 429
430 NormalPage* page = new (pageMemory->writableStart()) NormalPage(pageMemory, this); 430 NormalPage* page = new (pageMemory->writableStart()) NormalPage(pageMemory, this);
431 page->link(&m_firstPage); 431 page->link(&m_firstPage);
432 432
433 Heap::increaseAllocatedSpace(page->size()); 433 getThreadState()->heap().heapStats().increaseAllocatedSpace(page->size());
434 #if ENABLE(ASSERT) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) 434 #if ENABLE(ASSERT) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER)
435 // Allow the following addToFreeList() to add the newly allocated memory 435 // Allow the following addToFreeList() to add the newly allocated memory
436 // to the free list. 436 // to the free list.
437 ASAN_UNPOISON_MEMORY_REGION(page->payload(), page->payloadSize()); 437 ASAN_UNPOISON_MEMORY_REGION(page->payload(), page->payloadSize());
438 Address address = page->payload(); 438 Address address = page->payload();
439 for (size_t i = 0; i < page->payloadSize(); i++) 439 for (size_t i = 0; i < page->payloadSize(); i++)
440 address[i] = reuseAllowedZapValue; 440 address[i] = reuseAllowedZapValue;
441 ASAN_POISON_MEMORY_REGION(page->payload(), page->payloadSize()); 441 ASAN_POISON_MEMORY_REGION(page->payload(), page->payloadSize());
442 #endif 442 #endif
443 addToFreeList(page->payload(), page->payloadSize()); 443 addToFreeList(page->payload(), page->payloadSize());
444 } 444 }
445 445
446 void NormalPageArena::freePage(NormalPage* page) 446 void NormalPageArena::freePage(NormalPage* page)
447 { 447 {
448 Heap::decreaseAllocatedSpace(page->size()); 448 getThreadState()->heap().heapStats().decreaseAllocatedSpace(page->size());
449 449
450 if (page->terminating()) { 450 if (page->terminating()) {
451 // The thread is shutting down and this page is being removed as a part 451 // The thread is shutting down and this page is being removed as a part
452 // of the thread local GC. In that case the object could be traced in 452 // of the thread local GC. In that case the object could be traced in
453 // the next global GC if there is a dangling pointer from a live thread 453 // the next global GC if there is a dangling pointer from a live thread
454 // heap to this dead thread heap. To guard against this, we put the 454 // heap to this dead thread heap. To guard against this, we put the
455 // page into the orphaned page pool and zap the page memory. This 455 // page into the orphaned page pool and zap the page memory. This
456 // ensures that tracing the dangling pointer in the next global GC just 456 // ensures that tracing the dangling pointer in the next global GC just
457 // crashes instead of causing use-after-frees. After the next global 457 // crashes instead of causing use-after-frees. After the next global
458 // GC, the orphaned pages are removed. 458 // GC, the orphaned pages are removed.
459 Heap::getOrphanedPagePool()->addOrphanedPage(arenaIndex(), page); 459 getThreadState()->heap().getOrphanedPagePool()->addOrphanedPage(arenaInd ex(), page);
460 } else { 460 } else {
461 PageMemory* memory = page->storage(); 461 PageMemory* memory = page->storage();
462 page->~NormalPage(); 462 page->~NormalPage();
463 Heap::getFreePagePool()->addFreePage(arenaIndex(), memory); 463 getThreadState()->heap().getFreePagePool()->addFreePage(arenaIndex(), me mory);
464 } 464 }
465 } 465 }
466 466
467 bool NormalPageArena::coalesce() 467 bool NormalPageArena::coalesce()
468 { 468 {
469 // Don't coalesce arenas if there are not enough promptly freed entries 469 // Don't coalesce arenas if there are not enough promptly freed entries
470 // to be coalesced. 470 // to be coalesced.
471 // 471 //
472 // FIXME: This threshold is determined just to optimize blink_perf 472 // FIXME: This threshold is determined just to optimize blink_perf
473 // benchmarks. Coalescing is very sensitive to the threashold and 473 // benchmarks. Coalescing is very sensitive to the threashold and
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 } 559 }
560 560
561 bool NormalPageArena::expandObject(HeapObjectHeader* header, size_t newSize) 561 bool NormalPageArena::expandObject(HeapObjectHeader* header, size_t newSize)
562 { 562 {
563 // It's possible that Vector requests a smaller expanded size because 563 // It's possible that Vector requests a smaller expanded size because
564 // Vector::shrinkCapacity can set a capacity smaller than the actual payload 564 // Vector::shrinkCapacity can set a capacity smaller than the actual payload
565 // size. 565 // size.
566 ASSERT(header->checkHeader()); 566 ASSERT(header->checkHeader());
567 if (header->payloadSize() >= newSize) 567 if (header->payloadSize() >= newSize)
568 return true; 568 return true;
569 size_t allocationSize = Heap::allocationSizeFromSize(newSize); 569 size_t allocationSize = ThreadHeap::allocationSizeFromSize(newSize);
570 ASSERT(allocationSize > header->size()); 570 ASSERT(allocationSize > header->size());
571 size_t expandSize = allocationSize - header->size(); 571 size_t expandSize = allocationSize - header->size();
572 if (isObjectAllocatedAtAllocationPoint(header) && expandSize <= m_remainingA llocationSize) { 572 if (isObjectAllocatedAtAllocationPoint(header) && expandSize <= m_remainingA llocationSize) {
573 m_currentAllocationPoint += expandSize; 573 m_currentAllocationPoint += expandSize;
574 ASSERT(m_remainingAllocationSize >= expandSize); 574 ASSERT(m_remainingAllocationSize >= expandSize);
575 setRemainingAllocationSize(m_remainingAllocationSize - expandSize); 575 setRemainingAllocationSize(m_remainingAllocationSize - expandSize);
576 // Unpoison the memory used for the object (payload). 576 // Unpoison the memory used for the object (payload).
577 SET_MEMORY_ACCESSIBLE(header->payloadEnd(), expandSize); 577 SET_MEMORY_ACCESSIBLE(header->payloadEnd(), expandSize);
578 header->setSize(allocationSize); 578 header->setSize(allocationSize);
579 ASSERT(findPageFromAddress(header->payloadEnd() - 1)); 579 ASSERT(findPageFromAddress(header->payloadEnd() - 1));
580 return true; 580 return true;
581 } 581 }
582 return false; 582 return false;
583 } 583 }
584 584
585 bool NormalPageArena::shrinkObject(HeapObjectHeader* header, size_t newSize) 585 bool NormalPageArena::shrinkObject(HeapObjectHeader* header, size_t newSize)
586 { 586 {
587 ASSERT(header->checkHeader()); 587 ASSERT(header->checkHeader());
588 ASSERT(header->payloadSize() > newSize); 588 ASSERT(header->payloadSize() > newSize);
589 size_t allocationSize = Heap::allocationSizeFromSize(newSize); 589 size_t allocationSize = ThreadHeap::allocationSizeFromSize(newSize);
590 ASSERT(header->size() > allocationSize); 590 ASSERT(header->size() > allocationSize);
591 size_t shrinkSize = header->size() - allocationSize; 591 size_t shrinkSize = header->size() - allocationSize;
592 if (isObjectAllocatedAtAllocationPoint(header)) { 592 if (isObjectAllocatedAtAllocationPoint(header)) {
593 m_currentAllocationPoint -= shrinkSize; 593 m_currentAllocationPoint -= shrinkSize;
594 setRemainingAllocationSize(m_remainingAllocationSize + shrinkSize); 594 setRemainingAllocationSize(m_remainingAllocationSize + shrinkSize);
595 SET_MEMORY_INACCESSIBLE(m_currentAllocationPoint, shrinkSize); 595 SET_MEMORY_INACCESSIBLE(m_currentAllocationPoint, shrinkSize);
596 header->setSize(allocationSize); 596 header->setSize(allocationSize);
597 return true; 597 return true;
598 } 598 }
599 ASSERT(shrinkSize >= sizeof(HeapObjectHeader)); 599 ASSERT(shrinkSize >= sizeof(HeapObjectHeader));
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 Address LargeObjectArena::doAllocateLargeObjectPage(size_t allocationSize, size_ t gcInfoIndex) 790 Address LargeObjectArena::doAllocateLargeObjectPage(size_t allocationSize, size_ t gcInfoIndex)
791 { 791 {
792 size_t largeObjectSize = LargeObjectPage::pageHeaderSize() + allocationSize; 792 size_t largeObjectSize = LargeObjectPage::pageHeaderSize() + allocationSize;
793 // If ASan is supported we add allocationGranularity bytes to the allocated 793 // If ASan is supported we add allocationGranularity bytes to the allocated
794 // space and poison that to detect overflows 794 // space and poison that to detect overflows
795 #if defined(ADDRESS_SANITIZER) 795 #if defined(ADDRESS_SANITIZER)
796 largeObjectSize += allocationGranularity; 796 largeObjectSize += allocationGranularity;
797 #endif 797 #endif
798 798
799 getThreadState()->shouldFlushHeapDoesNotContainCache(); 799 getThreadState()->shouldFlushHeapDoesNotContainCache();
800 PageMemory* pageMemory = PageMemory::allocate(largeObjectSize, Heap::getRegi onTree()); 800 PageMemory* pageMemory = PageMemory::allocate(largeObjectSize, getThreadStat e()->heap().getRegionTree());
801 Address largeObjectAddress = pageMemory->writableStart(); 801 Address largeObjectAddress = pageMemory->writableStart();
802 Address headerAddress = largeObjectAddress + LargeObjectPage::pageHeaderSize (); 802 Address headerAddress = largeObjectAddress + LargeObjectPage::pageHeaderSize ();
803 #if ENABLE(ASSERT) 803 #if ENABLE(ASSERT)
804 // Verify that the allocated PageMemory is expectedly zeroed. 804 // Verify that the allocated PageMemory is expectedly zeroed.
805 for (size_t i = 0; i < largeObjectSize; ++i) 805 for (size_t i = 0; i < largeObjectSize; ++i)
806 ASSERT(!largeObjectAddress[i]); 806 ASSERT(!largeObjectAddress[i]);
807 #endif 807 #endif
808 ASSERT(gcInfoIndex > 0); 808 ASSERT(gcInfoIndex > 0);
809 HeapObjectHeader* header = new (NotNull, headerAddress) HeapObjectHeader(lar geObjectSizeInHeader, gcInfoIndex); 809 HeapObjectHeader* header = new (NotNull, headerAddress) HeapObjectHeader(lar geObjectSizeInHeader, gcInfoIndex);
810 Address result = headerAddress + sizeof(*header); 810 Address result = headerAddress + sizeof(*header);
811 ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask)); 811 ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask));
812 LargeObjectPage* largeObject = new (largeObjectAddress) LargeObjectPage(page Memory, this, allocationSize); 812 LargeObjectPage* largeObject = new (largeObjectAddress) LargeObjectPage(page Memory, this, allocationSize);
813 ASSERT(header->checkHeader()); 813 ASSERT(header->checkHeader());
814 814
815 // Poison the object header and allocationGranularity bytes after the object 815 // Poison the object header and allocationGranularity bytes after the object
816 ASAN_POISON_MEMORY_REGION(header, sizeof(*header)); 816 ASAN_POISON_MEMORY_REGION(header, sizeof(*header));
817 ASAN_POISON_MEMORY_REGION(largeObject->getAddress() + largeObject->size(), a llocationGranularity); 817 ASAN_POISON_MEMORY_REGION(largeObject->getAddress() + largeObject->size(), a llocationGranularity);
818 818
819 largeObject->link(&m_firstPage); 819 largeObject->link(&m_firstPage);
820 820
821 Heap::increaseAllocatedSpace(largeObject->size()); 821 getThreadState()->heap().heapStats().increaseAllocatedSpace(largeObject->siz e());
822 getThreadState()->increaseAllocatedObjectSize(largeObject->size()); 822 getThreadState()->increaseAllocatedObjectSize(largeObject->size());
823 return result; 823 return result;
824 } 824 }
825 825
826 void LargeObjectArena::freeLargeObjectPage(LargeObjectPage* object) 826 void LargeObjectArena::freeLargeObjectPage(LargeObjectPage* object)
827 { 827 {
828 ASAN_UNPOISON_MEMORY_REGION(object->payload(), object->payloadSize()); 828 ASAN_UNPOISON_MEMORY_REGION(object->payload(), object->payloadSize());
829 object->heapObjectHeader()->finalize(object->payload(), object->payloadSize( )); 829 object->heapObjectHeader()->finalize(object->payload(), object->payloadSize( ));
830 Heap::decreaseAllocatedSpace(object->size()); 830 getThreadState()->heap().heapStats().decreaseAllocatedSpace(object->size());
831 831
832 // Unpoison the object header and allocationGranularity bytes after the 832 // Unpoison the object header and allocationGranularity bytes after the
833 // object before freeing. 833 // object before freeing.
834 ASAN_UNPOISON_MEMORY_REGION(object->heapObjectHeader(), sizeof(HeapObjectHea der)); 834 ASAN_UNPOISON_MEMORY_REGION(object->heapObjectHeader(), sizeof(HeapObjectHea der));
835 ASAN_UNPOISON_MEMORY_REGION(object->getAddress() + object->size(), allocatio nGranularity); 835 ASAN_UNPOISON_MEMORY_REGION(object->getAddress() + object->size(), allocatio nGranularity);
836 836
837 if (object->terminating()) { 837 if (object->terminating()) {
838 ASSERT(ThreadState::current()->isTerminating()); 838 ASSERT(ThreadState::current()->isTerminating());
839 // The thread is shutting down and this page is being removed as a part 839 // The thread is shutting down and this page is being removed as a part
840 // of the thread local GC. In that case the object could be traced in 840 // of the thread local GC. In that case the object could be traced in
841 // the next global GC if there is a dangling pointer from a live thread 841 // the next global GC if there is a dangling pointer from a live thread
842 // heap to this dead thread heap. To guard against this, we put the 842 // heap to this dead thread heap. To guard against this, we put the
843 // page into the orphaned page pool and zap the page memory. This 843 // page into the orphaned page pool and zap the page memory. This
844 // ensures that tracing the dangling pointer in the next global GC just 844 // ensures that tracing the dangling pointer in the next global GC just
845 // crashes instead of causing use-after-frees. After the next global 845 // crashes instead of causing use-after-frees. After the next global
846 // GC, the orphaned pages are removed. 846 // GC, the orphaned pages are removed.
847 Heap::getOrphanedPagePool()->addOrphanedPage(arenaIndex(), object); 847 getThreadState()->heap().getOrphanedPagePool()->addOrphanedPage(arenaInd ex(), object);
848 } else { 848 } else {
849 ASSERT(!ThreadState::current()->isTerminating()); 849 ASSERT(!ThreadState::current()->isTerminating());
850 PageMemory* memory = object->storage(); 850 PageMemory* memory = object->storage();
851 object->~LargeObjectPage(); 851 object->~LargeObjectPage();
852 delete memory; 852 delete memory;
853 } 853 }
854 } 854 }
855 855
856 Address LargeObjectArena::lazySweepPages(size_t allocationSize, size_t gcInfoInd ex) 856 Address LargeObjectArena::lazySweepPages(size_t allocationSize, size_t gcInfoInd ex)
857 { 857 {
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
1134 // that memory on the freelist is zero filled. 1134 // that memory on the freelist is zero filled.
1135 SET_MEMORY_INACCESSIBLE(headerAddress, size); 1135 SET_MEMORY_INACCESSIBLE(headerAddress, size);
1136 headerAddress += size; 1136 headerAddress += size;
1137 continue; 1137 continue;
1138 } 1138 }
1139 if (startOfGap != headerAddress) { 1139 if (startOfGap != headerAddress) {
1140 pageArena->addToFreeList(startOfGap, headerAddress - startOfGap); 1140 pageArena->addToFreeList(startOfGap, headerAddress - startOfGap);
1141 #if !ENABLE(ASSERT) && !defined(LEAK_SANITIZER) && !defined(ADDRESS_SANITIZER) 1141 #if !ENABLE(ASSERT) && !defined(LEAK_SANITIZER) && !defined(ADDRESS_SANITIZER)
1142 // Discarding pages increases page faults and may regress performanc e. 1142 // Discarding pages increases page faults and may regress performanc e.
1143 // So we enable this only on low-RAM devices. 1143 // So we enable this only on low-RAM devices.
1144 if (Heap::isLowEndDevice()) 1144 if (ProcessHeap::isLowEndDevice())
1145 discardPages(startOfGap + sizeof(FreeListEntry), headerAddress); 1145 discardPages(startOfGap + sizeof(FreeListEntry), headerAddress);
1146 #endif 1146 #endif
1147 } 1147 }
1148 header->unmark(); 1148 header->unmark();
1149 headerAddress += size; 1149 headerAddress += size;
1150 markedObjectSize += size; 1150 markedObjectSize += size;
1151 startOfGap = headerAddress; 1151 startOfGap = headerAddress;
1152 } 1152 }
1153 if (startOfGap != payloadEnd()) { 1153 if (startOfGap != payloadEnd()) {
1154 pageArena->addToFreeList(startOfGap, payloadEnd() - startOfGap); 1154 pageArena->addToFreeList(startOfGap, payloadEnd() - startOfGap);
1155 #if !ENABLE(ASSERT) && !defined(LEAK_SANITIZER) && !defined(ADDRESS_SANITIZER) 1155 #if !ENABLE(ASSERT) && !defined(LEAK_SANITIZER) && !defined(ADDRESS_SANITIZER)
1156 if (Heap::isLowEndDevice()) 1156 if (ProcessHeap::isLowEndDevice())
1157 discardPages(startOfGap + sizeof(FreeListEntry), payloadEnd()); 1157 discardPages(startOfGap + sizeof(FreeListEntry), payloadEnd());
1158 #endif 1158 #endif
1159 } 1159 }
1160 1160
1161 if (markedObjectSize) 1161 if (markedObjectSize)
1162 pageArena->getThreadState()->increaseMarkedObjectSize(markedObjectSize); 1162 pageArena->getThreadState()->increaseMarkedObjectSize(markedObjectSize);
1163 } 1163 }
1164 1164
1165 void NormalPage::makeConsistentForGC() 1165 void NormalPage::makeConsistentForGC()
1166 { 1166 {
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 if (objectFields[i] != 0) 1312 if (objectFields[i] != 0)
1313 return false; 1313 return false;
1314 } 1314 }
1315 return true; 1315 return true;
1316 } 1316 }
1317 #endif 1317 #endif
1318 1318
1319 static void markPointer(Visitor* visitor, HeapObjectHeader* header) 1319 static void markPointer(Visitor* visitor, HeapObjectHeader* header)
1320 { 1320 {
1321 ASSERT(header->checkHeader()); 1321 ASSERT(header->checkHeader());
1322 const GCInfo* gcInfo = Heap::gcInfo(header->gcInfoIndex()); 1322 const GCInfo* gcInfo = ThreadHeap::gcInfo(header->gcInfoIndex());
1323 if (gcInfo->hasVTable() && !vTableInitialized(header->payload())) { 1323 if (gcInfo->hasVTable() && !vTableInitialized(header->payload())) {
1324 // We hit this branch when a GC strikes before GarbageCollected<>'s 1324 // We hit this branch when a GC strikes before GarbageCollected<>'s
1325 // constructor runs. 1325 // constructor runs.
1326 // 1326 //
1327 // class A : public GarbageCollected<A> { virtual void f() = 0; }; 1327 // class A : public GarbageCollected<A> { virtual void f() = 0; };
1328 // class B : public A { 1328 // class B : public A {
1329 // B() : A(foo()) { }; 1329 // B() : A(foo()) { };
1330 // }; 1330 // };
1331 // 1331 //
1332 // If foo() allocates something and triggers a GC, the vtable of A 1332 // If foo() allocates something and triggers a GC, the vtable of A
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
1562 1562
1563 m_hasEntries = true; 1563 m_hasEntries = true;
1564 size_t index = hash(address); 1564 size_t index = hash(address);
1565 ASSERT(!(index & 1)); 1565 ASSERT(!(index & 1));
1566 Address cachePage = roundToBlinkPageStart(address); 1566 Address cachePage = roundToBlinkPageStart(address);
1567 m_entries[index + 1] = m_entries[index]; 1567 m_entries[index + 1] = m_entries[index];
1568 m_entries[index] = cachePage; 1568 m_entries[index] = cachePage;
1569 } 1569 }
1570 1570
1571 } // namespace blink 1571 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/heap/HeapPage.h ('k') | third_party/WebKit/Source/platform/heap/HeapTerminatedArray.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698