Chromium Code Reviews| 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 // such a reference. | 294 // such a reference. |
| 295 template <typename T> | 295 template <typename T> |
| 296 NO_SANITIZE_ADDRESS static bool WillObjectBeLazilySwept( | 296 NO_SANITIZE_ADDRESS static bool WillObjectBeLazilySwept( |
| 297 const T* object_pointer) { | 297 const T* object_pointer) { |
| 298 static_assert(IsGarbageCollectedType<T>::value, | 298 static_assert(IsGarbageCollectedType<T>::value, |
| 299 "only objects deriving from GarbageCollected can be used."); | 299 "only objects deriving from GarbageCollected can be used."); |
| 300 BasePage* page = PageFromObject(object_pointer); | 300 BasePage* page = PageFromObject(object_pointer); |
| 301 // Page has been swept and it is still alive. | 301 // Page has been swept and it is still alive. |
| 302 if (page->HasBeenSwept()) | 302 if (page->HasBeenSwept()) |
| 303 return false; | 303 return false; |
| 304 ASSERT(page->Arena()->GetThreadState()->IsSweepingInProgress()); | 304 DCHECK(page->Arena()->GetThreadState()->IsSweepingInProgress()); |
| 305 | 305 |
| 306 // If marked and alive, the object hasn't yet been swept..and won't | 306 // If marked and alive, the object hasn't yet been swept..and won't |
| 307 // be once its page is processed. | 307 // be once its page is processed. |
| 308 if (ThreadHeap::IsHeapObjectAlive(const_cast<T*>(object_pointer))) | 308 if (ThreadHeap::IsHeapObjectAlive(const_cast<T*>(object_pointer))) |
| 309 return false; | 309 return false; |
| 310 | 310 |
| 311 if (page->IsLargeObjectPage()) | 311 if (page->IsLargeObjectPage()) |
| 312 return true; | 312 return true; |
| 313 | 313 |
| 314 // If the object is unmarked, it may be on the page currently being | 314 // If the object is unmarked, it may be on the page currently being |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 412 void FlushHeapDoesNotContainCache(); | 412 void FlushHeapDoesNotContainCache(); |
| 413 | 413 |
| 414 PagePool* GetFreePagePool() { return free_page_pool_.get(); } | 414 PagePool* GetFreePagePool() { return free_page_pool_.get(); } |
| 415 | 415 |
| 416 // This look-up uses the region search tree and a negative contains cache to | 416 // This look-up uses the region search tree and a negative contains cache to |
| 417 // provide an efficient mapping from arbitrary addresses to the containing | 417 // provide an efficient mapping from arbitrary addresses to the containing |
| 418 // heap-page if one exists. | 418 // heap-page if one exists. |
| 419 BasePage* LookupPageForAddress(Address); | 419 BasePage* LookupPageForAddress(Address); |
| 420 | 420 |
| 421 static const GCInfo* GcInfo(size_t gc_info_index) { | 421 static const GCInfo* GcInfo(size_t gc_info_index) { |
| 422 ASSERT(gc_info_index >= 1); | 422 DCHECK_GE(gc_info_index, 1u); |
| 423 ASSERT(gc_info_index < GCInfoTable::kMaxIndex); | 423 DCHECK(gc_info_index < GCInfoTable::kMaxIndex); |
|
Hwanseung Lee
2017/04/20 00:30:42
when replaced to DCHECK_LT, it was cause of build
| |
| 424 ASSERT(g_gc_info_table); | 424 DCHECK(g_gc_info_table); |
| 425 const GCInfo* info = g_gc_info_table[gc_info_index]; | 425 const GCInfo* info = g_gc_info_table[gc_info_index]; |
| 426 ASSERT(info); | 426 DCHECK(info); |
| 427 return info; | 427 return info; |
| 428 } | 428 } |
| 429 | 429 |
| 430 static void ReportMemoryUsageHistogram(); | 430 static void ReportMemoryUsageHistogram(); |
| 431 static void ReportMemoryUsageForTracing(); | 431 static void ReportMemoryUsageForTracing(); |
| 432 | 432 |
| 433 HeapCompact* Compaction(); | 433 HeapCompact* Compaction(); |
| 434 | 434 |
| 435 private: | 435 private: |
| 436 // Reset counters that track live and allocated-since-last-GC sizes. | 436 // Reset counters that track live and allocated-since-last-GC sizes. |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 565 public: | 565 public: |
| 566 ~VerifyEagerFinalization() { | 566 ~VerifyEagerFinalization() { |
| 567 // If this assert triggers, the class annotated as eagerly | 567 // If this assert triggers, the class annotated as eagerly |
| 568 // finalized ended up not being allocated on the heap | 568 // finalized ended up not being allocated on the heap |
| 569 // set aside for eager finalization. The reason is most | 569 // set aside for eager finalization. The reason is most |
| 570 // likely that the effective 'operator new' overload for | 570 // likely that the effective 'operator new' overload for |
| 571 // this class' leftmost base is for a class that is not | 571 // this class' leftmost base is for a class that is not |
| 572 // eagerly finalized. Declaring and defining an 'operator new' | 572 // eagerly finalized. Declaring and defining an 'operator new' |
| 573 // for this class is what's required -- consider using | 573 // for this class is what's required -- consider using |
| 574 // DECLARE_EAGER_FINALIZATION_OPERATOR_NEW(). | 574 // DECLARE_EAGER_FINALIZATION_OPERATOR_NEW(). |
| 575 ASSERT(IS_EAGERLY_FINALIZED()); | 575 DCHECK(IS_EAGERLY_FINALIZED()); |
| 576 } | 576 } |
| 577 }; | 577 }; |
| 578 #define EAGERLY_FINALIZE() \ | 578 #define EAGERLY_FINALIZE() \ |
| 579 private: \ | 579 private: \ |
| 580 VerifyEagerFinalization verify_eager_finalization_; \ | 580 VerifyEagerFinalization verify_eager_finalization_; \ |
| 581 \ | 581 \ |
| 582 public: \ | 582 public: \ |
| 583 typedef int IsEagerlyFinalizedMarker | 583 typedef int IsEagerlyFinalizedMarker |
| 584 #else | 584 #else |
| 585 #define EAGERLY_FINALIZE() \ | 585 #define EAGERLY_FINALIZE() \ |
| 586 public: \ | 586 public: \ |
| 587 typedef int IsEagerlyFinalizedMarker | 587 typedef int IsEagerlyFinalizedMarker |
| 588 #endif | 588 #endif |
| 589 | 589 |
| 590 inline Address ThreadHeap::AllocateOnArenaIndex(ThreadState* state, | 590 inline Address ThreadHeap::AllocateOnArenaIndex(ThreadState* state, |
| 591 size_t size, | 591 size_t size, |
| 592 int arena_index, | 592 int arena_index, |
| 593 size_t gc_info_index, | 593 size_t gc_info_index, |
| 594 const char* type_name) { | 594 const char* type_name) { |
| 595 ASSERT(state->IsAllocationAllowed()); | 595 DCHECK(state->IsAllocationAllowed()); |
| 596 ASSERT(arena_index != BlinkGC::kLargeObjectArenaIndex); | 596 DCHECK_NE(arena_index, BlinkGC::kLargeObjectArenaIndex); |
| 597 NormalPageArena* arena = | 597 NormalPageArena* arena = |
| 598 static_cast<NormalPageArena*>(state->Arena(arena_index)); | 598 static_cast<NormalPageArena*>(state->Arena(arena_index)); |
| 599 Address address = | 599 Address address = |
| 600 arena->AllocateObject(AllocationSizeFromSize(size), gc_info_index); | 600 arena->AllocateObject(AllocationSizeFromSize(size), gc_info_index); |
| 601 HeapAllocHooks::AllocationHookIfEnabled(address, size, type_name); | 601 HeapAllocHooks::AllocationHookIfEnabled(address, size, type_name); |
| 602 return address; | 602 return address; |
| 603 } | 603 } |
| 604 | 604 |
| 605 template <typename T> | 605 template <typename T> |
| 606 Address ThreadHeap::Allocate(size_t size, bool eagerly_sweep) { | 606 Address ThreadHeap::Allocate(size_t size, bool eagerly_sweep) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 620 | 620 |
| 621 // TODO(sof): promptly free the previous object. | 621 // TODO(sof): promptly free the previous object. |
| 622 if (!size) { | 622 if (!size) { |
| 623 // If the new size is 0 this is considered equivalent to free(previous). | 623 // If the new size is 0 this is considered equivalent to free(previous). |
| 624 return nullptr; | 624 return nullptr; |
| 625 } | 625 } |
| 626 | 626 |
| 627 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState(); | 627 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState(); |
| 628 HeapObjectHeader* previous_header = HeapObjectHeader::FromPayload(previous); | 628 HeapObjectHeader* previous_header = HeapObjectHeader::FromPayload(previous); |
| 629 BasePage* page = PageFromObject(previous_header); | 629 BasePage* page = PageFromObject(previous_header); |
| 630 ASSERT(page); | 630 DCHECK(page); |
| 631 | 631 |
| 632 // Determine arena index of new allocation. | 632 // Determine arena index of new allocation. |
| 633 int arena_index; | 633 int arena_index; |
| 634 if (size >= kLargeObjectSizeThreshold) { | 634 if (size >= kLargeObjectSizeThreshold) { |
| 635 arena_index = BlinkGC::kLargeObjectArenaIndex; | 635 arena_index = BlinkGC::kLargeObjectArenaIndex; |
| 636 } else { | 636 } else { |
| 637 arena_index = page->Arena()->ArenaIndex(); | 637 arena_index = page->Arena()->ArenaIndex(); |
| 638 if (IsNormalArenaIndex(arena_index) || | 638 if (IsNormalArenaIndex(arena_index) || |
| 639 arena_index == BlinkGC::kLargeObjectArenaIndex) | 639 arena_index == BlinkGC::kLargeObjectArenaIndex) |
| 640 arena_index = ArenaIndexForObjectSize(size); | 640 arena_index = ArenaIndexForObjectSize(size); |
| 641 } | 641 } |
| 642 | 642 |
| 643 size_t gc_info_index = GCInfoTrait<T>::Index(); | 643 size_t gc_info_index = GCInfoTrait<T>::Index(); |
| 644 // TODO(haraken): We don't support reallocate() for finalizable objects. | 644 // TODO(haraken): We don't support reallocate() for finalizable objects. |
| 645 ASSERT(!ThreadHeap::GcInfo(previous_header->GcInfoIndex())->HasFinalizer()); | 645 DCHECK(!ThreadHeap::GcInfo(previous_header->GcInfoIndex())->HasFinalizer()); |
| 646 ASSERT(previous_header->GcInfoIndex() == gc_info_index); | 646 DCHECK_EQ(previous_header->GcInfoIndex(), gc_info_index); |
| 647 HeapAllocHooks::FreeHookIfEnabled(static_cast<Address>(previous)); | 647 HeapAllocHooks::FreeHookIfEnabled(static_cast<Address>(previous)); |
| 648 Address address; | 648 Address address; |
| 649 if (arena_index == BlinkGC::kLargeObjectArenaIndex) { | 649 if (arena_index == BlinkGC::kLargeObjectArenaIndex) { |
| 650 address = page->Arena()->AllocateLargeObject(AllocationSizeFromSize(size), | 650 address = page->Arena()->AllocateLargeObject(AllocationSizeFromSize(size), |
| 651 gc_info_index); | 651 gc_info_index); |
| 652 } else { | 652 } else { |
| 653 const char* type_name = WTF_HEAP_PROFILER_TYPE_NAME(T); | 653 const char* type_name = WTF_HEAP_PROFILER_TYPE_NAME(T); |
| 654 address = ThreadHeap::AllocateOnArenaIndex(state, size, arena_index, | 654 address = ThreadHeap::AllocateOnArenaIndex(state, size, arena_index, |
| 655 gc_info_index, type_name); | 655 gc_info_index, type_name); |
| 656 } | 656 } |
| 657 size_t copy_size = previous_header->PayloadSize(); | 657 size_t copy_size = previous_header->PayloadSize(); |
| 658 if (copy_size > size) | 658 if (copy_size > size) |
| 659 copy_size = size; | 659 copy_size = size; |
| 660 memcpy(address, previous, copy_size); | 660 memcpy(address, previous, copy_size); |
| 661 return address; | 661 return address; |
| 662 } | 662 } |
| 663 | 663 |
| 664 template <typename T> | 664 template <typename T> |
| 665 void Visitor::HandleWeakCell(Visitor* self, void* object) { | 665 void Visitor::HandleWeakCell(Visitor* self, void* object) { |
| 666 T** cell = reinterpret_cast<T**>(object); | 666 T** cell = reinterpret_cast<T**>(object); |
| 667 if (*cell && !ObjectAliveTrait<T>::IsHeapObjectAlive(*cell)) | 667 if (*cell && !ObjectAliveTrait<T>::IsHeapObjectAlive(*cell)) |
| 668 *cell = nullptr; | 668 *cell = nullptr; |
| 669 } | 669 } |
| 670 | 670 |
| 671 } // namespace blink | 671 } // namespace blink |
| 672 | 672 |
| 673 #include "platform/heap/VisitorImpl.h" | 673 #include "platform/heap/VisitorImpl.h" |
| 674 | 674 |
| 675 #endif // Heap_h | 675 #endif // Heap_h |
| OLD | NEW |