| 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 2483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2494 state->setGCState(ThreadState::GCRunning); | 2494 state->setGCState(ThreadState::GCRunning); |
| 2495 state->makeConsistentForSweeping(); | 2495 state->makeConsistentForSweeping(); |
| 2496 objectPayloadSize += state->objectPayloadSizeForTesting(); | 2496 objectPayloadSize += state->objectPayloadSizeForTesting(); |
| 2497 state->setGCState(ThreadState::EagerSweepScheduled); | 2497 state->setGCState(ThreadState::EagerSweepScheduled); |
| 2498 state->setGCState(ThreadState::Sweeping); | 2498 state->setGCState(ThreadState::Sweeping); |
| 2499 state->setGCState(ThreadState::NoGCScheduled); | 2499 state->setGCState(ThreadState::NoGCScheduled); |
| 2500 } | 2500 } |
| 2501 return objectPayloadSize; | 2501 return objectPayloadSize; |
| 2502 } | 2502 } |
| 2503 | 2503 |
| 2504 void HeapAllocator::backingFree(void* address) | |
| 2505 { | |
| 2506 if (!address) | |
| 2507 return; | |
| 2508 | |
| 2509 ThreadState* state = ThreadState::current(); | |
| 2510 if (state->sweepForbidden()) | |
| 2511 return; | |
| 2512 ASSERT(!state->isInGC()); | |
| 2513 | |
| 2514 // Don't promptly free large objects because their page is never reused. | |
| 2515 // Don't free backings allocated on other threads. | |
| 2516 BasePage* page = pageFromObject(address); | |
| 2517 if (page->isLargeObjectPage() || page->heap()->threadState() != state) | |
| 2518 return; | |
| 2519 | |
| 2520 HeapObjectHeader* header = HeapObjectHeader::fromPayload(address); | |
| 2521 header->checkHeader(); | |
| 2522 NormalPageHeap* heap = static_cast<NormalPage*>(page)->heapForNormalPage(); | |
| 2523 state->promptlyFreed(header->gcInfoIndex()); | |
| 2524 heap->promptlyFreeObject(header); | |
| 2525 } | |
| 2526 | |
| 2527 void HeapAllocator::freeVectorBacking(void* address) | |
| 2528 { | |
| 2529 backingFree(address); | |
| 2530 } | |
| 2531 | |
| 2532 void HeapAllocator::freeInlineVectorBacking(void* address) | |
| 2533 { | |
| 2534 backingFree(address); | |
| 2535 } | |
| 2536 | |
| 2537 void HeapAllocator::freeHashTableBacking(void* address) | |
| 2538 { | |
| 2539 backingFree(address); | |
| 2540 } | |
| 2541 | |
| 2542 bool HeapAllocator::backingExpand(void* address, size_t newSize) | |
| 2543 { | |
| 2544 if (!address) | |
| 2545 return false; | |
| 2546 | |
| 2547 ThreadState* state = ThreadState::current(); | |
| 2548 if (state->sweepForbidden()) | |
| 2549 return false; | |
| 2550 ASSERT(!state->isInGC()); | |
| 2551 ASSERT(state->isAllocationAllowed()); | |
| 2552 | |
| 2553 // FIXME: Support expand for large objects. | |
| 2554 // Don't expand backings allocated on other threads. | |
| 2555 BasePage* page = pageFromObject(address); | |
| 2556 if (page->isLargeObjectPage() || page->heap()->threadState() != state) | |
| 2557 return false; | |
| 2558 | |
| 2559 HeapObjectHeader* header = HeapObjectHeader::fromPayload(address); | |
| 2560 header->checkHeader(); | |
| 2561 NormalPageHeap* heap = static_cast<NormalPage*>(page)->heapForNormalPage(); | |
| 2562 bool succeed = heap->expandObject(header, newSize); | |
| 2563 if (succeed) | |
| 2564 state->allocationPointAdjusted(heap->heapIndex()); | |
| 2565 return succeed; | |
| 2566 } | |
| 2567 | |
| 2568 bool HeapAllocator::expandVectorBacking(void* address, size_t newSize) | |
| 2569 { | |
| 2570 return backingExpand(address, newSize); | |
| 2571 } | |
| 2572 | |
| 2573 bool HeapAllocator::expandInlineVectorBacking(void* address, size_t newSize) | |
| 2574 { | |
| 2575 return backingExpand(address, newSize); | |
| 2576 } | |
| 2577 | |
| 2578 bool HeapAllocator::expandHashTableBacking(void* address, size_t newSize) | |
| 2579 { | |
| 2580 return backingExpand(address, newSize); | |
| 2581 } | |
| 2582 | |
| 2583 void HeapAllocator::backingShrink(void* address, size_t quantizedCurrentSize, si
ze_t quantizedShrunkSize) | |
| 2584 { | |
| 2585 // We shrink the object only if the shrinking will make a non-small | |
| 2586 // prompt-free block. | |
| 2587 // FIXME: Optimize the threshold size. | |
| 2588 if (quantizedCurrentSize <= quantizedShrunkSize + sizeof(HeapObjectHeader) +
sizeof(void*) * 32) | |
| 2589 return; | |
| 2590 | |
| 2591 if (!address) | |
| 2592 return; | |
| 2593 | |
| 2594 ThreadState* state = ThreadState::current(); | |
| 2595 if (state->sweepForbidden()) | |
| 2596 return; | |
| 2597 ASSERT(!state->isInGC()); | |
| 2598 ASSERT(state->isAllocationAllowed()); | |
| 2599 | |
| 2600 // FIXME: Support shrink for large objects. | |
| 2601 // Don't shrink backings allocated on other threads. | |
| 2602 BasePage* page = pageFromObject(address); | |
| 2603 if (page->isLargeObjectPage() || page->heap()->threadState() != state) | |
| 2604 return; | |
| 2605 | |
| 2606 HeapObjectHeader* header = HeapObjectHeader::fromPayload(address); | |
| 2607 header->checkHeader(); | |
| 2608 NormalPageHeap* heap = static_cast<NormalPage*>(page)->heapForNormalPage(); | |
| 2609 bool succeed = heap->shrinkObject(header, quantizedShrunkSize); | |
| 2610 if (succeed) | |
| 2611 state->allocationPointAdjusted(heap->heapIndex()); | |
| 2612 } | |
| 2613 | |
| 2614 BasePage* Heap::lookup(Address address) | 2504 BasePage* Heap::lookup(Address address) |
| 2615 { | 2505 { |
| 2616 ASSERT(ThreadState::current()->isInGC()); | 2506 ASSERT(ThreadState::current()->isInGC()); |
| 2617 if (!s_regionTree) | 2507 if (!s_regionTree) |
| 2618 return nullptr; | 2508 return nullptr; |
| 2619 if (PageMemoryRegion* region = s_regionTree->lookup(address)) { | 2509 if (PageMemoryRegion* region = s_regionTree->lookup(address)) { |
| 2620 BasePage* page = region->pageFromAddress(address); | 2510 BasePage* page = region->pageFromAddress(address); |
| 2621 return page && !page->orphaned() ? page : nullptr; | 2511 return page && !page->orphaned() ? page : nullptr; |
| 2622 } | 2512 } |
| 2623 return nullptr; | 2513 return nullptr; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2725 size_t Heap::s_allocatedObjectSize = 0; | 2615 size_t Heap::s_allocatedObjectSize = 0; |
| 2726 size_t Heap::s_allocatedSpace = 0; | 2616 size_t Heap::s_allocatedSpace = 0; |
| 2727 size_t Heap::s_markedObjectSize = 0; | 2617 size_t Heap::s_markedObjectSize = 0; |
| 2728 // We don't want to use 0 KB for the initial value because it may end up | 2618 // We don't want to use 0 KB for the initial value because it may end up |
| 2729 // triggering the first GC of some thread too prematurely. | 2619 // triggering the first GC of some thread too prematurely. |
| 2730 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; | 2620 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; |
| 2731 size_t Heap::s_externalObjectSizeAtLastGC = 0; | 2621 size_t Heap::s_externalObjectSizeAtLastGC = 0; |
| 2732 double Heap::s_estimatedMarkingTimePerByte = 0.0; | 2622 double Heap::s_estimatedMarkingTimePerByte = 0.0; |
| 2733 | 2623 |
| 2734 } // namespace blink | 2624 } // namespace blink |
| OLD | NEW |