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

Side by Side Diff: src/heap/spaces.cc

Issue 652543007: Add support for a target new space size (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: updates Created 6 years, 2 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/heap/spaces.h ('k') | test/cctest/cctest.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 // 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/v8.h" 5 #include "src/v8.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.h" 9 #include "src/full-codegen.h"
10 #include "src/heap/mark-compact.h" 10 #include "src/heap/mark-compact.h"
(...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1188 1188
1189 1189
1190 bool NewSpace::SetUp(int reserved_semispace_capacity, 1190 bool NewSpace::SetUp(int reserved_semispace_capacity,
1191 int maximum_semispace_capacity) { 1191 int maximum_semispace_capacity) {
1192 // Set up new space based on the preallocated memory block defined by 1192 // Set up new space based on the preallocated memory block defined by
1193 // start and size. The provided space is divided into two semi-spaces. 1193 // start and size. The provided space is divided into two semi-spaces.
1194 // To support fast containment testing in the new space, the size of 1194 // To support fast containment testing in the new space, the size of
1195 // this chunk must be a power of two and it must be aligned to its size. 1195 // this chunk must be a power of two and it must be aligned to its size.
1196 int initial_semispace_capacity = heap()->InitialSemiSpaceSize(); 1196 int initial_semispace_capacity = heap()->InitialSemiSpaceSize();
1197 1197
1198 int target_semispace_capacity = heap()->TargetSemiSpaceSize();
1199
1198 size_t size = 2 * reserved_semispace_capacity; 1200 size_t size = 2 * reserved_semispace_capacity;
1199 Address base = heap()->isolate()->memory_allocator()->ReserveAlignedMemory( 1201 Address base = heap()->isolate()->memory_allocator()->ReserveAlignedMemory(
1200 size, size, &reservation_); 1202 size, size, &reservation_);
1201 if (base == NULL) return false; 1203 if (base == NULL) return false;
1202 1204
1203 chunk_base_ = base; 1205 chunk_base_ = base;
1204 chunk_size_ = static_cast<uintptr_t>(size); 1206 chunk_size_ = static_cast<uintptr_t>(size);
1205 LOG(heap()->isolate(), NewEvent("InitialChunk", chunk_base_, chunk_size_)); 1207 LOG(heap()->isolate(), NewEvent("InitialChunk", chunk_base_, chunk_size_));
1206 1208
1207 DCHECK(initial_semispace_capacity <= maximum_semispace_capacity); 1209 DCHECK(initial_semispace_capacity <= maximum_semispace_capacity);
1208 DCHECK(base::bits::IsPowerOfTwo32(maximum_semispace_capacity)); 1210 DCHECK(base::bits::IsPowerOfTwo32(maximum_semispace_capacity));
1209 1211
1210 // Allocate and set up the histogram arrays if necessary. 1212 // Allocate and set up the histogram arrays if necessary.
1211 allocated_histogram_ = NewArray<HistogramInfo>(LAST_TYPE + 1); 1213 allocated_histogram_ = NewArray<HistogramInfo>(LAST_TYPE + 1);
1212 promoted_histogram_ = NewArray<HistogramInfo>(LAST_TYPE + 1); 1214 promoted_histogram_ = NewArray<HistogramInfo>(LAST_TYPE + 1);
1213 1215
1214 #define SET_NAME(name) \ 1216 #define SET_NAME(name) \
1215 allocated_histogram_[name].set_name(#name); \ 1217 allocated_histogram_[name].set_name(#name); \
1216 promoted_histogram_[name].set_name(#name); 1218 promoted_histogram_[name].set_name(#name);
1217 INSTANCE_TYPE_LIST(SET_NAME) 1219 INSTANCE_TYPE_LIST(SET_NAME)
1218 #undef SET_NAME 1220 #undef SET_NAME
1219 1221
1220 DCHECK(reserved_semispace_capacity == heap()->ReservedSemiSpaceSize()); 1222 DCHECK(reserved_semispace_capacity == heap()->ReservedSemiSpaceSize());
1221 DCHECK(static_cast<intptr_t>(chunk_size_) >= 1223 DCHECK(static_cast<intptr_t>(chunk_size_) >=
1222 2 * heap()->ReservedSemiSpaceSize()); 1224 2 * heap()->ReservedSemiSpaceSize());
1223 DCHECK(IsAddressAligned(chunk_base_, 2 * reserved_semispace_capacity, 0)); 1225 DCHECK(IsAddressAligned(chunk_base_, 2 * reserved_semispace_capacity, 0));
1224 1226
1225 to_space_.SetUp(chunk_base_, initial_semispace_capacity, 1227 to_space_.SetUp(chunk_base_, initial_semispace_capacity,
1226 maximum_semispace_capacity); 1228 target_semispace_capacity, maximum_semispace_capacity);
1227 from_space_.SetUp(chunk_base_ + reserved_semispace_capacity, 1229 from_space_.SetUp(chunk_base_ + reserved_semispace_capacity,
1228 initial_semispace_capacity, maximum_semispace_capacity); 1230 initial_semispace_capacity, target_semispace_capacity,
1231 maximum_semispace_capacity);
1229 if (!to_space_.Commit()) { 1232 if (!to_space_.Commit()) {
1230 return false; 1233 return false;
1231 } 1234 }
1232 DCHECK(!from_space_.is_committed()); // No need to use memory yet. 1235 DCHECK(!from_space_.is_committed()); // No need to use memory yet.
1233 1236
1234 start_ = chunk_base_; 1237 start_ = chunk_base_;
1235 address_mask_ = ~(2 * reserved_semispace_capacity - 1); 1238 address_mask_ = ~(2 * reserved_semispace_capacity - 1);
1236 object_mask_ = address_mask_ | kHeapObjectTagMask; 1239 object_mask_ = address_mask_ | kHeapObjectTagMask;
1237 object_expected_ = reinterpret_cast<uintptr_t>(start_) | kHeapObjectTag; 1240 object_expected_ = reinterpret_cast<uintptr_t>(start_) | kHeapObjectTag;
1238 1241
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 int new_capacity = 1281 int new_capacity =
1279 Min(MaximumCapacity(), 2 * static_cast<int>(TotalCapacity())); 1282 Min(MaximumCapacity(), 2 * static_cast<int>(TotalCapacity()));
1280 if (to_space_.GrowTo(new_capacity)) { 1283 if (to_space_.GrowTo(new_capacity)) {
1281 // Only grow from space if we managed to grow to-space. 1284 // Only grow from space if we managed to grow to-space.
1282 if (!from_space_.GrowTo(new_capacity)) { 1285 if (!from_space_.GrowTo(new_capacity)) {
1283 // If we managed to grow to-space but couldn't grow from-space, 1286 // If we managed to grow to-space but couldn't grow from-space,
1284 // attempt to shrink to-space. 1287 // attempt to shrink to-space.
1285 if (!to_space_.ShrinkTo(from_space_.TotalCapacity())) { 1288 if (!to_space_.ShrinkTo(from_space_.TotalCapacity())) {
1286 // We are in an inconsistent state because we could not 1289 // We are in an inconsistent state because we could not
1287 // commit/uncommit memory from new space. 1290 // commit/uncommit memory from new space.
1288 V8::FatalProcessOutOfMemory("Failed to grow new space."); 1291 CHECK(false);
1289 } 1292 }
1290 } 1293 }
1291 } 1294 }
1292 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); 1295 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
1293 } 1296 }
1294 1297
1295 1298
1299 bool NewSpace::GrowOnePage() {
1300 if (TotalCapacity() == MaximumCapacity()) return false;
1301 int new_capacity = static_cast<int>(TotalCapacity()) + Page::kPageSize;
1302 if (to_space_.GrowTo(new_capacity)) {
1303 // Only grow from space if we managed to grow to-space and the from space
1304 // is actually committed.
1305 if (from_space_.is_committed()) {
1306 if (!from_space_.GrowTo(new_capacity)) {
1307 // If we managed to grow to-space but couldn't grow from-space,
1308 // attempt to shrink to-space.
1309 if (!to_space_.ShrinkTo(from_space_.TotalCapacity())) {
1310 // We are in an inconsistent state because we could not
1311 // commit/uncommit memory from new space.
1312 CHECK(false);
1313 }
1314 return false;
1315 }
1316 } else {
1317 if (!from_space_.SetTotalCapacity(new_capacity)) {
1318 // Can't really happen, but better safe than sorry.
1319 CHECK(false);
1320 }
1321 }
1322 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
1323 return true;
1324 }
1325 return false;
1326 }
1327
1328
1296 void NewSpace::Shrink() { 1329 void NewSpace::Shrink() {
1297 int new_capacity = Max(InitialTotalCapacity(), 2 * SizeAsInt()); 1330 int new_capacity = Max(InitialTotalCapacity(), 2 * SizeAsInt());
1298 int rounded_new_capacity = RoundUp(new_capacity, Page::kPageSize); 1331 int rounded_new_capacity = RoundUp(new_capacity, Page::kPageSize);
1299 if (rounded_new_capacity < TotalCapacity() && 1332 if (rounded_new_capacity < TotalCapacity() &&
1300 to_space_.ShrinkTo(rounded_new_capacity)) { 1333 to_space_.ShrinkTo(rounded_new_capacity)) {
1301 // Only shrink from-space if we managed to shrink to-space. 1334 // Only shrink from-space if we managed to shrink to-space.
1302 from_space_.Reset(); 1335 from_space_.Reset();
1303 if (!from_space_.ShrinkTo(rounded_new_capacity)) { 1336 if (!from_space_.ShrinkTo(rounded_new_capacity)) {
1304 // If we managed to shrink to-space but couldn't shrink from 1337 // If we managed to shrink to-space but couldn't shrink from
1305 // space, attempt to grow to-space again. 1338 // space, attempt to grow to-space again.
1306 if (!to_space_.GrowTo(from_space_.TotalCapacity())) { 1339 if (!to_space_.GrowTo(from_space_.TotalCapacity())) {
1307 // We are in an inconsistent state because we could not 1340 // We are in an inconsistent state because we could not
1308 // commit/uncommit memory from new space. 1341 // commit/uncommit memory from new space.
1309 V8::FatalProcessOutOfMemory("Failed to shrink new space."); 1342 CHECK(false);
1310 } 1343 }
1311 } 1344 }
1312 } 1345 }
1313 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); 1346 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
1314 } 1347 }
1315 1348
1316 1349
1317 void NewSpace::UpdateAllocationInfo() { 1350 void NewSpace::UpdateAllocationInfo() {
1318 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); 1351 MemoryChunk::UpdateHighWaterMark(allocation_info_.top());
1319 allocation_info_.set_top(to_space_.page_low()); 1352 allocation_info_.set_top(to_space_.page_low());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1360 if (NewSpacePage::IsAtStart(top)) { 1393 if (NewSpacePage::IsAtStart(top)) {
1361 // The current page is already empty. Don't try to make another. 1394 // The current page is already empty. Don't try to make another.
1362 1395
1363 // We should only get here if someone asks to allocate more 1396 // We should only get here if someone asks to allocate more
1364 // than what can be stored in a single page. 1397 // than what can be stored in a single page.
1365 // TODO(gc): Change the limit on new-space allocation to prevent this 1398 // TODO(gc): Change the limit on new-space allocation to prevent this
1366 // from happening (all such allocations should go directly to LOSpace). 1399 // from happening (all such allocations should go directly to LOSpace).
1367 return false; 1400 return false;
1368 } 1401 }
1369 if (!to_space_.AdvancePage()) { 1402 if (!to_space_.AdvancePage()) {
1370 // Failed to get a new page in to-space. 1403 // Check if we reached the target capacity yet. If not, try to commit a page
1371 return false; 1404 // and continue.
1405 if ((to_space_.TotalCapacity() < to_space_.TargetCapacity()) &&
1406 GrowOnePage()) {
1407 if (!to_space_.AdvancePage()) {
1408 // It doesn't make sense that we managed to commit a page, but can't use
1409 // it.
1410 CHECK(false);
1411 }
1412 } else {
1413 // Failed to get a new page in to-space.
1414 return false;
1415 }
1372 } 1416 }
1373 1417
1374 // Clear remainder of current page. 1418 // Clear remainder of current page.
1375 Address limit = NewSpacePage::FromLimit(top)->area_end(); 1419 Address limit = NewSpacePage::FromLimit(top)->area_end();
1376 if (heap()->gc_state() == Heap::SCAVENGE) { 1420 if (heap()->gc_state() == Heap::SCAVENGE) {
1377 heap()->promotion_queue()->SetNewLimit(limit); 1421 heap()->promotion_queue()->SetNewLimit(limit);
1378 } 1422 }
1379 1423
1380 int remaining_in_page = static_cast<int>(limit - top); 1424 int remaining_in_page = static_cast<int>(limit - top);
1381 heap()->CreateFillerObjectAt(top, remaining_in_page); 1425 heap()->CreateFillerObjectAt(top, remaining_in_page);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1465 CHECK_EQ(from_space_.id(), kFromSpace); 1509 CHECK_EQ(from_space_.id(), kFromSpace);
1466 CHECK_EQ(to_space_.id(), kToSpace); 1510 CHECK_EQ(to_space_.id(), kToSpace);
1467 from_space_.Verify(); 1511 from_space_.Verify();
1468 to_space_.Verify(); 1512 to_space_.Verify();
1469 } 1513 }
1470 #endif 1514 #endif
1471 1515
1472 // ----------------------------------------------------------------------------- 1516 // -----------------------------------------------------------------------------
1473 // SemiSpace implementation 1517 // SemiSpace implementation
1474 1518
1475 void SemiSpace::SetUp(Address start, int initial_capacity, 1519 void SemiSpace::SetUp(Address start, int initial_capacity, int target_capacity,
1476 int maximum_capacity) { 1520 int maximum_capacity) {
1477 // Creates a space in the young generation. The constructor does not 1521 // Creates a space in the young generation. The constructor does not
1478 // allocate memory from the OS. A SemiSpace is given a contiguous chunk of 1522 // allocate memory from the OS. A SemiSpace is given a contiguous chunk of
1479 // memory of size 'capacity' when set up, and does not grow or shrink 1523 // memory of size 'capacity' when set up, and does not grow or shrink
1480 // otherwise. In the mark-compact collector, the memory region of the from 1524 // otherwise. In the mark-compact collector, the memory region of the from
1481 // space is used as the marking stack. It requires contiguous memory 1525 // space is used as the marking stack. It requires contiguous memory
1482 // addresses. 1526 // addresses.
1483 DCHECK(maximum_capacity >= Page::kPageSize); 1527 DCHECK(maximum_capacity >= Page::kPageSize);
1528 DCHECK(initial_capacity <= target_capacity);
1529 DCHECK(target_capacity <= maximum_capacity);
1484 initial_total_capacity_ = RoundDown(initial_capacity, Page::kPageSize); 1530 initial_total_capacity_ = RoundDown(initial_capacity, Page::kPageSize);
1485 total_capacity_ = initial_capacity; 1531 total_capacity_ = initial_capacity;
1532 target_capacity_ = RoundDown(target_capacity, Page::kPageSize);
1486 maximum_total_capacity_ = RoundDown(maximum_capacity, Page::kPageSize); 1533 maximum_total_capacity_ = RoundDown(maximum_capacity, Page::kPageSize);
1487 maximum_committed_ = 0; 1534 maximum_committed_ = 0;
1488 committed_ = false; 1535 committed_ = false;
1489 start_ = start; 1536 start_ = start;
1490 address_mask_ = ~(maximum_capacity - 1); 1537 address_mask_ = ~(maximum_capacity - 1);
1491 object_mask_ = address_mask_ | kHeapObjectTagMask; 1538 object_mask_ = address_mask_ | kHeapObjectTagMask;
1492 object_expected_ = reinterpret_cast<uintptr_t>(start) | kHeapObjectTag; 1539 object_expected_ = reinterpret_cast<uintptr_t>(start) | kHeapObjectTag;
1493 age_mark_ = start_; 1540 age_mark_ = start_;
1494 } 1541 }
1495 1542
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1604 anchor()->set_prev_page(new_last_page); 1651 anchor()->set_prev_page(new_last_page);
1605 DCHECK((current_page_ >= first_page()) && (current_page_ <= new_last_page)); 1652 DCHECK((current_page_ >= first_page()) && (current_page_ <= new_last_page));
1606 } 1653 }
1607 1654
1608 SetCapacity(new_capacity); 1655 SetCapacity(new_capacity);
1609 1656
1610 return true; 1657 return true;
1611 } 1658 }
1612 1659
1613 1660
1661 bool SemiSpace::SetTotalCapacity(int new_capacity) {
1662 CHECK(!is_committed());
1663 if (new_capacity >= initial_total_capacity_ &&
1664 new_capacity <= maximum_total_capacity_) {
1665 total_capacity_ = new_capacity;
1666 return true;
1667 }
1668 return false;
1669 }
1670
1671
1614 void SemiSpace::FlipPages(intptr_t flags, intptr_t mask) { 1672 void SemiSpace::FlipPages(intptr_t flags, intptr_t mask) {
1615 anchor_.set_owner(this); 1673 anchor_.set_owner(this);
1616 // Fixup back-pointers to anchor. Address of anchor changes 1674 // Fixup back-pointers to anchor. Address of anchor changes
1617 // when we swap. 1675 // when we swap.
1618 anchor_.prev_page()->set_next_page(&anchor_); 1676 anchor_.prev_page()->set_next_page(&anchor_);
1619 anchor_.next_page()->set_prev_page(&anchor_); 1677 anchor_.next_page()->set_prev_page(&anchor_);
1620 1678
1621 bool becomes_to_space = (id_ == kFromSpace); 1679 bool becomes_to_space = (id_ == kFromSpace);
1622 id_ = becomes_to_space ? kToSpace : kFromSpace; 1680 id_ = becomes_to_space ? kToSpace : kFromSpace;
1623 NewSpacePage* page = anchor_.next_page(); 1681 NewSpacePage* page = anchor_.next_page();
(...skipping 1487 matching lines...) Expand 10 before | Expand all | Expand 10 after
3111 object->ShortPrint(); 3169 object->ShortPrint();
3112 PrintF("\n"); 3170 PrintF("\n");
3113 } 3171 }
3114 printf(" --------------------------------------\n"); 3172 printf(" --------------------------------------\n");
3115 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); 3173 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes());
3116 } 3174 }
3117 3175
3118 #endif // DEBUG 3176 #endif // DEBUG
3119 } 3177 }
3120 } // namespace v8::internal 3178 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap/spaces.h ('k') | test/cctest/cctest.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698