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

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

Issue 1774943003: blink: Rename platform/ methods to prefix with get when they collide. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: clash-platform: rebase-yayyyyyyyy 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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 Heap::decreaseAllocatedSpace(page->size());
131 Heap::orphanedPagePool()->addOrphanedPage(arenaIndex(), page); 131 Heap::getOrphanedPagePool()->addOrphanedPage(arenaIndex(), 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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 void BaseArena::prepareHeapForTermination() 238 void BaseArena::prepareHeapForTermination()
239 { 239 {
240 ASSERT(!m_firstUnsweptPage); 240 ASSERT(!m_firstUnsweptPage);
241 for (BasePage* page = m_firstPage; page; page = page->next()) { 241 for (BasePage* page = m_firstPage; page; page = page->next()) {
242 page->setTerminating(); 242 page->setTerminating();
243 } 243 }
244 } 244 }
245 245
246 void BaseArena::prepareForSweep() 246 void BaseArena::prepareForSweep()
247 { 247 {
248 ASSERT(threadState()->isInGC()); 248 ASSERT(getThreadState()->isInGC());
249 ASSERT(!m_firstUnsweptPage); 249 ASSERT(!m_firstUnsweptPage);
250 250
251 // Move all pages to a list of unswept pages. 251 // Move all pages to a list of unswept pages.
252 m_firstUnsweptPage = m_firstPage; 252 m_firstUnsweptPage = m_firstPage;
253 m_firstPage = nullptr; 253 m_firstPage = nullptr;
254 } 254 }
255 255
256 #if defined(ADDRESS_SANITIZER) 256 #if defined(ADDRESS_SANITIZER)
257 void BaseArena::poisonArena(BlinkGC::ObjectsToPoison objectsToPoison, BlinkGC::P oisoning poisoning) 257 void BaseArena::poisonArena(BlinkGC::ObjectsToPoison objectsToPoison, BlinkGC::P oisoning poisoning)
258 { 258 {
(...skipping 19 matching lines...) Expand all
278 page->poisonObjects(objectsToPoison, poisoning); 278 page->poisonObjects(objectsToPoison, poisoning);
279 } 279 }
280 #endif 280 #endif
281 281
282 Address BaseArena::lazySweep(size_t allocationSize, size_t gcInfoIndex) 282 Address BaseArena::lazySweep(size_t allocationSize, size_t gcInfoIndex)
283 { 283 {
284 // If there are no pages to be swept, return immediately. 284 // If there are no pages to be swept, return immediately.
285 if (!m_firstUnsweptPage) 285 if (!m_firstUnsweptPage)
286 return nullptr; 286 return nullptr;
287 287
288 RELEASE_ASSERT(threadState()->isSweepingInProgress()); 288 RELEASE_ASSERT(getThreadState()->isSweepingInProgress());
289 289
290 // lazySweepPages() can be called recursively if finalizers invoked in 290 // lazySweepPages() can be called recursively if finalizers invoked in
291 // page->sweep() allocate memory and the allocation triggers 291 // page->sweep() allocate memory and the allocation triggers
292 // lazySweepPages(). This check prevents the sweeping from being executed 292 // lazySweepPages(). This check prevents the sweeping from being executed
293 // recursively. 293 // recursively.
294 if (threadState()->sweepForbidden()) 294 if (getThreadState()->sweepForbidden())
295 return nullptr; 295 return nullptr;
296 296
297 TRACE_EVENT0("blink_gc", "BaseArena::lazySweepPages"); 297 TRACE_EVENT0("blink_gc", "BaseArena::lazySweepPages");
298 ThreadState::SweepForbiddenScope sweepForbidden(threadState()); 298 ThreadState::SweepForbiddenScope sweepForbidden(getThreadState());
299 ScriptForbiddenIfMainThreadScope scriptForbidden; 299 ScriptForbiddenIfMainThreadScope scriptForbidden;
300 300
301 double startTime = WTF::currentTimeMS(); 301 double startTime = WTF::currentTimeMS();
302 Address result = lazySweepPages(allocationSize, gcInfoIndex); 302 Address result = lazySweepPages(allocationSize, gcInfoIndex);
303 threadState()->accumulateSweepingTime(WTF::currentTimeMS() - startTime); 303 getThreadState()->accumulateSweepingTime(WTF::currentTimeMS() - startTime);
304 Heap::reportMemoryUsageForTracing(); 304 Heap::reportMemoryUsageForTracing();
305 305
306 return result; 306 return result;
307 } 307 }
308 308
309 void BaseArena::sweepUnsweptPage() 309 void BaseArena::sweepUnsweptPage()
310 { 310 {
311 BasePage* page = m_firstUnsweptPage; 311 BasePage* page = m_firstUnsweptPage;
312 if (page->isEmpty()) { 312 if (page->isEmpty()) {
313 page->unlink(&m_firstUnsweptPage); 313 page->unlink(&m_firstUnsweptPage);
314 page->removeFromHeap(); 314 page->removeFromHeap();
315 } else { 315 } else {
316 // Sweep a page and move the page from m_firstUnsweptPages to 316 // Sweep a page and move the page from m_firstUnsweptPages to
317 // m_firstPages. 317 // m_firstPages.
318 page->sweep(); 318 page->sweep();
319 page->unlink(&m_firstUnsweptPage); 319 page->unlink(&m_firstUnsweptPage);
320 page->link(&m_firstPage); 320 page->link(&m_firstPage);
321 page->markAsSwept(); 321 page->markAsSwept();
322 } 322 }
323 } 323 }
324 324
325 bool BaseArena::lazySweepWithDeadline(double deadlineSeconds) 325 bool BaseArena::lazySweepWithDeadline(double deadlineSeconds)
326 { 326 {
327 // It might be heavy to call Platform::current()->monotonicallyIncreasingTim eSeconds() 327 // It might be heavy to call Platform::current()->monotonicallyIncreasingTim eSeconds()
328 // per page (i.e., 128 KB sweep or one LargeObject sweep), so we check 328 // per page (i.e., 128 KB sweep or one LargeObject sweep), so we check
329 // the deadline per 10 pages. 329 // the deadline per 10 pages.
330 static const int deadlineCheckInterval = 10; 330 static const int deadlineCheckInterval = 10;
331 331
332 RELEASE_ASSERT(threadState()->isSweepingInProgress()); 332 RELEASE_ASSERT(getThreadState()->isSweepingInProgress());
333 ASSERT(threadState()->sweepForbidden()); 333 ASSERT(getThreadState()->sweepForbidden());
334 ASSERT(!threadState()->isMainThread() || ScriptForbiddenScope::isScriptForbi dden()); 334 ASSERT(!getThreadState()->isMainThread() || ScriptForbiddenScope::isScriptFo rbidden());
335 335
336 int pageCount = 1; 336 int pageCount = 1;
337 while (m_firstUnsweptPage) { 337 while (m_firstUnsweptPage) {
338 sweepUnsweptPage(); 338 sweepUnsweptPage();
339 if (pageCount % deadlineCheckInterval == 0) { 339 if (pageCount % deadlineCheckInterval == 0) {
340 if (deadlineSeconds <= monotonicallyIncreasingTime()) { 340 if (deadlineSeconds <= monotonicallyIncreasingTime()) {
341 // Deadline has come. 341 // Deadline has come.
342 Heap::reportMemoryUsageForTracing(); 342 Heap::reportMemoryUsageForTracing();
343 return !m_firstUnsweptPage; 343 return !m_firstUnsweptPage;
344 } 344 }
345 } 345 }
346 pageCount++; 346 pageCount++;
347 } 347 }
348 Heap::reportMemoryUsageForTracing(); 348 Heap::reportMemoryUsageForTracing();
349 return true; 349 return true;
350 } 350 }
351 351
352 void BaseArena::completeSweep() 352 void BaseArena::completeSweep()
353 { 353 {
354 RELEASE_ASSERT(threadState()->isSweepingInProgress()); 354 RELEASE_ASSERT(getThreadState()->isSweepingInProgress());
355 ASSERT(threadState()->sweepForbidden()); 355 ASSERT(getThreadState()->sweepForbidden());
356 ASSERT(!threadState()->isMainThread() || ScriptForbiddenScope::isScriptForbi dden()); 356 ASSERT(!getThreadState()->isMainThread() || ScriptForbiddenScope::isScriptFo rbidden());
357 357
358 while (m_firstUnsweptPage) { 358 while (m_firstUnsweptPage) {
359 sweepUnsweptPage(); 359 sweepUnsweptPage();
360 } 360 }
361 Heap::reportMemoryUsageForTracing(); 361 Heap::reportMemoryUsageForTracing();
362 } 362 }
363 363
364 NormalPageArena::NormalPageArena(ThreadState* state, int index) 364 NormalPageArena::NormalPageArena(ThreadState* state, int index)
365 : BaseArena(state, index) 365 : BaseArena(state, index)
366 , m_currentAllocationPoint(nullptr) 366 , m_currentAllocationPoint(nullptr)
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 { 409 {
410 if (m_freeList.takeSnapshot(dumpName)) { 410 if (m_freeList.takeSnapshot(dumpName)) {
411 WebMemoryAllocatorDump* bucketsDump = BlinkGCMemoryDumpProvider::instanc e()->createMemoryAllocatorDumpForCurrentGC(dumpName + "/buckets"); 411 WebMemoryAllocatorDump* bucketsDump = BlinkGCMemoryDumpProvider::instanc e()->createMemoryAllocatorDumpForCurrentGC(dumpName + "/buckets");
412 WebMemoryAllocatorDump* pagesDump = BlinkGCMemoryDumpProvider::instance( )->createMemoryAllocatorDumpForCurrentGC(dumpName + "/pages"); 412 WebMemoryAllocatorDump* pagesDump = BlinkGCMemoryDumpProvider::instance( )->createMemoryAllocatorDumpForCurrentGC(dumpName + "/pages");
413 BlinkGCMemoryDumpProvider::instance()->currentProcessMemoryDump()->addOw nershipEdge(pagesDump->guid(), bucketsDump->guid()); 413 BlinkGCMemoryDumpProvider::instance()->currentProcessMemoryDump()->addOw nershipEdge(pagesDump->guid(), bucketsDump->guid());
414 } 414 }
415 } 415 }
416 416
417 void NormalPageArena::allocatePage() 417 void NormalPageArena::allocatePage()
418 { 418 {
419 threadState()->shouldFlushHeapDoesNotContainCache(); 419 getThreadState()->shouldFlushHeapDoesNotContainCache();
420 PageMemory* pageMemory = Heap::freePagePool()->takeFreePage(arenaIndex()); 420 PageMemory* pageMemory = Heap::getFreePagePool()->takeFreePage(arenaIndex()) ;
421 421
422 if (!pageMemory) { 422 if (!pageMemory) {
423 // Allocate a memory region for blinkPagesPerRegion pages that 423 // Allocate a memory region for blinkPagesPerRegion pages that
424 // will each have the following layout. 424 // will each have the following layout.
425 // 425 //
426 // [ guard os page | ... payload ... | guard os page ] 426 // [ guard os page | ... payload ... | guard os page ]
427 // ^---{ aligned to blink page size } 427 // ^---{ aligned to blink page size }
428 PageMemoryRegion* region = PageMemoryRegion::allocateNormalPages(); 428 PageMemoryRegion* region = PageMemoryRegion::allocateNormalPages();
429 429
430 // Setup the PageMemory object for each of the pages in the region. 430 // Setup the PageMemory object for each of the pages in the region.
431 for (size_t i = 0; i < blinkPagesPerRegion; ++i) { 431 for (size_t i = 0; i < blinkPagesPerRegion; ++i) {
432 PageMemory* memory = PageMemory::setupPageMemoryInRegion(region, i * blinkPageSize, blinkPagePayloadSize()); 432 PageMemory* memory = PageMemory::setupPageMemoryInRegion(region, i * blinkPageSize, blinkPagePayloadSize());
433 // Take the first possible page ensuring that this thread actually 433 // Take the first possible page ensuring that this thread actually
434 // gets a page and add the rest to the page pool. 434 // gets a page and add the rest to the page pool.
435 if (!pageMemory) { 435 if (!pageMemory) {
436 bool result = memory->commit(); 436 bool result = memory->commit();
437 // If you hit the ASSERT, it will mean that you're hitting 437 // If you hit the ASSERT, it will mean that you're hitting
438 // the limit of the number of mmapped regions OS can support 438 // the limit of the number of mmapped regions OS can support
439 // (e.g., /proc/sys/vm/max_map_count in Linux). 439 // (e.g., /proc/sys/vm/max_map_count in Linux).
440 RELEASE_ASSERT(result); 440 RELEASE_ASSERT(result);
441 pageMemory = memory; 441 pageMemory = memory;
442 } else { 442 } else {
443 Heap::freePagePool()->addFreePage(arenaIndex(), memory); 443 Heap::getFreePagePool()->addFreePage(arenaIndex(), memory);
444 } 444 }
445 } 445 }
446 } 446 }
447 447
448 NormalPage* page = new (pageMemory->writableStart()) NormalPage(pageMemory, this); 448 NormalPage* page = new (pageMemory->writableStart()) NormalPage(pageMemory, this);
449 page->link(&m_firstPage); 449 page->link(&m_firstPage);
450 450
451 Heap::increaseAllocatedSpace(page->size()); 451 Heap::increaseAllocatedSpace(page->size());
452 #if ENABLE(ASSERT) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) 452 #if ENABLE(ASSERT) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER)
453 // Allow the following addToFreeList() to add the newly allocated memory 453 // Allow the following addToFreeList() to add the newly allocated memory
(...skipping 13 matching lines...) Expand all
467 467
468 if (page->terminating()) { 468 if (page->terminating()) {
469 // The thread is shutting down and this page is being removed as a part 469 // The thread is shutting down and this page is being removed as a part
470 // of the thread local GC. In that case the object could be traced in 470 // of the thread local GC. In that case the object could be traced in
471 // the next global GC if there is a dangling pointer from a live thread 471 // the next global GC if there is a dangling pointer from a live thread
472 // heap to this dead thread heap. To guard against this, we put the 472 // heap to this dead thread heap. To guard against this, we put the
473 // page into the orphaned page pool and zap the page memory. This 473 // page into the orphaned page pool and zap the page memory. This
474 // ensures that tracing the dangling pointer in the next global GC just 474 // ensures that tracing the dangling pointer in the next global GC just
475 // crashes instead of causing use-after-frees. After the next global 475 // crashes instead of causing use-after-frees. After the next global
476 // GC, the orphaned pages are removed. 476 // GC, the orphaned pages are removed.
477 Heap::orphanedPagePool()->addOrphanedPage(arenaIndex(), page); 477 Heap::getOrphanedPagePool()->addOrphanedPage(arenaIndex(), page);
478 } else { 478 } else {
479 PageMemory* memory = page->storage(); 479 PageMemory* memory = page->storage();
480 page->~NormalPage(); 480 page->~NormalPage();
481 Heap::freePagePool()->addFreePage(arenaIndex(), memory); 481 Heap::getFreePagePool()->addFreePage(arenaIndex(), memory);
482 } 482 }
483 } 483 }
484 484
485 bool NormalPageArena::coalesce() 485 bool NormalPageArena::coalesce()
486 { 486 {
487 // Don't coalesce arenas if there are not enough promptly freed entries 487 // Don't coalesce arenas if there are not enough promptly freed entries
488 // to be coalesced. 488 // to be coalesced.
489 // 489 //
490 // FIXME: This threshold is determined just to optimize blink_perf 490 // FIXME: This threshold is determined just to optimize blink_perf
491 // benchmarks. Coalescing is very sensitive to the threashold and 491 // benchmarks. Coalescing is very sensitive to the threashold and
492 // we need further investigations on the coalescing scheme. 492 // we need further investigations on the coalescing scheme.
493 if (m_promptlyFreedSize < 1024 * 1024) 493 if (m_promptlyFreedSize < 1024 * 1024)
494 return false; 494 return false;
495 495
496 if (threadState()->sweepForbidden()) 496 if (getThreadState()->sweepForbidden())
497 return false; 497 return false;
498 498
499 ASSERT(!hasCurrentAllocationArea()); 499 ASSERT(!hasCurrentAllocationArea());
500 TRACE_EVENT0("blink_gc", "BaseArena::coalesce"); 500 TRACE_EVENT0("blink_gc", "BaseArena::coalesce");
501 501
502 // Rebuild free lists. 502 // Rebuild free lists.
503 m_freeList.clear(); 503 m_freeList.clear();
504 size_t freedSize = 0; 504 size_t freedSize = 0;
505 for (NormalPage* page = static_cast<NormalPage*>(m_firstPage); page; page = static_cast<NormalPage*>(page->next())) { 505 for (NormalPage* page = static_cast<NormalPage*>(m_firstPage); page; page = static_cast<NormalPage*>(page->next())) {
506 Address startOfGap = page->payload(); 506 Address startOfGap = page->payload();
(...skipping 29 matching lines...) Expand all
536 if (startOfGap != headerAddress) 536 if (startOfGap != headerAddress)
537 addToFreeList(startOfGap, headerAddress - startOfGap); 537 addToFreeList(startOfGap, headerAddress - startOfGap);
538 538
539 headerAddress += size; 539 headerAddress += size;
540 startOfGap = headerAddress; 540 startOfGap = headerAddress;
541 } 541 }
542 542
543 if (startOfGap != page->payloadEnd()) 543 if (startOfGap != page->payloadEnd())
544 addToFreeList(startOfGap, page->payloadEnd() - startOfGap); 544 addToFreeList(startOfGap, page->payloadEnd() - startOfGap);
545 } 545 }
546 threadState()->decreaseAllocatedObjectSize(freedSize); 546 getThreadState()->decreaseAllocatedObjectSize(freedSize);
547 ASSERT(m_promptlyFreedSize == freedSize); 547 ASSERT(m_promptlyFreedSize == freedSize);
548 m_promptlyFreedSize = 0; 548 m_promptlyFreedSize = 0;
549 return true; 549 return true;
550 } 550 }
551 551
552 void NormalPageArena::promptlyFreeObject(HeapObjectHeader* header) 552 void NormalPageArena::promptlyFreeObject(HeapObjectHeader* header)
553 { 553 {
554 ASSERT(!threadState()->sweepForbidden()); 554 ASSERT(!getThreadState()->sweepForbidden());
555 ASSERT(header->checkHeader()); 555 ASSERT(header->checkHeader());
556 Address address = reinterpret_cast<Address>(header); 556 Address address = reinterpret_cast<Address>(header);
557 Address payload = header->payload(); 557 Address payload = header->payload();
558 size_t size = header->size(); 558 size_t size = header->size();
559 size_t payloadSize = header->payloadSize(); 559 size_t payloadSize = header->payloadSize();
560 ASSERT(size > 0); 560 ASSERT(size > 0);
561 ASSERT(pageFromObject(address) == findPageFromAddress(address)); 561 ASSERT(pageFromObject(address) == findPageFromAddress(address));
562 562
563 { 563 {
564 ThreadState::SweepForbiddenScope forbiddenScope(threadState()); 564 ThreadState::SweepForbiddenScope forbiddenScope(getThreadState());
565 header->finalize(payload, payloadSize); 565 header->finalize(payload, payloadSize);
566 if (address + size == m_currentAllocationPoint) { 566 if (address + size == m_currentAllocationPoint) {
567 m_currentAllocationPoint = address; 567 m_currentAllocationPoint = address;
568 setRemainingAllocationSize(m_remainingAllocationSize + size); 568 setRemainingAllocationSize(m_remainingAllocationSize + size);
569 SET_MEMORY_INACCESSIBLE(address, size); 569 SET_MEMORY_INACCESSIBLE(address, size);
570 return; 570 return;
571 } 571 }
572 SET_MEMORY_INACCESSIBLE(payload, payloadSize); 572 SET_MEMORY_INACCESSIBLE(payload, payloadSize);
573 header->markPromptlyFreed(); 573 header->markPromptlyFreed();
574 } 574 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 } 654 }
655 655
656 void NormalPageArena::setRemainingAllocationSize(size_t newRemainingAllocationSi ze) 656 void NormalPageArena::setRemainingAllocationSize(size_t newRemainingAllocationSi ze)
657 { 657 {
658 m_remainingAllocationSize = newRemainingAllocationSize; 658 m_remainingAllocationSize = newRemainingAllocationSize;
659 659
660 // Sync recorded allocated-object size: 660 // Sync recorded allocated-object size:
661 // - if previous alloc checkpoint is larger, allocation size has increased. 661 // - if previous alloc checkpoint is larger, allocation size has increased.
662 // - if smaller, a net reduction in size since last call to updateRemaining AllocationSize(). 662 // - if smaller, a net reduction in size since last call to updateRemaining AllocationSize().
663 if (m_lastRemainingAllocationSize > m_remainingAllocationSize) 663 if (m_lastRemainingAllocationSize > m_remainingAllocationSize)
664 threadState()->increaseAllocatedObjectSize(m_lastRemainingAllocationSize - m_remainingAllocationSize); 664 getThreadState()->increaseAllocatedObjectSize(m_lastRemainingAllocationS ize - m_remainingAllocationSize);
665 else if (m_lastRemainingAllocationSize != m_remainingAllocationSize) 665 else if (m_lastRemainingAllocationSize != m_remainingAllocationSize)
666 threadState()->decreaseAllocatedObjectSize(m_remainingAllocationSize - m _lastRemainingAllocationSize); 666 getThreadState()->decreaseAllocatedObjectSize(m_remainingAllocationSize - m_lastRemainingAllocationSize);
667 m_lastRemainingAllocationSize = m_remainingAllocationSize; 667 m_lastRemainingAllocationSize = m_remainingAllocationSize;
668 } 668 }
669 669
670 void NormalPageArena::updateRemainingAllocationSize() 670 void NormalPageArena::updateRemainingAllocationSize()
671 { 671 {
672 if (m_lastRemainingAllocationSize > remainingAllocationSize()) { 672 if (m_lastRemainingAllocationSize > remainingAllocationSize()) {
673 threadState()->increaseAllocatedObjectSize(m_lastRemainingAllocationSize - remainingAllocationSize()); 673 getThreadState()->increaseAllocatedObjectSize(m_lastRemainingAllocationS ize - remainingAllocationSize());
674 m_lastRemainingAllocationSize = remainingAllocationSize(); 674 m_lastRemainingAllocationSize = remainingAllocationSize();
675 } 675 }
676 ASSERT(m_lastRemainingAllocationSize == remainingAllocationSize()); 676 ASSERT(m_lastRemainingAllocationSize == remainingAllocationSize());
677 } 677 }
678 678
679 void NormalPageArena::setAllocationPoint(Address point, size_t size) 679 void NormalPageArena::setAllocationPoint(Address point, size_t size)
680 { 680 {
681 #if ENABLE(ASSERT) 681 #if ENABLE(ASSERT)
682 if (point) { 682 if (point) {
683 ASSERT(size); 683 ASSERT(size);
(...skipping 12 matching lines...) Expand all
696 696
697 Address NormalPageArena::outOfLineAllocate(size_t allocationSize, size_t gcInfoI ndex) 697 Address NormalPageArena::outOfLineAllocate(size_t allocationSize, size_t gcInfoI ndex)
698 { 698 {
699 ASSERT(allocationSize > remainingAllocationSize()); 699 ASSERT(allocationSize > remainingAllocationSize());
700 ASSERT(allocationSize >= allocationGranularity); 700 ASSERT(allocationSize >= allocationGranularity);
701 701
702 // 1. If this allocation is big enough, allocate a large object. 702 // 1. If this allocation is big enough, allocate a large object.
703 if (allocationSize >= largeObjectSizeThreshold) { 703 if (allocationSize >= largeObjectSizeThreshold) {
704 // TODO(sof): support eagerly finalized large objects, if ever needed. 704 // TODO(sof): support eagerly finalized large objects, if ever needed.
705 RELEASE_ASSERT(arenaIndex() != BlinkGC::EagerSweepArenaIndex); 705 RELEASE_ASSERT(arenaIndex() != BlinkGC::EagerSweepArenaIndex);
706 LargeObjectArena* largeObjectArena = static_cast<LargeObjectArena*>(thre adState()->arena(BlinkGC::LargeObjectArenaIndex)); 706 LargeObjectArena* largeObjectArena = static_cast<LargeObjectArena*>(getT hreadState()->arena(BlinkGC::LargeObjectArenaIndex));
707 Address largeObject = largeObjectArena->allocateLargeObjectPage(allocati onSize, gcInfoIndex); 707 Address largeObject = largeObjectArena->allocateLargeObjectPage(allocati onSize, gcInfoIndex);
708 ASAN_MARK_LARGE_VECTOR_CONTAINER(this, largeObject); 708 ASAN_MARK_LARGE_VECTOR_CONTAINER(this, largeObject);
709 return largeObject; 709 return largeObject;
710 } 710 }
711 711
712 // 2. Try to allocate from a free list. 712 // 2. Try to allocate from a free list.
713 updateRemainingAllocationSize(); 713 updateRemainingAllocationSize();
714 Address result = allocateFromFreeList(allocationSize, gcInfoIndex); 714 Address result = allocateFromFreeList(allocationSize, gcInfoIndex);
715 if (result) 715 if (result)
716 return result; 716 return result;
717 717
718 // 3. Reset the allocation point. 718 // 3. Reset the allocation point.
719 setAllocationPoint(nullptr, 0); 719 setAllocationPoint(nullptr, 0);
720 720
721 // 4. Lazily sweep pages of this heap until we find a freed area for 721 // 4. Lazily sweep pages of this heap until we find a freed area for
722 // this allocation or we finish sweeping all pages of this heap. 722 // this allocation or we finish sweeping all pages of this heap.
723 result = lazySweep(allocationSize, gcInfoIndex); 723 result = lazySweep(allocationSize, gcInfoIndex);
724 if (result) 724 if (result)
725 return result; 725 return result;
726 726
727 // 5. Coalesce promptly freed areas and then try to allocate from a free 727 // 5. Coalesce promptly freed areas and then try to allocate from a free
728 // list. 728 // list.
729 if (coalesce()) { 729 if (coalesce()) {
730 result = allocateFromFreeList(allocationSize, gcInfoIndex); 730 result = allocateFromFreeList(allocationSize, gcInfoIndex);
731 if (result) 731 if (result)
732 return result; 732 return result;
733 } 733 }
734 734
735 // 6. Complete sweeping. 735 // 6. Complete sweeping.
736 threadState()->completeSweep(); 736 getThreadState()->completeSweep();
737 737
738 // 7. Check if we should trigger a GC. 738 // 7. Check if we should trigger a GC.
739 threadState()->scheduleGCIfNeeded(); 739 getThreadState()->scheduleGCIfNeeded();
740 740
741 // 8. Add a new page to this heap. 741 // 8. Add a new page to this heap.
742 allocatePage(); 742 allocatePage();
743 743
744 // 9. Try to allocate from a free list. This allocation must succeed. 744 // 9. Try to allocate from a free list. This allocation must succeed.
745 result = allocateFromFreeList(allocationSize, gcInfoIndex); 745 result = allocateFromFreeList(allocationSize, gcInfoIndex);
746 RELEASE_ASSERT(result); 746 RELEASE_ASSERT(result);
747 return result; 747 return result;
748 } 748 }
749 749
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 ASSERT(!(allocationSize & allocationMask)); 790 ASSERT(!(allocationSize & allocationMask));
791 791
792 // 1. Try to sweep large objects more than allocationSize bytes 792 // 1. Try to sweep large objects more than allocationSize bytes
793 // before allocating a new large object. 793 // before allocating a new large object.
794 Address result = lazySweep(allocationSize, gcInfoIndex); 794 Address result = lazySweep(allocationSize, gcInfoIndex);
795 if (result) 795 if (result)
796 return result; 796 return result;
797 797
798 // 2. If we have failed in sweeping allocationSize bytes, 798 // 2. If we have failed in sweeping allocationSize bytes,
799 // we complete sweeping before allocating this large object. 799 // we complete sweeping before allocating this large object.
800 threadState()->completeSweep(); 800 getThreadState()->completeSweep();
801 801
802 // 3. Check if we should trigger a GC. 802 // 3. Check if we should trigger a GC.
803 threadState()->scheduleGCIfNeeded(); 803 getThreadState()->scheduleGCIfNeeded();
804 804
805 return doAllocateLargeObjectPage(allocationSize, gcInfoIndex); 805 return doAllocateLargeObjectPage(allocationSize, gcInfoIndex);
806 } 806 }
807 807
808 Address LargeObjectArena::doAllocateLargeObjectPage(size_t allocationSize, size_ t gcInfoIndex) 808 Address LargeObjectArena::doAllocateLargeObjectPage(size_t allocationSize, size_ t gcInfoIndex)
809 { 809 {
810 size_t largeObjectSize = LargeObjectPage::pageHeaderSize() + allocationSize; 810 size_t largeObjectSize = LargeObjectPage::pageHeaderSize() + allocationSize;
811 // If ASan is supported we add allocationGranularity bytes to the allocated 811 // If ASan is supported we add allocationGranularity bytes to the allocated
812 // space and poison that to detect overflows 812 // space and poison that to detect overflows
813 #if defined(ADDRESS_SANITIZER) 813 #if defined(ADDRESS_SANITIZER)
814 largeObjectSize += allocationGranularity; 814 largeObjectSize += allocationGranularity;
815 #endif 815 #endif
816 816
817 threadState()->shouldFlushHeapDoesNotContainCache(); 817 getThreadState()->shouldFlushHeapDoesNotContainCache();
818 PageMemory* pageMemory = PageMemory::allocate(largeObjectSize); 818 PageMemory* pageMemory = PageMemory::allocate(largeObjectSize);
819 Address largeObjectAddress = pageMemory->writableStart(); 819 Address largeObjectAddress = pageMemory->writableStart();
820 Address headerAddress = largeObjectAddress + LargeObjectPage::pageHeaderSize (); 820 Address headerAddress = largeObjectAddress + LargeObjectPage::pageHeaderSize ();
821 #if ENABLE(ASSERT) 821 #if ENABLE(ASSERT)
822 // Verify that the allocated PageMemory is expectedly zeroed. 822 // Verify that the allocated PageMemory is expectedly zeroed.
823 for (size_t i = 0; i < largeObjectSize; ++i) 823 for (size_t i = 0; i < largeObjectSize; ++i)
824 ASSERT(!largeObjectAddress[i]); 824 ASSERT(!largeObjectAddress[i]);
825 #endif 825 #endif
826 ASSERT(gcInfoIndex > 0); 826 ASSERT(gcInfoIndex > 0);
827 HeapObjectHeader* header = new (NotNull, headerAddress) HeapObjectHeader(lar geObjectSizeInHeader, gcInfoIndex); 827 HeapObjectHeader* header = new (NotNull, headerAddress) HeapObjectHeader(lar geObjectSizeInHeader, gcInfoIndex);
828 Address result = headerAddress + sizeof(*header); 828 Address result = headerAddress + sizeof(*header);
829 ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask)); 829 ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask));
830 LargeObjectPage* largeObject = new (largeObjectAddress) LargeObjectPage(page Memory, this, allocationSize); 830 LargeObjectPage* largeObject = new (largeObjectAddress) LargeObjectPage(page Memory, this, allocationSize);
831 ASSERT(header->checkHeader()); 831 ASSERT(header->checkHeader());
832 832
833 // Poison the object header and allocationGranularity bytes after the object 833 // Poison the object header and allocationGranularity bytes after the object
834 ASAN_POISON_MEMORY_REGION(header, sizeof(*header)); 834 ASAN_POISON_MEMORY_REGION(header, sizeof(*header));
835 ASAN_POISON_MEMORY_REGION(largeObject->getAddress() + largeObject->size(), a llocationGranularity); 835 ASAN_POISON_MEMORY_REGION(largeObject->getAddress() + largeObject->size(), a llocationGranularity);
836 836
837 largeObject->link(&m_firstPage); 837 largeObject->link(&m_firstPage);
838 838
839 Heap::increaseAllocatedSpace(largeObject->size()); 839 Heap::increaseAllocatedSpace(largeObject->size());
840 threadState()->increaseAllocatedObjectSize(largeObject->size()); 840 getThreadState()->increaseAllocatedObjectSize(largeObject->size());
841 return result; 841 return result;
842 } 842 }
843 843
844 void LargeObjectArena::freeLargeObjectPage(LargeObjectPage* object) 844 void LargeObjectArena::freeLargeObjectPage(LargeObjectPage* object)
845 { 845 {
846 ASAN_UNPOISON_MEMORY_REGION(object->payload(), object->payloadSize()); 846 ASAN_UNPOISON_MEMORY_REGION(object->payload(), object->payloadSize());
847 object->heapObjectHeader()->finalize(object->payload(), object->payloadSize( )); 847 object->heapObjectHeader()->finalize(object->payload(), object->payloadSize( ));
848 Heap::decreaseAllocatedSpace(object->size()); 848 Heap::decreaseAllocatedSpace(object->size());
849 849
850 // Unpoison the object header and allocationGranularity bytes after the 850 // Unpoison the object header and allocationGranularity bytes after the
851 // object before freeing. 851 // object before freeing.
852 ASAN_UNPOISON_MEMORY_REGION(object->heapObjectHeader(), sizeof(HeapObjectHea der)); 852 ASAN_UNPOISON_MEMORY_REGION(object->heapObjectHeader(), sizeof(HeapObjectHea der));
853 ASAN_UNPOISON_MEMORY_REGION(object->getAddress() + object->size(), allocatio nGranularity); 853 ASAN_UNPOISON_MEMORY_REGION(object->getAddress() + object->size(), allocatio nGranularity);
854 854
855 if (object->terminating()) { 855 if (object->terminating()) {
856 ASSERT(ThreadState::current()->isTerminating()); 856 ASSERT(ThreadState::current()->isTerminating());
857 // The thread is shutting down and this page is being removed as a part 857 // The thread is shutting down and this page is being removed as a part
858 // of the thread local GC. In that case the object could be traced in 858 // of the thread local GC. In that case the object could be traced in
859 // the next global GC if there is a dangling pointer from a live thread 859 // the next global GC if there is a dangling pointer from a live thread
860 // heap to this dead thread heap. To guard against this, we put the 860 // heap to this dead thread heap. To guard against this, we put the
861 // page into the orphaned page pool and zap the page memory. This 861 // page into the orphaned page pool and zap the page memory. This
862 // ensures that tracing the dangling pointer in the next global GC just 862 // ensures that tracing the dangling pointer in the next global GC just
863 // crashes instead of causing use-after-frees. After the next global 863 // crashes instead of causing use-after-frees. After the next global
864 // GC, the orphaned pages are removed. 864 // GC, the orphaned pages are removed.
865 Heap::orphanedPagePool()->addOrphanedPage(arenaIndex(), object); 865 Heap::getOrphanedPagePool()->addOrphanedPage(arenaIndex(), object);
866 } else { 866 } else {
867 ASSERT(!ThreadState::current()->isTerminating()); 867 ASSERT(!ThreadState::current()->isTerminating());
868 PageMemory* memory = object->storage(); 868 PageMemory* memory = object->storage();
869 object->~LargeObjectPage(); 869 object->~LargeObjectPage();
870 delete memory; 870 delete memory;
871 } 871 }
872 } 872 }
873 873
874 Address LargeObjectArena::lazySweepPages(size_t allocationSize, size_t gcInfoInd ex) 874 Address LargeObjectArena::lazySweepPages(size_t allocationSize, size_t gcInfoInd ex)
875 { 875 {
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
1170 } 1170 }
1171 if (startOfGap != payloadEnd()) { 1171 if (startOfGap != payloadEnd()) {
1172 pageArena->addToFreeList(startOfGap, payloadEnd() - startOfGap); 1172 pageArena->addToFreeList(startOfGap, payloadEnd() - startOfGap);
1173 #if !ENABLE(ASSERT) && !defined(LEAK_SANITIZER) && !defined(ADDRESS_SANITIZER) 1173 #if !ENABLE(ASSERT) && !defined(LEAK_SANITIZER) && !defined(ADDRESS_SANITIZER)
1174 if (Heap::isLowEndDevice()) 1174 if (Heap::isLowEndDevice())
1175 discardPages(startOfGap + sizeof(FreeListEntry), payloadEnd()); 1175 discardPages(startOfGap + sizeof(FreeListEntry), payloadEnd());
1176 #endif 1176 #endif
1177 } 1177 }
1178 1178
1179 if (markedObjectSize) 1179 if (markedObjectSize)
1180 pageArena->threadState()->increaseMarkedObjectSize(markedObjectSize); 1180 pageArena->getThreadState()->increaseMarkedObjectSize(markedObjectSize);
1181 } 1181 }
1182 1182
1183 void NormalPage::makeConsistentForGC() 1183 void NormalPage::makeConsistentForGC()
1184 { 1184 {
1185 size_t markedObjectSize = 0; 1185 size_t markedObjectSize = 0;
1186 for (Address headerAddress = payload(); headerAddress < payloadEnd();) { 1186 for (Address headerAddress = payload(); headerAddress < payloadEnd();) {
1187 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress); 1187 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress);
1188 ASSERT(header->size() < blinkPagePayloadSize()); 1188 ASSERT(header->size() < blinkPagePayloadSize());
1189 // Check if a free list entry first since we cannot call 1189 // Check if a free list entry first since we cannot call
1190 // isMarked on a free list entry. 1190 // isMarked on a free list entry.
1191 if (header->isFree()) { 1191 if (header->isFree()) {
1192 headerAddress += header->size(); 1192 headerAddress += header->size();
1193 continue; 1193 continue;
1194 } 1194 }
1195 ASSERT(header->checkHeader()); 1195 ASSERT(header->checkHeader());
1196 if (header->isMarked()) { 1196 if (header->isMarked()) {
1197 header->unmark(); 1197 header->unmark();
1198 markedObjectSize += header->size(); 1198 markedObjectSize += header->size();
1199 } else { 1199 } else {
1200 header->markDead(); 1200 header->markDead();
1201 } 1201 }
1202 headerAddress += header->size(); 1202 headerAddress += header->size();
1203 } 1203 }
1204 if (markedObjectSize) 1204 if (markedObjectSize)
1205 arenaForNormalPage()->threadState()->increaseMarkedObjectSize(markedObje ctSize); 1205 arenaForNormalPage()->getThreadState()->increaseMarkedObjectSize(markedO bjectSize);
1206 } 1206 }
1207 1207
1208 void NormalPage::makeConsistentForMutator() 1208 void NormalPage::makeConsistentForMutator()
1209 { 1209 {
1210 Address startOfGap = payload(); 1210 Address startOfGap = payload();
1211 for (Address headerAddress = payload(); headerAddress < payloadEnd();) { 1211 for (Address headerAddress = payload(); headerAddress < payloadEnd();) {
1212 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress); 1212 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress);
1213 size_t size = header->size(); 1213 size_t size = header->size();
1214 ASSERT(size < blinkPagePayloadSize()); 1214 ASSERT(size < blinkPagePayloadSize());
1215 if (header->isPromptlyFreed()) 1215 if (header->isPromptlyFreed())
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1459 } 1459 }
1460 1460
1461 void LargeObjectPage::removeFromHeap() 1461 void LargeObjectPage::removeFromHeap()
1462 { 1462 {
1463 static_cast<LargeObjectArena*>(arena())->freeLargeObjectPage(this); 1463 static_cast<LargeObjectArena*>(arena())->freeLargeObjectPage(this);
1464 } 1464 }
1465 1465
1466 void LargeObjectPage::sweep() 1466 void LargeObjectPage::sweep()
1467 { 1467 {
1468 heapObjectHeader()->unmark(); 1468 heapObjectHeader()->unmark();
1469 arena()->threadState()->increaseMarkedObjectSize(size()); 1469 arena()->getThreadState()->increaseMarkedObjectSize(size());
1470 } 1470 }
1471 1471
1472 void LargeObjectPage::makeConsistentForGC() 1472 void LargeObjectPage::makeConsistentForGC()
1473 { 1473 {
1474 HeapObjectHeader* header = heapObjectHeader(); 1474 HeapObjectHeader* header = heapObjectHeader();
1475 if (header->isMarked()) { 1475 if (header->isMarked()) {
1476 header->unmark(); 1476 header->unmark();
1477 arena()->threadState()->increaseMarkedObjectSize(size()); 1477 arena()->getThreadState()->increaseMarkedObjectSize(size());
1478 } else { 1478 } else {
1479 header->markDead(); 1479 header->markDead();
1480 } 1480 }
1481 } 1481 }
1482 1482
1483 void LargeObjectPage::makeConsistentForMutator() 1483 void LargeObjectPage::makeConsistentForMutator()
1484 { 1484 {
1485 HeapObjectHeader* header = heapObjectHeader(); 1485 HeapObjectHeader* header = heapObjectHeader();
1486 if (header->isMarked()) 1486 if (header->isMarked())
1487 header->unmark(); 1487 header->unmark();
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1588 1588
1589 m_hasEntries = true; 1589 m_hasEntries = true;
1590 size_t index = hash(address); 1590 size_t index = hash(address);
1591 ASSERT(!(index & 1)); 1591 ASSERT(!(index & 1));
1592 Address cachePage = roundToBlinkPageStart(address); 1592 Address cachePage = roundToBlinkPageStart(address);
1593 m_entries[index + 1] = m_entries[index]; 1593 m_entries[index + 1] = m_entries[index];
1594 m_entries[index] = cachePage; 1594 m_entries[index] = cachePage;
1595 } 1595 }
1596 1596
1597 } // namespace blink 1597 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/heap/HeapPage.h ('k') | third_party/WebKit/Source/platform/heap/HeapTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698