| 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 intptr_t Size() = 0; | 374 virtual int 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(intptr_t max_capacity); | 494 static bool Setup(int 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 intptr_t Available() { | 585 static int Available() { return capacity_ < size_ ? 0 : capacity_ - size_; } |
| 586 return capacity_ < size_ ? 0 : capacity_ - size_; | |
| 587 } | |
| 588 | 586 |
| 589 // Returns allocated spaces in bytes. | 587 // Returns allocated spaces in bytes. |
| 590 static intptr_t Size() { return size_; } | 588 static int Size() { return size_; } |
| 591 | 589 |
| 592 // Returns allocated executable spaces in bytes. | 590 // Returns allocated executable spaces in bytes. |
| 593 static intptr_t SizeExecutable() { return size_executable_; } | 591 static int SizeExecutable() { return size_executable_; } |
| 594 | 592 |
| 595 // Returns maximum available bytes that the old space can have. | 593 // Returns maximum available bytes that the old space can have. |
| 596 static intptr_t MaxAvailable() { | 594 static int MaxAvailable() { |
| 597 return (Available() / Page::kPageSize) * Page::kObjectAreaSize; | 595 return (Available() / Page::kPageSize) * Page::kObjectAreaSize; |
| 598 } | 596 } |
| 599 | 597 |
| 600 // Links two pages. | 598 // Links two pages. |
| 601 static inline void SetNextPage(Page* prev, Page* next); | 599 static inline void SetNextPage(Page* prev, Page* next); |
| 602 | 600 |
| 603 // Returns the next page of a given page. | 601 // Returns the next page of a given page. |
| 604 static inline Page* GetNextPage(Page* p); | 602 static inline Page* GetNextPage(Page* p); |
| 605 | 603 |
| 606 // Checks whether a page belongs to a space. | 604 // Checks whether a page belongs to a space. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 // 8K * 8K * 16 = 1G bytes. | 642 // 8K * 8K * 16 = 1G bytes. |
| 645 #ifdef V8_TARGET_ARCH_X64 | 643 #ifdef V8_TARGET_ARCH_X64 |
| 646 static const int kPagesPerChunk = 32; | 644 static const int kPagesPerChunk = 32; |
| 647 #else | 645 #else |
| 648 static const int kPagesPerChunk = 16; | 646 static const int kPagesPerChunk = 16; |
| 649 #endif | 647 #endif |
| 650 static const int kChunkSize = kPagesPerChunk * Page::kPageSize; | 648 static const int kChunkSize = kPagesPerChunk * Page::kPageSize; |
| 651 | 649 |
| 652 private: | 650 private: |
| 653 // Maximum space size in bytes. | 651 // Maximum space size in bytes. |
| 654 static intptr_t capacity_; | 652 static int capacity_; |
| 655 | 653 |
| 656 // Allocated space size in bytes. | 654 // Allocated space size in bytes. |
| 657 static intptr_t size_; | 655 static int size_; |
| 658 // Allocated executable space size in bytes. | 656 // Allocated executable space size in bytes. |
| 659 static intptr_t size_executable_; | 657 static int size_executable_; |
| 660 | 658 |
| 661 struct MemoryAllocationCallbackRegistration { | 659 struct MemoryAllocationCallbackRegistration { |
| 662 MemoryAllocationCallbackRegistration(MemoryAllocationCallback callback, | 660 MemoryAllocationCallbackRegistration(MemoryAllocationCallback callback, |
| 663 ObjectSpace space, | 661 ObjectSpace space, |
| 664 AllocationAction action) | 662 AllocationAction action) |
| 665 : callback(callback), space(space), action(action) { | 663 : callback(callback), space(space), action(action) { |
| 666 } | 664 } |
| 667 MemoryAllocationCallback callback; | 665 MemoryAllocationCallback callback; |
| 668 ObjectSpace space; | 666 ObjectSpace space; |
| 669 AllocationAction action; | 667 AllocationAction action; |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 922 | 920 |
| 923 // Reset the allocation statistics (ie, available = capacity with no | 921 // Reset the allocation statistics (ie, available = capacity with no |
| 924 // wasted or allocated bytes). | 922 // wasted or allocated bytes). |
| 925 void Reset() { | 923 void Reset() { |
| 926 available_ = capacity_; | 924 available_ = capacity_; |
| 927 size_ = 0; | 925 size_ = 0; |
| 928 waste_ = 0; | 926 waste_ = 0; |
| 929 } | 927 } |
| 930 | 928 |
| 931 // Accessors for the allocation statistics. | 929 // Accessors for the allocation statistics. |
| 932 intptr_t Capacity() { return capacity_; } | 930 int Capacity() { return capacity_; } |
| 933 intptr_t Available() { return available_; } | 931 int Available() { return available_; } |
| 934 intptr_t Size() { return size_; } | 932 int Size() { return size_; } |
| 935 intptr_t Waste() { return waste_; } | 933 int Waste() { return waste_; } |
| 936 | 934 |
| 937 // Grow the space by adding available bytes. | 935 // Grow the space by adding available bytes. |
| 938 void ExpandSpace(int size_in_bytes) { | 936 void ExpandSpace(int size_in_bytes) { |
| 939 capacity_ += size_in_bytes; | 937 capacity_ += size_in_bytes; |
| 940 available_ += size_in_bytes; | 938 available_ += size_in_bytes; |
| 941 } | 939 } |
| 942 | 940 |
| 943 // Shrink the space by removing available bytes. | 941 // Shrink the space by removing available bytes. |
| 944 void ShrinkSpace(int size_in_bytes) { | 942 void ShrinkSpace(int size_in_bytes) { |
| 945 capacity_ -= size_in_bytes; | 943 capacity_ -= size_in_bytes; |
| 946 available_ -= size_in_bytes; | 944 available_ -= size_in_bytes; |
| 947 } | 945 } |
| 948 | 946 |
| 949 // Allocate from available bytes (available -> size). | 947 // Allocate from available bytes (available -> size). |
| 950 void AllocateBytes(int size_in_bytes) { | 948 void AllocateBytes(int size_in_bytes) { |
| 951 available_ -= size_in_bytes; | 949 available_ -= size_in_bytes; |
| 952 size_ += size_in_bytes; | 950 size_ += size_in_bytes; |
| 953 } | 951 } |
| 954 | 952 |
| 955 // Free allocated bytes, making them available (size -> available). | 953 // Free allocated bytes, making them available (size -> available). |
| 956 void DeallocateBytes(intptr_t size_in_bytes) { | 954 void DeallocateBytes(int size_in_bytes) { |
| 957 size_ -= size_in_bytes; | 955 size_ -= size_in_bytes; |
| 958 available_ += size_in_bytes; | 956 available_ += size_in_bytes; |
| 959 } | 957 } |
| 960 | 958 |
| 961 // Waste free bytes (available -> waste). | 959 // Waste free bytes (available -> waste). |
| 962 void WasteBytes(int size_in_bytes) { | 960 void WasteBytes(int size_in_bytes) { |
| 963 available_ -= size_in_bytes; | 961 available_ -= size_in_bytes; |
| 964 waste_ += size_in_bytes; | 962 waste_ += size_in_bytes; |
| 965 } | 963 } |
| 966 | 964 |
| 967 // Consider the wasted bytes to be allocated, as they contain filler | 965 // Consider the wasted bytes to be allocated, as they contain filler |
| 968 // objects (waste -> size). | 966 // objects (waste -> size). |
| 969 void FillWastedBytes(int size_in_bytes) { | 967 void FillWastedBytes(int size_in_bytes) { |
| 970 waste_ -= size_in_bytes; | 968 waste_ -= size_in_bytes; |
| 971 size_ += size_in_bytes; | 969 size_ += size_in_bytes; |
| 972 } | 970 } |
| 973 | 971 |
| 974 private: | 972 private: |
| 975 intptr_t capacity_; | 973 int capacity_; |
| 976 intptr_t available_; | 974 int available_; |
| 977 intptr_t size_; | 975 int size_; |
| 978 intptr_t waste_; | 976 int waste_; |
| 979 }; | 977 }; |
| 980 | 978 |
| 981 | 979 |
| 982 class PagedSpace : public Space { | 980 class PagedSpace : public Space { |
| 983 public: | 981 public: |
| 984 // Creates a space with a maximum capacity, and an id. | 982 // Creates a space with a maximum capacity, and an id. |
| 985 PagedSpace(intptr_t max_capacity, | 983 PagedSpace(int max_capacity, AllocationSpace id, Executability executable); |
| 986 AllocationSpace id, | |
| 987 Executability executable); | |
| 988 | 984 |
| 989 virtual ~PagedSpace() {} | 985 virtual ~PagedSpace() {} |
| 990 | 986 |
| 991 // Set up the space using the given address range of virtual memory (from | 987 // Set up the space using the given address range of virtual memory (from |
| 992 // the memory allocator's initial chunk) if possible. If the block of | 988 // the memory allocator's initial chunk) if possible. If the block of |
| 993 // addresses is not big enough to contain a single page-aligned page, a | 989 // addresses is not big enough to contain a single page-aligned page, a |
| 994 // fresh chunk will be allocated. | 990 // fresh chunk will be allocated. |
| 995 bool Setup(Address start, size_t size); | 991 bool Setup(Address start, size_t size); |
| 996 | 992 |
| 997 // Returns true if the space has been successfully set up and not | 993 // Returns true if the space has been successfully set up and not |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1028 | 1024 |
| 1029 // The limit of allocation for a page in this space. | 1025 // The limit of allocation for a page in this space. |
| 1030 virtual Address PageAllocationLimit(Page* page) = 0; | 1026 virtual Address PageAllocationLimit(Page* page) = 0; |
| 1031 | 1027 |
| 1032 void FlushTopPageWatermark() { | 1028 void FlushTopPageWatermark() { |
| 1033 AllocationTopPage()->SetCachedAllocationWatermark(top()); | 1029 AllocationTopPage()->SetCachedAllocationWatermark(top()); |
| 1034 AllocationTopPage()->InvalidateWatermark(true); | 1030 AllocationTopPage()->InvalidateWatermark(true); |
| 1035 } | 1031 } |
| 1036 | 1032 |
| 1037 // Current capacity without growing (Size() + Available() + Waste()). | 1033 // Current capacity without growing (Size() + Available() + Waste()). |
| 1038 intptr_t Capacity() { return accounting_stats_.Capacity(); } | 1034 int Capacity() { return accounting_stats_.Capacity(); } |
| 1039 | 1035 |
| 1040 // Total amount of memory committed for this space. For paged | 1036 // Total amount of memory committed for this space. For paged |
| 1041 // spaces this equals the capacity. | 1037 // spaces this equals the capacity. |
| 1042 intptr_t CommittedMemory() { return Capacity(); } | 1038 int CommittedMemory() { return Capacity(); } |
| 1043 | 1039 |
| 1044 // Available bytes without growing. | 1040 // Available bytes without growing. |
| 1045 intptr_t Available() { return accounting_stats_.Available(); } | 1041 int Available() { return accounting_stats_.Available(); } |
| 1046 | 1042 |
| 1047 // Allocated bytes in this space. | 1043 // Allocated bytes in this space. |
| 1048 virtual intptr_t Size() { return accounting_stats_.Size(); } | 1044 virtual int Size() { return accounting_stats_.Size(); } |
| 1049 | 1045 |
| 1050 // Wasted bytes due to fragmentation and not recoverable until the | 1046 // Wasted bytes due to fragmentation and not recoverable until the |
| 1051 // next GC of this space. | 1047 // next GC of this space. |
| 1052 intptr_t Waste() { return accounting_stats_.Waste(); } | 1048 int Waste() { return accounting_stats_.Waste(); } |
| 1053 | 1049 |
| 1054 // Returns the address of the first object in this space. | 1050 // Returns the address of the first object in this space. |
| 1055 Address bottom() { return first_page_->ObjectAreaStart(); } | 1051 Address bottom() { return first_page_->ObjectAreaStart(); } |
| 1056 | 1052 |
| 1057 // Returns the allocation pointer in this space. | 1053 // Returns the allocation pointer in this space. |
| 1058 Address top() { return allocation_info_.top; } | 1054 Address top() { return allocation_info_.top; } |
| 1059 | 1055 |
| 1060 // Allocate the requested number of bytes in the space if possible, return a | 1056 // Allocate the requested number of bytes in the space if possible, return a |
| 1061 // failure object if not. | 1057 // failure object if not. |
| 1062 inline Object* AllocateRaw(int size_in_bytes); | 1058 inline Object* AllocateRaw(int size_in_bytes); |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1325 return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_; | 1321 return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_; |
| 1326 } | 1322 } |
| 1327 | 1323 |
| 1328 // The offset of an address from the beginning of the space. | 1324 // The offset of an address from the beginning of the space. |
| 1329 int SpaceOffsetForAddress(Address addr) { | 1325 int SpaceOffsetForAddress(Address addr) { |
| 1330 return static_cast<int>(addr - low()); | 1326 return static_cast<int>(addr - low()); |
| 1331 } | 1327 } |
| 1332 | 1328 |
| 1333 // If we don't have these here then SemiSpace will be abstract. However | 1329 // If we don't have these here then SemiSpace will be abstract. However |
| 1334 // they should never be called. | 1330 // they should never be called. |
| 1335 virtual intptr_t Size() { | 1331 virtual int Size() { |
| 1336 UNREACHABLE(); | 1332 UNREACHABLE(); |
| 1337 return 0; | 1333 return 0; |
| 1338 } | 1334 } |
| 1339 | 1335 |
| 1340 virtual bool ReserveSpace(int bytes) { | 1336 virtual bool ReserveSpace(int bytes) { |
| 1341 UNREACHABLE(); | 1337 UNREACHABLE(); |
| 1342 return false; | 1338 return false; |
| 1343 } | 1339 } |
| 1344 | 1340 |
| 1345 bool is_committed() { return committed_; } | 1341 bool is_committed() { return committed_; } |
| 1346 bool Commit(); | 1342 bool Commit(); |
| 1347 bool Uncommit(); | 1343 bool Uncommit(); |
| 1348 | 1344 |
| 1349 #ifdef ENABLE_HEAP_PROTECTION | 1345 #ifdef ENABLE_HEAP_PROTECTION |
| 1350 // Protect/unprotect the space by marking it read-only/writable. | 1346 // Protect/unprotect the space by marking it read-only/writable. |
| 1351 virtual void Protect() {} | 1347 virtual void Protect() {} |
| 1352 virtual void Unprotect() {} | 1348 virtual void Unprotect() {} |
| 1353 #endif | 1349 #endif |
| 1354 | 1350 |
| 1355 #ifdef DEBUG | 1351 #ifdef DEBUG |
| 1356 virtual void Print(); | 1352 virtual void Print(); |
| 1357 virtual void Verify(); | 1353 virtual void Verify(); |
| 1358 #endif | 1354 #endif |
| 1359 | 1355 |
| 1360 // Returns the current capacity of the semi space. | 1356 // Returns the current capacity of the semi space. |
| 1361 intptr_t Capacity() { return capacity_; } | 1357 int Capacity() { return capacity_; } |
| 1362 | 1358 |
| 1363 // Returns the maximum capacity of the semi space. | 1359 // Returns the maximum capacity of the semi space. |
| 1364 int MaximumCapacity() { return maximum_capacity_; } | 1360 int MaximumCapacity() { return maximum_capacity_; } |
| 1365 | 1361 |
| 1366 // Returns the initial capacity of the semi space. | 1362 // Returns the initial capacity of the semi space. |
| 1367 int InitialCapacity() { return initial_capacity_; } | 1363 int InitialCapacity() { return initial_capacity_; } |
| 1368 | 1364 |
| 1369 private: | 1365 private: |
| 1370 // The current and maximum capacity of the space. | 1366 // The current and maximum capacity of the space. |
| 1371 int capacity_; | 1367 int capacity_; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1468 // semispace (not necessarily below the allocation pointer). | 1464 // semispace (not necessarily below the allocation pointer). |
| 1469 bool Contains(Address a) { | 1465 bool Contains(Address a) { |
| 1470 return (reinterpret_cast<uintptr_t>(a) & address_mask_) | 1466 return (reinterpret_cast<uintptr_t>(a) & address_mask_) |
| 1471 == reinterpret_cast<uintptr_t>(start_); | 1467 == reinterpret_cast<uintptr_t>(start_); |
| 1472 } | 1468 } |
| 1473 bool Contains(Object* o) { | 1469 bool Contains(Object* o) { |
| 1474 return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_; | 1470 return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_; |
| 1475 } | 1471 } |
| 1476 | 1472 |
| 1477 // Return the allocated bytes in the active semispace. | 1473 // Return the allocated bytes in the active semispace. |
| 1478 virtual intptr_t Size() { return static_cast<int>(top() - bottom()); } | 1474 virtual int Size() { return static_cast<int>(top() - bottom()); } |
| 1479 | 1475 |
| 1480 // Return the current capacity of a semispace. | 1476 // Return the current capacity of a semispace. |
| 1481 intptr_t Capacity() { | 1477 int Capacity() { |
| 1482 ASSERT(to_space_.Capacity() == from_space_.Capacity()); | 1478 ASSERT(to_space_.Capacity() == from_space_.Capacity()); |
| 1483 return to_space_.Capacity(); | 1479 return to_space_.Capacity(); |
| 1484 } | 1480 } |
| 1485 | 1481 |
| 1486 // Return the total amount of memory committed for new space. | 1482 // Return the total amount of memory committed for new space. |
| 1487 intptr_t CommittedMemory() { | 1483 int CommittedMemory() { |
| 1488 if (from_space_.is_committed()) return 2 * Capacity(); | 1484 if (from_space_.is_committed()) return 2 * Capacity(); |
| 1489 return Capacity(); | 1485 return Capacity(); |
| 1490 } | 1486 } |
| 1491 | 1487 |
| 1492 // Return the available bytes without growing in the active semispace. | 1488 // Return the available bytes without growing in the active semispace. |
| 1493 intptr_t Available() { return Capacity() - Size(); } | 1489 int Available() { return Capacity() - Size(); } |
| 1494 | 1490 |
| 1495 // Return the maximum capacity of a semispace. | 1491 // Return the maximum capacity of a semispace. |
| 1496 int MaximumCapacity() { | 1492 int MaximumCapacity() { |
| 1497 ASSERT(to_space_.MaximumCapacity() == from_space_.MaximumCapacity()); | 1493 ASSERT(to_space_.MaximumCapacity() == from_space_.MaximumCapacity()); |
| 1498 return to_space_.MaximumCapacity(); | 1494 return to_space_.MaximumCapacity(); |
| 1499 } | 1495 } |
| 1500 | 1496 |
| 1501 // Returns the initial capacity of a semispace. | 1497 // Returns the initial capacity of a semispace. |
| 1502 intptr_t InitialCapacity() { | 1498 int InitialCapacity() { |
| 1503 ASSERT(to_space_.InitialCapacity() == from_space_.InitialCapacity()); | 1499 ASSERT(to_space_.InitialCapacity() == from_space_.InitialCapacity()); |
| 1504 return to_space_.InitialCapacity(); | 1500 return to_space_.InitialCapacity(); |
| 1505 } | 1501 } |
| 1506 | 1502 |
| 1507 // Return the address of the allocation pointer in the active semispace. | 1503 // Return the address of the allocation pointer in the active semispace. |
| 1508 Address top() { return allocation_info_.top; } | 1504 Address top() { return allocation_info_.top; } |
| 1509 // Return the address of the first object in the active semispace. | 1505 // Return the address of the first object in the active semispace. |
| 1510 Address bottom() { return to_space_.low(); } | 1506 Address bottom() { return to_space_.low(); } |
| 1511 | 1507 |
| 1512 // Get the age mark of the inactive semispace. | 1508 // Get the age mark of the inactive semispace. |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1678 | 1674 |
| 1679 // The free list for the old space. | 1675 // The free list for the old space. |
| 1680 class OldSpaceFreeList BASE_EMBEDDED { | 1676 class OldSpaceFreeList BASE_EMBEDDED { |
| 1681 public: | 1677 public: |
| 1682 explicit OldSpaceFreeList(AllocationSpace owner); | 1678 explicit OldSpaceFreeList(AllocationSpace owner); |
| 1683 | 1679 |
| 1684 // Clear the free list. | 1680 // Clear the free list. |
| 1685 void Reset(); | 1681 void Reset(); |
| 1686 | 1682 |
| 1687 // Return the number of bytes available on the free list. | 1683 // Return the number of bytes available on the free list. |
| 1688 intptr_t available() { return available_; } | 1684 int available() { return available_; } |
| 1689 | 1685 |
| 1690 // Place a node on the free list. The block of size 'size_in_bytes' | 1686 // Place a node on the free list. The block of size 'size_in_bytes' |
| 1691 // starting at 'start' is placed on the free list. The return value is the | 1687 // starting at 'start' is placed on the free list. The return value is the |
| 1692 // number of bytes that have been lost due to internal fragmentation by | 1688 // number of bytes that have been lost due to internal fragmentation by |
| 1693 // freeing the block. Bookkeeping information will be written to the block, | 1689 // freeing the block. Bookkeeping information will be written to the block, |
| 1694 // ie, its contents will be destroyed. The start address should be word | 1690 // ie, its contents will be destroyed. The start address should be word |
| 1695 // aligned, and the size should be a non-zero multiple of the word size. | 1691 // aligned, and the size should be a non-zero multiple of the word size. |
| 1696 int Free(Address start, int size_in_bytes); | 1692 int Free(Address start, int size_in_bytes); |
| 1697 | 1693 |
| 1698 // Allocate a block of size 'size_in_bytes' from the free list. The block | 1694 // 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... |
| 1780 | 1776 |
| 1781 // The free list for the map space. | 1777 // The free list for the map space. |
| 1782 class FixedSizeFreeList BASE_EMBEDDED { | 1778 class FixedSizeFreeList BASE_EMBEDDED { |
| 1783 public: | 1779 public: |
| 1784 FixedSizeFreeList(AllocationSpace owner, int object_size); | 1780 FixedSizeFreeList(AllocationSpace owner, int object_size); |
| 1785 | 1781 |
| 1786 // Clear the free list. | 1782 // Clear the free list. |
| 1787 void Reset(); | 1783 void Reset(); |
| 1788 | 1784 |
| 1789 // Return the number of bytes available on the free list. | 1785 // Return the number of bytes available on the free list. |
| 1790 intptr_t available() { return available_; } | 1786 int available() { return available_; } |
| 1791 | 1787 |
| 1792 // Place a node on the free list. The block starting at 'start' (assumed to | 1788 // Place a node on the free list. The block starting at 'start' (assumed to |
| 1793 // have size object_size_) is placed on the free list. Bookkeeping | 1789 // have size object_size_) is placed on the free list. Bookkeeping |
| 1794 // information will be written to the block, ie, its contents will be | 1790 // information will be written to the block, ie, its contents will be |
| 1795 // destroyed. The start address should be word aligned. | 1791 // destroyed. The start address should be word aligned. |
| 1796 void Free(Address start); | 1792 void Free(Address start); |
| 1797 | 1793 |
| 1798 // Allocate a fixed sized block from the free list. The block is unitialized. | 1794 // Allocate a fixed sized block from the free list. The block is unitialized. |
| 1799 // A failure is returned if no block is available. | 1795 // A failure is returned if no block is available. |
| 1800 Object* Allocate(); | 1796 Object* Allocate(); |
| 1801 | 1797 |
| 1802 private: | 1798 private: |
| 1803 // Available bytes on the free list. | 1799 // Available bytes on the free list. |
| 1804 intptr_t available_; | 1800 int available_; |
| 1805 | 1801 |
| 1806 // The head of the free list. | 1802 // The head of the free list. |
| 1807 Address head_; | 1803 Address head_; |
| 1808 | 1804 |
| 1809 // The tail of the free list. | 1805 // The tail of the free list. |
| 1810 Address tail_; | 1806 Address tail_; |
| 1811 | 1807 |
| 1812 // The identity of the owning space, for building allocation Failure | 1808 // The identity of the owning space, for building allocation Failure |
| 1813 // objects. | 1809 // objects. |
| 1814 AllocationSpace owner_; | 1810 AllocationSpace owner_; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1829 // The constructor does not allocate pages from OS. | 1825 // The constructor does not allocate pages from OS. |
| 1830 explicit OldSpace(int max_capacity, | 1826 explicit OldSpace(int max_capacity, |
| 1831 AllocationSpace id, | 1827 AllocationSpace id, |
| 1832 Executability executable) | 1828 Executability executable) |
| 1833 : PagedSpace(max_capacity, id, executable), free_list_(id) { | 1829 : PagedSpace(max_capacity, id, executable), free_list_(id) { |
| 1834 page_extra_ = 0; | 1830 page_extra_ = 0; |
| 1835 } | 1831 } |
| 1836 | 1832 |
| 1837 // The bytes available on the free list (ie, not above the linear allocation | 1833 // The bytes available on the free list (ie, not above the linear allocation |
| 1838 // pointer). | 1834 // pointer). |
| 1839 intptr_t AvailableFree() { return free_list_.available(); } | 1835 int AvailableFree() { return free_list_.available(); } |
| 1840 | 1836 |
| 1841 // The limit of allocation for a page in this space. | 1837 // The limit of allocation for a page in this space. |
| 1842 virtual Address PageAllocationLimit(Page* page) { | 1838 virtual Address PageAllocationLimit(Page* page) { |
| 1843 return page->ObjectAreaEnd(); | 1839 return page->ObjectAreaEnd(); |
| 1844 } | 1840 } |
| 1845 | 1841 |
| 1846 // Give a block of memory to the space's free list. It might be added to | 1842 // Give a block of memory to the space's free list. It might be added to |
| 1847 // the free list or accounted as waste. | 1843 // the free list or accounted as waste. |
| 1848 // If add_to_freelist is false then just accounting stats are updated and | 1844 // If add_to_freelist is false then just accounting stats are updated and |
| 1849 // no attempt to add area to free list is made. | 1845 // no attempt to add area to free list is made. |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2126 | 2122 |
| 2127 // Returns the object in this chunk. | 2123 // Returns the object in this chunk. |
| 2128 inline HeapObject* GetObject(); | 2124 inline HeapObject* GetObject(); |
| 2129 | 2125 |
| 2130 // Given a requested size returns the physical size of a chunk to be | 2126 // Given a requested size returns the physical size of a chunk to be |
| 2131 // allocated. | 2127 // allocated. |
| 2132 static int ChunkSizeFor(int size_in_bytes); | 2128 static int ChunkSizeFor(int size_in_bytes); |
| 2133 | 2129 |
| 2134 // Given a chunk size, returns the object size it can accommodate. Used by | 2130 // Given a chunk size, returns the object size it can accommodate. Used by |
| 2135 // LargeObjectSpace::Available. | 2131 // LargeObjectSpace::Available. |
| 2136 static intptr_t ObjectSizeFor(intptr_t chunk_size) { | 2132 static int ObjectSizeFor(int chunk_size) { |
| 2137 if (chunk_size <= (Page::kPageSize + Page::kObjectStartOffset)) return 0; | 2133 if (chunk_size <= (Page::kPageSize + Page::kObjectStartOffset)) return 0; |
| 2138 return chunk_size - Page::kPageSize - Page::kObjectStartOffset; | 2134 return chunk_size - Page::kPageSize - Page::kObjectStartOffset; |
| 2139 } | 2135 } |
| 2140 | 2136 |
| 2141 private: | 2137 private: |
| 2142 // A pointer to the next large object chunk in the space or NULL. | 2138 // A pointer to the next large object chunk in the space or NULL. |
| 2143 LargeObjectChunk* next_; | 2139 LargeObjectChunk* next_; |
| 2144 | 2140 |
| 2145 // The size of this chunk. | 2141 // The size of this chunk. |
| 2146 size_t size_; | 2142 size_t size_; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2162 void TearDown(); | 2158 void TearDown(); |
| 2163 | 2159 |
| 2164 // Allocates a (non-FixedArray, non-Code) large object. | 2160 // Allocates a (non-FixedArray, non-Code) large object. |
| 2165 Object* AllocateRaw(int size_in_bytes); | 2161 Object* AllocateRaw(int size_in_bytes); |
| 2166 // Allocates a large Code object. | 2162 // Allocates a large Code object. |
| 2167 Object* AllocateRawCode(int size_in_bytes); | 2163 Object* AllocateRawCode(int size_in_bytes); |
| 2168 // Allocates a large FixedArray. | 2164 // Allocates a large FixedArray. |
| 2169 Object* AllocateRawFixedArray(int size_in_bytes); | 2165 Object* AllocateRawFixedArray(int size_in_bytes); |
| 2170 | 2166 |
| 2171 // Available bytes for objects in this space. | 2167 // Available bytes for objects in this space. |
| 2172 intptr_t Available() { | 2168 int Available() { |
| 2173 return LargeObjectChunk::ObjectSizeFor(MemoryAllocator::Available()); | 2169 return LargeObjectChunk::ObjectSizeFor(MemoryAllocator::Available()); |
| 2174 } | 2170 } |
| 2175 | 2171 |
| 2176 virtual intptr_t Size() { | 2172 virtual int Size() { |
| 2177 return size_; | 2173 return size_; |
| 2178 } | 2174 } |
| 2179 | 2175 |
| 2180 int PageCount() { | 2176 int PageCount() { |
| 2181 return page_count_; | 2177 return page_count_; |
| 2182 } | 2178 } |
| 2183 | 2179 |
| 2184 // Finds an object for a given address, returns Failure::Exception() | 2180 // Finds an object for a given address, returns Failure::Exception() |
| 2185 // if it is not found. The function iterates through all objects in this | 2181 // if it is not found. The function iterates through all objects in this |
| 2186 // space, may be slow. | 2182 // space, may be slow. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2220 void ReportStatistics(); | 2216 void ReportStatistics(); |
| 2221 void CollectCodeStatistics(); | 2217 void CollectCodeStatistics(); |
| 2222 #endif | 2218 #endif |
| 2223 // Checks whether an address is in the object area in this space. It | 2219 // Checks whether an address is in the object area in this space. It |
| 2224 // iterates all objects in the space. May be slow. | 2220 // iterates all objects in the space. May be slow. |
| 2225 bool SlowContains(Address addr) { return !FindObject(addr)->IsFailure(); } | 2221 bool SlowContains(Address addr) { return !FindObject(addr)->IsFailure(); } |
| 2226 | 2222 |
| 2227 private: | 2223 private: |
| 2228 // The head of the linked list of large object chunks. | 2224 // The head of the linked list of large object chunks. |
| 2229 LargeObjectChunk* first_chunk_; | 2225 LargeObjectChunk* first_chunk_; |
| 2230 intptr_t size_; // allocated bytes | 2226 int size_; // allocated bytes |
| 2231 int page_count_; // number of chunks | 2227 int page_count_; // number of chunks |
| 2232 | 2228 |
| 2233 | 2229 |
| 2234 // Shared implementation of AllocateRaw, AllocateRawCode and | 2230 // Shared implementation of AllocateRaw, AllocateRawCode and |
| 2235 // AllocateRawFixedArray. | 2231 // AllocateRawFixedArray. |
| 2236 Object* AllocateRawInternal(int requested_size, | 2232 Object* AllocateRawInternal(int requested_size, |
| 2237 int object_size, | 2233 int object_size, |
| 2238 Executability executable); | 2234 Executability executable); |
| 2239 | 2235 |
| 2240 friend class LargeObjectIterator; | 2236 friend class LargeObjectIterator; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2256 | 2252 |
| 2257 private: | 2253 private: |
| 2258 LargeObjectChunk* current_; | 2254 LargeObjectChunk* current_; |
| 2259 HeapObjectCallback size_func_; | 2255 HeapObjectCallback size_func_; |
| 2260 }; | 2256 }; |
| 2261 | 2257 |
| 2262 | 2258 |
| 2263 } } // namespace v8::internal | 2259 } } // namespace v8::internal |
| 2264 | 2260 |
| 2265 #endif // V8_SPACES_H_ | 2261 #endif // V8_SPACES_H_ |
| OLD | NEW |