| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/heap/spaces.h" | 5 #include "src/heap/spaces.h" |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
| 9 #include "src/base/platform/semaphore.h" | 9 #include "src/base/platform/semaphore.h" |
| 10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 chunk->typed_old_to_old_slots_ = nullptr; | 493 chunk->typed_old_to_old_slots_ = nullptr; |
| 494 chunk->skip_list_ = nullptr; | 494 chunk->skip_list_ = nullptr; |
| 495 chunk->write_barrier_counter_ = kWriteBarrierCounterGranularity; | 495 chunk->write_barrier_counter_ = kWriteBarrierCounterGranularity; |
| 496 chunk->progress_bar_ = 0; | 496 chunk->progress_bar_ = 0; |
| 497 chunk->high_water_mark_.SetValue(static_cast<intptr_t>(area_start - base)); | 497 chunk->high_water_mark_.SetValue(static_cast<intptr_t>(area_start - base)); |
| 498 chunk->concurrent_sweeping_state().SetValue(kSweepingDone); | 498 chunk->concurrent_sweeping_state().SetValue(kSweepingDone); |
| 499 chunk->mutex_ = new base::Mutex(); | 499 chunk->mutex_ = new base::Mutex(); |
| 500 chunk->available_in_free_list_ = 0; | 500 chunk->available_in_free_list_ = 0; |
| 501 chunk->wasted_memory_ = 0; | 501 chunk->wasted_memory_ = 0; |
| 502 chunk->ResetLiveBytes(); | 502 chunk->ResetLiveBytes(); |
| 503 Bitmap::Clear(chunk); | 503 chunk->ClearLiveness(); |
| 504 chunk->set_next_chunk(nullptr); | 504 chunk->set_next_chunk(nullptr); |
| 505 chunk->set_prev_chunk(nullptr); | 505 chunk->set_prev_chunk(nullptr); |
| 506 chunk->local_tracker_ = nullptr; | 506 chunk->local_tracker_ = nullptr; |
| 507 | 507 |
| 508 DCHECK(OFFSET_OF(MemoryChunk, flags_) == kFlagsOffset); | 508 DCHECK(OFFSET_OF(MemoryChunk, flags_) == kFlagsOffset); |
| 509 DCHECK(OFFSET_OF(MemoryChunk, live_byte_count_) == kLiveBytesOffset); | 509 DCHECK(OFFSET_OF(MemoryChunk, live_byte_count_) == kLiveBytesOffset); |
| 510 | 510 |
| 511 if (executable == EXECUTABLE) { | 511 if (executable == EXECUTABLE) { |
| 512 chunk->SetFlag(IS_EXECUTABLE); | 512 chunk->SetFlag(IS_EXECUTABLE); |
| 513 } | 513 } |
| (...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1053 DCHECK_NULL(local_tracker_); | 1053 DCHECK_NULL(local_tracker_); |
| 1054 local_tracker_ = new LocalArrayBufferTracker(heap()); | 1054 local_tracker_ = new LocalArrayBufferTracker(heap()); |
| 1055 } | 1055 } |
| 1056 | 1056 |
| 1057 void MemoryChunk::ReleaseLocalTracker() { | 1057 void MemoryChunk::ReleaseLocalTracker() { |
| 1058 DCHECK_NOT_NULL(local_tracker_); | 1058 DCHECK_NOT_NULL(local_tracker_); |
| 1059 delete local_tracker_; | 1059 delete local_tracker_; |
| 1060 local_tracker_ = nullptr; | 1060 local_tracker_ = nullptr; |
| 1061 } | 1061 } |
| 1062 | 1062 |
| 1063 void MemoryChunk::ClearLiveness() { |
| 1064 markbits()->Clear(); |
| 1065 ResetLiveBytes(); |
| 1066 } |
| 1067 |
| 1063 // ----------------------------------------------------------------------------- | 1068 // ----------------------------------------------------------------------------- |
| 1064 // PagedSpace implementation | 1069 // PagedSpace implementation |
| 1065 | 1070 |
| 1066 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::NEW_SPACE) == | 1071 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::NEW_SPACE) == |
| 1067 ObjectSpace::kObjectSpaceNewSpace); | 1072 ObjectSpace::kObjectSpaceNewSpace); |
| 1068 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::OLD_SPACE) == | 1073 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::OLD_SPACE) == |
| 1069 ObjectSpace::kObjectSpaceOldSpace); | 1074 ObjectSpace::kObjectSpaceOldSpace); |
| 1070 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::CODE_SPACE) == | 1075 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::CODE_SPACE) == |
| 1071 ObjectSpace::kObjectSpaceCodeSpace); | 1076 ObjectSpace::kObjectSpaceCodeSpace); |
| 1072 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::MAP_SPACE) == | 1077 STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::MAP_SPACE) == |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1221 | 1226 |
| 1222 AccountCommitted(static_cast<intptr_t>(p->size())); | 1227 AccountCommitted(static_cast<intptr_t>(p->size())); |
| 1223 | 1228 |
| 1224 // Pages created during bootstrapping may contain immortal immovable objects. | 1229 // Pages created during bootstrapping may contain immortal immovable objects. |
| 1225 if (!heap()->deserialization_complete()) p->MarkNeverEvacuate(); | 1230 if (!heap()->deserialization_complete()) p->MarkNeverEvacuate(); |
| 1226 | 1231 |
| 1227 // When incremental marking was activated, old space pages are allocated | 1232 // When incremental marking was activated, old space pages are allocated |
| 1228 // black. | 1233 // black. |
| 1229 if (heap()->incremental_marking()->black_allocation() && | 1234 if (heap()->incremental_marking()->black_allocation() && |
| 1230 identity() == OLD_SPACE) { | 1235 identity() == OLD_SPACE) { |
| 1231 Bitmap::SetAllBits(p); | 1236 p->markbits()->SetAllBits(); |
| 1232 p->SetFlag(Page::BLACK_PAGE); | 1237 p->SetFlag(Page::BLACK_PAGE); |
| 1233 if (FLAG_trace_incremental_marking) { | 1238 if (FLAG_trace_incremental_marking) { |
| 1234 PrintIsolate(heap()->isolate(), "Added black page %p\n", | 1239 PrintIsolate(heap()->isolate(), "Added black page %p\n", |
| 1235 static_cast<void*>(p)); | 1240 static_cast<void*>(p)); |
| 1236 } | 1241 } |
| 1237 } | 1242 } |
| 1238 | 1243 |
| 1239 DCHECK(Capacity() <= heap()->MaxOldGenerationSize()); | 1244 DCHECK(Capacity() <= heap()->MaxOldGenerationSize()); |
| 1240 | 1245 |
| 1241 p->InsertAfter(anchor_.prev_page()); | 1246 p->InsertAfter(anchor_.prev_page()); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1320 // Perform space-specific object verification. | 1325 // Perform space-specific object verification. |
| 1321 VerifyObject(object); | 1326 VerifyObject(object); |
| 1322 | 1327 |
| 1323 // The object itself should look OK. | 1328 // The object itself should look OK. |
| 1324 object->ObjectVerify(); | 1329 object->ObjectVerify(); |
| 1325 | 1330 |
| 1326 // All the interior pointers should be contained in the heap. | 1331 // All the interior pointers should be contained in the heap. |
| 1327 int size = object->Size(); | 1332 int size = object->Size(); |
| 1328 object->IterateBody(map->instance_type(), size, visitor); | 1333 object->IterateBody(map->instance_type(), size, visitor); |
| 1329 if (!page->IsFlagSet(Page::BLACK_PAGE) && | 1334 if (!page->IsFlagSet(Page::BLACK_PAGE) && |
| 1330 Marking::IsBlack(Marking::MarkBitFrom(object))) { | 1335 Marking::IsBlack(ObjectMarking::MarkBitFrom(object))) { |
| 1331 black_size += size; | 1336 black_size += size; |
| 1332 } | 1337 } |
| 1333 | 1338 |
| 1334 CHECK(object->address() + size <= top); | 1339 CHECK(object->address() + size <= top); |
| 1335 end_of_previous_object = object->address() + size; | 1340 end_of_previous_object = object->address() + size; |
| 1336 } | 1341 } |
| 1337 CHECK_LE(black_size, page->LiveBytes()); | 1342 CHECK_LE(black_size, page->LiveBytes()); |
| 1338 } | 1343 } |
| 1339 CHECK(allocation_pointer_found_in_space); | 1344 CHECK(allocation_pointer_found_in_space); |
| 1340 } | 1345 } |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1455 } | 1460 } |
| 1456 } | 1461 } |
| 1457 while (actual_pages < expected_pages) { | 1462 while (actual_pages < expected_pages) { |
| 1458 actual_pages++; | 1463 actual_pages++; |
| 1459 current_page = | 1464 current_page = |
| 1460 heap()->memory_allocator()->AllocatePage<MemoryAllocator::kPooled>( | 1465 heap()->memory_allocator()->AllocatePage<MemoryAllocator::kPooled>( |
| 1461 Page::kAllocatableMemory, this, executable()); | 1466 Page::kAllocatableMemory, this, executable()); |
| 1462 if (current_page == nullptr) return false; | 1467 if (current_page == nullptr) return false; |
| 1463 DCHECK_NOT_NULL(current_page); | 1468 DCHECK_NOT_NULL(current_page); |
| 1464 current_page->InsertAfter(anchor()); | 1469 current_page->InsertAfter(anchor()); |
| 1465 Bitmap::Clear(current_page); | 1470 current_page->ClearLiveness(); |
| 1466 current_page->SetFlags(anchor()->prev_page()->GetFlags(), | 1471 current_page->SetFlags(anchor()->prev_page()->GetFlags(), |
| 1467 Page::kCopyAllFlags); | 1472 Page::kCopyAllFlags); |
| 1468 heap()->CreateFillerObjectAt(current_page->area_start(), | 1473 heap()->CreateFillerObjectAt(current_page->area_start(), |
| 1469 current_page->area_size(), | 1474 current_page->area_size(), |
| 1470 ClearRecordedSlots::kNo); | 1475 ClearRecordedSlots::kNo); |
| 1471 } | 1476 } |
| 1472 } | 1477 } |
| 1473 return true; | 1478 return true; |
| 1474 } | 1479 } |
| 1475 | 1480 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1523 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 1528 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |
| 1524 } | 1529 } |
| 1525 | 1530 |
| 1526 | 1531 |
| 1527 void NewSpace::ResetAllocationInfo() { | 1532 void NewSpace::ResetAllocationInfo() { |
| 1528 Address old_top = allocation_info_.top(); | 1533 Address old_top = allocation_info_.top(); |
| 1529 to_space_.Reset(); | 1534 to_space_.Reset(); |
| 1530 UpdateAllocationInfo(); | 1535 UpdateAllocationInfo(); |
| 1531 // Clear all mark-bits in the to-space. | 1536 // Clear all mark-bits in the to-space. |
| 1532 for (Page* p : to_space_) { | 1537 for (Page* p : to_space_) { |
| 1533 Bitmap::Clear(p); | 1538 p->ClearLiveness(); |
| 1534 } | 1539 } |
| 1535 InlineAllocationStep(old_top, allocation_info_.top(), nullptr, 0); | 1540 InlineAllocationStep(old_top, allocation_info_.top(), nullptr, 0); |
| 1536 } | 1541 } |
| 1537 | 1542 |
| 1538 | 1543 |
| 1539 void NewSpace::UpdateInlineAllocationLimit(int size_in_bytes) { | 1544 void NewSpace::UpdateInlineAllocationLimit(int size_in_bytes) { |
| 1540 if (heap()->inline_allocation_disabled()) { | 1545 if (heap()->inline_allocation_disabled()) { |
| 1541 // Lowest limit when linear allocation was disabled. | 1546 // Lowest limit when linear allocation was disabled. |
| 1542 Address high = to_space_.page_high(); | 1547 Address high = to_space_.page_high(); |
| 1543 Address new_top = allocation_info_.top() + size_in_bytes; | 1548 Address new_top = allocation_info_.top() + size_in_bytes; |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1821 DCHECK_NE(last_page, anchor()); | 1826 DCHECK_NE(last_page, anchor()); |
| 1822 for (int pages_added = 0; pages_added < delta_pages; pages_added++) { | 1827 for (int pages_added = 0; pages_added < delta_pages; pages_added++) { |
| 1823 Page* new_page = | 1828 Page* new_page = |
| 1824 heap()->memory_allocator()->AllocatePage<MemoryAllocator::kPooled>( | 1829 heap()->memory_allocator()->AllocatePage<MemoryAllocator::kPooled>( |
| 1825 Page::kAllocatableMemory, this, executable()); | 1830 Page::kAllocatableMemory, this, executable()); |
| 1826 if (new_page == nullptr) { | 1831 if (new_page == nullptr) { |
| 1827 RewindPages(last_page, pages_added); | 1832 RewindPages(last_page, pages_added); |
| 1828 return false; | 1833 return false; |
| 1829 } | 1834 } |
| 1830 new_page->InsertAfter(last_page); | 1835 new_page->InsertAfter(last_page); |
| 1831 Bitmap::Clear(new_page); | 1836 new_page->ClearLiveness(); |
| 1832 // Duplicate the flags that was set on the old page. | 1837 // Duplicate the flags that was set on the old page. |
| 1833 new_page->SetFlags(last_page->GetFlags(), Page::kCopyOnFlipFlagsMask); | 1838 new_page->SetFlags(last_page->GetFlags(), Page::kCopyOnFlipFlagsMask); |
| 1834 last_page = new_page; | 1839 last_page = new_page; |
| 1835 } | 1840 } |
| 1836 AccountCommitted(static_cast<intptr_t>(delta)); | 1841 AccountCommitted(static_cast<intptr_t>(delta)); |
| 1837 current_capacity_ = new_capacity; | 1842 current_capacity_ = new_capacity; |
| 1838 return true; | 1843 return true; |
| 1839 } | 1844 } |
| 1840 | 1845 |
| 1841 void SemiSpace::RewindPages(Page* start, int num_pages) { | 1846 void SemiSpace::RewindPages(Page* start, int num_pages) { |
| (...skipping 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2902 } | 2907 } |
| 2903 } | 2908 } |
| 2904 return NULL; | 2909 return NULL; |
| 2905 } | 2910 } |
| 2906 | 2911 |
| 2907 | 2912 |
| 2908 void LargeObjectSpace::ClearMarkingStateOfLiveObjects() { | 2913 void LargeObjectSpace::ClearMarkingStateOfLiveObjects() { |
| 2909 LargePage* current = first_page_; | 2914 LargePage* current = first_page_; |
| 2910 while (current != NULL) { | 2915 while (current != NULL) { |
| 2911 HeapObject* object = current->GetObject(); | 2916 HeapObject* object = current->GetObject(); |
| 2912 MarkBit mark_bit = Marking::MarkBitFrom(object); | 2917 MarkBit mark_bit = ObjectMarking::MarkBitFrom(object); |
| 2913 DCHECK(Marking::IsBlack(mark_bit)); | 2918 DCHECK(Marking::IsBlack(mark_bit)); |
| 2914 Marking::BlackToWhite(mark_bit); | 2919 Marking::BlackToWhite(mark_bit); |
| 2915 Page::FromAddress(object->address())->ResetProgressBar(); | 2920 Page::FromAddress(object->address())->ResetProgressBar(); |
| 2916 Page::FromAddress(object->address())->ResetLiveBytes(); | 2921 Page::FromAddress(object->address())->ResetLiveBytes(); |
| 2917 current = current->next_page(); | 2922 current = current->next_page(); |
| 2918 } | 2923 } |
| 2919 } | 2924 } |
| 2920 | 2925 |
| 2921 void LargeObjectSpace::InsertChunkMapEntries(LargePage* page) { | 2926 void LargeObjectSpace::InsertChunkMapEntries(LargePage* page) { |
| 2922 // Register all MemoryChunk::kAlignment-aligned chunks covered by | 2927 // Register all MemoryChunk::kAlignment-aligned chunks covered by |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2946 for (uintptr_t key = start; key <= limit; key++) { | 2951 for (uintptr_t key = start; key <= limit; key++) { |
| 2947 chunk_map_.Remove(reinterpret_cast<void*>(key), static_cast<uint32_t>(key)); | 2952 chunk_map_.Remove(reinterpret_cast<void*>(key), static_cast<uint32_t>(key)); |
| 2948 } | 2953 } |
| 2949 } | 2954 } |
| 2950 | 2955 |
| 2951 void LargeObjectSpace::FreeUnmarkedObjects() { | 2956 void LargeObjectSpace::FreeUnmarkedObjects() { |
| 2952 LargePage* previous = NULL; | 2957 LargePage* previous = NULL; |
| 2953 LargePage* current = first_page_; | 2958 LargePage* current = first_page_; |
| 2954 while (current != NULL) { | 2959 while (current != NULL) { |
| 2955 HeapObject* object = current->GetObject(); | 2960 HeapObject* object = current->GetObject(); |
| 2956 MarkBit mark_bit = Marking::MarkBitFrom(object); | 2961 MarkBit mark_bit = ObjectMarking::MarkBitFrom(object); |
| 2957 DCHECK(!Marking::IsGrey(mark_bit)); | 2962 DCHECK(!Marking::IsGrey(mark_bit)); |
| 2958 if (Marking::IsBlack(mark_bit)) { | 2963 if (Marking::IsBlack(mark_bit)) { |
| 2959 Address free_start; | 2964 Address free_start; |
| 2960 if ((free_start = current->GetAddressToShrink()) != 0) { | 2965 if ((free_start = current->GetAddressToShrink()) != 0) { |
| 2961 // TODO(hpayer): Perform partial free concurrently. | 2966 // TODO(hpayer): Perform partial free concurrently. |
| 2962 current->ClearOutOfLiveRangeSlots(free_start); | 2967 current->ClearOutOfLiveRangeSlots(free_start); |
| 2963 RemoveChunkMapEntries(current, free_start); | 2968 RemoveChunkMapEntries(current, free_start); |
| 2964 heap()->memory_allocator()->PartialFreeMemory(current, free_start); | 2969 heap()->memory_allocator()->PartialFreeMemory(current, free_start); |
| 2965 } | 2970 } |
| 2966 previous = current; | 2971 previous = current; |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3078 | 3083 |
| 3079 void Page::Print() { | 3084 void Page::Print() { |
| 3080 // Make a best-effort to print the objects in the page. | 3085 // Make a best-effort to print the objects in the page. |
| 3081 PrintF("Page@%p in %s\n", static_cast<void*>(this->address()), | 3086 PrintF("Page@%p in %s\n", static_cast<void*>(this->address()), |
| 3082 AllocationSpaceName(this->owner()->identity())); | 3087 AllocationSpaceName(this->owner()->identity())); |
| 3083 printf(" --------------------------------------\n"); | 3088 printf(" --------------------------------------\n"); |
| 3084 HeapObjectIterator objects(this); | 3089 HeapObjectIterator objects(this); |
| 3085 unsigned mark_size = 0; | 3090 unsigned mark_size = 0; |
| 3086 for (HeapObject* object = objects.Next(); object != NULL; | 3091 for (HeapObject* object = objects.Next(); object != NULL; |
| 3087 object = objects.Next()) { | 3092 object = objects.Next()) { |
| 3088 bool is_marked = Marking::IsBlackOrGrey(Marking::MarkBitFrom(object)); | 3093 bool is_marked = Marking::IsBlackOrGrey(ObjectMarking::MarkBitFrom(object)); |
| 3089 PrintF(" %c ", (is_marked ? '!' : ' ')); // Indent a little. | 3094 PrintF(" %c ", (is_marked ? '!' : ' ')); // Indent a little. |
| 3090 if (is_marked) { | 3095 if (is_marked) { |
| 3091 mark_size += object->Size(); | 3096 mark_size += object->Size(); |
| 3092 } | 3097 } |
| 3093 object->ShortPrint(); | 3098 object->ShortPrint(); |
| 3094 PrintF("\n"); | 3099 PrintF("\n"); |
| 3095 } | 3100 } |
| 3096 printf(" --------------------------------------\n"); | 3101 printf(" --------------------------------------\n"); |
| 3097 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3102 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
| 3098 } | 3103 } |
| 3099 | 3104 |
| 3100 #endif // DEBUG | 3105 #endif // DEBUG |
| 3101 } // namespace internal | 3106 } // namespace internal |
| 3102 } // namespace v8 | 3107 } // namespace v8 |
| OLD | NEW |