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 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1308 | 1308 |
1309 // Allocate a block of size 'size_in_bytes' from the free list. The block | 1309 // Allocate a block of size 'size_in_bytes' from the free list. The block |
1310 // is unitialized. A failure is returned if no block is available. The | 1310 // is unitialized. A failure is returned if no block is available. The |
1311 // number of bytes lost to fragmentation is returned in the output parameter | 1311 // number of bytes lost to fragmentation is returned in the output parameter |
1312 // 'wasted_bytes'. The size should be a non-zero multiple of the word size. | 1312 // 'wasted_bytes'. The size should be a non-zero multiple of the word size. |
1313 Object* Allocate(int size_in_bytes, int* wasted_bytes); | 1313 Object* Allocate(int size_in_bytes, int* wasted_bytes); |
1314 | 1314 |
1315 private: | 1315 private: |
1316 // The size range of blocks, in bytes. (Smaller allocations are allowed, but | 1316 // The size range of blocks, in bytes. (Smaller allocations are allowed, but |
1317 // will always result in waste.) | 1317 // will always result in waste.) |
1318 static const int kMinBlockSize = | 1318 static const int kMinBlockSize = 2 * kPointerSize; |
1319 POINTER_SIZE_ALIGN(ByteArray::kHeaderSize) + kPointerSize; | |
1320 static const int kMaxBlockSize = Page::kMaxHeapObjectSize; | 1319 static const int kMaxBlockSize = Page::kMaxHeapObjectSize; |
1321 | 1320 |
1322 // The identity of the owning space, for building allocation Failure | 1321 // The identity of the owning space, for building allocation Failure |
1323 // objects. | 1322 // objects. |
1324 AllocationSpace owner_; | 1323 AllocationSpace owner_; |
1325 | 1324 |
1326 // Total available bytes in all blocks on this free list. | 1325 // Total available bytes in all blocks on this free list. |
1327 int available_; | 1326 int available_; |
1328 | 1327 |
1329 // Blocks are put on exact free lists in an array, indexed by size in words. | 1328 // Blocks are put on exact free lists in an array, indexed by size in words. |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1384 #ifdef DEBUG | 1383 #ifdef DEBUG |
1385 // Does this free list contain a free block located at the address of 'node'? | 1384 // Does this free list contain a free block located at the address of 'node'? |
1386 bool Contains(FreeListNode* node); | 1385 bool Contains(FreeListNode* node); |
1387 #endif | 1386 #endif |
1388 | 1387 |
1389 DISALLOW_COPY_AND_ASSIGN(OldSpaceFreeList); | 1388 DISALLOW_COPY_AND_ASSIGN(OldSpaceFreeList); |
1390 }; | 1389 }; |
1391 | 1390 |
1392 | 1391 |
1393 // The free list for the map space. | 1392 // The free list for the map space. |
1394 class MapSpaceFreeList BASE_EMBEDDED { | 1393 class FixedSizeFreeList BASE_EMBEDDED { |
1395 public: | 1394 public: |
1396 explicit MapSpaceFreeList(AllocationSpace owner); | 1395 FixedSizeFreeList(AllocationSpace owner, int object_size); |
1397 | 1396 |
1398 // Clear the free list. | 1397 // Clear the free list. |
1399 void Reset(); | 1398 void Reset(); |
1400 | 1399 |
1401 // Return the number of bytes available on the free list. | 1400 // Return the number of bytes available on the free list. |
1402 int available() { return available_; } | 1401 int available() { return available_; } |
1403 | 1402 |
1404 // Place a node on the free list. The block starting at 'start' (assumed to | 1403 // Place a node on the free list. The block starting at 'start' (assumed to |
1405 // have size Map::kSize) is placed on the free list. Bookkeeping | 1404 // have size object_size_) is placed on the free list. Bookkeeping |
1406 // information will be written to the block, ie, its contents will be | 1405 // information will be written to the block, ie, its contents will be |
1407 // destroyed. The start address should be word aligned. | 1406 // destroyed. The start address should be word aligned. |
1408 void Free(Address start); | 1407 void Free(Address start); |
1409 | 1408 |
1410 // Allocate a map-sized block from the free list. The block is unitialized. | 1409 // Allocate a fixed sized block from the free list. The block is unitialized. |
1411 // A failure is returned if no block is available. | 1410 // A failure is returned if no block is available. |
1412 Object* Allocate(); | 1411 Object* Allocate(); |
1413 | 1412 |
1414 private: | 1413 private: |
1415 // Available bytes on the free list. | 1414 // Available bytes on the free list. |
1416 int available_; | 1415 int available_; |
1417 | 1416 |
1418 // The head of the free list. | 1417 // The head of the free list. |
1419 Address head_; | 1418 Address head_; |
1420 | 1419 |
1421 // The identity of the owning space, for building allocation Failure | 1420 // The identity of the owning space, for building allocation Failure |
1422 // objects. | 1421 // objects. |
1423 AllocationSpace owner_; | 1422 AllocationSpace owner_; |
1424 | 1423 |
1425 DISALLOW_COPY_AND_ASSIGN(MapSpaceFreeList); | 1424 // The size of the objects in this space. |
| 1425 int object_size_; |
| 1426 |
| 1427 DISALLOW_COPY_AND_ASSIGN(FixedSizeFreeList); |
1426 }; | 1428 }; |
1427 | 1429 |
1428 | 1430 |
1429 // ----------------------------------------------------------------------------- | 1431 // ----------------------------------------------------------------------------- |
1430 // Old object space (excluding map objects) | 1432 // Old object space (excluding map objects) |
1431 | 1433 |
1432 class OldSpace : public PagedSpace { | 1434 class OldSpace : public PagedSpace { |
1433 public: | 1435 public: |
1434 // Creates an old space object with a given maximum capacity. | 1436 // Creates an old space object with a given maximum capacity. |
1435 // The constructor does not allocate pages from OS. | 1437 // The constructor does not allocate pages from OS. |
(...skipping 17 matching lines...) Expand all Loading... |
1453 void Free(Address start, int size_in_bytes) { | 1455 void Free(Address start, int size_in_bytes) { |
1454 int wasted_bytes = free_list_.Free(start, size_in_bytes); | 1456 int wasted_bytes = free_list_.Free(start, size_in_bytes); |
1455 accounting_stats_.DeallocateBytes(size_in_bytes); | 1457 accounting_stats_.DeallocateBytes(size_in_bytes); |
1456 accounting_stats_.WasteBytes(wasted_bytes); | 1458 accounting_stats_.WasteBytes(wasted_bytes); |
1457 } | 1459 } |
1458 | 1460 |
1459 // Prepare for full garbage collection. Resets the relocation pointer and | 1461 // Prepare for full garbage collection. Resets the relocation pointer and |
1460 // clears the free list. | 1462 // clears the free list. |
1461 virtual void PrepareForMarkCompact(bool will_compact); | 1463 virtual void PrepareForMarkCompact(bool will_compact); |
1462 | 1464 |
1463 // Adjust the top of relocation pointer to point to the end of the object | |
1464 // given by 'address' and 'size_in_bytes'. Move it to the next page if | |
1465 // necessary, ensure that it points to the address, then increment it by the | |
1466 // size. | |
1467 void MCAdjustRelocationEnd(Address address, int size_in_bytes); | |
1468 | |
1469 // Updates the allocation pointer to the relocation top after a mark-compact | 1465 // Updates the allocation pointer to the relocation top after a mark-compact |
1470 // collection. | 1466 // collection. |
1471 virtual void MCCommitRelocationInfo(); | 1467 virtual void MCCommitRelocationInfo(); |
1472 | 1468 |
1473 #ifdef DEBUG | 1469 #ifdef DEBUG |
1474 // Verify integrity of this space. | 1470 // Verify integrity of this space. |
1475 virtual void Verify(); | 1471 virtual void Verify(); |
1476 | 1472 |
1477 // Reports statistics for the space | 1473 // Reports statistics for the space |
1478 void ReportStatistics(); | 1474 void ReportStatistics(); |
1479 // Dump the remembered sets in the space to stdout. | 1475 // Dump the remembered sets in the space to stdout. |
1480 void PrintRSet(); | 1476 void PrintRSet(); |
1481 #endif | 1477 #endif |
1482 | 1478 |
1483 protected: | 1479 protected: |
1484 // Virtual function in the superclass. Slow path of AllocateRaw. | 1480 // Virtual function in the superclass. Slow path of AllocateRaw. |
1485 HeapObject* SlowAllocateRaw(int size_in_bytes); | 1481 HeapObject* SlowAllocateRaw(int size_in_bytes); |
1486 | 1482 |
1487 // Virtual function in the superclass. Allocate linearly at the start of | 1483 // Virtual function in the superclass. Allocate linearly at the start of |
1488 // the page after current_page (there is assumed to be one). | 1484 // the page after current_page (there is assumed to be one). |
1489 HeapObject* AllocateInNextPage(Page* current_page, int size_in_bytes); | 1485 HeapObject* AllocateInNextPage(Page* current_page, int size_in_bytes); |
1490 | 1486 |
1491 private: | 1487 private: |
1492 // The space's free list. | 1488 // The space's free list. |
1493 OldSpaceFreeList free_list_; | 1489 OldSpaceFreeList free_list_; |
1494 | 1490 |
1495 // During relocation, we keep a pointer to the most recently relocated | |
1496 // object in order to know when to move to the next page. | |
1497 Address mc_end_of_relocation_; | |
1498 | |
1499 public: | 1491 public: |
1500 TRACK_MEMORY("OldSpace") | 1492 TRACK_MEMORY("OldSpace") |
1501 }; | 1493 }; |
1502 | 1494 |
1503 | 1495 |
1504 // ----------------------------------------------------------------------------- | 1496 // ----------------------------------------------------------------------------- |
1505 // Old space for all map objects | 1497 // Old space for objects of a fixed size |
1506 | 1498 |
1507 class MapSpace : public PagedSpace { | 1499 class FixedSpace : public PagedSpace { |
1508 public: | 1500 public: |
1509 // Creates a map space object with a maximum capacity. | 1501 FixedSpace(int max_capacity, |
1510 explicit MapSpace(int max_capacity, AllocationSpace id) | 1502 AllocationSpace id, |
1511 : PagedSpace(max_capacity, id, NOT_EXECUTABLE), free_list_(id) { } | 1503 int object_size_in_bytes, |
| 1504 const char* name) |
| 1505 : PagedSpace(max_capacity, id, NOT_EXECUTABLE), |
| 1506 object_size_in_bytes_(object_size_in_bytes), |
| 1507 name_(name), |
| 1508 free_list_(id, object_size_in_bytes), |
| 1509 page_extra_(Page::kObjectAreaSize % object_size_in_bytes) { } |
1512 | 1510 |
1513 // The top of allocation in a page in this space. Undefined if page is unused. | 1511 // The top of allocation in a page in this space. Undefined if page is unused. |
1514 virtual Address PageAllocationTop(Page* page) { | 1512 virtual Address PageAllocationTop(Page* page) { |
1515 return page == TopPageOf(allocation_info_) ? top() | 1513 return page == TopPageOf(allocation_info_) ? top() |
1516 : page->ObjectAreaEnd() - kPageExtra; | 1514 : page->ObjectAreaEnd() - page_extra_; |
1517 } | 1515 } |
1518 | 1516 |
1519 // Give a map-sized block of memory to the space's free list. | 1517 int object_size_in_bytes() { return object_size_in_bytes_; } |
| 1518 |
| 1519 // Give a fixed sized block of memory to the space's free list. |
1520 void Free(Address start) { | 1520 void Free(Address start) { |
1521 free_list_.Free(start); | 1521 free_list_.Free(start); |
1522 accounting_stats_.DeallocateBytes(Map::kSize); | 1522 accounting_stats_.DeallocateBytes(Map::kSize); |
1523 } | 1523 } |
1524 | 1524 |
1525 // Given an index, returns the page address. | |
1526 Address PageAddress(int page_index) { return page_addresses_[page_index]; } | |
1527 | |
1528 // Prepares for a mark-compact GC. | 1525 // Prepares for a mark-compact GC. |
1529 virtual void PrepareForMarkCompact(bool will_compact); | 1526 virtual void PrepareForMarkCompact(bool will_compact); |
1530 | 1527 |
1531 // Updates the allocation pointer to the relocation top after a mark-compact | 1528 // Updates the allocation pointer to the relocation top after a mark-compact |
1532 // collection. | 1529 // collection. |
1533 virtual void MCCommitRelocationInfo(); | 1530 virtual void MCCommitRelocationInfo(); |
1534 | 1531 |
1535 #ifdef DEBUG | 1532 #ifdef DEBUG |
1536 // Verify integrity of this space. | 1533 // Verify integrity of this space. |
1537 virtual void Verify(); | 1534 virtual void Verify(); |
1538 | 1535 |
| 1536 // Implement by subclasses to verify an actual object in the space. |
| 1537 virtual void VerifyObject(HeapObject* obj) = 0; |
| 1538 |
1539 // Reports statistic info of the space | 1539 // Reports statistic info of the space |
1540 void ReportStatistics(); | 1540 void ReportStatistics(); |
| 1541 |
1541 // Dump the remembered sets in the space to stdout. | 1542 // Dump the remembered sets in the space to stdout. |
1542 void PrintRSet(); | 1543 void PrintRSet(); |
1543 #endif | 1544 #endif |
1544 | 1545 |
1545 // Constants. | |
1546 static const int kMapPageIndexBits = 10; | |
1547 static const int kMaxMapPageIndex = (1 << kMapPageIndexBits) - 1; | |
1548 | |
1549 static const int kPageExtra = Page::kObjectAreaSize % Map::kSize; | |
1550 | |
1551 protected: | 1546 protected: |
1552 // Virtual function in the superclass. Slow path of AllocateRaw. | 1547 // Virtual function in the superclass. Slow path of AllocateRaw. |
1553 HeapObject* SlowAllocateRaw(int size_in_bytes); | 1548 HeapObject* SlowAllocateRaw(int size_in_bytes); |
1554 | 1549 |
1555 // Virtual function in the superclass. Allocate linearly at the start of | 1550 // Virtual function in the superclass. Allocate linearly at the start of |
1556 // the page after current_page (there is assumed to be one). | 1551 // the page after current_page (there is assumed to be one). |
1557 HeapObject* AllocateInNextPage(Page* current_page, int size_in_bytes); | 1552 HeapObject* AllocateInNextPage(Page* current_page, int size_in_bytes); |
1558 | 1553 |
1559 private: | 1554 private: |
| 1555 // The size of objects in this space. |
| 1556 int object_size_in_bytes_; |
| 1557 |
| 1558 // The name of this space. |
| 1559 const char* name_; |
| 1560 |
1560 // The space's free list. | 1561 // The space's free list. |
1561 MapSpaceFreeList free_list_; | 1562 FixedSizeFreeList free_list_; |
1562 | 1563 |
| 1564 // Bytes of each page that cannot be allocated. |
| 1565 int page_extra_; |
| 1566 }; |
| 1567 |
| 1568 |
| 1569 // ----------------------------------------------------------------------------- |
| 1570 // Old space for all map objects |
| 1571 |
| 1572 class MapSpace : public FixedSpace { |
| 1573 public: |
| 1574 // Creates a map space object with a maximum capacity. |
| 1575 MapSpace(int max_capacity, AllocationSpace id) |
| 1576 : FixedSpace(max_capacity, id, Map::kSize, "map") {} |
| 1577 |
| 1578 // Prepares for a mark-compact GC. |
| 1579 virtual void PrepareForMarkCompact(bool will_compact); |
| 1580 |
| 1581 // Given an index, returns the page address. |
| 1582 Address PageAddress(int page_index) { return page_addresses_[page_index]; } |
| 1583 |
| 1584 // Constants. |
| 1585 static const int kMaxMapPageIndex = (1 << MapWord::kMapPageIndexBits) - 1; |
| 1586 |
| 1587 protected: |
| 1588 #ifdef DEBUG |
| 1589 virtual void VerifyObject(HeapObject* obj); |
| 1590 #endif |
| 1591 |
| 1592 private: |
1563 // An array of page start address in a map space. | 1593 // An array of page start address in a map space. |
1564 Address page_addresses_[kMaxMapPageIndex + 1]; | 1594 Address page_addresses_[kMaxMapPageIndex + 1]; |
1565 | 1595 |
1566 public: | 1596 public: |
1567 TRACK_MEMORY("MapSpace") | 1597 TRACK_MEMORY("MapSpace") |
1568 }; | 1598 }; |
1569 | 1599 |
1570 | 1600 |
1571 // ----------------------------------------------------------------------------- | 1601 // ----------------------------------------------------------------------------- |
| 1602 // Old space for all global object property cell objects |
| 1603 |
| 1604 class CellSpace : public FixedSpace { |
| 1605 public: |
| 1606 // Creates a property cell space object with a maximum capacity. |
| 1607 CellSpace(int max_capacity, AllocationSpace id) |
| 1608 : FixedSpace(max_capacity, id, JSGlobalPropertyCell::kSize, "cell") {} |
| 1609 |
| 1610 protected: |
| 1611 #ifdef DEBUG |
| 1612 virtual void VerifyObject(HeapObject* obj); |
| 1613 #endif |
| 1614 |
| 1615 public: |
| 1616 TRACK_MEMORY("MapSpace") |
| 1617 }; |
| 1618 |
| 1619 |
| 1620 // ----------------------------------------------------------------------------- |
1572 // Large objects ( > Page::kMaxHeapObjectSize ) are allocated and managed by | 1621 // Large objects ( > Page::kMaxHeapObjectSize ) are allocated and managed by |
1573 // the large object space. A large object is allocated from OS heap with | 1622 // the large object space. A large object is allocated from OS heap with |
1574 // extra padding bytes (Page::kPageSize + Page::kObjectStartOffset). | 1623 // extra padding bytes (Page::kPageSize + Page::kObjectStartOffset). |
1575 // A large object always starts at Page::kObjectStartOffset to a page. | 1624 // A large object always starts at Page::kObjectStartOffset to a page. |
1576 // Large objects do not move during garbage collections. | 1625 // Large objects do not move during garbage collections. |
1577 | 1626 |
1578 // A LargeObjectChunk holds exactly one large object page with exactly one | 1627 // A LargeObjectChunk holds exactly one large object page with exactly one |
1579 // large object. | 1628 // large object. |
1580 class LargeObjectChunk { | 1629 class LargeObjectChunk { |
1581 public: | 1630 public: |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1741 | 1790 |
1742 private: | 1791 private: |
1743 LargeObjectChunk* current_; | 1792 LargeObjectChunk* current_; |
1744 HeapObjectCallback size_func_; | 1793 HeapObjectCallback size_func_; |
1745 }; | 1794 }; |
1746 | 1795 |
1747 | 1796 |
1748 } } // namespace v8::internal | 1797 } } // namespace v8::internal |
1749 | 1798 |
1750 #endif // V8_SPACES_H_ | 1799 #endif // V8_SPACES_H_ |
OLD | NEW |