| 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 return addr >= body() && addr < address() + size(); | 369 return addr >= body() && addr < address() + size(); |
| 370 } | 370 } |
| 371 | 371 |
| 372 enum MemoryChunkFlags { | 372 enum MemoryChunkFlags { |
| 373 IS_EXECUTABLE, | 373 IS_EXECUTABLE, |
| 374 WAS_SWEPT_CONSERVATIVELY, | 374 WAS_SWEPT_CONSERVATIVELY, |
| 375 CONTAINS_ONLY_DATA, | 375 CONTAINS_ONLY_DATA, |
| 376 POINTERS_TO_HERE_ARE_INTERESTING, | 376 POINTERS_TO_HERE_ARE_INTERESTING, |
| 377 POINTERS_FROM_HERE_ARE_INTERESTING, | 377 POINTERS_FROM_HERE_ARE_INTERESTING, |
| 378 SCAN_ON_SCAVENGE, | 378 SCAN_ON_SCAVENGE, |
| 379 IN_NEW_SPACE, | 379 IN_FROM_SPACE, // Mutually exclusive with IN_TO_SPACE. |
| 380 IN_TO_SPACE, // All pages in new space has one of these two set. |
| 380 NUM_MEMORY_CHUNK_FLAGS | 381 NUM_MEMORY_CHUNK_FLAGS |
| 381 }; | 382 }; |
| 382 | 383 |
| 383 void SetFlag(int flag) { | 384 void SetFlag(int flag) { |
| 384 flags_ |= 1 << flag; | 385 flags_ |= (1 << flag); |
| 385 } | 386 } |
| 386 | 387 |
| 387 void ClearFlag(int flag) { | 388 void ClearFlag(int flag) { |
| 388 flags_ &= ~(1 << flag); | 389 flags_ &= ~(1 << flag); |
| 389 } | 390 } |
| 390 | 391 |
| 392 void SetFlagTo(int flag, bool value) { |
| 393 if (value) { |
| 394 SetFlag(flag); |
| 395 } else { |
| 396 ClearFlag(flag); |
| 397 } |
| 398 } |
| 399 |
| 391 bool IsFlagSet(int flag) { | 400 bool IsFlagSet(int flag) { |
| 392 return (flags_ & (1 << flag)) != 0; | 401 return (flags_ & (1 << flag)) != 0; |
| 393 } | 402 } |
| 394 | 403 |
| 395 void CopyFlagsFrom(MemoryChunk* chunk) { | 404 // Set or clear multiple flags at a time. The flags in the mask |
| 396 flags_ = chunk->flags_; | 405 // are set to the value in "flags", the rest retain the current value |
| 406 // in flags_. |
| 407 void SetFlags(intptr_t flags, intptr_t mask) { |
| 408 flags_ = (flags_ & ~mask) | (flags & mask); |
| 397 } | 409 } |
| 398 | 410 |
| 411 // Return all current flags. |
| 412 intptr_t GetFlags() { return flags_; } |
| 413 |
| 399 static const intptr_t kAlignment = (1 << kPageSizeBits); | 414 static const intptr_t kAlignment = (1 << kPageSizeBits); |
| 400 | 415 |
| 401 static const intptr_t kAlignmentMask = kAlignment - 1; | 416 static const intptr_t kAlignmentMask = kAlignment - 1; |
| 402 | 417 |
| 403 static const size_t kHeaderSize = kPointerSize + kPointerSize + kPointerSize + | 418 static const size_t kHeaderSize = kPointerSize + kPointerSize + kPointerSize + |
| 404 kPointerSize + kPointerSize + kPointerSize + kPointerSize + kPointerSize; | 419 kPointerSize + kPointerSize + kPointerSize + kPointerSize + kPointerSize; |
| 405 | 420 |
| 406 static const int kBodyOffset = | 421 static const int kBodyOffset = |
| 407 CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize + Bitmap::kSize)); | 422 CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize + Bitmap::kSize)); |
| 408 | 423 |
| 409 // The start offset of the object area in a page. Aligned to both maps and | 424 // The start offset of the object area in a page. Aligned to both maps and |
| 410 // code alignment to be suitable for both. Also aligned to 32 words because | 425 // code alignment to be suitable for both. Also aligned to 32 words because |
| 411 // the marking bitmap is arranged in 32 bit chunks. | 426 // the marking bitmap is arranged in 32 bit chunks. |
| 412 static const int kObjectStartAlignment = 32 * kPointerSize; | 427 static const int kObjectStartAlignment = 32 * kPointerSize; |
| 413 static const int kObjectStartOffset = kBodyOffset - 1 + | 428 static const int kObjectStartOffset = kBodyOffset - 1 + |
| 414 (kObjectStartAlignment - (kBodyOffset - 1) % kObjectStartAlignment); | 429 (kObjectStartAlignment - (kBodyOffset - 1) % kObjectStartAlignment); |
| 415 | 430 |
| 416 size_t size() const { return size_; } | 431 size_t size() const { return size_; } |
| 417 | 432 |
| 418 Executability executable() { | 433 Executability executable() { |
| 419 return IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE; | 434 return IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE; |
| 420 } | 435 } |
| 421 | 436 |
| 422 bool ContainsOnlyData() { | 437 bool ContainsOnlyData() { |
| 423 return IsFlagSet(CONTAINS_ONLY_DATA); | 438 return IsFlagSet(CONTAINS_ONLY_DATA); |
| 424 } | 439 } |
| 425 | 440 |
| 426 bool InNewSpace() { | 441 bool InNewSpace() { |
| 427 return IsFlagSet(IN_NEW_SPACE); | 442 return (flags_ & ((1 << IN_FROM_SPACE) | (1 << IN_TO_SPACE))) != 0; |
| 443 } |
| 444 |
| 445 bool InToSpace() { |
| 446 return IsFlagSet(IN_TO_SPACE); |
| 447 } |
| 448 |
| 449 bool InFromSpace() { |
| 450 return IsFlagSet(IN_FROM_SPACE); |
| 428 } | 451 } |
| 429 | 452 |
| 430 // --------------------------------------------------------------------- | 453 // --------------------------------------------------------------------- |
| 431 // Markbits support | 454 // Markbits support |
| 432 | 455 |
| 433 inline Bitmap* markbits() { | 456 inline Bitmap* markbits() { |
| 434 return Bitmap::FromAddress(address() + kHeaderSize); | 457 return Bitmap::FromAddress(address() + kHeaderSize); |
| 435 } | 458 } |
| 436 | 459 |
| 437 void PrintMarkbits() { markbits()->Print(); } | 460 void PrintMarkbits() { markbits()->Print(); } |
| (...skipping 1001 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1439 | 1462 |
| 1440 const char* name() { return name_; } | 1463 const char* name() { return name_; } |
| 1441 void set_name(const char* name) { name_ = name; } | 1464 void set_name(const char* name) { name_ = name; } |
| 1442 | 1465 |
| 1443 private: | 1466 private: |
| 1444 const char* name_; | 1467 const char* name_; |
| 1445 }; | 1468 }; |
| 1446 #endif | 1469 #endif |
| 1447 | 1470 |
| 1448 | 1471 |
| 1472 enum SemiSpaceId { |
| 1473 kFromSpace = 0, |
| 1474 kToSpace = 1 |
| 1475 }; |
| 1476 |
| 1477 |
| 1449 class NewSpacePage : public MemoryChunk { | 1478 class NewSpacePage : public MemoryChunk { |
| 1450 public: | 1479 public: |
| 1480 // GC related flags copied from from-space to to-space when |
| 1481 // flipping semispaces. |
| 1482 static const intptr_t kCopyOnFlipFlagsMask = |
| 1483 (1 << MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING) | |
| 1484 (1 << MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING) | |
| 1485 (1 << MemoryChunk::SCAN_ON_SCAVENGE); |
| 1486 |
| 1451 inline NewSpacePage* next_page() const { | 1487 inline NewSpacePage* next_page() const { |
| 1452 return static_cast<NewSpacePage*>(next_chunk()); | 1488 return static_cast<NewSpacePage*>(next_chunk()); |
| 1453 } | 1489 } |
| 1454 | 1490 |
| 1455 inline void set_next_page(NewSpacePage* page) { | 1491 inline void set_next_page(NewSpacePage* page) { |
| 1456 set_next_chunk(page); | 1492 set_next_chunk(page); |
| 1457 } | 1493 } |
| 1458 private: | 1494 private: |
| 1459 // Finds the NewSpacePage containg the given address. | 1495 // Finds the NewSpacePage containg the given address. |
| 1460 static NewSpacePage* FromAddress(Address address_in_page) { | 1496 static NewSpacePage* FromAddress(Address address_in_page) { |
| 1461 Address page_start = | 1497 Address page_start = |
| 1462 reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address_in_page) & | 1498 reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address_in_page) & |
| 1463 ~Page::kPageAlignmentMask); | 1499 ~Page::kPageAlignmentMask); |
| 1464 return reinterpret_cast<NewSpacePage*>(page_start); | 1500 return reinterpret_cast<NewSpacePage*>(page_start); |
| 1465 } | 1501 } |
| 1466 | 1502 |
| 1467 static NewSpacePage* Initialize(Heap* heap, Address start); | 1503 static NewSpacePage* Initialize(Heap* heap, |
| 1504 Address start, |
| 1505 SemiSpaceId semispace); |
| 1468 | 1506 |
| 1469 friend class SemiSpace; | 1507 friend class SemiSpace; |
| 1470 friend class SemiSpaceIterator; | 1508 friend class SemiSpaceIterator; |
| 1471 }; | 1509 }; |
| 1472 | 1510 |
| 1473 | 1511 |
| 1474 // ----------------------------------------------------------------------------- | 1512 // ----------------------------------------------------------------------------- |
| 1475 // SemiSpace in young generation | 1513 // SemiSpace in young generation |
| 1476 // | 1514 // |
| 1477 // A semispace is a contiguous chunk of memory holding page-like memory | 1515 // A semispace is a contiguous chunk of memory holding page-like memory |
| 1478 // chunks. The mark-compact collector uses the memory of the first page in | 1516 // chunks. The mark-compact collector uses the memory of the first page in |
| 1479 // the from space as a marking stack when tracing live objects. | 1517 // the from space as a marking stack when tracing live objects. |
| 1480 | 1518 |
| 1481 class SemiSpace : public Space { | 1519 class SemiSpace : public Space { |
| 1482 public: | 1520 public: |
| 1483 // Constructor. | 1521 // Constructor. |
| 1484 explicit SemiSpace(Heap* heap) : Space(heap, NEW_SPACE, NOT_EXECUTABLE) { | 1522 SemiSpace(Heap* heap, SemiSpaceId semispace) |
| 1485 start_ = NULL; | 1523 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), |
| 1486 age_mark_ = NULL; | 1524 start_(NULL), |
| 1487 } | 1525 age_mark_(NULL), |
| 1526 id_(semispace) { } |
| 1488 | 1527 |
| 1489 // Sets up the semispace using the given chunk. | 1528 // Sets up the semispace using the given chunk. |
| 1490 bool Setup(Address start, int initial_capacity, int maximum_capacity); | 1529 bool Setup(Address start, int initial_capacity, int maximum_capacity); |
| 1491 | 1530 |
| 1492 // Tear down the space. Heap memory was not allocated by the space, so it | 1531 // Tear down the space. Heap memory was not allocated by the space, so it |
| 1493 // is not deallocated here. | 1532 // is not deallocated here. |
| 1494 void TearDown(); | 1533 void TearDown(); |
| 1495 | 1534 |
| 1496 // True if the space has been set up but not torn down. | 1535 // True if the space has been set up but not torn down. |
| 1497 bool HasBeenSetup() { return start_ != NULL; } | 1536 bool HasBeenSetup() { return start_ != NULL; } |
| 1498 | 1537 |
| 1499 // Grow the size of the semispace by committing extra virtual memory. | 1538 // Grow the size of the semispace by committing extra virtual memory. |
| 1500 // Assumes that the caller has checked that the semispace has not reached | 1539 // Assumes that the caller has checked that the semispace has not reached |
| 1501 // its maximum capacity (and thus there is space available in the reserved | 1540 // its maximum capacity (and thus there is space available in the reserved |
| 1502 // address range to grow). | 1541 // address range to grow). |
| 1503 bool Grow(); | 1542 bool Grow(); |
| 1504 | 1543 |
| 1505 // Grow the semispace to the new capacity. The new capacity | 1544 // Grow the semispace to the new capacity. The new capacity |
| 1506 // requested must be larger than the current capacity. | 1545 // requested must be larger than the current capacity. |
| 1507 bool GrowTo(int new_capacity); | 1546 bool GrowTo(int new_capacity); |
| 1508 | 1547 |
| 1509 // Shrinks the semispace to the new capacity. The new capacity | 1548 // Shrinks the semispace to the new capacity. The new capacity |
| 1510 // requested must be more than the amount of used memory in the | 1549 // requested must be more than the amount of used memory in the |
| 1511 // semispace and less than the current capacity. | 1550 // semispace and less than the current capacity. |
| 1512 bool ShrinkTo(int new_capacity); | 1551 bool ShrinkTo(int new_capacity); |
| 1513 | 1552 |
| 1553 // Flips the semispace between being from-space and to-space. |
| 1554 // Copies the flags into the masked positions on all pages in the space. |
| 1555 void Flip(intptr_t flags, intptr_t flag_mask); |
| 1556 |
| 1514 // Returns the start address of the space. | 1557 // Returns the start address of the space. |
| 1515 Address low() { | 1558 Address low() { |
| 1516 return NewSpacePage::FromAddress(start_)->body(); | 1559 return NewSpacePage::FromAddress(start_)->body(); |
| 1517 } | 1560 } |
| 1518 | 1561 |
| 1519 // Returns one past the end address of the space. | 1562 // Returns one past the end address of the space. |
| 1520 Address high() { | 1563 Address high() { |
| 1521 // TODO(gc): Change when there is more than one page. | 1564 // TODO(gc): Change when there is more than one page. |
| 1522 return current_page_->body() + current_page_->body_size(); | 1565 return current_page_->body() + current_page_->body_size(); |
| 1523 } | 1566 } |
| 1524 | 1567 |
| 1525 // Age mark accessors. | 1568 // Age mark accessors. |
| 1526 Address age_mark() { return age_mark_; } | 1569 Address age_mark() { return age_mark_; } |
| 1527 void set_age_mark(Address mark) { age_mark_ = mark; } | 1570 void set_age_mark(Address mark) { age_mark_ = mark; } |
| 1528 | 1571 |
| 1529 // True if the address is in the address range of this semispace (not | |
| 1530 // necessarily below the allocation pointer). | |
| 1531 bool Contains(Address a) { | |
| 1532 return (reinterpret_cast<uintptr_t>(a) & address_mask_) | |
| 1533 == reinterpret_cast<uintptr_t>(start_); | |
| 1534 } | |
| 1535 | |
| 1536 // True if the object is a heap object in the address range of this | |
| 1537 // semispace (not necessarily below the allocation pointer). | |
| 1538 bool Contains(Object* o) { | |
| 1539 return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_; | |
| 1540 } | |
| 1541 | |
| 1542 // The offset of an address from the beginning of the space. | 1572 // The offset of an address from the beginning of the space. |
| 1543 int SpaceOffsetForAddress(Address addr) { | 1573 int SpaceOffsetForAddress(Address addr) { |
| 1544 return static_cast<int>(addr - low()); | 1574 return static_cast<int>(addr - low()); |
| 1545 } | 1575 } |
| 1546 | 1576 |
| 1547 // If we don't have these here then SemiSpace will be abstract. However | 1577 // If we don't have these here then SemiSpace will be abstract. However |
| 1548 // they should never be called. | 1578 // they should never be called. |
| 1549 virtual intptr_t Size() { | 1579 virtual intptr_t Size() { |
| 1550 UNREACHABLE(); | 1580 UNREACHABLE(); |
| 1551 return 0; | 1581 return 0; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1593 Address start_; | 1623 Address start_; |
| 1594 // Used to govern object promotion during mark-compact collection. | 1624 // Used to govern object promotion during mark-compact collection. |
| 1595 Address age_mark_; | 1625 Address age_mark_; |
| 1596 | 1626 |
| 1597 // Masks and comparison values to test for containment in this semispace. | 1627 // Masks and comparison values to test for containment in this semispace. |
| 1598 uintptr_t address_mask_; | 1628 uintptr_t address_mask_; |
| 1599 uintptr_t object_mask_; | 1629 uintptr_t object_mask_; |
| 1600 uintptr_t object_expected_; | 1630 uintptr_t object_expected_; |
| 1601 | 1631 |
| 1602 bool committed_; | 1632 bool committed_; |
| 1633 SemiSpaceId id_; |
| 1603 | 1634 |
| 1604 NewSpacePage* current_page_; | 1635 NewSpacePage* current_page_; |
| 1605 | 1636 |
| 1606 public: | 1637 public: |
| 1607 TRACK_MEMORY("SemiSpace") | 1638 TRACK_MEMORY("SemiSpace") |
| 1608 }; | 1639 }; |
| 1609 | 1640 |
| 1610 | 1641 |
| 1611 // A SemiSpaceIterator is an ObjectIterator that iterates over the active | 1642 // A SemiSpaceIterator is an ObjectIterator that iterates over the active |
| 1612 // semispace of the heap's new space. It iterates over the objects in the | 1643 // semispace of the heap's new space. It iterates over the objects in the |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1661 // The young generation space. | 1692 // The young generation space. |
| 1662 // | 1693 // |
| 1663 // The new space consists of a contiguous pair of semispaces. It simply | 1694 // The new space consists of a contiguous pair of semispaces. It simply |
| 1664 // forwards most functions to the appropriate semispace. | 1695 // forwards most functions to the appropriate semispace. |
| 1665 | 1696 |
| 1666 class NewSpace : public Space { | 1697 class NewSpace : public Space { |
| 1667 public: | 1698 public: |
| 1668 // Constructor. | 1699 // Constructor. |
| 1669 explicit NewSpace(Heap* heap) | 1700 explicit NewSpace(Heap* heap) |
| 1670 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), | 1701 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), |
| 1671 to_space_(heap), | 1702 to_space_(heap, kToSpace), |
| 1672 from_space_(heap) {} | 1703 from_space_(heap, kFromSpace) {} |
| 1673 | 1704 |
| 1674 // Sets up the new space using the given chunk. | 1705 // Sets up the new space using the given chunk. |
| 1675 bool Setup(int max_semispace_size); | 1706 bool Setup(int max_semispace_size); |
| 1676 | 1707 |
| 1677 // Tears down the space. Heap memory was not allocated by the space, so it | 1708 // Tears down the space. Heap memory was not allocated by the space, so it |
| 1678 // is not deallocated here. | 1709 // is not deallocated here. |
| 1679 void TearDown(); | 1710 void TearDown(); |
| 1680 | 1711 |
| 1681 // True if the space has been set up but not torn down. | 1712 // True if the space has been set up but not torn down. |
| 1682 bool HasBeenSetup() { | 1713 bool HasBeenSetup() { |
| 1683 return to_space_.HasBeenSetup() && from_space_.HasBeenSetup(); | 1714 return to_space_.HasBeenSetup() && from_space_.HasBeenSetup(); |
| 1684 } | 1715 } |
| 1685 | 1716 |
| 1686 // Flip the pair of spaces. | 1717 // Flip the pair of spaces. |
| 1687 void Flip(); | 1718 void Flip(); |
| 1688 | 1719 |
| 1689 // Grow the capacity of the semispaces. Assumes that they are not at | 1720 // Grow the capacity of the semispaces. Assumes that they are not at |
| 1690 // their maximum capacity. | 1721 // their maximum capacity. |
| 1691 void Grow(); | 1722 void Grow(); |
| 1692 | 1723 |
| 1693 // Shrink the capacity of the semispaces. | 1724 // Shrink the capacity of the semispaces. |
| 1694 void Shrink(); | 1725 void Shrink(); |
| 1695 | 1726 |
| 1696 // True if the address or object lies in the address range of either | 1727 // True if the address or object lies in the address range of either |
| 1697 // semispace (not necessarily below the allocation pointer). | 1728 // semispace (not necessarily below the allocation pointer). |
| 1698 bool Contains(Address a) { | 1729 bool Contains(Address a) { |
| 1730 // TODO(gc): Replace by PageContains when we stop passing |
| 1731 // pointers to non-paged space. |
| 1699 return (reinterpret_cast<uintptr_t>(a) & address_mask_) | 1732 return (reinterpret_cast<uintptr_t>(a) & address_mask_) |
| 1700 == reinterpret_cast<uintptr_t>(start_); | 1733 == reinterpret_cast<uintptr_t>(start_); |
| 1701 } | 1734 } |
| 1702 | 1735 |
| 1703 // True if the address or object lies on a NewSpacePage. | 1736 // True if the address or object lies on a NewSpacePage. |
| 1704 // Must be a pointer into a heap page, and if it's a large object | 1737 // Must be a pointer into a heap page, and if it's a large object |
| 1705 // page, it must be a pointer into the beginning of it. | 1738 // page, it must be a pointer into the beginning of it. |
| 1706 // TODO(gc): When every call to Contains is converted to PageContains, | 1739 // TODO(gc): When every call to Contains is converted to PageContains, |
| 1707 // remove Contains and rename PageContains to Contains. | 1740 // remove Contains and rename PageContains to Contains. |
| 1708 bool PageContains(Address a) { | 1741 bool PageContains(Address a) { |
| 1709 if ((reinterpret_cast<intptr_t>(a) & ~kHeapObjectTagMask) == | 1742 MemoryChunk* page = MemoryChunk::FromAddress(a); |
| 1710 static_cast<intptr_t>(0)) { | 1743 // Tagged zero-page pointers are not real heap pointers. |
| 1711 // Tagged zero-page pointers are not real heap pointers. | 1744 // TODO(gc): Remove when we no longer have tagged zero-page |
| 1712 // TODO(gc): Remove when we no longer have tagged zero-page | 1745 // pointers intermingled with real heap object pointers. |
| 1713 // pointers intermingled with real heap object pointers. | 1746 if (!page->is_valid()) return false; |
| 1714 return false; | 1747 return page->InNewSpace(); |
| 1715 } | |
| 1716 return MemoryChunk::FromAddress(a)->InNewSpace(); | |
| 1717 } | 1748 } |
| 1718 | 1749 |
| 1719 bool Contains(Object* o) { | 1750 bool Contains(Object* o) { |
| 1720 return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_; | |
| 1721 } | |
| 1722 | |
| 1723 bool PageContains(Object* o) { | |
| 1724 if (o->IsSmi()) return false; | 1751 if (o->IsSmi()) return false; |
| 1725 if ((reinterpret_cast<uintptr_t>(o) & ~kHeapObjectTagMask) == | 1752 Address a = reinterpret_cast<Address>(o); |
| 1726 static_cast<uintptr_t>(0)) { | 1753 MemoryChunk* page = MemoryChunk::FromAddress(a); |
| 1727 // Tagged zero-page pointers are not real heap pointers. | 1754 if (!page->is_valid()) return false; |
| 1728 // TODO(gc): Remove when we no longer have tagged zero-page | 1755 return page->InNewSpace(); |
| 1729 // pointers intermingled with real heap object pointers. | |
| 1730 return false; | |
| 1731 } | |
| 1732 Address a = HeapObject::cast(o)->address(); | |
| 1733 return MemoryChunk::FromAddress(a)->InNewSpace(); | |
| 1734 } | 1756 } |
| 1735 | 1757 |
| 1736 // Return the allocated bytes in the active semispace. | 1758 // Return the allocated bytes in the active semispace. |
| 1737 virtual intptr_t Size() { return static_cast<int>(top() - bottom()); } | 1759 virtual intptr_t Size() { return static_cast<int>(top() - bottom()); } |
| 1738 // The same, but returning an int. We have to have the one that returns | 1760 // The same, but returning an int. We have to have the one that returns |
| 1739 // intptr_t because it is inherited, but if we know we are dealing with the | 1761 // intptr_t because it is inherited, but if we know we are dealing with the |
| 1740 // new space, which can't get as big as the other spaces then this is useful: | 1762 // new space, which can't get as big as the other spaces then this is useful: |
| 1741 int SizeAsInt() { return static_cast<int>(Size()); } | 1763 int SizeAsInt() { return static_cast<int>(Size()); } |
| 1742 | 1764 |
| 1743 // Return the current capacity of a semispace. | 1765 // Return the current capacity of a semispace. |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1826 Address ToSpaceHigh() { return to_space_.high(); } | 1848 Address ToSpaceHigh() { return to_space_.high(); } |
| 1827 | 1849 |
| 1828 // Offsets from the beginning of the semispaces. | 1850 // Offsets from the beginning of the semispaces. |
| 1829 int ToSpaceOffsetForAddress(Address a) { | 1851 int ToSpaceOffsetForAddress(Address a) { |
| 1830 return to_space_.SpaceOffsetForAddress(a); | 1852 return to_space_.SpaceOffsetForAddress(a); |
| 1831 } | 1853 } |
| 1832 int FromSpaceOffsetForAddress(Address a) { | 1854 int FromSpaceOffsetForAddress(Address a) { |
| 1833 return from_space_.SpaceOffsetForAddress(a); | 1855 return from_space_.SpaceOffsetForAddress(a); |
| 1834 } | 1856 } |
| 1835 | 1857 |
| 1858 inline bool ToSpaceContains(Address address) { |
| 1859 MemoryChunk* page = MemoryChunk::FromAddress(address); |
| 1860 return page->is_valid() && page->InToSpace(); |
| 1861 } |
| 1862 |
| 1863 inline bool FromSpaceContains(Address address) { |
| 1864 MemoryChunk* page = MemoryChunk::FromAddress(address); |
| 1865 return page->is_valid() && page->InFromSpace(); |
| 1866 } |
| 1867 |
| 1836 // True if the object is a heap object in the address range of the | 1868 // True if the object is a heap object in the address range of the |
| 1837 // respective semispace (not necessarily below the allocation pointer of the | 1869 // respective semispace (not necessarily below the allocation pointer of the |
| 1838 // semispace). | 1870 // semispace). |
| 1839 bool ToSpaceContains(Object* o) { return to_space_.Contains(o); } | 1871 bool ToSpaceContains(Object* o) { |
| 1840 bool FromSpaceContains(Object* o) { return from_space_.Contains(o); } | 1872 if (o->IsSmi()) return false; |
| 1873 Address address = reinterpret_cast<Address>(o); |
| 1874 return ToSpaceContains(address); |
| 1875 } |
| 1841 | 1876 |
| 1842 bool ToSpaceContains(Address a) { return to_space_.Contains(a); } | 1877 bool FromSpaceContains(Object* o) { |
| 1843 bool FromSpaceContains(Address a) { return from_space_.Contains(a); } | 1878 if (o->IsSmi()) return false; |
| 1879 Address address = reinterpret_cast<Address>(o); |
| 1880 return FromSpaceContains(address); |
| 1881 } |
| 1844 | 1882 |
| 1845 virtual bool ReserveSpace(int bytes); | 1883 virtual bool ReserveSpace(int bytes); |
| 1846 | 1884 |
| 1847 // Resizes a sequential string which must be the most recent thing that was | 1885 // Resizes a sequential string which must be the most recent thing that was |
| 1848 // allocated in new space. | 1886 // allocated in new space. |
| 1849 template <typename StringType> | 1887 template <typename StringType> |
| 1850 inline void ShrinkStringAtAllocationBoundary(String* string, int len); | 1888 inline void ShrinkStringAtAllocationBoundary(String* string, int len); |
| 1851 | 1889 |
| 1852 #ifdef ENABLE_HEAP_PROTECTION | 1890 #ifdef ENABLE_HEAP_PROTECTION |
| 1853 // Protect/unprotect the space by marking it read-only/writable. | 1891 // Protect/unprotect the space by marking it read-only/writable. |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2289 } | 2327 } |
| 2290 // Must be small, since an iteration is used for lookup. | 2328 // Must be small, since an iteration is used for lookup. |
| 2291 static const int kMaxComments = 64; | 2329 static const int kMaxComments = 64; |
| 2292 }; | 2330 }; |
| 2293 #endif | 2331 #endif |
| 2294 | 2332 |
| 2295 | 2333 |
| 2296 } } // namespace v8::internal | 2334 } } // namespace v8::internal |
| 2297 | 2335 |
| 2298 #endif // V8_SPACES_H_ | 2336 #endif // V8_SPACES_H_ |
| OLD | NEW |