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/full-codegen/full-codegen.h" | 9 #include "src/full-codegen/full-codegen.h" |
10 #include "src/heap/slots-buffer.h" | 10 #include "src/heap/slots-buffer.h" |
(...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 | 951 |
952 | 952 |
953 PagedSpace::PagedSpace(Heap* heap, AllocationSpace space, | 953 PagedSpace::PagedSpace(Heap* heap, AllocationSpace space, |
954 Executability executable) | 954 Executability executable) |
955 : Space(heap, space, executable), | 955 : Space(heap, space, executable), |
956 free_list_(this), | 956 free_list_(this), |
957 end_of_unswept_pages_(NULL) { | 957 end_of_unswept_pages_(NULL) { |
958 area_size_ = MemoryAllocator::PageAreaSize(space); | 958 area_size_ = MemoryAllocator::PageAreaSize(space); |
959 accounting_stats_.Clear(); | 959 accounting_stats_.Clear(); |
960 | 960 |
961 allocation_info_.set_top(NULL); | 961 allocation_info_.Reset(nullptr, nullptr); |
962 allocation_info_.set_limit(NULL); | |
963 | 962 |
964 anchor_.InitializeAsAnchor(this); | 963 anchor_.InitializeAsAnchor(this); |
965 } | 964 } |
966 | 965 |
967 | 966 |
968 bool PagedSpace::SetUp() { return true; } | 967 bool PagedSpace::SetUp() { return true; } |
969 | 968 |
970 | 969 |
971 bool PagedSpace::HasBeenSetUp() { return true; } | 970 bool PagedSpace::HasBeenSetUp() { return true; } |
972 | 971 |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1241 } | 1240 } |
1242 | 1241 |
1243 if (page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE)) { | 1242 if (page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE)) { |
1244 heap()->decrement_scan_on_scavenge_pages(); | 1243 heap()->decrement_scan_on_scavenge_pages(); |
1245 page->ClearFlag(MemoryChunk::SCAN_ON_SCAVENGE); | 1244 page->ClearFlag(MemoryChunk::SCAN_ON_SCAVENGE); |
1246 } | 1245 } |
1247 | 1246 |
1248 DCHECK(!free_list_.ContainsPageFreeListItems(page)); | 1247 DCHECK(!free_list_.ContainsPageFreeListItems(page)); |
1249 | 1248 |
1250 if (Page::FromAllocationTop(allocation_info_.top()) == page) { | 1249 if (Page::FromAllocationTop(allocation_info_.top()) == page) { |
1251 allocation_info_.set_top(NULL); | 1250 allocation_info_.Reset(nullptr, nullptr); |
1252 allocation_info_.set_limit(NULL); | |
1253 } | 1251 } |
1254 | 1252 |
1255 // If page is still in a list, unlink it from that list. | 1253 // If page is still in a list, unlink it from that list. |
1256 if (page->next_chunk() != NULL) { | 1254 if (page->next_chunk() != NULL) { |
1257 DCHECK(page->prev_chunk() != NULL); | 1255 DCHECK(page->prev_chunk() != NULL); |
1258 page->Unlink(); | 1256 page->Unlink(); |
1259 } | 1257 } |
1260 | 1258 |
1261 AccountUncommitted(static_cast<intptr_t>(page->size())); | 1259 AccountUncommitted(static_cast<intptr_t>(page->size())); |
1262 heap()->QueueMemoryChunkForFree(page); | 1260 heap()->QueueMemoryChunkForFree(page); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1383 if (allocated_histogram_) { | 1381 if (allocated_histogram_) { |
1384 DeleteArray(allocated_histogram_); | 1382 DeleteArray(allocated_histogram_); |
1385 allocated_histogram_ = NULL; | 1383 allocated_histogram_ = NULL; |
1386 } | 1384 } |
1387 if (promoted_histogram_) { | 1385 if (promoted_histogram_) { |
1388 DeleteArray(promoted_histogram_); | 1386 DeleteArray(promoted_histogram_); |
1389 promoted_histogram_ = NULL; | 1387 promoted_histogram_ = NULL; |
1390 } | 1388 } |
1391 | 1389 |
1392 start_ = NULL; | 1390 start_ = NULL; |
1393 allocation_info_.set_top(NULL); | 1391 allocation_info_.Reset(nullptr, nullptr); |
1394 allocation_info_.set_limit(NULL); | 1392 |
1395 | 1393 |
1396 to_space_.TearDown(); | 1394 to_space_.TearDown(); |
1397 from_space_.TearDown(); | 1395 from_space_.TearDown(); |
1398 | 1396 |
1399 heap()->isolate()->memory_allocator()->FreeNewSpaceMemory( | 1397 heap()->isolate()->memory_allocator()->FreeNewSpaceMemory( |
1400 chunk_base_, &reservation_, NOT_EXECUTABLE); | 1398 chunk_base_, &reservation_, NOT_EXECUTABLE); |
1401 | 1399 |
1402 chunk_base_ = NULL; | 1400 chunk_base_ = NULL; |
1403 chunk_size_ = 0; | 1401 chunk_size_ = 0; |
1404 } | 1402 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1473 // We are in an inconsistent state because we could not | 1471 // We are in an inconsistent state because we could not |
1474 // commit/uncommit memory from new space. | 1472 // commit/uncommit memory from new space. |
1475 CHECK(false); | 1473 CHECK(false); |
1476 } | 1474 } |
1477 } | 1475 } |
1478 } | 1476 } |
1479 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 1477 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |
1480 } | 1478 } |
1481 | 1479 |
1482 | 1480 |
| 1481 void LocalAllocationBuffer::Close() { |
| 1482 if (IsValid()) { |
| 1483 heap_->CreateFillerObjectAt( |
| 1484 allocation_info_.top(), |
| 1485 static_cast<int>(allocation_info_.limit() - allocation_info_.top())); |
| 1486 } |
| 1487 } |
| 1488 |
| 1489 |
| 1490 LocalAllocationBuffer::LocalAllocationBuffer(Heap* heap, |
| 1491 AllocationInfo allocation_info) |
| 1492 : heap_(heap), allocation_info_(allocation_info) { |
| 1493 if (IsValid()) { |
| 1494 heap_->CreateFillerObjectAt( |
| 1495 allocation_info_.top(), |
| 1496 static_cast<int>(allocation_info_.limit() - allocation_info_.top())); |
| 1497 } |
| 1498 } |
| 1499 |
| 1500 |
| 1501 LocalAllocationBuffer::LocalAllocationBuffer( |
| 1502 const LocalAllocationBuffer& other) { |
| 1503 *this = other; |
| 1504 } |
| 1505 |
| 1506 |
| 1507 LocalAllocationBuffer& LocalAllocationBuffer::operator=( |
| 1508 const LocalAllocationBuffer& other) { |
| 1509 Close(); |
| 1510 heap_ = other.heap_; |
| 1511 allocation_info_ = other.allocation_info_; |
| 1512 |
| 1513 // This is needed since we (a) cannot yet use move-semantics, and (b) want |
| 1514 // to make the use of the class easy by it as value and (c) implicitly call |
| 1515 // {Close} upon copy. |
| 1516 const_cast<LocalAllocationBuffer&>(other) |
| 1517 .allocation_info_.Reset(nullptr, nullptr); |
| 1518 return *this; |
| 1519 } |
| 1520 |
| 1521 |
1483 void NewSpace::UpdateAllocationInfo() { | 1522 void NewSpace::UpdateAllocationInfo() { |
1484 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); | 1523 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); |
1485 allocation_info_.set_top(to_space_.page_low()); | 1524 allocation_info_.Reset(to_space_.page_low(), to_space_.page_high()); |
1486 allocation_info_.set_limit(to_space_.page_high()); | |
1487 UpdateInlineAllocationLimit(0); | 1525 UpdateInlineAllocationLimit(0); |
1488 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 1526 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |
1489 } | 1527 } |
1490 | 1528 |
1491 | 1529 |
1492 void NewSpace::ResetAllocationInfo() { | 1530 void NewSpace::ResetAllocationInfo() { |
1493 Address old_top = allocation_info_.top(); | 1531 Address old_top = allocation_info_.top(); |
1494 to_space_.Reset(); | 1532 to_space_.Reset(); |
1495 UpdateAllocationInfo(); | 1533 UpdateAllocationInfo(); |
1496 pages_used_ = 0; | 1534 pages_used_ = 0; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1559 | 1597 |
1560 int remaining_in_page = static_cast<int>(limit - top); | 1598 int remaining_in_page = static_cast<int>(limit - top); |
1561 heap()->CreateFillerObjectAt(top, remaining_in_page); | 1599 heap()->CreateFillerObjectAt(top, remaining_in_page); |
1562 pages_used_++; | 1600 pages_used_++; |
1563 UpdateAllocationInfo(); | 1601 UpdateAllocationInfo(); |
1564 | 1602 |
1565 return true; | 1603 return true; |
1566 } | 1604 } |
1567 | 1605 |
1568 | 1606 |
| 1607 bool NewSpace::AddFreshPageSynchronized() { |
| 1608 base::LockGuard<base::Mutex> guard(&mutex_); |
| 1609 return AddFreshPage(); |
| 1610 } |
| 1611 |
| 1612 |
1569 bool NewSpace::EnsureAllocation(int size_in_bytes, | 1613 bool NewSpace::EnsureAllocation(int size_in_bytes, |
1570 AllocationAlignment alignment) { | 1614 AllocationAlignment alignment) { |
1571 Address old_top = allocation_info_.top(); | 1615 Address old_top = allocation_info_.top(); |
1572 Address high = to_space_.page_high(); | 1616 Address high = to_space_.page_high(); |
1573 int filler_size = Heap::GetFillToAlign(old_top, alignment); | 1617 int filler_size = Heap::GetFillToAlign(old_top, alignment); |
1574 int aligned_size_in_bytes = size_in_bytes + filler_size; | 1618 int aligned_size_in_bytes = size_in_bytes + filler_size; |
1575 | 1619 |
1576 if (old_top + aligned_size_in_bytes >= high) { | 1620 if (old_top + aligned_size_in_bytes >= high) { |
1577 // Not enough room in the page, try to allocate a new one. | 1621 // Not enough room in the page, try to allocate a new one. |
1578 if (!AddFreshPage()) { | 1622 if (!AddFreshPage()) { |
(...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2756 | 2800 |
2757 | 2801 |
2758 void PagedSpace::EvictEvacuationCandidatesFromLinearAllocationArea() { | 2802 void PagedSpace::EvictEvacuationCandidatesFromLinearAllocationArea() { |
2759 if (allocation_info_.top() >= allocation_info_.limit()) return; | 2803 if (allocation_info_.top() >= allocation_info_.limit()) return; |
2760 | 2804 |
2761 if (!Page::FromAllocationTop(allocation_info_.top())->CanAllocate()) { | 2805 if (!Page::FromAllocationTop(allocation_info_.top())->CanAllocate()) { |
2762 // Create filler object to keep page iterable if it was iterable. | 2806 // Create filler object to keep page iterable if it was iterable. |
2763 int remaining = | 2807 int remaining = |
2764 static_cast<int>(allocation_info_.limit() - allocation_info_.top()); | 2808 static_cast<int>(allocation_info_.limit() - allocation_info_.top()); |
2765 heap()->CreateFillerObjectAt(allocation_info_.top(), remaining); | 2809 heap()->CreateFillerObjectAt(allocation_info_.top(), remaining); |
2766 | 2810 allocation_info_.Reset(nullptr, nullptr); |
2767 allocation_info_.set_top(nullptr); | |
2768 allocation_info_.set_limit(nullptr); | |
2769 } | 2811 } |
2770 } | 2812 } |
2771 | 2813 |
2772 | 2814 |
2773 HeapObject* PagedSpace::SweepAndRetryAllocation(int size_in_bytes) { | 2815 HeapObject* PagedSpace::SweepAndRetryAllocation(int size_in_bytes) { |
2774 MarkCompactCollector* collector = heap()->mark_compact_collector(); | 2816 MarkCompactCollector* collector = heap()->mark_compact_collector(); |
2775 if (collector->sweeping_in_progress()) { | 2817 if (collector->sweeping_in_progress()) { |
2776 // Wait for the sweeper threads here and complete the sweeping phase. | 2818 // Wait for the sweeper threads here and complete the sweeping phase. |
2777 collector->EnsureSweepingCompleted(); | 2819 collector->EnsureSweepingCompleted(); |
2778 | 2820 |
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3323 object->ShortPrint(); | 3365 object->ShortPrint(); |
3324 PrintF("\n"); | 3366 PrintF("\n"); |
3325 } | 3367 } |
3326 printf(" --------------------------------------\n"); | 3368 printf(" --------------------------------------\n"); |
3327 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3369 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
3328 } | 3370 } |
3329 | 3371 |
3330 #endif // DEBUG | 3372 #endif // DEBUG |
3331 } // namespace internal | 3373 } // namespace internal |
3332 } // namespace v8 | 3374 } // namespace v8 |
OLD | NEW |