| 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 SLOW_ASSERT(top == NULL || |
| 1325 (reinterpret_cast<intptr_t>(top) & HeapObjectTagMask()) == 0); |
| 1326 top_ = top; |
| 1327 } |
| 1328 |
| 1329 INLINE(Address top()) const { |
| 1330 SLOW_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 SLOW_ASSERT(limit == NULL || |
| 1341 (reinterpret_cast<intptr_t>(limit) & HeapObjectTagMask()) == 0); |
| 1342 limit_ = limit; |
| 1343 } |
| 1344 |
| 1345 INLINE(Address limit()) const { |
| 1346 SLOW_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 } |
| 1757 |
| 1758 enum AllocationType { |
| 1759 NEW_OBJECT, |
| 1760 MOVE_OBJECT |
| 1761 }; |
| 1716 | 1762 |
| 1717 // 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 |
| 1718 // failure object if not. | 1764 // failure object if not. |
| 1719 MUST_USE_RESULT inline MaybeObject* AllocateRaw(int size_in_bytes); | 1765 MUST_USE_RESULT inline MaybeObject* AllocateRaw( |
| 1766 int size_in_bytes, |
| 1767 AllocationType event = NEW_OBJECT); |
| 1720 | 1768 |
| 1721 virtual bool ReserveSpace(int bytes); | 1769 virtual bool ReserveSpace(int bytes); |
| 1722 | 1770 |
| 1723 // Give a block of memory to the space's free list. It might be added to | 1771 // Give a block of memory to the space's free list. It might be added to |
| 1724 // the free list or accounted as waste. | 1772 // the free list or accounted as waste. |
| 1725 // If add_to_freelist is false then just accounting stats are updated and | 1773 // If add_to_freelist is false then just accounting stats are updated and |
| 1726 // no attempt to add area to free list is made. | 1774 // no attempt to add area to free list is made. |
| 1727 int Free(Address start, int size_in_bytes) { | 1775 int Free(Address start, int size_in_bytes) { |
| 1728 int wasted = free_list_.Free(start, size_in_bytes); | 1776 int wasted = free_list_.Free(start, size_in_bytes); |
| 1729 accounting_stats_.DeallocateBytes(size_in_bytes - wasted); | 1777 accounting_stats_.DeallocateBytes(size_in_bytes - wasted); |
| 1730 return size_in_bytes - wasted; | 1778 return size_in_bytes - wasted; |
| 1731 } | 1779 } |
| 1732 | 1780 |
| 1733 void ResetFreeList() { | 1781 void ResetFreeList() { |
| 1734 free_list_.Reset(); | 1782 free_list_.Reset(); |
| 1735 } | 1783 } |
| 1736 | 1784 |
| 1737 // Set space allocation info. | 1785 // Set space allocation info. |
| 1738 void SetTop(Address top, Address limit) { | 1786 void SetTop(Address top, Address limit) { |
| 1739 ASSERT(top == limit || | 1787 ASSERT(top == limit || |
| 1740 Page::FromAddress(top) == Page::FromAddress(limit - 1)); | 1788 Page::FromAddress(top) == Page::FromAddress(limit - 1)); |
| 1741 MemoryChunk::UpdateHighWaterMark(allocation_info_.top); | 1789 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); |
| 1742 allocation_info_.top = top; | 1790 allocation_info_.set_top(top); |
| 1743 allocation_info_.limit = limit; | 1791 allocation_info_.set_limit(limit); |
| 1744 } | 1792 } |
| 1745 | 1793 |
| 1746 void Allocate(int bytes) { | 1794 void Allocate(int bytes) { |
| 1747 accounting_stats_.AllocateBytes(bytes); | 1795 accounting_stats_.AllocateBytes(bytes); |
| 1748 } | 1796 } |
| 1749 | 1797 |
| 1750 void IncreaseCapacity(int size) { | 1798 void IncreaseCapacity(int size) { |
| 1751 accounting_stats_.ExpandSpace(size); | 1799 accounting_stats_.ExpandSpace(size); |
| 1752 } | 1800 } |
| 1753 | 1801 |
| (...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2374 } | 2422 } |
| 2375 | 2423 |
| 2376 // Returns the initial capacity of a semispace. | 2424 // Returns the initial capacity of a semispace. |
| 2377 int InitialCapacity() { | 2425 int InitialCapacity() { |
| 2378 ASSERT(to_space_.InitialCapacity() == from_space_.InitialCapacity()); | 2426 ASSERT(to_space_.InitialCapacity() == from_space_.InitialCapacity()); |
| 2379 return to_space_.InitialCapacity(); | 2427 return to_space_.InitialCapacity(); |
| 2380 } | 2428 } |
| 2381 | 2429 |
| 2382 // Return the address of the allocation pointer in the active semispace. | 2430 // Return the address of the allocation pointer in the active semispace. |
| 2383 Address top() { | 2431 Address top() { |
| 2384 ASSERT(to_space_.current_page()->ContainsLimit(allocation_info_.top)); | 2432 ASSERT(to_space_.current_page()->ContainsLimit(allocation_info_.top())); |
| 2385 return allocation_info_.top; | 2433 return allocation_info_.top(); |
| 2386 } | 2434 } |
| 2435 |
| 2436 void set_top(Address top) { |
| 2437 ASSERT(to_space_.current_page()->ContainsLimit(top)); |
| 2438 allocation_info_.set_top(top); |
| 2439 } |
| 2440 |
| 2387 // Return the address of the first object in the active semispace. | 2441 // Return the address of the first object in the active semispace. |
| 2388 Address bottom() { return to_space_.space_start(); } | 2442 Address bottom() { return to_space_.space_start(); } |
| 2389 | 2443 |
| 2390 // Get the age mark of the inactive semispace. | 2444 // Get the age mark of the inactive semispace. |
| 2391 Address age_mark() { return from_space_.age_mark(); } | 2445 Address age_mark() { return from_space_.age_mark(); } |
| 2392 // Set the age mark in the active semispace. | 2446 // Set the age mark in the active semispace. |
| 2393 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); } |
| 2394 | 2448 |
| 2395 // 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 |
| 2396 // new space with the mask will result in the start address. | 2450 // new space with the mask will result in the start address. |
| 2397 Address start() { return start_; } | 2451 Address start() { return start_; } |
| 2398 uintptr_t mask() { return address_mask_; } | 2452 uintptr_t mask() { return address_mask_; } |
| 2399 | 2453 |
| 2400 INLINE(uint32_t AddressToMarkbitIndex(Address addr)) { | 2454 INLINE(uint32_t AddressToMarkbitIndex(Address addr)) { |
| 2401 ASSERT(Contains(addr)); | 2455 ASSERT(Contains(addr)); |
| 2402 ASSERT(IsAligned(OffsetFrom(addr), kPointerSize) || | 2456 ASSERT(IsAligned(OffsetFrom(addr), kPointerSize) || |
| 2403 IsAligned(OffsetFrom(addr) - 1, kPointerSize)); | 2457 IsAligned(OffsetFrom(addr) - 1, kPointerSize)); |
| 2404 return static_cast<uint32_t>(addr - start_) >> kPointerSizeLog2; | 2458 return static_cast<uint32_t>(addr - start_) >> kPointerSizeLog2; |
| 2405 } | 2459 } |
| 2406 | 2460 |
| 2407 INLINE(Address MarkbitIndexToAddress(uint32_t index)) { | 2461 INLINE(Address MarkbitIndexToAddress(uint32_t index)) { |
| 2408 return reinterpret_cast<Address>(index << kPointerSizeLog2); | 2462 return reinterpret_cast<Address>(index << kPointerSizeLog2); |
| 2409 } | 2463 } |
| 2410 | 2464 |
| 2411 // The allocation top and limit addresses. | 2465 // The allocation top and limit address. |
| 2412 Address* allocation_top_address() { return &allocation_info_.top; } | 2466 Address* allocation_top_address() { |
| 2413 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 } |
| 2414 | 2474 |
| 2415 MUST_USE_RESULT INLINE(MaybeObject* AllocateRaw(int size_in_bytes)); | 2475 MUST_USE_RESULT INLINE(MaybeObject* AllocateRaw(int size_in_bytes)); |
| 2416 | 2476 |
| 2417 // Reset the allocation pointer to the beginning of the active semispace. | 2477 // Reset the allocation pointer to the beginning of the active semispace. |
| 2418 void ResetAllocationInfo(); | 2478 void ResetAllocationInfo(); |
| 2419 | 2479 |
| 2420 void LowerInlineAllocationLimit(intptr_t step) { | 2480 void LowerInlineAllocationLimit(intptr_t step) { |
| 2421 inline_allocation_limit_step_ = step; | 2481 inline_allocation_limit_step_ = step; |
| 2422 if (step == 0) { | 2482 if (step == 0) { |
| 2423 allocation_info_.limit = to_space_.page_high(); | 2483 allocation_info_.set_limit(to_space_.page_high()); |
| 2424 } else { | 2484 } else { |
| 2425 allocation_info_.limit = Min( | 2485 Address new_limit = Min( |
| 2426 allocation_info_.top + inline_allocation_limit_step_, | 2486 allocation_info_.top() + inline_allocation_limit_step_, |
| 2427 allocation_info_.limit); | 2487 allocation_info_.limit()); |
| 2488 allocation_info_.set_limit(new_limit); |
| 2428 } | 2489 } |
| 2429 top_on_previous_step_ = allocation_info_.top; | 2490 top_on_previous_step_ = allocation_info_.top(); |
| 2430 } | 2491 } |
| 2431 | 2492 |
| 2432 // 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, |
| 2433 // 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 |
| 2434 // same page, so FromSpaceStart() might be above FromSpaceEnd(). | 2495 // same page, so FromSpaceStart() might be above FromSpaceEnd(). |
| 2435 Address FromSpacePageLow() { return from_space_.page_low(); } | 2496 Address FromSpacePageLow() { return from_space_.page_low(); } |
| 2436 Address FromSpacePageHigh() { return from_space_.page_high(); } | 2497 Address FromSpacePageHigh() { return from_space_.page_high(); } |
| 2437 Address FromSpaceStart() { return from_space_.space_start(); } | 2498 Address FromSpaceStart() { return from_space_.space_start(); } |
| 2438 Address FromSpaceEnd() { return from_space_.space_end(); } | 2499 Address FromSpaceEnd() { return from_space_.space_end(); } |
| 2439 | 2500 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2566 } | 2627 } |
| 2567 | 2628 |
| 2568 public: | 2629 public: |
| 2569 TRACK_MEMORY("OldSpace") | 2630 TRACK_MEMORY("OldSpace") |
| 2570 }; | 2631 }; |
| 2571 | 2632 |
| 2572 | 2633 |
| 2573 // 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 |
| 2574 // should be the end of the space. | 2635 // should be the end of the space. |
| 2575 #define ASSERT_SEMISPACE_ALLOCATION_INFO(info, space) \ | 2636 #define ASSERT_SEMISPACE_ALLOCATION_INFO(info, space) \ |
| 2576 SLOW_ASSERT((space).page_low() <= (info).top \ | 2637 SLOW_ASSERT((space).page_low() <= (info).top() \ |
| 2577 && (info).top <= (space).page_high() \ | 2638 && (info).top() <= (space).page_high() \ |
| 2578 && (info).limit <= (space).page_high()) | 2639 && (info).limit() <= (space).page_high()) |
| 2579 | 2640 |
| 2580 | 2641 |
| 2581 // ----------------------------------------------------------------------------- | 2642 // ----------------------------------------------------------------------------- |
| 2582 // Old space for objects of a fixed size | 2643 // Old space for objects of a fixed size |
| 2583 | 2644 |
| 2584 class FixedSpace : public PagedSpace { | 2645 class FixedSpace : public PagedSpace { |
| 2585 public: | 2646 public: |
| 2586 FixedSpace(Heap* heap, | 2647 FixedSpace(Heap* heap, |
| 2587 intptr_t max_capacity, | 2648 intptr_t max_capacity, |
| 2588 AllocationSpace id, | 2649 AllocationSpace id, |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2896 } | 2957 } |
| 2897 // Must be small, since an iteration is used for lookup. | 2958 // Must be small, since an iteration is used for lookup. |
| 2898 static const int kMaxComments = 64; | 2959 static const int kMaxComments = 64; |
| 2899 }; | 2960 }; |
| 2900 #endif | 2961 #endif |
| 2901 | 2962 |
| 2902 | 2963 |
| 2903 } } // namespace v8::internal | 2964 } } // namespace v8::internal |
| 2904 | 2965 |
| 2905 #endif // V8_SPACES_H_ | 2966 #endif // V8_SPACES_H_ |
| OLD | NEW |