| 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 |