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

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

Issue 1853783002: [heap] Non-contiguous young generation (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed offline comment (not passing size/executability for pooled allocation) Created 4 years, 8 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
« no previous file with comments | « src/heap/heap.cc ('k') | src/heap/spaces.cc » ('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 #ifndef V8_HEAP_SPACES_H_ 5 #ifndef V8_HEAP_SPACES_H_
6 #define V8_HEAP_SPACES_H_ 6 #define V8_HEAP_SPACES_H_
7 7
8 #include "src/allocation.h" 8 #include "src/allocation.h"
9 #include "src/atomic-utils.h" 9 #include "src/atomic-utils.h"
10 #include "src/base/atomicops.h" 10 #include "src/base/atomicops.h"
11 #include "src/base/bits.h" 11 #include "src/base/bits.h"
12 #include "src/base/platform/mutex.h" 12 #include "src/base/platform/mutex.h"
13 #include "src/flags.h" 13 #include "src/flags.h"
14 #include "src/hashmap.h" 14 #include "src/hashmap.h"
15 #include "src/list.h" 15 #include "src/list.h"
16 #include "src/objects.h" 16 #include "src/objects.h"
17 #include "src/utils.h" 17 #include "src/utils.h"
18 18
19 namespace v8 { 19 namespace v8 {
20 namespace internal { 20 namespace internal {
21 21
22 class AllocationInfo; 22 class AllocationInfo;
23 class AllocationObserver; 23 class AllocationObserver;
24 class CompactionSpace; 24 class CompactionSpace;
25 class CompactionSpaceCollection; 25 class CompactionSpaceCollection;
26 class FreeList; 26 class FreeList;
27 class Isolate; 27 class Isolate;
28 class MemoryAllocator; 28 class MemoryAllocator;
29 class MemoryChunk; 29 class MemoryChunk;
30 class NewSpacePage;
30 class Page; 31 class Page;
31 class PagedSpace; 32 class PagedSpace;
32 class SemiSpace; 33 class SemiSpace;
33 class SkipList; 34 class SkipList;
34 class SlotsBuffer; 35 class SlotsBuffer;
35 class SlotSet; 36 class SlotSet;
36 class TypedSlotSet; 37 class TypedSlotSet;
37 class Space; 38 class Space;
38 39
39 // ----------------------------------------------------------------------------- 40 // -----------------------------------------------------------------------------
(...skipping 1199 matching lines...) Expand 10 before | Expand all | Expand 10 after
1239 1240
1240 // ---------------------------------------------------------------------------- 1241 // ----------------------------------------------------------------------------
1241 // A space acquires chunks of memory from the operating system. The memory 1242 // A space acquires chunks of memory from the operating system. The memory
1242 // allocator allocated and deallocates pages for the paged heap spaces and large 1243 // allocator allocated and deallocates pages for the paged heap spaces and large
1243 // pages for large object space. 1244 // pages for large object space.
1244 // 1245 //
1245 // Each space has to manage it's own pages. 1246 // Each space has to manage it's own pages.
1246 // 1247 //
1247 class MemoryAllocator { 1248 class MemoryAllocator {
1248 public: 1249 public:
1250 enum AllocationMode {
1251 kRegular,
1252 kPooled,
1253 };
1254
1249 explicit MemoryAllocator(Isolate* isolate); 1255 explicit MemoryAllocator(Isolate* isolate);
1250 1256
1251 // Initializes its internal bookkeeping structures. 1257 // Initializes its internal bookkeeping structures.
1252 // Max capacity of the total space and executable memory limit. 1258 // Max capacity of the total space and executable memory limit.
1253 bool SetUp(intptr_t max_capacity, intptr_t capacity_executable); 1259 bool SetUp(intptr_t max_capacity, intptr_t capacity_executable);
1254 1260
1255 void TearDown(); 1261 void TearDown();
1256 1262
1257 Page* AllocatePage(intptr_t size, PagedSpace* owner, 1263 // Allocates either Page or NewSpacePage from the allocator. AllocationMode
1258 Executability executable); 1264 // is used to indicate whether pooled allocation, which only works for
1265 // MemoryChunk::kPageSize, should be tried first.
1266 template <typename PageType, MemoryAllocator::AllocationMode mode = kRegular,
1267 typename SpaceType>
1268 PageType* AllocatePage(intptr_t size, SpaceType* owner,
1269 Executability executable);
1259 1270
1260 LargePage* AllocateLargePage(intptr_t object_size, Space* owner, 1271 LargePage* AllocateLargePage(intptr_t object_size, Space* owner,
1261 Executability executable); 1272 Executability executable);
1262 1273
1263 // PreFree logically frees the object, i.e., it takes care of the size 1274 // PreFree logically frees the object, i.e., it takes care of the size
1264 // bookkeeping and calls the allocation callback. 1275 // bookkeeping and calls the allocation callback.
1265 void PreFreeMemory(MemoryChunk* chunk); 1276 void PreFreeMemory(MemoryChunk* chunk);
1266 1277
1267 // FreeMemory can be called concurrently when PreFree was executed before. 1278 // FreeMemory can be called concurrently when PreFree was executed before.
1268 void PerformFreeMemory(MemoryChunk* chunk); 1279 void PerformFreeMemory(MemoryChunk* chunk);
1269 1280
1270 // Free is a wrapper method, which calls PreFree and PerformFreeMemory 1281 // Free is a wrapper method, which calls PreFree and PerformFreeMemory
1271 // together. 1282 // together.
1272 void Free(MemoryChunk* chunk); 1283 void Free(MemoryChunk* chunk);
Hannes Payer (out of office) 2016/04/05 12:38:49 Maybe also templatize Free?
Michael Lippautz 2016/04/05 12:47:59 Done.
1273 1284
1285 // Free that chunk into the pool.
1286 void FreePooled(MemoryChunk* chunk);
1287
1274 // Returns allocated spaces in bytes. 1288 // Returns allocated spaces in bytes.
1275 intptr_t Size() { return size_.Value(); } 1289 intptr_t Size() { return size_.Value(); }
1276 1290
1277 // Returns allocated executable spaces in bytes. 1291 // Returns allocated executable spaces in bytes.
1278 intptr_t SizeExecutable() { return size_executable_.Value(); } 1292 intptr_t SizeExecutable() { return size_executable_.Value(); }
1279 1293
1280 // Returns the maximum available bytes of heaps. 1294 // Returns the maximum available bytes of heaps.
1281 intptr_t Available() { 1295 intptr_t Available() {
1282 intptr_t size = Size(); 1296 intptr_t size = Size();
1283 return capacity_ < size ? 0 : capacity_ - size; 1297 return capacity_ < size ? 0 : capacity_ - size;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1315 Executability executable, Space* space); 1329 Executability executable, Space* space);
1316 1330
1317 Address ReserveAlignedMemory(size_t requested, size_t alignment, 1331 Address ReserveAlignedMemory(size_t requested, size_t alignment,
1318 base::VirtualMemory* controller); 1332 base::VirtualMemory* controller);
1319 Address AllocateAlignedMemory(size_t reserve_size, size_t commit_size, 1333 Address AllocateAlignedMemory(size_t reserve_size, size_t commit_size,
1320 size_t alignment, Executability executable, 1334 size_t alignment, Executability executable,
1321 base::VirtualMemory* controller); 1335 base::VirtualMemory* controller);
1322 1336
1323 bool CommitMemory(Address addr, size_t size, Executability executable); 1337 bool CommitMemory(Address addr, size_t size, Executability executable);
1324 1338
1325 void FreeNewSpaceMemory(Address addr, base::VirtualMemory* reservation,
1326 Executability executable);
1327 void FreeMemory(base::VirtualMemory* reservation, Executability executable); 1339 void FreeMemory(base::VirtualMemory* reservation, Executability executable);
1328 void FreeMemory(Address addr, size_t size, Executability executable); 1340 void FreeMemory(Address addr, size_t size, Executability executable);
1329 1341
1330 // Commit a contiguous block of memory from the initial chunk. Assumes that 1342 // Commit a contiguous block of memory from the initial chunk. Assumes that
1331 // the address is not NULL, the size is greater than zero, and that the 1343 // the address is not NULL, the size is greater than zero, and that the
1332 // block is contained in the initial chunk. Returns true if it succeeded 1344 // block is contained in the initial chunk. Returns true if it succeeded
1333 // and false otherwise. 1345 // and false otherwise.
1334 bool CommitBlock(Address start, size_t size, Executability executable); 1346 bool CommitBlock(Address start, size_t size, Executability executable);
1335 1347
1336 // Uncommit a contiguous block of memory [start..(start+size)[. 1348 // Uncommit a contiguous block of memory [start..(start+size)[.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1369 DCHECK_NE(LO_SPACE, space); 1381 DCHECK_NE(LO_SPACE, space);
1370 return (space == CODE_SPACE) ? CodePageAreaSize() 1382 return (space == CODE_SPACE) ? CodePageAreaSize()
1371 : Page::kAllocatableMemory; 1383 : Page::kAllocatableMemory;
1372 } 1384 }
1373 1385
1374 MUST_USE_RESULT bool CommitExecutableMemory(base::VirtualMemory* vm, 1386 MUST_USE_RESULT bool CommitExecutableMemory(base::VirtualMemory* vm,
1375 Address start, size_t commit_size, 1387 Address start, size_t commit_size,
1376 size_t reserved_size); 1388 size_t reserved_size);
1377 1389
1378 private: 1390 private:
1391 // See AllocatePage for public interface. Note that currently we only support
1392 // pools for NOT_EXECUTABLE pages of size MemoryChunk::kPageSize.
1393 template <typename SpaceType>
1394 MemoryChunk* AllocatePagePooled(SpaceType* owner);
1395
1379 Isolate* isolate_; 1396 Isolate* isolate_;
1380 1397
1381 // Maximum space size in bytes. 1398 // Maximum space size in bytes.
1382 intptr_t capacity_; 1399 intptr_t capacity_;
1383 // Maximum subset of capacity_ that can be executable 1400 // Maximum subset of capacity_ that can be executable
1384 intptr_t capacity_executable_; 1401 intptr_t capacity_executable_;
1385 1402
1386 // Allocated space size in bytes. 1403 // Allocated space size in bytes.
1387 AtomicNumber<intptr_t> size_; 1404 AtomicNumber<intptr_t> size_;
1388 // Allocated executable space size in bytes. 1405 // Allocated executable space size in bytes.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1422 // values only if they did not change in between. 1439 // values only if they did not change in between.
1423 void* ptr = nullptr; 1440 void* ptr = nullptr;
1424 do { 1441 do {
1425 ptr = lowest_ever_allocated_.Value(); 1442 ptr = lowest_ever_allocated_.Value();
1426 } while ((low < ptr) && !lowest_ever_allocated_.TrySetValue(ptr, low)); 1443 } while ((low < ptr) && !lowest_ever_allocated_.TrySetValue(ptr, low));
1427 do { 1444 do {
1428 ptr = highest_ever_allocated_.Value(); 1445 ptr = highest_ever_allocated_.Value();
1429 } while ((high > ptr) && !highest_ever_allocated_.TrySetValue(ptr, high)); 1446 } while ((high > ptr) && !highest_ever_allocated_.TrySetValue(ptr, high));
1430 } 1447 }
1431 1448
1449 List<MemoryChunk*> chunk_pool_;
1450
1432 DISALLOW_IMPLICIT_CONSTRUCTORS(MemoryAllocator); 1451 DISALLOW_IMPLICIT_CONSTRUCTORS(MemoryAllocator);
1433 }; 1452 };
1434 1453
1435 1454
1436 // ----------------------------------------------------------------------------- 1455 // -----------------------------------------------------------------------------
1437 // Interface for heap object iterator to be implemented by all object space 1456 // Interface for heap object iterator to be implemented by all object space
1438 // object iterators. 1457 // object iterators.
1439 // 1458 //
1440 // NOTE: The space specific object iterators also implements the own next() 1459 // NOTE: The space specific object iterators also implements the own next()
1441 // method which is used to avoid using virtual functions 1460 // method which is used to avoid using virtual functions
(...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after
2262 private: 2281 private:
2263 const char* name_; 2282 const char* name_;
2264 }; 2283 };
2265 2284
2266 2285
2267 enum SemiSpaceId { kFromSpace = 0, kToSpace = 1 }; 2286 enum SemiSpaceId { kFromSpace = 0, kToSpace = 1 };
2268 2287
2269 2288
2270 class NewSpacePage : public MemoryChunk { 2289 class NewSpacePage : public MemoryChunk {
2271 public: 2290 public:
2291 static inline NewSpacePage* Initialize(Heap* heap, MemoryChunk* chunk,
2292 Executability executable,
2293 SemiSpace* owner);
2294
2272 static bool IsAtStart(Address addr) { 2295 static bool IsAtStart(Address addr) {
2273 return (reinterpret_cast<intptr_t>(addr) & Page::kPageAlignmentMask) == 2296 return (reinterpret_cast<intptr_t>(addr) & Page::kPageAlignmentMask) ==
2274 kObjectStartOffset; 2297 kObjectStartOffset;
2275 } 2298 }
2276 2299
2277 static bool IsAtEnd(Address addr) { 2300 static bool IsAtEnd(Address addr) {
2278 return (reinterpret_cast<intptr_t>(addr) & Page::kPageAlignmentMask) == 0; 2301 return (reinterpret_cast<intptr_t>(addr) & Page::kPageAlignmentMask) == 0;
2279 } 2302 }
2280 2303
2281 // Finds the NewSpacePage containing the given address. 2304 // Finds the NewSpacePage containing the given address.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2319 // GC related flags copied from from-space to to-space when 2342 // GC related flags copied from from-space to to-space when
2320 // flipping semispaces. 2343 // flipping semispaces.
2321 static const intptr_t kCopyOnFlipFlagsMask = 2344 static const intptr_t kCopyOnFlipFlagsMask =
2322 (1 << MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING) | 2345 (1 << MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING) |
2323 (1 << MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); 2346 (1 << MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING);
2324 2347
2325 // Create a NewSpacePage object that is only used as anchor 2348 // Create a NewSpacePage object that is only used as anchor
2326 // for the doubly-linked list of real pages. 2349 // for the doubly-linked list of real pages.
2327 explicit NewSpacePage(SemiSpace* owner) { InitializeAsAnchor(owner); } 2350 explicit NewSpacePage(SemiSpace* owner) { InitializeAsAnchor(owner); }
2328 2351
2329 static NewSpacePage* Initialize(Heap* heap, Address start,
2330 SemiSpace* semi_space);
2331
2332 // Intialize a fake NewSpacePage used as sentinel at the ends 2352 // Intialize a fake NewSpacePage used as sentinel at the ends
2333 // of a doubly-linked list of real NewSpacePages. 2353 // of a doubly-linked list of real NewSpacePages.
2334 // Only uses the prev/next links, and sets flags to not be in new-space. 2354 // Only uses the prev/next links, and sets flags to not be in new-space.
2335 void InitializeAsAnchor(SemiSpace* owner); 2355 void InitializeAsAnchor(SemiSpace* owner);
2336 2356
2337 friend class SemiSpace; 2357 friend class SemiSpace;
2338 friend class SemiSpaceIterator; 2358 friend class SemiSpaceIterator;
2339 }; 2359 };
2340 2360
2341 2361
2342 // ----------------------------------------------------------------------------- 2362 // -----------------------------------------------------------------------------
2343 // SemiSpace in young generation 2363 // SemiSpace in young generation
2344 // 2364 //
2345 // A SemiSpace is a contiguous chunk of memory holding page-like memory chunks. 2365 // A SemiSpace is a contiguous chunk of memory holding page-like memory chunks.
2346 // The mark-compact collector uses the memory of the first page in the from 2366 // The mark-compact collector uses the memory of the first page in the from
2347 // space as a marking stack when tracing live objects. 2367 // space as a marking stack when tracing live objects.
2348 class SemiSpace : public Space { 2368 class SemiSpace : public Space {
2349 public: 2369 public:
2350 static void Swap(SemiSpace* from, SemiSpace* to); 2370 static void Swap(SemiSpace* from, SemiSpace* to);
2351 2371
2352 SemiSpace(Heap* heap, SemiSpaceId semispace) 2372 SemiSpace(Heap* heap, SemiSpaceId semispace)
2353 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), 2373 : Space(heap, NEW_SPACE, NOT_EXECUTABLE),
2354 current_capacity_(0), 2374 current_capacity_(0),
2355 maximum_capacity_(0), 2375 maximum_capacity_(0),
2356 minimum_capacity_(0), 2376 minimum_capacity_(0),
2357 start_(nullptr),
2358 age_mark_(nullptr), 2377 age_mark_(nullptr),
2359 committed_(false), 2378 committed_(false),
2360 id_(semispace), 2379 id_(semispace),
2361 anchor_(this), 2380 anchor_(this),
2362 current_page_(nullptr) {} 2381 current_page_(nullptr) {}
2363 2382
2364 inline bool Contains(HeapObject* o); 2383 inline bool Contains(HeapObject* o);
2365 inline bool Contains(Object* o); 2384 inline bool Contains(Object* o);
2366 inline bool ContainsSlow(Address a); 2385 inline bool ContainsSlow(Address a);
2367 2386
2368 // Creates a space in the young generation. The constructor does not 2387 void SetUp(int initial_capacity, int maximum_capacity);
2369 // allocate memory from the OS. 2388 void TearDown();
2370 void SetUp(Address start, int initial_capacity, int maximum_capacity); 2389 bool HasBeenSetUp() { return maximum_capacity_ != 0; }
2371 2390
2372 // Tear down the space. Heap memory was not allocated by the space, so it 2391 bool Commit();
2373 // is not deallocated here. 2392 bool Uncommit();
2374 void TearDown(); 2393 bool is_committed() { return committed_; }
2375 2394
2376 // True if the space has been set up but not torn down. 2395 // Grow the semispace to the new capacity. The new capacity requested must
2377 bool HasBeenSetUp() { return start_ != nullptr; } 2396 // be larger than the current capacity and less than the maximum capacity.
2378
2379 // Grow the semispace to the new capacity. The new capacity
2380 // requested must be larger than the current capacity and less than
2381 // the maximum capacity.
2382 bool GrowTo(int new_capacity); 2397 bool GrowTo(int new_capacity);
2383 2398
2384 // Shrinks the semispace to the new capacity. The new capacity 2399 // Shrinks the semispace to the new capacity. The new capacity requested
2385 // requested must be more than the amount of used memory in the 2400 // must be more than the amount of used memory in the semispace and less
2386 // semispace and less than the current capacity. 2401 // than the current capacity.
2387 bool ShrinkTo(int new_capacity); 2402 bool ShrinkTo(int new_capacity);
2388 2403
2389 // Returns the start address of the first page of the space. 2404 // Returns the start address of the first page of the space.
2390 Address space_start() { 2405 Address space_start() {
2391 DCHECK_NE(anchor_.next_page(), &anchor_); 2406 DCHECK_NE(anchor_.next_page(), anchor());
2392 return anchor_.next_page()->area_start(); 2407 return anchor_.next_page()->area_start();
2393 } 2408 }
2394 2409
2410 NewSpacePage* first_page() { return anchor_.next_page(); }
2411 NewSpacePage* current_page() { return current_page_; }
2412
2413 // Returns one past the end address of the space.
2414 Address space_end() { return anchor_.prev_page()->area_end(); }
2415
2395 // Returns the start address of the current page of the space. 2416 // Returns the start address of the current page of the space.
2396 Address page_low() { return current_page_->area_start(); } 2417 Address page_low() { return current_page_->area_start(); }
2397 2418
2398 // Returns one past the end address of the space.
2399 Address space_end() { return anchor_.prev_page()->area_end(); }
2400
2401 // Returns one past the end address of the current page of the space. 2419 // Returns one past the end address of the current page of the space.
2402 Address page_high() { return current_page_->area_end(); } 2420 Address page_high() { return current_page_->area_end(); }
2403 2421
2404 bool AdvancePage() { 2422 bool AdvancePage() {
2405 NewSpacePage* next_page = current_page_->next_page(); 2423 NewSpacePage* next_page = current_page_->next_page();
2406 if (next_page == anchor()) return false; 2424 if (next_page == anchor()) return false;
2407 current_page_ = next_page; 2425 current_page_ = next_page;
2408 return true; 2426 return true;
2409 } 2427 }
2410 2428
2411 // Resets the space to using the first page. 2429 // Resets the space to using the first page.
2412 void Reset(); 2430 void Reset();
2413 2431
2414 // Age mark accessors. 2432 // Age mark accessors.
2415 Address age_mark() { return age_mark_; } 2433 Address age_mark() { return age_mark_; }
2416 void set_age_mark(Address mark); 2434 void set_age_mark(Address mark);
2417 2435
2418 bool is_committed() { return committed_; } 2436 // Returns the current capacity of the semispace.
2419 bool Commit();
2420 bool Uncommit();
2421
2422 NewSpacePage* first_page() { return anchor_.next_page(); }
2423 NewSpacePage* current_page() { return current_page_; }
2424
2425 // Returns the current total capacity of the semispace.
2426 int current_capacity() { return current_capacity_; } 2437 int current_capacity() { return current_capacity_; }
2427 2438
2428 // Returns the maximum total capacity of the semispace. 2439 // Returns the maximum capacity of the semispace.
2429 int maximum_capacity() { return maximum_capacity_; } 2440 int maximum_capacity() { return maximum_capacity_; }
2430 2441
2431 // Returns the initial capacity of the semispace. 2442 // Returns the initial capacity of the semispace.
2432 int minimum_capacity() { return minimum_capacity_; } 2443 int minimum_capacity() { return minimum_capacity_; }
2433 2444
2434 SemiSpaceId id() { return id_; } 2445 SemiSpaceId id() { return id_; }
2435 2446
2436 // Approximate amount of physical memory committed for this space. 2447 // Approximate amount of physical memory committed for this space.
2437 size_t CommittedPhysicalMemory() override; 2448 size_t CommittedPhysicalMemory() override;
2438 2449
(...skipping 21 matching lines...) Expand all
2460 #else 2471 #else
2461 // Do nothing. 2472 // Do nothing.
2462 inline static void AssertValidRange(Address from, Address to) {} 2473 inline static void AssertValidRange(Address from, Address to) {}
2463 #endif 2474 #endif
2464 2475
2465 #ifdef VERIFY_HEAP 2476 #ifdef VERIFY_HEAP
2466 virtual void Verify(); 2477 virtual void Verify();
2467 #endif 2478 #endif
2468 2479
2469 private: 2480 private:
2470 NewSpacePage* anchor() { return &anchor_; } 2481 inline NewSpacePage* anchor() { return &anchor_; }
2471
2472 void set_current_capacity(int new_capacity) {
2473 current_capacity_ = new_capacity;
2474 }
2475 2482
2476 // Copies the flags into the masked positions on all pages in the space. 2483 // Copies the flags into the masked positions on all pages in the space.
2477 void FixPagesFlags(intptr_t flags, intptr_t flag_mask); 2484 void FixPagesFlags(intptr_t flags, intptr_t flag_mask);
2478 2485
2479 // The currently committed space capacity. 2486 // The currently committed space capacity.
2480 int current_capacity_; 2487 int current_capacity_;
2481 2488
2482 // The maximum capacity that can be used by this space. 2489 // The maximum capacity that can be used by this space.
2483 int maximum_capacity_; 2490 int maximum_capacity_;
2484 2491
2485 // The mimnimum capacity for the space. A space cannot shrink below this size. 2492 // The minimum capacity for the space. A space cannot shrink below this size.
2486 int minimum_capacity_; 2493 int minimum_capacity_;
2487 2494
2488 // The start address of the space.
2489 Address start_;
2490 // Used to govern object promotion during mark-compact collection. 2495 // Used to govern object promotion during mark-compact collection.
2491 Address age_mark_; 2496 Address age_mark_;
2492 2497
2493 bool committed_; 2498 bool committed_;
2494 SemiSpaceId id_; 2499 SemiSpaceId id_;
2495 2500
2496 NewSpacePage anchor_; 2501 NewSpacePage anchor_;
2497 NewSpacePage* current_page_; 2502 NewSpacePage* current_page_;
2498 2503
2499 friend class SemiSpaceIterator; 2504 friend class SemiSpaceIterator;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2555 2560
2556 2561
2557 // ----------------------------------------------------------------------------- 2562 // -----------------------------------------------------------------------------
2558 // The young generation space. 2563 // The young generation space.
2559 // 2564 //
2560 // The new space consists of a contiguous pair of semispaces. It simply 2565 // The new space consists of a contiguous pair of semispaces. It simply
2561 // forwards most functions to the appropriate semispace. 2566 // forwards most functions to the appropriate semispace.
2562 2567
2563 class NewSpace : public Space { 2568 class NewSpace : public Space {
2564 public: 2569 public:
2565 // Constructor.
2566 explicit NewSpace(Heap* heap) 2570 explicit NewSpace(Heap* heap)
2567 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), 2571 : Space(heap, NEW_SPACE, NOT_EXECUTABLE),
2568 to_space_(heap, kToSpace), 2572 to_space_(heap, kToSpace),
2569 from_space_(heap, kFromSpace), 2573 from_space_(heap, kFromSpace),
2570 reservation_(), 2574 reservation_(),
2571 top_on_previous_step_(0) {} 2575 pages_used_(0),
2576 top_on_previous_step_(0),
2577 allocated_histogram_(nullptr),
2578 promoted_histogram_(nullptr) {}
2572 2579
2573 inline bool Contains(HeapObject* o); 2580 inline bool Contains(HeapObject* o);
2574 inline bool ContainsSlow(Address a); 2581 inline bool ContainsSlow(Address a);
2575 inline bool Contains(Object* o); 2582 inline bool Contains(Object* o);
2576 2583
2577 // Sets up the new space using the given chunk. 2584 bool SetUp(int initial_semispace_capacity, int max_semispace_capacity);
2578 bool SetUp(int reserved_semispace_size_, int max_semi_space_size);
2579 2585
2580 // Tears down the space. Heap memory was not allocated by the space, so it 2586 // Tears down the space. Heap memory was not allocated by the space, so it
2581 // is not deallocated here. 2587 // is not deallocated here.
2582 void TearDown(); 2588 void TearDown();
2583 2589
2584 // True if the space has been set up but not torn down. 2590 // True if the space has been set up but not torn down.
2585 bool HasBeenSetUp() { 2591 bool HasBeenSetUp() {
2586 return to_space_.HasBeenSetUp() && from_space_.HasBeenSetUp(); 2592 return to_space_.HasBeenSetUp() && from_space_.HasBeenSetUp();
2587 } 2593 }
2588 2594
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2631 return from_space_.MaximumCommittedMemory() + 2637 return from_space_.MaximumCommittedMemory() +
2632 to_space_.MaximumCommittedMemory(); 2638 to_space_.MaximumCommittedMemory();
2633 } 2639 }
2634 2640
2635 // Approximate amount of physical memory committed for this space. 2641 // Approximate amount of physical memory committed for this space.
2636 size_t CommittedPhysicalMemory() override; 2642 size_t CommittedPhysicalMemory() override;
2637 2643
2638 // Return the available bytes without growing. 2644 // Return the available bytes without growing.
2639 intptr_t Available() override { return Capacity() - Size(); } 2645 intptr_t Available() override { return Capacity() - Size(); }
2640 2646
2641 intptr_t PagesFromStart(Address addr) {
2642 return static_cast<intptr_t>(addr - bottom()) / Page::kPageSize;
2643 }
2644
2645 size_t AllocatedSinceLastGC() { 2647 size_t AllocatedSinceLastGC() {
2646 intptr_t allocated = top() - to_space_.age_mark(); 2648 bool seen_age_mark = false;
Hannes Payer (out of office) 2016/04/05 12:38:49 Maybe we should fix this function at some point to
Michael Lippautz 2016/04/05 12:47:59 Ack.
2647 if (allocated < 0) { 2649 Address age_mark = to_space_.age_mark();
2648 // Runtime has lowered the top below the age mark. 2650 NewSpacePage* current_page = to_space_.first_page();
2651 NewSpacePage* age_mark_page = NewSpacePage::FromAddress(age_mark);
2652 NewSpacePage* last_page = NewSpacePage::FromAddress(top() - kPointerSize);
2653 if (age_mark_page == last_page) {
2654 if (top() - age_mark >= 0) {
2655 return top() - age_mark;
2656 }
2657 // Top was reset at some point, invalidating this metric.
2649 return 0; 2658 return 0;
2650 } 2659 }
2651 // Correctly account for non-allocatable regions at the beginning of 2660 while (current_page != last_page) {
2652 // each page from the age_mark() to the top(). 2661 if (current_page == age_mark_page) {
2653 intptr_t pages = 2662 seen_age_mark = true;
2654 PagesFromStart(top()) - PagesFromStart(to_space_.age_mark()); 2663 break;
2655 allocated -= pages * (NewSpacePage::kObjectStartOffset); 2664 }
2656 DCHECK(0 <= allocated && allocated <= Size()); 2665 current_page = current_page->next_page();
2666 }
2667 if (!seen_age_mark) {
2668 // Top was reset at some point, invalidating this metric.
2669 return 0;
2670 }
2671 intptr_t allocated = age_mark_page->area_end() - age_mark;
2672 DCHECK_EQ(current_page, age_mark_page);
2673 current_page = age_mark_page->next_page();
2674 while (current_page != last_page) {
2675 allocated += NewSpacePage::kAllocatableMemory;
2676 current_page = current_page->next_page();
2677 }
2678 allocated += top() - current_page->area_start();
2679 DCHECK_LE(0, allocated);
2680 DCHECK_LE(allocated, Size());
2657 return static_cast<size_t>(allocated); 2681 return static_cast<size_t>(allocated);
2658 } 2682 }
2659 2683
2660 // Return the maximum capacity of a semispace. 2684 // Return the maximum capacity of a semispace.
2661 int MaximumCapacity() { 2685 int MaximumCapacity() {
2662 DCHECK(to_space_.maximum_capacity() == from_space_.maximum_capacity()); 2686 DCHECK(to_space_.maximum_capacity() == from_space_.maximum_capacity());
2663 return to_space_.maximum_capacity(); 2687 return to_space_.maximum_capacity();
2664 } 2688 }
2665 2689
2666 bool IsAtMaximumCapacity() { return TotalCapacity() == MaximumCapacity(); } 2690 bool IsAtMaximumCapacity() { return TotalCapacity() == MaximumCapacity(); }
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
2798 2822
2799 void PauseAllocationObservers() override; 2823 void PauseAllocationObservers() override;
2800 void ResumeAllocationObservers() override; 2824 void ResumeAllocationObservers() override;
2801 2825
2802 private: 2826 private:
2803 // Update allocation info to match the current to-space page. 2827 // Update allocation info to match the current to-space page.
2804 void UpdateAllocationInfo(); 2828 void UpdateAllocationInfo();
2805 2829
2806 base::Mutex mutex_; 2830 base::Mutex mutex_;
2807 2831
2808 Address chunk_base_;
2809 uintptr_t chunk_size_;
2810
2811 // The semispaces. 2832 // The semispaces.
2812 SemiSpace to_space_; 2833 SemiSpace to_space_;
2813 SemiSpace from_space_; 2834 SemiSpace from_space_;
2814 base::VirtualMemory reservation_; 2835 base::VirtualMemory reservation_;
2815 int pages_used_; 2836 int pages_used_;
2816 2837
2817 // Allocation pointer and limit for normal allocation and allocation during 2838 // Allocation pointer and limit for normal allocation and allocation during
2818 // mark-compact collection. 2839 // mark-compact collection.
2819 AllocationInfo allocation_info_; 2840 AllocationInfo allocation_info_;
2820 2841
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
3085 count = 0; 3106 count = 0;
3086 } 3107 }
3087 // Must be small, since an iteration is used for lookup. 3108 // Must be small, since an iteration is used for lookup.
3088 static const int kMaxComments = 64; 3109 static const int kMaxComments = 64;
3089 }; 3110 };
3090 #endif 3111 #endif
3091 } // namespace internal 3112 } // namespace internal
3092 } // namespace v8 3113 } // namespace v8
3093 3114
3094 #endif // V8_HEAP_SPACES_H_ 3115 #endif // V8_HEAP_SPACES_H_
OLDNEW
« no previous file with comments | « src/heap/heap.cc ('k') | src/heap/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698