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 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 // Sweep a page and move the page from m_firstUnsweptPages to | 294 // Sweep a page and move the page from m_firstUnsweptPages to |
295 // m_firstPages. | 295 // m_firstPages. |
296 page->sweep(); | 296 page->sweep(); |
297 page->unlink(&m_firstUnsweptPage); | 297 page->unlink(&m_firstUnsweptPage); |
298 page->link(&m_firstPage); | 298 page->link(&m_firstPage); |
299 page->markAsSwept(); | 299 page->markAsSwept(); |
300 } | 300 } |
301 } | 301 } |
302 | 302 |
303 bool BaseArena::lazySweepWithDeadline(double deadlineSeconds) { | 303 bool BaseArena::lazySweepWithDeadline(double deadlineSeconds) { |
304 // It might be heavy to call Platform::current()->monotonicallyIncreasingTimeS
econds() | 304 // It might be heavy to call |
305 // per page (i.e., 128 KB sweep or one LargeObject sweep), so we check | 305 // Platform::current()->monotonicallyIncreasingTimeSeconds() per page (i.e., |
306 // the deadline per 10 pages. | 306 // 128 KB sweep or one LargeObject sweep), so we check the deadline per 10 |
| 307 // pages. |
307 static const int deadlineCheckInterval = 10; | 308 static const int deadlineCheckInterval = 10; |
308 | 309 |
309 RELEASE_ASSERT(getThreadState()->isSweepingInProgress()); | 310 RELEASE_ASSERT(getThreadState()->isSweepingInProgress()); |
310 ASSERT(getThreadState()->sweepForbidden()); | 311 ASSERT(getThreadState()->sweepForbidden()); |
311 ASSERT(!getThreadState()->isMainThread() || | 312 ASSERT(!getThreadState()->isMainThread() || |
312 ScriptForbiddenScope::isScriptForbidden()); | 313 ScriptForbiddenScope::isScriptForbidden()); |
313 | 314 |
314 NormalPageArena* normalArena = nullptr; | 315 NormalPageArena* normalArena = nullptr; |
315 if (m_firstUnsweptPage && !m_firstUnsweptPage->isLargeObjectPage()) { | 316 if (m_firstUnsweptPage && !m_firstUnsweptPage->isLargeObjectPage()) { |
316 // Mark this NormalPageArena as being lazily swept. | 317 // Mark this NormalPageArena as being lazily swept. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 LargeObjectArena* largeObjectArena = static_cast<LargeObjectArena*>( | 358 LargeObjectArena* largeObjectArena = static_cast<LargeObjectArena*>( |
358 getThreadState()->arena(BlinkGC::LargeObjectArenaIndex)); | 359 getThreadState()->arena(BlinkGC::LargeObjectArenaIndex)); |
359 Address largeObject = | 360 Address largeObject = |
360 largeObjectArena->allocateLargeObjectPage(allocationSize, gcInfoIndex); | 361 largeObjectArena->allocateLargeObjectPage(allocationSize, gcInfoIndex); |
361 ASAN_MARK_LARGE_VECTOR_CONTAINER(this, largeObject); | 362 ASAN_MARK_LARGE_VECTOR_CONTAINER(this, largeObject); |
362 return largeObject; | 363 return largeObject; |
363 } | 364 } |
364 | 365 |
365 bool BaseArena::willObjectBeLazilySwept(BasePage* page, | 366 bool BaseArena::willObjectBeLazilySwept(BasePage* page, |
366 void* objectPointer) const { | 367 void* objectPointer) const { |
367 // If not on the current page being (potentially) lazily swept, |objectPointer
| | 368 // If not on the current page being (potentially) lazily swept, |
368 // is an unmarked, sweepable object. | 369 // |objectPointer| is an unmarked, sweepable object. |
369 if (page != m_firstUnsweptPage) | 370 if (page != m_firstUnsweptPage) |
370 return true; | 371 return true; |
371 | 372 |
372 DCHECK(!page->isLargeObjectPage()); | 373 DCHECK(!page->isLargeObjectPage()); |
373 // Check if the arena is currently being lazily swept. | 374 // Check if the arena is currently being lazily swept. |
374 NormalPage* normalPage = reinterpret_cast<NormalPage*>(page); | 375 NormalPage* normalPage = reinterpret_cast<NormalPage*>(page); |
375 NormalPageArena* normalArena = normalPage->arenaForNormalPage(); | 376 NormalPageArena* normalArena = normalPage->arenaForNormalPage(); |
376 if (!normalArena->isLazySweeping()) | 377 if (!normalArena->isLazySweeping()) |
377 return true; | 378 return true; |
378 | 379 |
379 // Rare special case: unmarked object is on the page being lazily swept, | 380 // Rare special case: unmarked object is on the page being lazily swept, |
380 // and a finalizer for an object on that page calls ThreadHeap::willObjectBeLa
zilySwept(). | 381 // and a finalizer for an object on that page calls |
| 382 // ThreadHeap::willObjectBeLazilySwept(). |
381 // | 383 // |
382 // Need to determine if |objectPointer| represents a live (unmarked) object or
an | 384 // Need to determine if |objectPointer| represents a live (unmarked) object or |
383 // unmarked object that will be lazily swept later. As lazy page sweeping | 385 // an unmarked object that will be lazily swept later. As lazy page sweeping |
384 // doesn't record a frontier pointer representing how far along it is, the | 386 // doesn't record a frontier pointer representing how far along it is, the |
385 // page is scanned from the start, skipping past freed & unmarked regions. | 387 // page is scanned from the start, skipping past freed & unmarked regions. |
386 // | 388 // |
387 // If no marked objects are encountered before |objectPointer|, we know | 389 // If no marked objects are encountered before |objectPointer|, we know that |
388 // that the finalizing object calling willObjectBeLazilySwept() comes later, | 390 // the finalizing object calling willObjectBeLazilySwept() comes later, and |
389 // and |objectPointer| has been deemed to be alive already (=> it won't be swe
pt.) | 391 // |objectPointer| has been deemed to be alive already (=> it won't be swept.) |
390 // | 392 // |
391 // If a marked object is encountered before |objectPointer|, it will | 393 // If a marked object is encountered before |objectPointer|, it will |
392 // not have been lazily swept past already. Hence it represents an unmarked, | 394 // not have been lazily swept past already. Hence it represents an unmarked, |
393 // sweepable object. | 395 // sweepable object. |
394 // | 396 // |
395 // As willObjectBeLazilySwept() is used rarely and it happening to be | 397 // As willObjectBeLazilySwept() is used rarely and it happening to be |
396 // used while runnning a finalizer on the page being lazily swept is | 398 // used while runnning a finalizer on the page being lazily swept is |
397 // even rarer, the page scan is considered acceptable and something | 399 // even rarer, the page scan is considered acceptable and something |
398 // really wanted -- willObjectBeLazilySwept()'s result can be trusted. | 400 // really wanted -- willObjectBeLazilySwept()'s result can be trusted. |
399 Address pageEnd = normalPage->payloadEnd(); | 401 Address pageEnd = normalPage->payloadEnd(); |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 } | 730 } |
729 return result; | 731 return result; |
730 } | 732 } |
731 | 733 |
732 void NormalPageArena::setRemainingAllocationSize( | 734 void NormalPageArena::setRemainingAllocationSize( |
733 size_t newRemainingAllocationSize) { | 735 size_t newRemainingAllocationSize) { |
734 m_remainingAllocationSize = newRemainingAllocationSize; | 736 m_remainingAllocationSize = newRemainingAllocationSize; |
735 | 737 |
736 // Sync recorded allocated-object size: | 738 // Sync recorded allocated-object size: |
737 // - if previous alloc checkpoint is larger, allocation size has increased. | 739 // - if previous alloc checkpoint is larger, allocation size has increased. |
738 // - if smaller, a net reduction in size since last call to updateRemainingAl
locationSize(). | 740 // - if smaller, a net reduction in size since last call to |
| 741 // updateRemainingAllocationSize(). |
739 if (m_lastRemainingAllocationSize > m_remainingAllocationSize) | 742 if (m_lastRemainingAllocationSize > m_remainingAllocationSize) |
740 getThreadState()->increaseAllocatedObjectSize( | 743 getThreadState()->increaseAllocatedObjectSize( |
741 m_lastRemainingAllocationSize - m_remainingAllocationSize); | 744 m_lastRemainingAllocationSize - m_remainingAllocationSize); |
742 else if (m_lastRemainingAllocationSize != m_remainingAllocationSize) | 745 else if (m_lastRemainingAllocationSize != m_remainingAllocationSize) |
743 getThreadState()->decreaseAllocatedObjectSize( | 746 getThreadState()->decreaseAllocatedObjectSize( |
744 m_remainingAllocationSize - m_lastRemainingAllocationSize); | 747 m_remainingAllocationSize - m_lastRemainingAllocationSize); |
745 m_lastRemainingAllocationSize = m_remainingAllocationSize; | 748 m_lastRemainingAllocationSize = m_remainingAllocationSize; |
746 } | 749 } |
747 | 750 |
748 void NormalPageArena::updateRemainingAllocationSize() { | 751 void NormalPageArena::updateRemainingAllocationSize() { |
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1476 pageDump->AddScalar("live_size", "bytes", liveSize); | 1479 pageDump->AddScalar("live_size", "bytes", liveSize); |
1477 pageDump->AddScalar("dead_size", "bytes", deadSize); | 1480 pageDump->AddScalar("dead_size", "bytes", deadSize); |
1478 pageDump->AddScalar("free_size", "bytes", freeSize); | 1481 pageDump->AddScalar("free_size", "bytes", freeSize); |
1479 heapInfo.freeSize += freeSize; | 1482 heapInfo.freeSize += freeSize; |
1480 heapInfo.freeCount += freeCount; | 1483 heapInfo.freeCount += freeCount; |
1481 } | 1484 } |
1482 | 1485 |
1483 #if ENABLE(ASSERT) | 1486 #if ENABLE(ASSERT) |
1484 bool NormalPage::contains(Address addr) { | 1487 bool NormalPage::contains(Address addr) { |
1485 Address blinkPageStart = roundToBlinkPageStart(getAddress()); | 1488 Address blinkPageStart = roundToBlinkPageStart(getAddress()); |
1486 ASSERT( | 1489 // Page is at aligned address plus guard page size. |
1487 blinkPageStart == | 1490 ASSERT(blinkPageStart == getAddress() - blinkGuardPageSize); |
1488 getAddress() - | |
1489 blinkGuardPageSize); // Page is at aligned address plus guard page si
ze. | |
1490 return blinkPageStart <= addr && addr < blinkPageStart + blinkPageSize; | 1491 return blinkPageStart <= addr && addr < blinkPageStart + blinkPageSize; |
1491 } | 1492 } |
1492 #endif | 1493 #endif |
1493 | 1494 |
1494 LargeObjectPage::LargeObjectPage(PageMemory* storage, | 1495 LargeObjectPage::LargeObjectPage(PageMemory* storage, |
1495 BaseArena* arena, | 1496 BaseArena* arena, |
1496 size_t payloadSize) | 1497 size_t payloadSize) |
1497 : BasePage(storage, arena), | 1498 : BasePage(storage, arena), |
1498 m_payloadSize(payloadSize) | 1499 m_payloadSize(payloadSize) |
1499 #if ENABLE(ASAN_CONTAINER_ANNOTATIONS) | 1500 #if ENABLE(ASAN_CONTAINER_ANNOTATIONS) |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1630 | 1631 |
1631 m_hasEntries = true; | 1632 m_hasEntries = true; |
1632 size_t index = hash(address); | 1633 size_t index = hash(address); |
1633 ASSERT(!(index & 1)); | 1634 ASSERT(!(index & 1)); |
1634 Address cachePage = roundToBlinkPageStart(address); | 1635 Address cachePage = roundToBlinkPageStart(address); |
1635 m_entries[index + 1] = m_entries[index]; | 1636 m_entries[index + 1] = m_entries[index]; |
1636 m_entries[index] = cachePage; | 1637 m_entries[index] = cachePage; |
1637 } | 1638 } |
1638 | 1639 |
1639 } // namespace blink | 1640 } // namespace blink |
OLD | NEW |