OLD | NEW |
---|---|
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
364 : id_(id), executable_(executable) {} | 364 : id_(id), executable_(executable) {} |
365 | 365 |
366 virtual ~Space() {} | 366 virtual ~Space() {} |
367 | 367 |
368 // Does the space need executable memory? | 368 // Does the space need executable memory? |
369 Executability executable() { return executable_; } | 369 Executability executable() { return executable_; } |
370 | 370 |
371 // Identity used in error reporting. | 371 // Identity used in error reporting. |
372 AllocationSpace identity() { return id_; } | 372 AllocationSpace identity() { return id_; } |
373 | 373 |
374 virtual int Size() = 0; | 374 virtual intptr_t Size() = 0; |
375 | 375 |
376 #ifdef ENABLE_HEAP_PROTECTION | 376 #ifdef ENABLE_HEAP_PROTECTION |
377 // Protect/unprotect the space by marking it read-only/writable. | 377 // Protect/unprotect the space by marking it read-only/writable. |
378 virtual void Protect() = 0; | 378 virtual void Protect() = 0; |
379 virtual void Unprotect() = 0; | 379 virtual void Unprotect() = 0; |
380 #endif | 380 #endif |
381 | 381 |
382 #ifdef DEBUG | 382 #ifdef DEBUG |
383 virtual void Print() = 0; | 383 virtual void Print() = 0; |
384 #endif | 384 #endif |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
484 // induces a constraint on the order of pages in a linked lists. We say that | 484 // induces a constraint on the order of pages in a linked lists. We say that |
485 // pages are linked in the chunk-order if and only if every two consecutive | 485 // pages are linked in the chunk-order if and only if every two consecutive |
486 // pages from the same chunk are consecutive in the linked list. | 486 // pages from the same chunk are consecutive in the linked list. |
487 // | 487 // |
488 | 488 |
489 | 489 |
490 class MemoryAllocator : public AllStatic { | 490 class MemoryAllocator : public AllStatic { |
491 public: | 491 public: |
492 // Initializes its internal bookkeeping structures. | 492 // Initializes its internal bookkeeping structures. |
493 // Max capacity of the total space. | 493 // Max capacity of the total space. |
494 static bool Setup(int max_capacity); | 494 static bool Setup(intptr_t max_capacity); |
495 | 495 |
496 // Deletes valid chunks. | 496 // Deletes valid chunks. |
497 static void TearDown(); | 497 static void TearDown(); |
498 | 498 |
499 // Reserves an initial address range of virtual memory to be split between | 499 // Reserves an initial address range of virtual memory to be split between |
500 // the two new space semispaces, the old space, and the map space. The | 500 // the two new space semispaces, the old space, and the map space. The |
501 // memory is not yet committed or assigned to spaces and split into pages. | 501 // memory is not yet committed or assigned to spaces and split into pages. |
502 // The initial chunk is unmapped when the memory allocator is torn down. | 502 // The initial chunk is unmapped when the memory allocator is torn down. |
503 // This function should only be called when there is not already a reserved | 503 // This function should only be called when there is not already a reserved |
504 // initial chunk (initial_chunk_ should be NULL). It returns the start | 504 // initial chunk (initial_chunk_ should be NULL). It returns the start |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
575 | 575 |
576 static void AddMemoryAllocationCallback(MemoryAllocationCallback callback, | 576 static void AddMemoryAllocationCallback(MemoryAllocationCallback callback, |
577 ObjectSpace space, | 577 ObjectSpace space, |
578 AllocationAction action); | 578 AllocationAction action); |
579 static void RemoveMemoryAllocationCallback( | 579 static void RemoveMemoryAllocationCallback( |
580 MemoryAllocationCallback callback); | 580 MemoryAllocationCallback callback); |
581 static bool MemoryAllocationCallbackRegistered( | 581 static bool MemoryAllocationCallbackRegistered( |
582 MemoryAllocationCallback callback); | 582 MemoryAllocationCallback callback); |
583 | 583 |
584 // Returns the maximum available bytes of heaps. | 584 // Returns the maximum available bytes of heaps. |
585 static int Available() { return capacity_ < size_ ? 0 : capacity_ - size_; } | 585 static intptr_t Available() { |
586 return capacity_ < size_ ? 0 : capacity_ - size_; | |
587 } | |
586 | 588 |
587 // Returns allocated spaces in bytes. | 589 // Returns allocated spaces in bytes. |
588 static int Size() { return size_; } | 590 static intptr_t Size() { return size_; } |
589 | 591 |
590 // Returns allocated executable spaces in bytes. | 592 // Returns allocated executable spaces in bytes. |
591 static int SizeExecutable() { return size_executable_; } | 593 static intptr_t SizeExecutable() { return size_executable_; } |
592 | 594 |
593 // Returns maximum available bytes that the old space can have. | 595 // Returns maximum available bytes that the old space can have. |
594 static int MaxAvailable() { | 596 static intptr_t MaxAvailable() { |
595 return (Available() / Page::kPageSize) * Page::kObjectAreaSize; | 597 return (Available() / Page::kPageSize) * Page::kObjectAreaSize; |
596 } | 598 } |
597 | 599 |
598 // Links two pages. | 600 // Links two pages. |
599 static inline void SetNextPage(Page* prev, Page* next); | 601 static inline void SetNextPage(Page* prev, Page* next); |
600 | 602 |
601 // Returns the next page of a given page. | 603 // Returns the next page of a given page. |
602 static inline Page* GetNextPage(Page* p); | 604 static inline Page* GetNextPage(Page* p); |
603 | 605 |
604 // Checks whether a page belongs to a space. | 606 // Checks whether a page belongs to a space. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
642 // 8K * 8K * 16 = 1G bytes. | 644 // 8K * 8K * 16 = 1G bytes. |
643 #ifdef V8_TARGET_ARCH_X64 | 645 #ifdef V8_TARGET_ARCH_X64 |
644 static const int kPagesPerChunk = 32; | 646 static const int kPagesPerChunk = 32; |
645 #else | 647 #else |
646 static const int kPagesPerChunk = 16; | 648 static const int kPagesPerChunk = 16; |
647 #endif | 649 #endif |
648 static const int kChunkSize = kPagesPerChunk * Page::kPageSize; | 650 static const int kChunkSize = kPagesPerChunk * Page::kPageSize; |
649 | 651 |
650 private: | 652 private: |
651 // Maximum space size in bytes. | 653 // Maximum space size in bytes. |
652 static int capacity_; | 654 static intptr_t capacity_; |
653 | 655 |
654 // Allocated space size in bytes. | 656 // Allocated space size in bytes. |
655 static int size_; | 657 static intptr_t size_; |
656 // Allocated executable space size in bytes. | 658 // Allocated executable space size in bytes. |
657 static int size_executable_; | 659 static intptr_t size_executable_; |
658 | 660 |
659 struct MemoryAllocationCallbackRegistration { | 661 struct MemoryAllocationCallbackRegistration { |
660 MemoryAllocationCallbackRegistration(MemoryAllocationCallback callback, | 662 MemoryAllocationCallbackRegistration(MemoryAllocationCallback callback, |
661 ObjectSpace space, | 663 ObjectSpace space, |
662 AllocationAction action) | 664 AllocationAction action) |
663 : callback(callback), space(space), action(action) { | 665 : callback(callback), space(space), action(action) { |
664 } | 666 } |
665 MemoryAllocationCallback callback; | 667 MemoryAllocationCallback callback; |
666 ObjectSpace space; | 668 ObjectSpace space; |
667 AllocationAction action; | 669 AllocationAction action; |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
920 | 922 |
921 // Reset the allocation statistics (ie, available = capacity with no | 923 // Reset the allocation statistics (ie, available = capacity with no |
922 // wasted or allocated bytes). | 924 // wasted or allocated bytes). |
923 void Reset() { | 925 void Reset() { |
924 available_ = capacity_; | 926 available_ = capacity_; |
925 size_ = 0; | 927 size_ = 0; |
926 waste_ = 0; | 928 waste_ = 0; |
927 } | 929 } |
928 | 930 |
929 // Accessors for the allocation statistics. | 931 // Accessors for the allocation statistics. |
930 int Capacity() { return capacity_; } | 932 intptr_t Capacity() { return capacity_; } |
931 int Available() { return available_; } | 933 intptr_t Available() { return available_; } |
932 int Size() { return size_; } | 934 intptr_t Size() { return size_; } |
933 int Waste() { return waste_; } | 935 intptr_t Waste() { return waste_; } |
934 | 936 |
935 // Grow the space by adding available bytes. | 937 // Grow the space by adding available bytes. |
936 void ExpandSpace(int size_in_bytes) { | 938 void ExpandSpace(int size_in_bytes) { |
937 capacity_ += size_in_bytes; | 939 capacity_ += size_in_bytes; |
938 available_ += size_in_bytes; | 940 available_ += size_in_bytes; |
939 } | 941 } |
940 | 942 |
941 // Shrink the space by removing available bytes. | 943 // Shrink the space by removing available bytes. |
942 void ShrinkSpace(int size_in_bytes) { | 944 void ShrinkSpace(int size_in_bytes) { |
943 capacity_ -= size_in_bytes; | 945 capacity_ -= size_in_bytes; |
944 available_ -= size_in_bytes; | 946 available_ -= size_in_bytes; |
945 } | 947 } |
946 | 948 |
947 // Allocate from available bytes (available -> size). | 949 // Allocate from available bytes (available -> size). |
948 void AllocateBytes(int size_in_bytes) { | 950 void AllocateBytes(intptr_t size_in_bytes) { |
949 available_ -= size_in_bytes; | 951 available_ -= size_in_bytes; |
950 size_ += size_in_bytes; | 952 size_ += size_in_bytes; |
951 } | 953 } |
952 | 954 |
953 // Free allocated bytes, making them available (size -> available). | 955 // Free allocated bytes, making them available (size -> available). |
954 void DeallocateBytes(int size_in_bytes) { | 956 void DeallocateBytes(intptr_t size_in_bytes) { |
955 size_ -= size_in_bytes; | 957 size_ -= size_in_bytes; |
956 available_ += size_in_bytes; | 958 available_ += size_in_bytes; |
957 } | 959 } |
958 | 960 |
959 // Waste free bytes (available -> waste). | 961 // Waste free bytes (available -> waste). |
960 void WasteBytes(int size_in_bytes) { | 962 void WasteBytes(int size_in_bytes) { |
961 available_ -= size_in_bytes; | 963 available_ -= size_in_bytes; |
962 waste_ += size_in_bytes; | 964 waste_ += size_in_bytes; |
963 } | 965 } |
964 | 966 |
965 // Consider the wasted bytes to be allocated, as they contain filler | 967 // Consider the wasted bytes to be allocated, as they contain filler |
966 // objects (waste -> size). | 968 // objects (waste -> size). |
967 void FillWastedBytes(int size_in_bytes) { | 969 void FillWastedBytes(intptr_t size_in_bytes) { |
968 waste_ -= size_in_bytes; | 970 waste_ -= size_in_bytes; |
969 size_ += size_in_bytes; | 971 size_ += size_in_bytes; |
970 } | 972 } |
971 | 973 |
972 private: | 974 private: |
973 int capacity_; | 975 intptr_t capacity_; |
974 int available_; | 976 intptr_t available_; |
975 int size_; | 977 intptr_t size_; |
976 int waste_; | 978 intptr_t waste_; |
977 }; | 979 }; |
978 | 980 |
979 | 981 |
980 class PagedSpace : public Space { | 982 class PagedSpace : public Space { |
981 public: | 983 public: |
982 // Creates a space with a maximum capacity, and an id. | 984 // Creates a space with a maximum capacity, and an id. |
983 PagedSpace(int max_capacity, AllocationSpace id, Executability executable); | 985 PagedSpace(intptr_t max_capacity, |
986 AllocationSpace id, | |
987 Executability executable); | |
984 | 988 |
985 virtual ~PagedSpace() {} | 989 virtual ~PagedSpace() {} |
986 | 990 |
987 // Set up the space using the given address range of virtual memory (from | 991 // Set up the space using the given address range of virtual memory (from |
988 // the memory allocator's initial chunk) if possible. If the block of | 992 // the memory allocator's initial chunk) if possible. If the block of |
989 // addresses is not big enough to contain a single page-aligned page, a | 993 // addresses is not big enough to contain a single page-aligned page, a |
990 // fresh chunk will be allocated. | 994 // fresh chunk will be allocated. |
991 bool Setup(Address start, size_t size); | 995 bool Setup(Address start, size_t size); |
992 | 996 |
993 // Returns true if the space has been successfully set up and not | 997 // Returns true if the space has been successfully set up and not |
(...skipping 30 matching lines...) Expand all Loading... | |
1024 | 1028 |
1025 // The limit of allocation for a page in this space. | 1029 // The limit of allocation for a page in this space. |
1026 virtual Address PageAllocationLimit(Page* page) = 0; | 1030 virtual Address PageAllocationLimit(Page* page) = 0; |
1027 | 1031 |
1028 void FlushTopPageWatermark() { | 1032 void FlushTopPageWatermark() { |
1029 AllocationTopPage()->SetCachedAllocationWatermark(top()); | 1033 AllocationTopPage()->SetCachedAllocationWatermark(top()); |
1030 AllocationTopPage()->InvalidateWatermark(true); | 1034 AllocationTopPage()->InvalidateWatermark(true); |
1031 } | 1035 } |
1032 | 1036 |
1033 // Current capacity without growing (Size() + Available() + Waste()). | 1037 // Current capacity without growing (Size() + Available() + Waste()). |
1034 int Capacity() { return accounting_stats_.Capacity(); } | 1038 intptr_t Capacity() { return accounting_stats_.Capacity(); } |
1035 | 1039 |
1036 // Total amount of memory committed for this space. For paged | 1040 // Total amount of memory committed for this space. For paged |
1037 // spaces this equals the capacity. | 1041 // spaces this equals the capacity. |
1038 int CommittedMemory() { return Capacity(); } | 1042 intptr_t CommittedMemory() { return Capacity(); } |
1039 | 1043 |
1040 // Available bytes without growing. | 1044 // Available bytes without growing. |
1041 int Available() { return accounting_stats_.Available(); } | 1045 intptr_t Available() { return accounting_stats_.Available(); } |
1042 | 1046 |
1043 // Allocated bytes in this space. | 1047 // Allocated bytes in this space. |
1044 virtual int Size() { return accounting_stats_.Size(); } | 1048 virtual intptr_t Size() { return accounting_stats_.Size(); } |
1045 | 1049 |
1046 // Wasted bytes due to fragmentation and not recoverable until the | 1050 // Wasted bytes due to fragmentation and not recoverable until the |
1047 // next GC of this space. | 1051 // next GC of this space. |
1048 int Waste() { return accounting_stats_.Waste(); } | 1052 intptr_t Waste() { return accounting_stats_.Waste(); } |
1049 | 1053 |
1050 // Returns the address of the first object in this space. | 1054 // Returns the address of the first object in this space. |
1051 Address bottom() { return first_page_->ObjectAreaStart(); } | 1055 Address bottom() { return first_page_->ObjectAreaStart(); } |
1052 | 1056 |
1053 // Returns the allocation pointer in this space. | 1057 // Returns the allocation pointer in this space. |
1054 Address top() { return allocation_info_.top; } | 1058 Address top() { return allocation_info_.top; } |
1055 | 1059 |
1056 // Allocate the requested number of bytes in the space if possible, return a | 1060 // Allocate the requested number of bytes in the space if possible, return a |
1057 // failure object if not. | 1061 // failure object if not. |
1058 inline Object* AllocateRaw(int size_in_bytes); | 1062 inline Object* AllocateRaw(int size_in_bytes); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1130 static void ResetCodeStatistics(); | 1134 static void ResetCodeStatistics(); |
1131 #endif | 1135 #endif |
1132 | 1136 |
1133 // Returns the page of the allocation pointer. | 1137 // Returns the page of the allocation pointer. |
1134 Page* AllocationTopPage() { return TopPageOf(allocation_info_); } | 1138 Page* AllocationTopPage() { return TopPageOf(allocation_info_); } |
1135 | 1139 |
1136 void RelinkPageListInChunkOrder(bool deallocate_blocks); | 1140 void RelinkPageListInChunkOrder(bool deallocate_blocks); |
1137 | 1141 |
1138 protected: | 1142 protected: |
1139 // Maximum capacity of this space. | 1143 // Maximum capacity of this space. |
1140 int max_capacity_; | 1144 intptr_t max_capacity_; |
1141 | 1145 |
1142 // Accounting information for this space. | 1146 // Accounting information for this space. |
1143 AllocationStats accounting_stats_; | 1147 AllocationStats accounting_stats_; |
1144 | 1148 |
1145 // The first page in this space. | 1149 // The first page in this space. |
1146 Page* first_page_; | 1150 Page* first_page_; |
1147 | 1151 |
1148 // The last page in this space. Initially set in Setup, updated in | 1152 // The last page in this space. Initially set in Setup, updated in |
1149 // Expand and Shrink. | 1153 // Expand and Shrink. |
1150 Page* last_page_; | 1154 Page* last_page_; |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1321 return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_; | 1325 return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_; |
1322 } | 1326 } |
1323 | 1327 |
1324 // The offset of an address from the beginning of the space. | 1328 // The offset of an address from the beginning of the space. |
1325 int SpaceOffsetForAddress(Address addr) { | 1329 int SpaceOffsetForAddress(Address addr) { |
1326 return static_cast<int>(addr - low()); | 1330 return static_cast<int>(addr - low()); |
1327 } | 1331 } |
1328 | 1332 |
1329 // If we don't have these here then SemiSpace will be abstract. However | 1333 // If we don't have these here then SemiSpace will be abstract. However |
1330 // they should never be called. | 1334 // they should never be called. |
1331 virtual int Size() { | 1335 virtual intptr_t Size() { |
1332 UNREACHABLE(); | 1336 UNREACHABLE(); |
1333 return 0; | 1337 return 0; |
1334 } | 1338 } |
1335 | 1339 |
1336 virtual bool ReserveSpace(int bytes) { | 1340 virtual bool ReserveSpace(int bytes) { |
1337 UNREACHABLE(); | 1341 UNREACHABLE(); |
1338 return false; | 1342 return false; |
1339 } | 1343 } |
1340 | 1344 |
1341 bool is_committed() { return committed_; } | 1345 bool is_committed() { return committed_; } |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1464 // semispace (not necessarily below the allocation pointer). | 1468 // semispace (not necessarily below the allocation pointer). |
1465 bool Contains(Address a) { | 1469 bool Contains(Address a) { |
1466 return (reinterpret_cast<uintptr_t>(a) & address_mask_) | 1470 return (reinterpret_cast<uintptr_t>(a) & address_mask_) |
1467 == reinterpret_cast<uintptr_t>(start_); | 1471 == reinterpret_cast<uintptr_t>(start_); |
1468 } | 1472 } |
1469 bool Contains(Object* o) { | 1473 bool Contains(Object* o) { |
1470 return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_; | 1474 return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_; |
1471 } | 1475 } |
1472 | 1476 |
1473 // Return the allocated bytes in the active semispace. | 1477 // Return the allocated bytes in the active semispace. |
1474 virtual int Size() { return static_cast<int>(top() - bottom()); } | 1478 virtual intptr_t Size() { return static_cast<int>(top() - bottom()); } |
1479 // The same, but returning an int. We have to have the one that returns | |
1480 // intptr_t because it is inherited, but if we know we are dealing with the | |
1481 // new space, which can't get as big as the other spaces then this is useful: | |
1482 int IntSize() { return static_cast<int>(Size()); } | |
Vyacheslav Egorov (Chromium)
2010/09/29 14:55:20
SizeAsInt ?
Erik Corry
2010/09/30 07:09:38
Done.
| |
1475 | 1483 |
1476 // Return the current capacity of a semispace. | 1484 // Return the current capacity of a semispace. |
1477 int Capacity() { | 1485 intptr_t Capacity() { |
1478 ASSERT(to_space_.Capacity() == from_space_.Capacity()); | 1486 ASSERT(to_space_.Capacity() == from_space_.Capacity()); |
1479 return to_space_.Capacity(); | 1487 return to_space_.Capacity(); |
1480 } | 1488 } |
1481 | 1489 |
1482 // Return the total amount of memory committed for new space. | 1490 // Return the total amount of memory committed for new space. |
1483 int CommittedMemory() { | 1491 intptr_t CommittedMemory() { |
1484 if (from_space_.is_committed()) return 2 * Capacity(); | 1492 if (from_space_.is_committed()) return 2 * Capacity(); |
1485 return Capacity(); | 1493 return Capacity(); |
1486 } | 1494 } |
1487 | 1495 |
1488 // Return the available bytes without growing in the active semispace. | 1496 // Return the available bytes without growing in the active semispace. |
1489 int Available() { return Capacity() - Size(); } | 1497 intptr_t Available() { return Capacity() - Size(); } |
1490 | 1498 |
1491 // Return the maximum capacity of a semispace. | 1499 // Return the maximum capacity of a semispace. |
1492 int MaximumCapacity() { | 1500 int MaximumCapacity() { |
1493 ASSERT(to_space_.MaximumCapacity() == from_space_.MaximumCapacity()); | 1501 ASSERT(to_space_.MaximumCapacity() == from_space_.MaximumCapacity()); |
1494 return to_space_.MaximumCapacity(); | 1502 return to_space_.MaximumCapacity(); |
1495 } | 1503 } |
1496 | 1504 |
1497 // Returns the initial capacity of a semispace. | 1505 // Returns the initial capacity of a semispace. |
1498 int InitialCapacity() { | 1506 int InitialCapacity() { |
1499 ASSERT(to_space_.InitialCapacity() == from_space_.InitialCapacity()); | 1507 ASSERT(to_space_.InitialCapacity() == from_space_.InitialCapacity()); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1674 | 1682 |
1675 // The free list for the old space. | 1683 // The free list for the old space. |
1676 class OldSpaceFreeList BASE_EMBEDDED { | 1684 class OldSpaceFreeList BASE_EMBEDDED { |
1677 public: | 1685 public: |
1678 explicit OldSpaceFreeList(AllocationSpace owner); | 1686 explicit OldSpaceFreeList(AllocationSpace owner); |
1679 | 1687 |
1680 // Clear the free list. | 1688 // Clear the free list. |
1681 void Reset(); | 1689 void Reset(); |
1682 | 1690 |
1683 // Return the number of bytes available on the free list. | 1691 // Return the number of bytes available on the free list. |
1684 int available() { return available_; } | 1692 intptr_t available() { return available_; } |
1685 | 1693 |
1686 // Place a node on the free list. The block of size 'size_in_bytes' | 1694 // Place a node on the free list. The block of size 'size_in_bytes' |
1687 // starting at 'start' is placed on the free list. The return value is the | 1695 // starting at 'start' is placed on the free list. The return value is the |
1688 // number of bytes that have been lost due to internal fragmentation by | 1696 // number of bytes that have been lost due to internal fragmentation by |
1689 // freeing the block. Bookkeeping information will be written to the block, | 1697 // freeing the block. Bookkeeping information will be written to the block, |
1690 // ie, its contents will be destroyed. The start address should be word | 1698 // ie, its contents will be destroyed. The start address should be word |
1691 // aligned, and the size should be a non-zero multiple of the word size. | 1699 // aligned, and the size should be a non-zero multiple of the word size. |
1692 int Free(Address start, int size_in_bytes); | 1700 int Free(Address start, int size_in_bytes); |
1693 | 1701 |
1694 // Allocate a block of size 'size_in_bytes' from the free list. The block | 1702 // Allocate a block of size 'size_in_bytes' from the free list. The block |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1776 | 1784 |
1777 // The free list for the map space. | 1785 // The free list for the map space. |
1778 class FixedSizeFreeList BASE_EMBEDDED { | 1786 class FixedSizeFreeList BASE_EMBEDDED { |
1779 public: | 1787 public: |
1780 FixedSizeFreeList(AllocationSpace owner, int object_size); | 1788 FixedSizeFreeList(AllocationSpace owner, int object_size); |
1781 | 1789 |
1782 // Clear the free list. | 1790 // Clear the free list. |
1783 void Reset(); | 1791 void Reset(); |
1784 | 1792 |
1785 // Return the number of bytes available on the free list. | 1793 // Return the number of bytes available on the free list. |
1786 int available() { return available_; } | 1794 intptr_t available() { return available_; } |
1787 | 1795 |
1788 // Place a node on the free list. The block starting at 'start' (assumed to | 1796 // Place a node on the free list. The block starting at 'start' (assumed to |
1789 // have size object_size_) is placed on the free list. Bookkeeping | 1797 // have size object_size_) is placed on the free list. Bookkeeping |
1790 // information will be written to the block, ie, its contents will be | 1798 // information will be written to the block, ie, its contents will be |
1791 // destroyed. The start address should be word aligned. | 1799 // destroyed. The start address should be word aligned. |
1792 void Free(Address start); | 1800 void Free(Address start); |
1793 | 1801 |
1794 // Allocate a fixed sized block from the free list. The block is unitialized. | 1802 // Allocate a fixed sized block from the free list. The block is unitialized. |
1795 // A failure is returned if no block is available. | 1803 // A failure is returned if no block is available. |
1796 Object* Allocate(); | 1804 Object* Allocate(); |
1797 | 1805 |
1798 private: | 1806 private: |
1799 // Available bytes on the free list. | 1807 // Available bytes on the free list. |
1800 int available_; | 1808 intptr_t available_; |
1801 | 1809 |
1802 // The head of the free list. | 1810 // The head of the free list. |
1803 Address head_; | 1811 Address head_; |
1804 | 1812 |
1805 // The tail of the free list. | 1813 // The tail of the free list. |
1806 Address tail_; | 1814 Address tail_; |
1807 | 1815 |
1808 // The identity of the owning space, for building allocation Failure | 1816 // The identity of the owning space, for building allocation Failure |
1809 // objects. | 1817 // objects. |
1810 AllocationSpace owner_; | 1818 AllocationSpace owner_; |
1811 | 1819 |
1812 // The size of the objects in this space. | 1820 // The size of the objects in this space. |
1813 int object_size_; | 1821 int object_size_; |
1814 | 1822 |
1815 DISALLOW_COPY_AND_ASSIGN(FixedSizeFreeList); | 1823 DISALLOW_COPY_AND_ASSIGN(FixedSizeFreeList); |
1816 }; | 1824 }; |
1817 | 1825 |
1818 | 1826 |
1819 // ----------------------------------------------------------------------------- | 1827 // ----------------------------------------------------------------------------- |
1820 // Old object space (excluding map objects) | 1828 // Old object space (excluding map objects) |
1821 | 1829 |
1822 class OldSpace : public PagedSpace { | 1830 class OldSpace : public PagedSpace { |
1823 public: | 1831 public: |
1824 // Creates an old space object with a given maximum capacity. | 1832 // Creates an old space object with a given maximum capacity. |
1825 // The constructor does not allocate pages from OS. | 1833 // The constructor does not allocate pages from OS. |
1826 explicit OldSpace(int max_capacity, | 1834 explicit OldSpace(intptr_t max_capacity, |
1827 AllocationSpace id, | 1835 AllocationSpace id, |
1828 Executability executable) | 1836 Executability executable) |
1829 : PagedSpace(max_capacity, id, executable), free_list_(id) { | 1837 : PagedSpace(max_capacity, id, executable), free_list_(id) { |
1830 page_extra_ = 0; | 1838 page_extra_ = 0; |
1831 } | 1839 } |
1832 | 1840 |
1833 // The bytes available on the free list (ie, not above the linear allocation | 1841 // The bytes available on the free list (ie, not above the linear allocation |
1834 // pointer). | 1842 // pointer). |
1835 int AvailableFree() { return free_list_.available(); } | 1843 intptr_t AvailableFree() { return free_list_.available(); } |
1836 | 1844 |
1837 // The limit of allocation for a page in this space. | 1845 // The limit of allocation for a page in this space. |
1838 virtual Address PageAllocationLimit(Page* page) { | 1846 virtual Address PageAllocationLimit(Page* page) { |
1839 return page->ObjectAreaEnd(); | 1847 return page->ObjectAreaEnd(); |
1840 } | 1848 } |
1841 | 1849 |
1842 // Give a block of memory to the space's free list. It might be added to | 1850 // Give a block of memory to the space's free list. It might be added to |
1843 // the free list or accounted as waste. | 1851 // the free list or accounted as waste. |
1844 // If add_to_freelist is false then just accounting stats are updated and | 1852 // If add_to_freelist is false then just accounting stats are updated and |
1845 // no attempt to add area to free list is made. | 1853 // no attempt to add area to free list is made. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1886 public: | 1894 public: |
1887 TRACK_MEMORY("OldSpace") | 1895 TRACK_MEMORY("OldSpace") |
1888 }; | 1896 }; |
1889 | 1897 |
1890 | 1898 |
1891 // ----------------------------------------------------------------------------- | 1899 // ----------------------------------------------------------------------------- |
1892 // Old space for objects of a fixed size | 1900 // Old space for objects of a fixed size |
1893 | 1901 |
1894 class FixedSpace : public PagedSpace { | 1902 class FixedSpace : public PagedSpace { |
1895 public: | 1903 public: |
1896 FixedSpace(int max_capacity, | 1904 FixedSpace(intptr_t max_capacity, |
1897 AllocationSpace id, | 1905 AllocationSpace id, |
1898 int object_size_in_bytes, | 1906 int object_size_in_bytes, |
1899 const char* name) | 1907 const char* name) |
1900 : PagedSpace(max_capacity, id, NOT_EXECUTABLE), | 1908 : PagedSpace(max_capacity, id, NOT_EXECUTABLE), |
1901 object_size_in_bytes_(object_size_in_bytes), | 1909 object_size_in_bytes_(object_size_in_bytes), |
1902 name_(name), | 1910 name_(name), |
1903 free_list_(id, object_size_in_bytes) { | 1911 free_list_(id, object_size_in_bytes) { |
1904 page_extra_ = Page::kObjectAreaSize % object_size_in_bytes; | 1912 page_extra_ = Page::kObjectAreaSize % object_size_in_bytes; |
1905 } | 1913 } |
1906 | 1914 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1961 FixedSizeFreeList free_list_; | 1969 FixedSizeFreeList free_list_; |
1962 }; | 1970 }; |
1963 | 1971 |
1964 | 1972 |
1965 // ----------------------------------------------------------------------------- | 1973 // ----------------------------------------------------------------------------- |
1966 // Old space for all map objects | 1974 // Old space for all map objects |
1967 | 1975 |
1968 class MapSpace : public FixedSpace { | 1976 class MapSpace : public FixedSpace { |
1969 public: | 1977 public: |
1970 // Creates a map space object with a maximum capacity. | 1978 // Creates a map space object with a maximum capacity. |
1971 MapSpace(int max_capacity, int max_map_space_pages, AllocationSpace id) | 1979 MapSpace(intptr_t max_capacity, int max_map_space_pages, AllocationSpace id) |
1972 : FixedSpace(max_capacity, id, Map::kSize, "map"), | 1980 : FixedSpace(max_capacity, id, Map::kSize, "map"), |
1973 max_map_space_pages_(max_map_space_pages) { | 1981 max_map_space_pages_(max_map_space_pages) { |
1974 ASSERT(max_map_space_pages < kMaxMapPageIndex); | 1982 ASSERT(max_map_space_pages < kMaxMapPageIndex); |
1975 } | 1983 } |
1976 | 1984 |
1977 // Prepares for a mark-compact GC. | 1985 // Prepares for a mark-compact GC. |
1978 virtual void PrepareForMarkCompact(bool will_compact); | 1986 virtual void PrepareForMarkCompact(bool will_compact); |
1979 | 1987 |
1980 // Given an index, returns the page address. | 1988 // Given an index, returns the page address. |
1981 Address PageAddress(int page_index) { return page_addresses_[page_index]; } | 1989 Address PageAddress(int page_index) { return page_addresses_[page_index]; } |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2066 TRACK_MEMORY("MapSpace") | 2074 TRACK_MEMORY("MapSpace") |
2067 }; | 2075 }; |
2068 | 2076 |
2069 | 2077 |
2070 // ----------------------------------------------------------------------------- | 2078 // ----------------------------------------------------------------------------- |
2071 // Old space for all global object property cell objects | 2079 // Old space for all global object property cell objects |
2072 | 2080 |
2073 class CellSpace : public FixedSpace { | 2081 class CellSpace : public FixedSpace { |
2074 public: | 2082 public: |
2075 // Creates a property cell space object with a maximum capacity. | 2083 // Creates a property cell space object with a maximum capacity. |
2076 CellSpace(int max_capacity, AllocationSpace id) | 2084 CellSpace(intptr_t max_capacity, AllocationSpace id) |
2077 : FixedSpace(max_capacity, id, JSGlobalPropertyCell::kSize, "cell") {} | 2085 : FixedSpace(max_capacity, id, JSGlobalPropertyCell::kSize, "cell") {} |
2078 | 2086 |
2079 protected: | 2087 protected: |
2080 #ifdef DEBUG | 2088 #ifdef DEBUG |
2081 virtual void VerifyObject(HeapObject* obj); | 2089 virtual void VerifyObject(HeapObject* obj); |
2082 #endif | 2090 #endif |
2083 | 2091 |
2084 public: | 2092 public: |
2085 TRACK_MEMORY("CellSpace") | 2093 TRACK_MEMORY("CellSpace") |
2086 }; | 2094 }; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2122 | 2130 |
2123 // Returns the object in this chunk. | 2131 // Returns the object in this chunk. |
2124 inline HeapObject* GetObject(); | 2132 inline HeapObject* GetObject(); |
2125 | 2133 |
2126 // Given a requested size returns the physical size of a chunk to be | 2134 // Given a requested size returns the physical size of a chunk to be |
2127 // allocated. | 2135 // allocated. |
2128 static int ChunkSizeFor(int size_in_bytes); | 2136 static int ChunkSizeFor(int size_in_bytes); |
2129 | 2137 |
2130 // Given a chunk size, returns the object size it can accommodate. Used by | 2138 // Given a chunk size, returns the object size it can accommodate. Used by |
2131 // LargeObjectSpace::Available. | 2139 // LargeObjectSpace::Available. |
2132 static int ObjectSizeFor(int chunk_size) { | 2140 static intptr_t ObjectSizeFor(intptr_t chunk_size) { |
2133 if (chunk_size <= (Page::kPageSize + Page::kObjectStartOffset)) return 0; | 2141 if (chunk_size <= (Page::kPageSize + Page::kObjectStartOffset)) return 0; |
2134 return chunk_size - Page::kPageSize - Page::kObjectStartOffset; | 2142 return chunk_size - Page::kPageSize - Page::kObjectStartOffset; |
2135 } | 2143 } |
2136 | 2144 |
2137 private: | 2145 private: |
2138 // A pointer to the next large object chunk in the space or NULL. | 2146 // A pointer to the next large object chunk in the space or NULL. |
2139 LargeObjectChunk* next_; | 2147 LargeObjectChunk* next_; |
2140 | 2148 |
2141 // The size of this chunk. | 2149 // The size of this chunk. |
2142 size_t size_; | 2150 size_t size_; |
(...skipping 15 matching lines...) Expand all Loading... | |
2158 void TearDown(); | 2166 void TearDown(); |
2159 | 2167 |
2160 // Allocates a (non-FixedArray, non-Code) large object. | 2168 // Allocates a (non-FixedArray, non-Code) large object. |
2161 Object* AllocateRaw(int size_in_bytes); | 2169 Object* AllocateRaw(int size_in_bytes); |
2162 // Allocates a large Code object. | 2170 // Allocates a large Code object. |
2163 Object* AllocateRawCode(int size_in_bytes); | 2171 Object* AllocateRawCode(int size_in_bytes); |
2164 // Allocates a large FixedArray. | 2172 // Allocates a large FixedArray. |
2165 Object* AllocateRawFixedArray(int size_in_bytes); | 2173 Object* AllocateRawFixedArray(int size_in_bytes); |
2166 | 2174 |
2167 // Available bytes for objects in this space. | 2175 // Available bytes for objects in this space. |
2168 int Available() { | 2176 intptr_t Available() { |
2169 return LargeObjectChunk::ObjectSizeFor(MemoryAllocator::Available()); | 2177 return LargeObjectChunk::ObjectSizeFor(MemoryAllocator::Available()); |
2170 } | 2178 } |
2171 | 2179 |
2172 virtual int Size() { | 2180 virtual intptr_t Size() { |
2173 return size_; | 2181 return size_; |
2174 } | 2182 } |
2175 | 2183 |
2176 int PageCount() { | 2184 int PageCount() { |
2177 return page_count_; | 2185 return page_count_; |
2178 } | 2186 } |
2179 | 2187 |
2180 // Finds an object for a given address, returns Failure::Exception() | 2188 // Finds an object for a given address, returns Failure::Exception() |
2181 // if it is not found. The function iterates through all objects in this | 2189 // if it is not found. The function iterates through all objects in this |
2182 // space, may be slow. | 2190 // space, may be slow. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2216 void ReportStatistics(); | 2224 void ReportStatistics(); |
2217 void CollectCodeStatistics(); | 2225 void CollectCodeStatistics(); |
2218 #endif | 2226 #endif |
2219 // Checks whether an address is in the object area in this space. It | 2227 // Checks whether an address is in the object area in this space. It |
2220 // iterates all objects in the space. May be slow. | 2228 // iterates all objects in the space. May be slow. |
2221 bool SlowContains(Address addr) { return !FindObject(addr)->IsFailure(); } | 2229 bool SlowContains(Address addr) { return !FindObject(addr)->IsFailure(); } |
2222 | 2230 |
2223 private: | 2231 private: |
2224 // The head of the linked list of large object chunks. | 2232 // The head of the linked list of large object chunks. |
2225 LargeObjectChunk* first_chunk_; | 2233 LargeObjectChunk* first_chunk_; |
2226 int size_; // allocated bytes | 2234 intptr_t size_; // allocated bytes |
2227 int page_count_; // number of chunks | 2235 int page_count_; // number of chunks |
2228 | 2236 |
2229 | 2237 |
2230 // Shared implementation of AllocateRaw, AllocateRawCode and | 2238 // Shared implementation of AllocateRaw, AllocateRawCode and |
2231 // AllocateRawFixedArray. | 2239 // AllocateRawFixedArray. |
2232 Object* AllocateRawInternal(int requested_size, | 2240 Object* AllocateRawInternal(int requested_size, |
2233 int object_size, | 2241 int object_size, |
2234 Executability executable); | 2242 Executability executable); |
2235 | 2243 |
2236 friend class LargeObjectIterator; | 2244 friend class LargeObjectIterator; |
(...skipping 15 matching lines...) Expand all Loading... | |
2252 | 2260 |
2253 private: | 2261 private: |
2254 LargeObjectChunk* current_; | 2262 LargeObjectChunk* current_; |
2255 HeapObjectCallback size_func_; | 2263 HeapObjectCallback size_func_; |
2256 }; | 2264 }; |
2257 | 2265 |
2258 | 2266 |
2259 } } // namespace v8::internal | 2267 } } // namespace v8::internal |
2260 | 2268 |
2261 #endif // V8_SPACES_H_ | 2269 #endif // V8_SPACES_H_ |
OLD | NEW |