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