Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: src/spaces.cc

Issue 133443009: A64: Synchronize with r17441. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/spaces.h ('k') | src/spaces-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 11 matching lines...) Expand all
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "macro-assembler.h" 30 #include "macro-assembler.h"
31 #include "mark-compact.h" 31 #include "mark-compact.h"
32 #include "msan.h"
32 #include "platform.h" 33 #include "platform.h"
33 34
34 namespace v8 { 35 namespace v8 {
35 namespace internal { 36 namespace internal {
36 37
37 38
38 // ---------------------------------------------------------------------------- 39 // ----------------------------------------------------------------------------
39 // HeapObjectIterator 40 // HeapObjectIterator
40 41
41 HeapObjectIterator::HeapObjectIterator(PagedSpace* space) { 42 HeapObjectIterator::HeapObjectIterator(PagedSpace* space) {
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 } 711 }
711 712
712 MemoryChunk* result = MemoryChunk::Initialize(heap, 713 MemoryChunk* result = MemoryChunk::Initialize(heap,
713 base, 714 base,
714 chunk_size, 715 chunk_size,
715 area_start, 716 area_start,
716 area_end, 717 area_end,
717 executable, 718 executable,
718 owner); 719 owner);
719 result->set_reserved_memory(&reservation); 720 result->set_reserved_memory(&reservation);
721 MSAN_MEMORY_IS_INITIALIZED(base, chunk_size);
720 return result; 722 return result;
721 } 723 }
722 724
723 725
724 void Page::ResetFreeListStatistics() { 726 void Page::ResetFreeListStatistics() {
725 non_available_small_blocks_ = 0; 727 non_available_small_blocks_ = 0;
726 available_in_small_free_list_ = 0; 728 available_in_small_free_list_ = 0;
727 available_in_medium_free_list_ = 0; 729 available_in_medium_free_list_ = 0;
728 available_in_large_free_list_ = 0; 730 available_in_large_free_list_ = 0;
729 available_in_huge_free_list_ = 0; 731 available_in_huge_free_list_ = 0;
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 if (id == CODE_SPACE) { 953 if (id == CODE_SPACE) {
952 area_size_ = heap->isolate()->memory_allocator()-> 954 area_size_ = heap->isolate()->memory_allocator()->
953 CodePageAreaSize(); 955 CodePageAreaSize();
954 } else { 956 } else {
955 area_size_ = Page::kPageSize - Page::kObjectStartOffset; 957 area_size_ = Page::kPageSize - Page::kObjectStartOffset;
956 } 958 }
957 max_capacity_ = (RoundDown(max_capacity, Page::kPageSize) / Page::kPageSize) 959 max_capacity_ = (RoundDown(max_capacity, Page::kPageSize) / Page::kPageSize)
958 * AreaSize(); 960 * AreaSize();
959 accounting_stats_.Clear(); 961 accounting_stats_.Clear();
960 962
961 allocation_info_.top = NULL; 963 allocation_info_.set_top(NULL);
962 allocation_info_.limit = NULL; 964 allocation_info_.set_limit(NULL);
963 965
964 anchor_.InitializeAsAnchor(this); 966 anchor_.InitializeAsAnchor(this);
965 } 967 }
966 968
967 969
968 bool PagedSpace::SetUp() { 970 bool PagedSpace::SetUp() {
969 return true; 971 return true;
970 } 972 }
971 973
972 974
973 bool PagedSpace::HasBeenSetUp() { 975 bool PagedSpace::HasBeenSetUp() {
974 return true; 976 return true;
975 } 977 }
976 978
977 979
978 void PagedSpace::TearDown() { 980 void PagedSpace::TearDown() {
979 PageIterator iterator(this); 981 PageIterator iterator(this);
980 while (iterator.has_next()) { 982 while (iterator.has_next()) {
981 heap()->isolate()->memory_allocator()->Free(iterator.next()); 983 heap()->isolate()->memory_allocator()->Free(iterator.next());
982 } 984 }
983 anchor_.set_next_page(&anchor_); 985 anchor_.set_next_page(&anchor_);
984 anchor_.set_prev_page(&anchor_); 986 anchor_.set_prev_page(&anchor_);
985 accounting_stats_.Clear(); 987 accounting_stats_.Clear();
986 } 988 }
987 989
988 990
989 size_t PagedSpace::CommittedPhysicalMemory() { 991 size_t PagedSpace::CommittedPhysicalMemory() {
990 if (!VirtualMemory::HasLazyCommits()) return CommittedMemory(); 992 if (!VirtualMemory::HasLazyCommits()) return CommittedMemory();
991 MemoryChunk::UpdateHighWaterMark(allocation_info_.top); 993 MemoryChunk::UpdateHighWaterMark(allocation_info_.top());
992 size_t size = 0; 994 size_t size = 0;
993 PageIterator it(this); 995 PageIterator it(this);
994 while (it.has_next()) { 996 while (it.has_next()) {
995 size += it.next()->CommittedPhysicalMemory(); 997 size += it.next()->CommittedPhysicalMemory();
996 } 998 }
997 return size; 999 return size;
998 } 1000 }
999 1001
1000 1002
1001 MaybeObject* PagedSpace::FindObject(Address addr) { 1003 MaybeObject* PagedSpace::FindObject(Address addr) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 case PROPERTY_CELL_SPACE: 1072 case PROPERTY_CELL_SPACE:
1071 size = 8 * kPointerSize * KB; 1073 size = 8 * kPointerSize * KB;
1072 break; 1074 break;
1073 case CODE_SPACE: 1075 case CODE_SPACE:
1074 if (heap()->isolate()->code_range()->exists()) { 1076 if (heap()->isolate()->code_range()->exists()) {
1075 // When code range exists, code pages are allocated in a special way 1077 // When code range exists, code pages are allocated in a special way
1076 // (from the reserved code range). That part of the code is not yet 1078 // (from the reserved code range). That part of the code is not yet
1077 // upgraded to handle small pages. 1079 // upgraded to handle small pages.
1078 size = AreaSize(); 1080 size = AreaSize();
1079 } else { 1081 } else {
1080 size = 384 * KB; 1082 #if V8_TARGET_ARCH_MIPS
1083 // TODO(plind): Investigate larger code stubs size on MIPS.
1084 size = 480 * KB;
1085 #else
1086 size = 416 * KB;
1087 #endif
1081 } 1088 }
1082 break; 1089 break;
1083 default: 1090 default:
1084 UNREACHABLE(); 1091 UNREACHABLE();
1085 } 1092 }
1086 return Min(size, AreaSize()); 1093 return Min(size, AreaSize());
1087 } 1094 }
1088 1095
1089 1096
1090 int PagedSpace::CountTotalPages() { 1097 int PagedSpace::CountTotalPages() {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1128 } 1135 }
1129 1136
1130 if (page->WasSwept()) { 1137 if (page->WasSwept()) {
1131 intptr_t size = free_list_.EvictFreeListItems(page); 1138 intptr_t size = free_list_.EvictFreeListItems(page);
1132 accounting_stats_.AllocateBytes(size); 1139 accounting_stats_.AllocateBytes(size);
1133 ASSERT_EQ(AreaSize(), static_cast<int>(size)); 1140 ASSERT_EQ(AreaSize(), static_cast<int>(size));
1134 } else { 1141 } else {
1135 DecreaseUnsweptFreeBytes(page); 1142 DecreaseUnsweptFreeBytes(page);
1136 } 1143 }
1137 1144
1138 if (Page::FromAllocationTop(allocation_info_.top) == page) { 1145 if (Page::FromAllocationTop(allocation_info_.top()) == page) {
1139 allocation_info_.top = allocation_info_.limit = NULL; 1146 allocation_info_.set_top(NULL);
1147 allocation_info_.set_limit(NULL);
1140 } 1148 }
1141 1149
1142 if (unlink) { 1150 if (unlink) {
1143 page->Unlink(); 1151 page->Unlink();
1144 } 1152 }
1145 if (page->IsFlagSet(MemoryChunk::CONTAINS_ONLY_DATA)) { 1153 if (page->IsFlagSet(MemoryChunk::CONTAINS_ONLY_DATA)) {
1146 heap()->isolate()->memory_allocator()->Free(page); 1154 heap()->isolate()->memory_allocator()->Free(page);
1147 } else { 1155 } else {
1148 heap()->QueueMemoryChunkForFree(page); 1156 heap()->QueueMemoryChunkForFree(page);
1149 } 1157 }
1150 1158
1151 ASSERT(Capacity() > 0); 1159 ASSERT(Capacity() > 0);
1152 accounting_stats_.ShrinkSpace(AreaSize()); 1160 accounting_stats_.ShrinkSpace(AreaSize());
1153 } 1161 }
1154 1162
1155 1163
1156 #ifdef DEBUG 1164 #ifdef DEBUG
1157 void PagedSpace::Print() { } 1165 void PagedSpace::Print() { }
1158 #endif 1166 #endif
1159 1167
1160 #ifdef VERIFY_HEAP 1168 #ifdef VERIFY_HEAP
1161 void PagedSpace::Verify(ObjectVisitor* visitor) { 1169 void PagedSpace::Verify(ObjectVisitor* visitor) {
1162 // We can only iterate over the pages if they were swept precisely. 1170 // We can only iterate over the pages if they were swept precisely.
1163 if (was_swept_conservatively_) return; 1171 if (was_swept_conservatively_) return;
1164 1172
1165 bool allocation_pointer_found_in_space = 1173 bool allocation_pointer_found_in_space =
1166 (allocation_info_.top == allocation_info_.limit); 1174 (allocation_info_.top() == allocation_info_.limit());
1167 PageIterator page_iterator(this); 1175 PageIterator page_iterator(this);
1168 while (page_iterator.has_next()) { 1176 while (page_iterator.has_next()) {
1169 Page* page = page_iterator.next(); 1177 Page* page = page_iterator.next();
1170 CHECK(page->owner() == this); 1178 CHECK(page->owner() == this);
1171 if (page == Page::FromAllocationTop(allocation_info_.top)) { 1179 if (page == Page::FromAllocationTop(allocation_info_.top())) {
1172 allocation_pointer_found_in_space = true; 1180 allocation_pointer_found_in_space = true;
1173 } 1181 }
1174 CHECK(page->WasSweptPrecisely()); 1182 CHECK(page->WasSweptPrecisely());
1175 HeapObjectIterator it(page, NULL); 1183 HeapObjectIterator it(page, NULL);
1176 Address end_of_previous_object = page->area_start(); 1184 Address end_of_previous_object = page->area_start();
1177 Address top = page->area_end(); 1185 Address top = page->area_end();
1178 int black_size = 0; 1186 int black_size = 0;
1179 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { 1187 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) {
1180 CHECK(end_of_previous_object <= object->address()); 1188 CHECK(end_of_previous_object <= object->address());
1181 1189
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 if (allocated_histogram_) { 1280 if (allocated_histogram_) {
1273 DeleteArray(allocated_histogram_); 1281 DeleteArray(allocated_histogram_);
1274 allocated_histogram_ = NULL; 1282 allocated_histogram_ = NULL;
1275 } 1283 }
1276 if (promoted_histogram_) { 1284 if (promoted_histogram_) {
1277 DeleteArray(promoted_histogram_); 1285 DeleteArray(promoted_histogram_);
1278 promoted_histogram_ = NULL; 1286 promoted_histogram_ = NULL;
1279 } 1287 }
1280 1288
1281 start_ = NULL; 1289 start_ = NULL;
1282 allocation_info_.top = NULL; 1290 allocation_info_.set_top(NULL);
1283 allocation_info_.limit = NULL; 1291 allocation_info_.set_limit(NULL);
1284 1292
1285 to_space_.TearDown(); 1293 to_space_.TearDown();
1286 from_space_.TearDown(); 1294 from_space_.TearDown();
1287 1295
1288 LOG(heap()->isolate(), DeleteEvent("InitialChunk", chunk_base_)); 1296 LOG(heap()->isolate(), DeleteEvent("InitialChunk", chunk_base_));
1289 1297
1290 ASSERT(reservation_.IsReserved()); 1298 ASSERT(reservation_.IsReserved());
1291 heap()->isolate()->memory_allocator()->FreeMemory(&reservation_, 1299 heap()->isolate()->memory_allocator()->FreeMemory(&reservation_,
1292 NOT_EXECUTABLE); 1300 NOT_EXECUTABLE);
1293 chunk_base_ = NULL; 1301 chunk_base_ = NULL;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1330 if (!from_space_.ShrinkTo(rounded_new_capacity)) { 1338 if (!from_space_.ShrinkTo(rounded_new_capacity)) {
1331 // If we managed to shrink to-space but couldn't shrink from 1339 // If we managed to shrink to-space but couldn't shrink from
1332 // space, attempt to grow to-space again. 1340 // space, attempt to grow to-space again.
1333 if (!to_space_.GrowTo(from_space_.Capacity())) { 1341 if (!to_space_.GrowTo(from_space_.Capacity())) {
1334 // We are in an inconsistent state because we could not 1342 // We are in an inconsistent state because we could not
1335 // commit/uncommit memory from new space. 1343 // commit/uncommit memory from new space.
1336 V8::FatalProcessOutOfMemory("Failed to shrink new space."); 1344 V8::FatalProcessOutOfMemory("Failed to shrink new space.");
1337 } 1345 }
1338 } 1346 }
1339 } 1347 }
1340 allocation_info_.limit = to_space_.page_high(); 1348 allocation_info_.set_limit(to_space_.page_high());
1341 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); 1349 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
1342 } 1350 }
1343 1351
1344 1352
1345 void NewSpace::UpdateAllocationInfo() { 1353 void NewSpace::UpdateAllocationInfo() {
1346 MemoryChunk::UpdateHighWaterMark(allocation_info_.top); 1354 MemoryChunk::UpdateHighWaterMark(allocation_info_.top());
1347 allocation_info_.top = to_space_.page_low(); 1355 allocation_info_.set_top(to_space_.page_low());
1348 allocation_info_.limit = to_space_.page_high(); 1356 allocation_info_.set_limit(to_space_.page_high());
1349 1357
1350 // Lower limit during incremental marking. 1358 // Lower limit during incremental marking.
1351 if (heap()->incremental_marking()->IsMarking() && 1359 if (heap()->incremental_marking()->IsMarking() &&
1352 inline_allocation_limit_step() != 0) { 1360 inline_allocation_limit_step() != 0) {
1353 Address new_limit = 1361 Address new_limit =
1354 allocation_info_.top + inline_allocation_limit_step(); 1362 allocation_info_.top() + inline_allocation_limit_step();
1355 allocation_info_.limit = Min(new_limit, allocation_info_.limit); 1363 allocation_info_.set_limit(Min(new_limit, allocation_info_.limit()));
1356 } 1364 }
1357 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); 1365 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
1358 } 1366 }
1359 1367
1360 1368
1361 void NewSpace::ResetAllocationInfo() { 1369 void NewSpace::ResetAllocationInfo() {
1362 to_space_.Reset(); 1370 to_space_.Reset();
1363 UpdateAllocationInfo(); 1371 UpdateAllocationInfo();
1364 pages_used_ = 0; 1372 pages_used_ = 0;
1365 // Clear all mark-bits in the to-space. 1373 // Clear all mark-bits in the to-space.
1366 NewSpacePageIterator it(&to_space_); 1374 NewSpacePageIterator it(&to_space_);
1367 while (it.has_next()) { 1375 while (it.has_next()) {
1368 Bitmap::Clear(it.next()); 1376 Bitmap::Clear(it.next());
1369 } 1377 }
1370 } 1378 }
1371 1379
1372 1380
1373 bool NewSpace::AddFreshPage() { 1381 bool NewSpace::AddFreshPage() {
1374 Address top = allocation_info_.top; 1382 Address top = allocation_info_.top();
1375 if (NewSpacePage::IsAtStart(top)) { 1383 if (NewSpacePage::IsAtStart(top)) {
1376 // The current page is already empty. Don't try to make another. 1384 // The current page is already empty. Don't try to make another.
1377 1385
1378 // We should only get here if someone asks to allocate more 1386 // We should only get here if someone asks to allocate more
1379 // than what can be stored in a single page. 1387 // than what can be stored in a single page.
1380 // TODO(gc): Change the limit on new-space allocation to prevent this 1388 // TODO(gc): Change the limit on new-space allocation to prevent this
1381 // from happening (all such allocations should go directly to LOSpace). 1389 // from happening (all such allocations should go directly to LOSpace).
1382 return false; 1390 return false;
1383 } 1391 }
1384 if (!to_space_.AdvancePage()) { 1392 if (!to_space_.AdvancePage()) {
(...skipping 11 matching lines...) Expand all
1396 int remaining_in_page = static_cast<int>(limit - top); 1404 int remaining_in_page = static_cast<int>(limit - top);
1397 heap()->CreateFillerObjectAt(top, remaining_in_page); 1405 heap()->CreateFillerObjectAt(top, remaining_in_page);
1398 pages_used_++; 1406 pages_used_++;
1399 UpdateAllocationInfo(); 1407 UpdateAllocationInfo();
1400 1408
1401 return true; 1409 return true;
1402 } 1410 }
1403 1411
1404 1412
1405 MaybeObject* NewSpace::SlowAllocateRaw(int size_in_bytes) { 1413 MaybeObject* NewSpace::SlowAllocateRaw(int size_in_bytes) {
1406 Address old_top = allocation_info_.top; 1414 Address old_top = allocation_info_.top();
1407 Address new_top = old_top + size_in_bytes; 1415 Address new_top = old_top + size_in_bytes;
1408 Address high = to_space_.page_high(); 1416 Address high = to_space_.page_high();
1409 if (allocation_info_.limit < high) { 1417 if (allocation_info_.limit() < high) {
1410 // Incremental marking has lowered the limit to get a 1418 // Incremental marking has lowered the limit to get a
1411 // chance to do a step. 1419 // chance to do a step.
1412 allocation_info_.limit = Min( 1420 Address new_limit = Min(
1413 allocation_info_.limit + inline_allocation_limit_step_, 1421 allocation_info_.limit() + inline_allocation_limit_step_,
1414 high); 1422 high);
1423 allocation_info_.set_limit(new_limit);
1415 int bytes_allocated = static_cast<int>(new_top - top_on_previous_step_); 1424 int bytes_allocated = static_cast<int>(new_top - top_on_previous_step_);
1416 heap()->incremental_marking()->Step( 1425 heap()->incremental_marking()->Step(
1417 bytes_allocated, IncrementalMarking::GC_VIA_STACK_GUARD); 1426 bytes_allocated, IncrementalMarking::GC_VIA_STACK_GUARD);
1418 top_on_previous_step_ = new_top; 1427 top_on_previous_step_ = new_top;
1419 return AllocateRaw(size_in_bytes); 1428 return AllocateRaw(size_in_bytes);
1420 } else if (AddFreshPage()) { 1429 } else if (AddFreshPage()) {
1421 // Switched to new page. Try allocating again. 1430 // Switched to new page. Try allocating again.
1422 int bytes_allocated = static_cast<int>(old_top - top_on_previous_step_); 1431 int bytes_allocated = static_cast<int>(old_top - top_on_previous_step_);
1423 heap()->incremental_marking()->Step( 1432 heap()->incremental_marking()->Step(
1424 bytes_allocated, IncrementalMarking::GC_VIA_STACK_GUARD); 1433 bytes_allocated, IncrementalMarking::GC_VIA_STACK_GUARD);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1513 1522
1514 void SemiSpace::TearDown() { 1523 void SemiSpace::TearDown() {
1515 start_ = NULL; 1524 start_ = NULL;
1516 capacity_ = 0; 1525 capacity_ = 0;
1517 } 1526 }
1518 1527
1519 1528
1520 bool SemiSpace::Commit() { 1529 bool SemiSpace::Commit() {
1521 ASSERT(!is_committed()); 1530 ASSERT(!is_committed());
1522 int pages = capacity_ / Page::kPageSize; 1531 int pages = capacity_ / Page::kPageSize;
1523 Address end = start_ + maximum_capacity_; 1532 if (!heap()->isolate()->memory_allocator()->CommitBlock(start_,
1524 Address start = end - pages * Page::kPageSize;
1525 if (!heap()->isolate()->memory_allocator()->CommitBlock(start,
1526 capacity_, 1533 capacity_,
1527 executable())) { 1534 executable())) {
1528 return false; 1535 return false;
1529 } 1536 }
1530 1537
1531 NewSpacePage* page = anchor(); 1538 NewSpacePage* current = anchor();
1532 for (int i = 1; i <= pages; i++) { 1539 for (int i = 0; i < pages; i++) {
1533 NewSpacePage* new_page = 1540 NewSpacePage* new_page =
1534 NewSpacePage::Initialize(heap(), end - i * Page::kPageSize, this); 1541 NewSpacePage::Initialize(heap(), start_ + i * Page::kPageSize, this);
1535 new_page->InsertAfter(page); 1542 new_page->InsertAfter(current);
1536 page = new_page; 1543 current = new_page;
1537 } 1544 }
1538 1545
1539 committed_ = true; 1546 committed_ = true;
1540 Reset(); 1547 Reset();
1541 return true; 1548 return true;
1542 } 1549 }
1543 1550
1544 1551
1545 bool SemiSpace::Uncommit() { 1552 bool SemiSpace::Uncommit() {
1546 ASSERT(is_committed()); 1553 ASSERT(is_committed());
(...skipping 23 matching lines...) Expand all
1570 bool SemiSpace::GrowTo(int new_capacity) { 1577 bool SemiSpace::GrowTo(int new_capacity) {
1571 if (!is_committed()) { 1578 if (!is_committed()) {
1572 if (!Commit()) return false; 1579 if (!Commit()) return false;
1573 } 1580 }
1574 ASSERT((new_capacity & Page::kPageAlignmentMask) == 0); 1581 ASSERT((new_capacity & Page::kPageAlignmentMask) == 0);
1575 ASSERT(new_capacity <= maximum_capacity_); 1582 ASSERT(new_capacity <= maximum_capacity_);
1576 ASSERT(new_capacity > capacity_); 1583 ASSERT(new_capacity > capacity_);
1577 int pages_before = capacity_ / Page::kPageSize; 1584 int pages_before = capacity_ / Page::kPageSize;
1578 int pages_after = new_capacity / Page::kPageSize; 1585 int pages_after = new_capacity / Page::kPageSize;
1579 1586
1580 Address end = start_ + maximum_capacity_;
1581 Address start = end - new_capacity;
1582 size_t delta = new_capacity - capacity_; 1587 size_t delta = new_capacity - capacity_;
1583 1588
1584 ASSERT(IsAligned(delta, OS::AllocateAlignment())); 1589 ASSERT(IsAligned(delta, OS::AllocateAlignment()));
1585 if (!heap()->isolate()->memory_allocator()->CommitBlock( 1590 if (!heap()->isolate()->memory_allocator()->CommitBlock(
1586 start, delta, executable())) { 1591 start_ + capacity_, delta, executable())) {
1587 return false; 1592 return false;
1588 } 1593 }
1589 capacity_ = new_capacity; 1594 capacity_ = new_capacity;
1590 NewSpacePage* last_page = anchor()->prev_page(); 1595 NewSpacePage* last_page = anchor()->prev_page();
1591 ASSERT(last_page != anchor()); 1596 ASSERT(last_page != anchor());
1592 for (int i = pages_before + 1; i <= pages_after; i++) { 1597 for (int i = pages_before; i < pages_after; i++) {
1593 Address page_address = end - i * Page::kPageSize; 1598 Address page_address = start_ + i * Page::kPageSize;
1594 NewSpacePage* new_page = NewSpacePage::Initialize(heap(), 1599 NewSpacePage* new_page = NewSpacePage::Initialize(heap(),
1595 page_address, 1600 page_address,
1596 this); 1601 this);
1597 new_page->InsertAfter(last_page); 1602 new_page->InsertAfter(last_page);
1598 Bitmap::Clear(new_page); 1603 Bitmap::Clear(new_page);
1599 // Duplicate the flags that was set on the old page. 1604 // Duplicate the flags that was set on the old page.
1600 new_page->SetFlags(last_page->GetFlags(), 1605 new_page->SetFlags(last_page->GetFlags(),
1601 NewSpacePage::kCopyOnFlipFlagsMask); 1606 NewSpacePage::kCopyOnFlipFlagsMask);
1602 last_page = new_page; 1607 last_page = new_page;
1603 } 1608 }
1604 return true; 1609 return true;
1605 } 1610 }
1606 1611
1607 1612
1608 bool SemiSpace::ShrinkTo(int new_capacity) { 1613 bool SemiSpace::ShrinkTo(int new_capacity) {
1609 ASSERT((new_capacity & Page::kPageAlignmentMask) == 0); 1614 ASSERT((new_capacity & Page::kPageAlignmentMask) == 0);
1610 ASSERT(new_capacity >= initial_capacity_); 1615 ASSERT(new_capacity >= initial_capacity_);
1611 ASSERT(new_capacity < capacity_); 1616 ASSERT(new_capacity < capacity_);
1612 if (is_committed()) { 1617 if (is_committed()) {
1613 // Semispaces grow backwards from the end of their allocated capacity,
1614 // so we find the before and after start addresses relative to the
1615 // end of the space.
1616 Address space_end = start_ + maximum_capacity_;
1617 Address old_start = space_end - capacity_;
1618 size_t delta = capacity_ - new_capacity; 1618 size_t delta = capacity_ - new_capacity;
1619 ASSERT(IsAligned(delta, OS::AllocateAlignment())); 1619 ASSERT(IsAligned(delta, OS::AllocateAlignment()));
1620 1620
1621 MemoryAllocator* allocator = heap()->isolate()->memory_allocator(); 1621 MemoryAllocator* allocator = heap()->isolate()->memory_allocator();
1622 if (!allocator->UncommitBlock(old_start, delta)) { 1622 if (!allocator->UncommitBlock(start_ + new_capacity, delta)) {
1623 return false; 1623 return false;
1624 } 1624 }
1625 1625
1626 int pages_after = new_capacity / Page::kPageSize; 1626 int pages_after = new_capacity / Page::kPageSize;
1627 NewSpacePage* new_last_page = 1627 NewSpacePage* new_last_page =
1628 NewSpacePage::FromAddress(space_end - pages_after * Page::kPageSize); 1628 NewSpacePage::FromAddress(start_ + (pages_after - 1) * Page::kPageSize);
1629 new_last_page->set_next_page(anchor()); 1629 new_last_page->set_next_page(anchor());
1630 anchor()->set_prev_page(new_last_page); 1630 anchor()->set_prev_page(new_last_page);
1631 ASSERT((current_page_ <= first_page()) && (current_page_ >= new_last_page)); 1631 ASSERT((current_page_ >= first_page()) && (current_page_ <= new_last_page));
1632 } 1632 }
1633 1633
1634 capacity_ = new_capacity; 1634 capacity_ = new_capacity;
1635 1635
1636 return true; 1636 return true;
1637 } 1637 }
1638 1638
1639 1639
1640 void SemiSpace::FlipPages(intptr_t flags, intptr_t mask) { 1640 void SemiSpace::FlipPages(intptr_t flags, intptr_t mask) {
1641 anchor_.set_owner(this); 1641 anchor_.set_owner(this);
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
1968 void NewSpace::RecordPromotion(HeapObject* obj) { 1968 void NewSpace::RecordPromotion(HeapObject* obj) {
1969 InstanceType type = obj->map()->instance_type(); 1969 InstanceType type = obj->map()->instance_type();
1970 ASSERT(0 <= type && type <= LAST_TYPE); 1970 ASSERT(0 <= type && type <= LAST_TYPE);
1971 promoted_histogram_[type].increment_number(1); 1971 promoted_histogram_[type].increment_number(1);
1972 promoted_histogram_[type].increment_bytes(obj->Size()); 1972 promoted_histogram_[type].increment_bytes(obj->Size());
1973 } 1973 }
1974 1974
1975 1975
1976 size_t NewSpace::CommittedPhysicalMemory() { 1976 size_t NewSpace::CommittedPhysicalMemory() {
1977 if (!VirtualMemory::HasLazyCommits()) return CommittedMemory(); 1977 if (!VirtualMemory::HasLazyCommits()) return CommittedMemory();
1978 MemoryChunk::UpdateHighWaterMark(allocation_info_.top); 1978 MemoryChunk::UpdateHighWaterMark(allocation_info_.top());
1979 size_t size = to_space_.CommittedPhysicalMemory(); 1979 size_t size = to_space_.CommittedPhysicalMemory();
1980 if (from_space_.is_committed()) { 1980 if (from_space_.is_committed()) {
1981 size += from_space_.CommittedPhysicalMemory(); 1981 size += from_space_.CommittedPhysicalMemory();
1982 } 1982 }
1983 return size; 1983 return size;
1984 } 1984 }
1985 1985
1986 1986
1987 // ----------------------------------------------------------------------------- 1987 // -----------------------------------------------------------------------------
1988 // Free lists for old object spaces implementation 1988 // Free lists for old object spaces implementation
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
2494 // space than the minimum NewSpace size. The limit can be set lower than 2494 // space than the minimum NewSpace size. The limit can be set lower than
2495 // the end of new space either because there is more space on the next page 2495 // the end of new space either because there is more space on the next page
2496 // or because we have lowered the limit in order to get periodic incremental 2496 // or because we have lowered the limit in order to get periodic incremental
2497 // marking. The most reliable way to ensure that there is linear space is 2497 // marking. The most reliable way to ensure that there is linear space is
2498 // to do the allocation, then rewind the limit. 2498 // to do the allocation, then rewind the limit.
2499 ASSERT(bytes <= InitialCapacity()); 2499 ASSERT(bytes <= InitialCapacity());
2500 MaybeObject* maybe = AllocateRaw(bytes); 2500 MaybeObject* maybe = AllocateRaw(bytes);
2501 Object* object = NULL; 2501 Object* object = NULL;
2502 if (!maybe->ToObject(&object)) return false; 2502 if (!maybe->ToObject(&object)) return false;
2503 HeapObject* allocation = HeapObject::cast(object); 2503 HeapObject* allocation = HeapObject::cast(object);
2504 Address top = allocation_info_.top; 2504 Address top = allocation_info_.top();
2505 if ((top - bytes) == allocation->address()) { 2505 if ((top - bytes) == allocation->address()) {
2506 allocation_info_.top = allocation->address(); 2506 allocation_info_.set_top(allocation->address());
2507 return true; 2507 return true;
2508 } 2508 }
2509 // There may be a borderline case here where the allocation succeeded, but 2509 // There may be a borderline case here where the allocation succeeded, but
2510 // the limit and top have moved on to a new page. In that case we try again. 2510 // the limit and top have moved on to a new page. In that case we try again.
2511 return ReserveSpace(bytes); 2511 return ReserveSpace(bytes);
2512 } 2512 }
2513 2513
2514 2514
2515 void PagedSpace::PrepareForMarkCompact() { 2515 void PagedSpace::PrepareForMarkCompact() {
2516 // We don't have a linear allocation area while sweeping. It will be restored 2516 // We don't have a linear allocation area while sweeping. It will be restored
(...skipping 25 matching lines...) Expand all
2542 unswept_free_bytes_ = 0; 2542 unswept_free_bytes_ = 0;
2543 2543
2544 // Clear the free list before a full GC---it will be rebuilt afterward. 2544 // Clear the free list before a full GC---it will be rebuilt afterward.
2545 free_list_.Reset(); 2545 free_list_.Reset();
2546 } 2546 }
2547 2547
2548 2548
2549 bool PagedSpace::ReserveSpace(int size_in_bytes) { 2549 bool PagedSpace::ReserveSpace(int size_in_bytes) {
2550 ASSERT(size_in_bytes <= AreaSize()); 2550 ASSERT(size_in_bytes <= AreaSize());
2551 ASSERT(size_in_bytes == RoundSizeDownToObjectAlignment(size_in_bytes)); 2551 ASSERT(size_in_bytes == RoundSizeDownToObjectAlignment(size_in_bytes));
2552 Address current_top = allocation_info_.top; 2552 Address current_top = allocation_info_.top();
2553 Address new_top = current_top + size_in_bytes; 2553 Address new_top = current_top + size_in_bytes;
2554 if (new_top <= allocation_info_.limit) return true; 2554 if (new_top <= allocation_info_.limit()) return true;
2555 2555
2556 HeapObject* new_area = free_list_.Allocate(size_in_bytes); 2556 HeapObject* new_area = free_list_.Allocate(size_in_bytes);
2557 if (new_area == NULL) new_area = SlowAllocateRaw(size_in_bytes); 2557 if (new_area == NULL) new_area = SlowAllocateRaw(size_in_bytes);
2558 if (new_area == NULL) return false; 2558 if (new_area == NULL) return false;
2559 2559
2560 int old_linear_size = static_cast<int>(limit() - top()); 2560 int old_linear_size = static_cast<int>(limit() - top());
2561 // Mark the old linear allocation area with a free space so it can be 2561 // Mark the old linear allocation area with a free space so it can be
2562 // skipped when scanning the heap. This also puts it back in the free list 2562 // skipped when scanning the heap. This also puts it back in the free list
2563 // if it is big enough. 2563 // if it is big enough.
2564 Free(top(), old_linear_size); 2564 Free(top(), old_linear_size);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2619 first_unswept_page_ = p; 2619 first_unswept_page_ = p;
2620 } 2620 }
2621 2621
2622 heap()->FreeQueuedChunks(); 2622 heap()->FreeQueuedChunks();
2623 2623
2624 return IsLazySweepingComplete(); 2624 return IsLazySweepingComplete();
2625 } 2625 }
2626 2626
2627 2627
2628 void PagedSpace::EvictEvacuationCandidatesFromFreeLists() { 2628 void PagedSpace::EvictEvacuationCandidatesFromFreeLists() {
2629 if (allocation_info_.top >= allocation_info_.limit) return; 2629 if (allocation_info_.top() >= allocation_info_.limit()) return;
2630 2630
2631 if (Page::FromAllocationTop(allocation_info_.top)->IsEvacuationCandidate()) { 2631 if (Page::FromAllocationTop(allocation_info_.top())->
2632 IsEvacuationCandidate()) {
2632 // Create filler object to keep page iterable if it was iterable. 2633 // Create filler object to keep page iterable if it was iterable.
2633 int remaining = 2634 int remaining =
2634 static_cast<int>(allocation_info_.limit - allocation_info_.top); 2635 static_cast<int>(allocation_info_.limit() - allocation_info_.top());
2635 heap()->CreateFillerObjectAt(allocation_info_.top, remaining); 2636 heap()->CreateFillerObjectAt(allocation_info_.top(), remaining);
2636 2637
2637 allocation_info_.top = NULL; 2638 allocation_info_.set_top(NULL);
2638 allocation_info_.limit = NULL; 2639 allocation_info_.set_limit(NULL);
2639 } 2640 }
2640 } 2641 }
2641 2642
2642 2643
2643 bool PagedSpace::EnsureSweeperProgress(intptr_t size_in_bytes) { 2644 bool PagedSpace::EnsureSweeperProgress(intptr_t size_in_bytes) {
2644 MarkCompactCollector* collector = heap()->mark_compact_collector(); 2645 MarkCompactCollector* collector = heap()->mark_compact_collector();
2645 if (collector->AreSweeperThreadsActivated()) { 2646 if (collector->AreSweeperThreadsActivated()) {
2646 if (collector->IsConcurrentSweepingInProgress()) { 2647 if (collector->IsConcurrentSweepingInProgress()) {
2647 if (collector->StealMemoryFromSweeperThreads(this) < size_in_bytes) { 2648 if (collector->StealMemoryFromSweeperThreads(this) < size_in_bytes) {
2648 if (!collector->sequential_sweeping()) { 2649 if (!collector->sequential_sweeping()) {
(...skipping 29 matching lines...) Expand all
2678 // Free list allocation failed and there is no next page. Fail if we have 2679 // Free list allocation failed and there is no next page. Fail if we have
2679 // hit the old generation size limit that should cause a garbage 2680 // hit the old generation size limit that should cause a garbage
2680 // collection. 2681 // collection.
2681 if (!heap()->always_allocate() && 2682 if (!heap()->always_allocate() &&
2682 heap()->OldGenerationAllocationLimitReached()) { 2683 heap()->OldGenerationAllocationLimitReached()) {
2683 return NULL; 2684 return NULL;
2684 } 2685 }
2685 2686
2686 // Try to expand the space and allocate in the new next page. 2687 // Try to expand the space and allocate in the new next page.
2687 if (Expand()) { 2688 if (Expand()) {
2689 ASSERT(CountTotalPages() > 1 || size_in_bytes <= free_list_.available());
2688 return free_list_.Allocate(size_in_bytes); 2690 return free_list_.Allocate(size_in_bytes);
2689 } 2691 }
2690 2692
2691 // Last ditch, sweep all the remaining pages to try to find space. This may 2693 // Last ditch, sweep all the remaining pages to try to find space. This may
2692 // cause a pause. 2694 // cause a pause.
2693 if (!IsLazySweepingComplete()) { 2695 if (!IsLazySweepingComplete()) {
2694 EnsureSweeperProgress(kMaxInt); 2696 EnsureSweeperProgress(kMaxInt);
2695 2697
2696 // Retry the free list allocation. 2698 // Retry the free list allocation.
2697 HeapObject* object = free_list_.Allocate(size_in_bytes); 2699 HeapObject* object = free_list_.Allocate(size_in_bytes);
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
3221 object->ShortPrint(); 3223 object->ShortPrint();
3222 PrintF("\n"); 3224 PrintF("\n");
3223 } 3225 }
3224 printf(" --------------------------------------\n"); 3226 printf(" --------------------------------------\n");
3225 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); 3227 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes());
3226 } 3228 }
3227 3229
3228 #endif // DEBUG 3230 #endif // DEBUG
3229 3231
3230 } } // namespace v8::internal 3232 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/spaces.h ('k') | src/spaces-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698