OLD | NEW |
---|---|
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 1299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1310 | 1310 |
1311 | 1311 |
1312 // ----------------------------------------------------------------------------- | 1312 // ----------------------------------------------------------------------------- |
1313 // A space has a circular list of pages. The next page can be accessed via | 1313 // A space has a circular list of pages. The next page can be accessed via |
1314 // Page::next_page() call. | 1314 // Page::next_page() call. |
1315 | 1315 |
1316 // An abstraction of allocation and relocation pointers in a page-structured | 1316 // An abstraction of allocation and relocation pointers in a page-structured |
1317 // space. | 1317 // space. |
1318 class AllocationInfo { | 1318 class AllocationInfo { |
1319 public: | 1319 public: |
1320 AllocationInfo() : top(NULL), limit(NULL) { | 1320 AllocationInfo() : top_(NULL), limit_(NULL) { |
1321 } | 1321 } |
1322 | 1322 |
1323 Address top; // Current allocation top. | 1323 INLINE(void set_top(Address top)) { |
1324 Address limit; // Current allocation limit. | 1324 ASSERT(top == NULL || |
Michael Starzinger
2013/10/25 08:34:56
nit: As discussed offline, maybe consider making a
Hannes Payer (out of office)
2013/11/20 09:58:47
Done.
| |
1325 (reinterpret_cast<intptr_t>(top) & HeapObjectTagMask()) == 0); | |
1326 top_ = top; | |
1327 } | |
1328 | |
1329 INLINE(Address top()) const { | |
1330 ASSERT(top_ == NULL || | |
1331 (reinterpret_cast<intptr_t>(top_) & HeapObjectTagMask()) == 0); | |
1332 return top_; | |
1333 } | |
1334 | |
1335 Address* top_address() { | |
1336 return &top_; | |
1337 } | |
1338 | |
1339 INLINE(void set_limit(Address limit)) { | |
1340 ASSERT(limit == NULL || | |
1341 (reinterpret_cast<intptr_t>(limit) & HeapObjectTagMask()) == 0); | |
1342 limit_ = limit; | |
1343 } | |
1344 | |
1345 INLINE(Address limit()) const { | |
1346 ASSERT(limit_ == NULL || | |
1347 (reinterpret_cast<intptr_t>(limit_) & HeapObjectTagMask()) == 0); | |
1348 return limit_; | |
1349 } | |
1350 | |
1351 Address* limit_address() { | |
1352 return &limit_; | |
1353 } | |
1325 | 1354 |
1326 #ifdef DEBUG | 1355 #ifdef DEBUG |
1327 bool VerifyPagedAllocation() { | 1356 bool VerifyPagedAllocation() { |
1328 return (Page::FromAllocationTop(top) == Page::FromAllocationTop(limit)) | 1357 return (Page::FromAllocationTop(top_) == Page::FromAllocationTop(limit_)) |
1329 && (top <= limit); | 1358 && (top_ <= limit_); |
1330 } | 1359 } |
1331 #endif | 1360 #endif |
1361 | |
1362 private: | |
1363 // Current allocation top. | |
1364 Address top_; | |
1365 // Current allocation limit. | |
1366 Address limit_; | |
1332 }; | 1367 }; |
1333 | 1368 |
1334 | 1369 |
1335 // An abstraction of the accounting statistics of a page-structured space. | 1370 // An abstraction of the accounting statistics of a page-structured space. |
1336 // The 'capacity' of a space is the number of object-area bytes (i.e., not | 1371 // The 'capacity' of a space is the number of object-area bytes (i.e., not |
1337 // including page bookkeeping structures) currently in the space. The 'size' | 1372 // including page bookkeeping structures) currently in the space. The 'size' |
1338 // of a space is the number of allocated bytes, the 'waste' in the space is | 1373 // of a space is the number of allocated bytes, the 'waste' in the space is |
1339 // the number of bytes that are not allocated and not available to | 1374 // the number of bytes that are not allocated and not available to |
1340 // allocation without reorganizing the space via a GC (e.g. small blocks due | 1375 // allocation without reorganizing the space via a GC (e.g. small blocks due |
1341 // to internal fragmentation, top of page areas in map space), and the bytes | 1376 // to internal fragmentation, top of page areas in map space), and the bytes |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1700 // As size, but the bytes in lazily swept pages are estimated and the bytes | 1735 // As size, but the bytes in lazily swept pages are estimated and the bytes |
1701 // in the current linear allocation area are not included. | 1736 // in the current linear allocation area are not included. |
1702 virtual intptr_t SizeOfObjects(); | 1737 virtual intptr_t SizeOfObjects(); |
1703 | 1738 |
1704 // Wasted bytes in this space. These are just the bytes that were thrown away | 1739 // Wasted bytes in this space. These are just the bytes that were thrown away |
1705 // due to being too small to use for allocation. They do not include the | 1740 // due to being too small to use for allocation. They do not include the |
1706 // free bytes that were not found at all due to lazy sweeping. | 1741 // free bytes that were not found at all due to lazy sweeping. |
1707 virtual intptr_t Waste() { return accounting_stats_.Waste(); } | 1742 virtual intptr_t Waste() { return accounting_stats_.Waste(); } |
1708 | 1743 |
1709 // Returns the allocation pointer in this space. | 1744 // Returns the allocation pointer in this space. |
1710 Address top() { return allocation_info_.top; } | 1745 Address top() { return allocation_info_.top(); } |
1711 Address limit() { return allocation_info_.limit; } | 1746 Address limit() { return allocation_info_.limit(); } |
1712 | 1747 |
1713 // The allocation top and limit addresses. | 1748 // The allocation top address. |
1714 Address* allocation_top_address() { return &allocation_info_.top; } | 1749 Address* allocation_top_address() { |
1715 Address* allocation_limit_address() { return &allocation_info_.limit; } | 1750 return allocation_info_.top_address(); |
1751 } | |
1752 | |
1753 // The allocation limit address. | |
1754 Address* allocation_limit_address() { | |
1755 return allocation_info_.limit_address(); | |
1756 } | |
1716 | 1757 |
1717 enum AllocationType { | 1758 enum AllocationType { |
1718 NEW_OBJECT, | 1759 NEW_OBJECT, |
1719 MOVE_OBJECT | 1760 MOVE_OBJECT |
1720 }; | 1761 }; |
1721 | 1762 |
1722 // Allocate the requested number of bytes in the space if possible, return a | 1763 // Allocate the requested number of bytes in the space if possible, return a |
1723 // failure object if not. | 1764 // failure object if not. |
1724 MUST_USE_RESULT inline MaybeObject* AllocateRaw( | 1765 MUST_USE_RESULT inline MaybeObject* AllocateRaw( |
1725 int size_in_bytes, | 1766 int size_in_bytes, |
(...skipping 12 matching lines...) Expand all Loading... | |
1738 } | 1779 } |
1739 | 1780 |
1740 void ResetFreeList() { | 1781 void ResetFreeList() { |
1741 free_list_.Reset(); | 1782 free_list_.Reset(); |
1742 } | 1783 } |
1743 | 1784 |
1744 // Set space allocation info. | 1785 // Set space allocation info. |
1745 void SetTop(Address top, Address limit) { | 1786 void SetTop(Address top, Address limit) { |
1746 ASSERT(top == limit || | 1787 ASSERT(top == limit || |
1747 Page::FromAddress(top) == Page::FromAddress(limit - 1)); | 1788 Page::FromAddress(top) == Page::FromAddress(limit - 1)); |
1748 MemoryChunk::UpdateHighWaterMark(allocation_info_.top); | 1789 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); |
1749 allocation_info_.top = top; | 1790 allocation_info_.set_top(top); |
1750 allocation_info_.limit = limit; | 1791 allocation_info_.set_limit(limit); |
1751 } | 1792 } |
1752 | 1793 |
1753 void Allocate(int bytes) { | 1794 void Allocate(int bytes) { |
1754 accounting_stats_.AllocateBytes(bytes); | 1795 accounting_stats_.AllocateBytes(bytes); |
1755 } | 1796 } |
1756 | 1797 |
1757 void IncreaseCapacity(int size) { | 1798 void IncreaseCapacity(int size) { |
1758 accounting_stats_.ExpandSpace(size); | 1799 accounting_stats_.ExpandSpace(size); |
1759 } | 1800 } |
1760 | 1801 |
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2381 } | 2422 } |
2382 | 2423 |
2383 // Returns the initial capacity of a semispace. | 2424 // Returns the initial capacity of a semispace. |
2384 int InitialCapacity() { | 2425 int InitialCapacity() { |
2385 ASSERT(to_space_.InitialCapacity() == from_space_.InitialCapacity()); | 2426 ASSERT(to_space_.InitialCapacity() == from_space_.InitialCapacity()); |
2386 return to_space_.InitialCapacity(); | 2427 return to_space_.InitialCapacity(); |
2387 } | 2428 } |
2388 | 2429 |
2389 // Return the address of the allocation pointer in the active semispace. | 2430 // Return the address of the allocation pointer in the active semispace. |
2390 Address top() { | 2431 Address top() { |
2391 ASSERT(to_space_.current_page()->ContainsLimit(allocation_info_.top)); | 2432 ASSERT(to_space_.current_page()->ContainsLimit(allocation_info_.top())); |
2392 return allocation_info_.top; | 2433 return allocation_info_.top(); |
2393 } | 2434 } |
2435 | |
2436 void set_top(Address top) { | |
2437 ASSERT(to_space_.current_page()->ContainsLimit(top)); | |
2438 allocation_info_.set_top(top); | |
2439 } | |
2440 | |
2394 // Return the address of the first object in the active semispace. | 2441 // Return the address of the first object in the active semispace. |
2395 Address bottom() { return to_space_.space_start(); } | 2442 Address bottom() { return to_space_.space_start(); } |
2396 | 2443 |
2397 // Get the age mark of the inactive semispace. | 2444 // Get the age mark of the inactive semispace. |
2398 Address age_mark() { return from_space_.age_mark(); } | 2445 Address age_mark() { return from_space_.age_mark(); } |
2399 // Set the age mark in the active semispace. | 2446 // Set the age mark in the active semispace. |
2400 void set_age_mark(Address mark) { to_space_.set_age_mark(mark); } | 2447 void set_age_mark(Address mark) { to_space_.set_age_mark(mark); } |
2401 | 2448 |
2402 // The start address of the space and a bit mask. Anding an address in the | 2449 // The start address of the space and a bit mask. Anding an address in the |
2403 // new space with the mask will result in the start address. | 2450 // new space with the mask will result in the start address. |
2404 Address start() { return start_; } | 2451 Address start() { return start_; } |
2405 uintptr_t mask() { return address_mask_; } | 2452 uintptr_t mask() { return address_mask_; } |
2406 | 2453 |
2407 INLINE(uint32_t AddressToMarkbitIndex(Address addr)) { | 2454 INLINE(uint32_t AddressToMarkbitIndex(Address addr)) { |
2408 ASSERT(Contains(addr)); | 2455 ASSERT(Contains(addr)); |
2409 ASSERT(IsAligned(OffsetFrom(addr), kPointerSize) || | 2456 ASSERT(IsAligned(OffsetFrom(addr), kPointerSize) || |
2410 IsAligned(OffsetFrom(addr) - 1, kPointerSize)); | 2457 IsAligned(OffsetFrom(addr) - 1, kPointerSize)); |
2411 return static_cast<uint32_t>(addr - start_) >> kPointerSizeLog2; | 2458 return static_cast<uint32_t>(addr - start_) >> kPointerSizeLog2; |
2412 } | 2459 } |
2413 | 2460 |
2414 INLINE(Address MarkbitIndexToAddress(uint32_t index)) { | 2461 INLINE(Address MarkbitIndexToAddress(uint32_t index)) { |
2415 return reinterpret_cast<Address>(index << kPointerSizeLog2); | 2462 return reinterpret_cast<Address>(index << kPointerSizeLog2); |
2416 } | 2463 } |
2417 | 2464 |
2418 // The allocation top and limit addresses. | 2465 // The allocation top and limit address. |
2419 Address* allocation_top_address() { return &allocation_info_.top; } | 2466 Address* allocation_top_address() { |
2420 Address* allocation_limit_address() { return &allocation_info_.limit; } | 2467 return allocation_info_.top_address(); |
2468 } | |
2469 | |
2470 // The allocation limit address. | |
2471 Address* allocation_limit_address() { | |
2472 return allocation_info_.limit_address(); | |
2473 } | |
2421 | 2474 |
2422 MUST_USE_RESULT INLINE(MaybeObject* AllocateRaw(int size_in_bytes)); | 2475 MUST_USE_RESULT INLINE(MaybeObject* AllocateRaw(int size_in_bytes)); |
2423 | 2476 |
2424 // Reset the allocation pointer to the beginning of the active semispace. | 2477 // Reset the allocation pointer to the beginning of the active semispace. |
2425 void ResetAllocationInfo(); | 2478 void ResetAllocationInfo(); |
2426 | 2479 |
2427 void LowerInlineAllocationLimit(intptr_t step) { | 2480 void LowerInlineAllocationLimit(intptr_t step) { |
2428 inline_allocation_limit_step_ = step; | 2481 inline_allocation_limit_step_ = step; |
2429 if (step == 0) { | 2482 if (step == 0) { |
2430 allocation_info_.limit = to_space_.page_high(); | 2483 allocation_info_.set_limit(to_space_.page_high()); |
2431 } else { | 2484 } else { |
2432 allocation_info_.limit = Min( | 2485 Address new_limit = Min( |
2433 allocation_info_.top + inline_allocation_limit_step_, | 2486 allocation_info_.top() + inline_allocation_limit_step_, |
2434 allocation_info_.limit); | 2487 allocation_info_.limit()); |
2488 allocation_info_.set_limit(new_limit); | |
2435 } | 2489 } |
2436 top_on_previous_step_ = allocation_info_.top; | 2490 top_on_previous_step_ = allocation_info_.top(); |
2437 } | 2491 } |
2438 | 2492 |
2439 // Get the extent of the inactive semispace (for use as a marking stack, | 2493 // Get the extent of the inactive semispace (for use as a marking stack, |
2440 // or to zap it). Notice: space-addresses are not necessarily on the | 2494 // or to zap it). Notice: space-addresses are not necessarily on the |
2441 // same page, so FromSpaceStart() might be above FromSpaceEnd(). | 2495 // same page, so FromSpaceStart() might be above FromSpaceEnd(). |
2442 Address FromSpacePageLow() { return from_space_.page_low(); } | 2496 Address FromSpacePageLow() { return from_space_.page_low(); } |
2443 Address FromSpacePageHigh() { return from_space_.page_high(); } | 2497 Address FromSpacePageHigh() { return from_space_.page_high(); } |
2444 Address FromSpaceStart() { return from_space_.space_start(); } | 2498 Address FromSpaceStart() { return from_space_.space_start(); } |
2445 Address FromSpaceEnd() { return from_space_.space_end(); } | 2499 Address FromSpaceEnd() { return from_space_.space_end(); } |
2446 | 2500 |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2573 } | 2627 } |
2574 | 2628 |
2575 public: | 2629 public: |
2576 TRACK_MEMORY("OldSpace") | 2630 TRACK_MEMORY("OldSpace") |
2577 }; | 2631 }; |
2578 | 2632 |
2579 | 2633 |
2580 // For contiguous spaces, top should be in the space (or at the end) and limit | 2634 // For contiguous spaces, top should be in the space (or at the end) and limit |
2581 // should be the end of the space. | 2635 // should be the end of the space. |
2582 #define ASSERT_SEMISPACE_ALLOCATION_INFO(info, space) \ | 2636 #define ASSERT_SEMISPACE_ALLOCATION_INFO(info, space) \ |
2583 SLOW_ASSERT((space).page_low() <= (info).top \ | 2637 SLOW_ASSERT((space).page_low() <= (info).top() \ |
2584 && (info).top <= (space).page_high() \ | 2638 && (info).top() <= (space).page_high() \ |
2585 && (info).limit <= (space).page_high()) | 2639 && (info).limit() <= (space).page_high()) |
2586 | 2640 |
2587 | 2641 |
2588 // ----------------------------------------------------------------------------- | 2642 // ----------------------------------------------------------------------------- |
2589 // Old space for objects of a fixed size | 2643 // Old space for objects of a fixed size |
2590 | 2644 |
2591 class FixedSpace : public PagedSpace { | 2645 class FixedSpace : public PagedSpace { |
2592 public: | 2646 public: |
2593 FixedSpace(Heap* heap, | 2647 FixedSpace(Heap* heap, |
2594 intptr_t max_capacity, | 2648 intptr_t max_capacity, |
2595 AllocationSpace id, | 2649 AllocationSpace id, |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2903 } | 2957 } |
2904 // Must be small, since an iteration is used for lookup. | 2958 // Must be small, since an iteration is used for lookup. |
2905 static const int kMaxComments = 64; | 2959 static const int kMaxComments = 64; |
2906 }; | 2960 }; |
2907 #endif | 2961 #endif |
2908 | 2962 |
2909 | 2963 |
2910 } } // namespace v8::internal | 2964 } } // namespace v8::internal |
2911 | 2965 |
2912 #endif // V8_SPACES_H_ | 2966 #endif // V8_SPACES_H_ |
OLD | NEW |