Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 369 } | 369 } |
| 370 | 370 |
| 371 enum MemoryChunkFlags { | 371 enum MemoryChunkFlags { |
| 372 IS_EXECUTABLE, | 372 IS_EXECUTABLE, |
| 373 WAS_SWEPT_CONSERVATIVELY, | 373 WAS_SWEPT_CONSERVATIVELY, |
| 374 CONTAINS_ONLY_DATA, | 374 CONTAINS_ONLY_DATA, |
| 375 POINTERS_TO_HERE_ARE_INTERESTING, | 375 POINTERS_TO_HERE_ARE_INTERESTING, |
| 376 POINTERS_FROM_HERE_ARE_INTERESTING, | 376 POINTERS_FROM_HERE_ARE_INTERESTING, |
| 377 SCAN_ON_SCAVENGE, | 377 SCAN_ON_SCAVENGE, |
| 378 IN_NEW_SPACE, | 378 IN_NEW_SPACE, |
| 379 SEMI_SPACE_TAG, | |
| 379 NUM_MEMORY_CHUNK_FLAGS | 380 NUM_MEMORY_CHUNK_FLAGS |
| 380 }; | 381 }; |
| 381 | 382 |
| 382 void SetFlag(int flag) { | 383 void SetFlag(int flag) { |
| 383 flags_ |= 1 << flag; | 384 flags_ |= 1 << flag; |
| 384 } | 385 } |
| 385 | 386 |
| 386 void ClearFlag(int flag) { | 387 void ClearFlag(int flag) { |
| 387 flags_ &= ~(1 << flag); | 388 flags_ &= ~(1 << flag); |
| 388 } | 389 } |
| 389 | 390 |
| 390 bool IsFlagSet(int flag) { | 391 bool IsFlagSet(int flag) { |
| 391 return (flags_ & (1 << flag)) != 0; | 392 return (flags_ & (1 << flag)) != 0; |
| 392 } | 393 } |
| 393 | 394 |
| 394 void CopyFlagsFrom(MemoryChunk* chunk) { | |
| 395 flags_ = chunk->flags_; | |
| 396 } | |
| 397 | |
| 398 static const intptr_t kAlignment = (1 << kPageSizeBits); | 395 static const intptr_t kAlignment = (1 << kPageSizeBits); |
| 399 | 396 |
| 400 static const intptr_t kAlignmentMask = kAlignment - 1; | 397 static const intptr_t kAlignmentMask = kAlignment - 1; |
| 401 | 398 |
| 402 static const size_t kHeaderSize = kPointerSize + kPointerSize + kPointerSize + | 399 static const size_t kHeaderSize = kPointerSize + kPointerSize + kPointerSize + |
| 403 kPointerSize + kPointerSize + kPointerSize + kPointerSize + kPointerSize; | 400 kPointerSize + kPointerSize + kPointerSize + kPointerSize + kPointerSize; |
| 404 | 401 |
| 405 static const int kBodyOffset = | 402 static const int kBodyOffset = |
| 406 CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize + Bitmap::kSize)); | 403 CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize + Bitmap::kSize)); |
| 407 | 404 |
| (...skipping 1029 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1437 HistogramInfo() : NumberAndSizeInfo() {} | 1434 HistogramInfo() : NumberAndSizeInfo() {} |
| 1438 | 1435 |
| 1439 const char* name() { return name_; } | 1436 const char* name() { return name_; } |
| 1440 void set_name(const char* name) { name_ = name; } | 1437 void set_name(const char* name) { name_ = name; } |
| 1441 | 1438 |
| 1442 private: | 1439 private: |
| 1443 const char* name_; | 1440 const char* name_; |
| 1444 }; | 1441 }; |
| 1445 #endif | 1442 #endif |
| 1446 | 1443 |
| 1444 // Give numbers to semispaces, so we can see which semispace a newspace | |
| 1445 // page belongs to. | |
| 1446 enum SemiSpaceId { | |
| 1447 kFirstSemiSpace, | |
| 1448 kSecondSemiSpace | |
| 1449 }; | |
| 1450 | |
| 1447 | 1451 |
| 1448 class NewSpacePage : public MemoryChunk { | 1452 class NewSpacePage : public MemoryChunk { |
| 1449 public: | 1453 public: |
| 1450 inline NewSpacePage* next_page() const { | 1454 inline NewSpacePage* next_page() const { |
| 1451 return static_cast<NewSpacePage*>(next_chunk()); | 1455 return static_cast<NewSpacePage*>(next_chunk()); |
| 1452 } | 1456 } |
| 1453 | 1457 |
| 1454 inline void set_next_page(NewSpacePage* page) { | 1458 inline void set_next_page(NewSpacePage* page) { |
| 1455 set_next_chunk(page); | 1459 set_next_chunk(page); |
| 1456 } | 1460 } |
| 1461 | |
| 1462 static NewSpacePage* cast(MemoryChunk* page) { | |
| 1463 ASSERT(page->IsFlagSet(MemoryChunk::IN_NEW_SPACE)); | |
| 1464 return reinterpret_cast<NewSpacePage*>(page); | |
| 1465 } | |
| 1466 | |
| 1467 SemiSpaceId GetSemiSpaceId() { | |
| 1468 return IsFlagSet(MemoryChunk::SEMI_SPACE_TAG) ? kSecondSemiSpace | |
| 1469 : kFirstSemiSpace; | |
| 1470 } | |
| 1471 | |
| 1472 void CopyFlagsFrom(NewSpacePage* chunk) { | |
|
Erik Corry
2011/05/23 12:58:56
This is called CopyFlagsFrom, but it only copies o
| |
| 1473 intptr_t semi_space_mask = 1 << MemoryChunk::SEMI_SPACE_TAG; | |
| 1474 flags_ = (flags_ & semi_space_mask) | (chunk->flags_ & ~(semi_space_mask)); | |
| 1475 } | |
| 1476 | |
| 1477 | |
| 1457 private: | 1478 private: |
| 1458 // Finds the NewSpacePage containg the given address. | 1479 // Finds the NewSpacePage containg the given address. |
| 1459 static NewSpacePage* FromAddress(Address address_in_page) { | 1480 static NewSpacePage* FromAddress(Address address_in_page) { |
| 1460 Address page_start = | 1481 Address page_start = |
| 1461 reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address_in_page) & | 1482 reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address_in_page) & |
| 1462 ~Page::kPageAlignmentMask); | 1483 ~Page::kPageAlignmentMask); |
| 1463 return reinterpret_cast<NewSpacePage*>(page_start); | 1484 return reinterpret_cast<NewSpacePage*>(page_start); |
| 1464 } | 1485 } |
| 1465 | 1486 |
| 1466 static NewSpacePage* Initialize(Heap* heap, Address start); | 1487 static NewSpacePage* Initialize(Heap* heap, Address start, SemiSpaceId id); |
| 1467 | 1488 |
| 1468 friend class SemiSpace; | 1489 friend class SemiSpace; |
| 1469 friend class SemiSpaceIterator; | 1490 friend class SemiSpaceIterator; |
| 1470 }; | 1491 }; |
| 1471 | 1492 |
| 1472 | 1493 |
| 1473 // ----------------------------------------------------------------------------- | 1494 // ----------------------------------------------------------------------------- |
| 1474 // SemiSpace in young generation | 1495 // SemiSpace in young generation |
| 1475 // | 1496 // |
| 1476 // A semispace is a contiguous chunk of memory holding page-like memory | 1497 // A semispace is a contiguous chunk of memory holding page-like memory |
| 1477 // chunks. The mark-compact collector uses the memory of the first page in | 1498 // chunks. The mark-compact collector uses the memory of the first page in |
| 1478 // the from space as a marking stack when tracing live objects. | 1499 // the from space as a marking stack when tracing live objects. |
| 1479 | 1500 |
| 1480 class SemiSpace : public Space { | 1501 class SemiSpace : public Space { |
| 1481 public: | 1502 public: |
| 1482 // Constructor. | 1503 // Constructor. |
| 1483 explicit SemiSpace(Heap* heap) : Space(heap, NEW_SPACE, NOT_EXECUTABLE) { | 1504 SemiSpace(Heap* heap, SemiSpaceId id) |
| 1484 start_ = NULL; | 1505 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), |
| 1485 age_mark_ = NULL; | 1506 start_(NULL), |
| 1486 } | 1507 age_mark_(NULL), |
| 1508 id_(id) { } | |
| 1487 | 1509 |
| 1488 // Sets up the semispace using the given chunk. | 1510 // Sets up the semispace using the given chunk. |
| 1489 bool Setup(Address start, int initial_capacity, int maximum_capacity); | 1511 bool Setup(Address start, int initial_capacity, int maximum_capacity); |
| 1490 | 1512 |
| 1491 // Tear down the space. Heap memory was not allocated by the space, so it | 1513 // Tear down the space. Heap memory was not allocated by the space, so it |
| 1492 // is not deallocated here. | 1514 // is not deallocated here. |
| 1493 void TearDown(); | 1515 void TearDown(); |
| 1494 | 1516 |
| 1495 // True if the space has been set up but not torn down. | 1517 // True if the space has been set up but not torn down. |
| 1496 bool HasBeenSetup() { return start_ != NULL; } | 1518 bool HasBeenSetup() { return start_ != NULL; } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1528 // True if the address is in the address range of this semispace (not | 1550 // True if the address is in the address range of this semispace (not |
| 1529 // necessarily below the allocation pointer). | 1551 // necessarily below the allocation pointer). |
| 1530 bool Contains(Address a) { | 1552 bool Contains(Address a) { |
| 1531 return (reinterpret_cast<uintptr_t>(a) & address_mask_) | 1553 return (reinterpret_cast<uintptr_t>(a) & address_mask_) |
| 1532 == reinterpret_cast<uintptr_t>(start_); | 1554 == reinterpret_cast<uintptr_t>(start_); |
| 1533 } | 1555 } |
| 1534 | 1556 |
| 1535 // True if the object is a heap object in the address range of this | 1557 // True if the object is a heap object in the address range of this |
| 1536 // semispace (not necessarily below the allocation pointer). | 1558 // semispace (not necessarily below the allocation pointer). |
| 1537 bool Contains(Object* o) { | 1559 bool Contains(Object* o) { |
| 1538 return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_; | 1560 if (o->IsSmi()) { |
|
Erik Corry
2011/05/23 12:58:56
this is SemiSpace::Contains(), but I think what we
Lasse Reichstein
2011/05/24 10:53:42
Will do.
That also means that the CopyFlagsFrom f
| |
| 1561 return false; | |
| 1562 } | |
| 1563 if ((reinterpret_cast<uintptr_t>(o) & ~kHeapObjectTagMask) == 0u) { | |
| 1564 // A heap-object tagged NULL pointer. | |
| 1565 return false; | |
| 1566 } | |
| 1567 MemoryChunk* page = | |
| 1568 MemoryChunk::FromAddress(HeapObject::cast(o)->address()); | |
| 1569 return (page->InNewSpace() && | |
| 1570 NewSpacePage::cast(page)->GetSemiSpaceId() == id_); | |
| 1539 } | 1571 } |
| 1540 | 1572 |
| 1541 // The offset of an address from the beginning of the space. | 1573 // The offset of an address from the beginning of the space. |
| 1542 int SpaceOffsetForAddress(Address addr) { | 1574 int SpaceOffsetForAddress(Address addr) { |
| 1543 return static_cast<int>(addr - low()); | 1575 return static_cast<int>(addr - low()); |
| 1544 } | 1576 } |
| 1545 | 1577 |
| 1546 // If we don't have these here then SemiSpace will be abstract. However | 1578 // If we don't have these here then SemiSpace will be abstract. However |
| 1547 // they should never be called. | 1579 // they should never be called. |
| 1548 virtual intptr_t Size() { | 1580 virtual intptr_t Size() { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1593 // Used to govern object promotion during mark-compact collection. | 1625 // Used to govern object promotion during mark-compact collection. |
| 1594 Address age_mark_; | 1626 Address age_mark_; |
| 1595 | 1627 |
| 1596 // Masks and comparison values to test for containment in this semispace. | 1628 // Masks and comparison values to test for containment in this semispace. |
| 1597 uintptr_t address_mask_; | 1629 uintptr_t address_mask_; |
| 1598 uintptr_t object_mask_; | 1630 uintptr_t object_mask_; |
| 1599 uintptr_t object_expected_; | 1631 uintptr_t object_expected_; |
| 1600 | 1632 |
| 1601 bool committed_; | 1633 bool committed_; |
| 1602 | 1634 |
| 1635 SemiSpaceId id_; | |
| 1603 NewSpacePage* current_page_; | 1636 NewSpacePage* current_page_; |
| 1604 | 1637 |
| 1605 public: | 1638 public: |
| 1606 TRACK_MEMORY("SemiSpace") | 1639 TRACK_MEMORY("SemiSpace") |
| 1607 }; | 1640 }; |
| 1608 | 1641 |
| 1609 | 1642 |
| 1610 // A SemiSpaceIterator is an ObjectIterator that iterates over the active | 1643 // A SemiSpaceIterator is an ObjectIterator that iterates over the active |
| 1611 // semispace of the heap's new space. It iterates over the objects in the | 1644 // semispace of the heap's new space. It iterates over the objects in the |
| 1612 // semispace from a given start address (defaulting to the bottom of the | 1645 // semispace from a given start address (defaulting to the bottom of the |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1660 // The young generation space. | 1693 // The young generation space. |
| 1661 // | 1694 // |
| 1662 // The new space consists of a contiguous pair of semispaces. It simply | 1695 // The new space consists of a contiguous pair of semispaces. It simply |
| 1663 // forwards most functions to the appropriate semispace. | 1696 // forwards most functions to the appropriate semispace. |
| 1664 | 1697 |
| 1665 class NewSpace : public Space { | 1698 class NewSpace : public Space { |
| 1666 public: | 1699 public: |
| 1667 // Constructor. | 1700 // Constructor. |
| 1668 explicit NewSpace(Heap* heap) | 1701 explicit NewSpace(Heap* heap) |
| 1669 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), | 1702 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), |
| 1670 to_space_(heap), | 1703 to_space_(heap, kFirstSemiSpace), |
| 1671 from_space_(heap) {} | 1704 from_space_(heap, kSecondSemiSpace) {} |
| 1672 | 1705 |
| 1673 // Sets up the new space using the given chunk. | 1706 // Sets up the new space using the given chunk. |
| 1674 bool Setup(int max_semispace_size); | 1707 bool Setup(int max_semispace_size); |
| 1675 | 1708 |
| 1676 // Tears down the space. Heap memory was not allocated by the space, so it | 1709 // Tears down the space. Heap memory was not allocated by the space, so it |
| 1677 // is not deallocated here. | 1710 // is not deallocated here. |
| 1678 void TearDown(); | 1711 void TearDown(); |
| 1679 | 1712 |
| 1680 // True if the space has been set up but not torn down. | 1713 // True if the space has been set up but not torn down. |
| 1681 bool HasBeenSetup() { | 1714 bool HasBeenSetup() { |
| (...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2288 } | 2321 } |
| 2289 // Must be small, since an iteration is used for lookup. | 2322 // Must be small, since an iteration is used for lookup. |
| 2290 static const int kMaxComments = 64; | 2323 static const int kMaxComments = 64; |
| 2291 }; | 2324 }; |
| 2292 #endif | 2325 #endif |
| 2293 | 2326 |
| 2294 | 2327 |
| 2295 } } // namespace v8::internal | 2328 } } // namespace v8::internal |
| 2296 | 2329 |
| 2297 #endif // V8_SPACES_H_ | 2330 #endif // V8_SPACES_H_ |
| OLD | NEW |