Chromium Code Reviews| 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 |