| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 class GCTracer; | 206 class GCTracer; |
| 207 class HeapStats; | 207 class HeapStats; |
| 208 | 208 |
| 209 | 209 |
| 210 typedef String* (*ExternalStringTableUpdaterCallback)(Object** pointer); | 210 typedef String* (*ExternalStringTableUpdaterCallback)(Object** pointer); |
| 211 | 211 |
| 212 typedef bool (*DirtyRegionCallback)(Address start, | 212 typedef bool (*DirtyRegionCallback)(Address start, |
| 213 Address end, | 213 Address end, |
| 214 ObjectSlotCallback copy_object_func); | 214 ObjectSlotCallback copy_object_func); |
| 215 | 215 |
| 216 enum RootsPartition { |
| 217 kStrongRootsList, |
| 218 kBootstrapperRoots, |
| 219 kTopRoots, |
| 220 kRelocatableRoots, |
| 221 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 222 kDebugRoots, |
| 223 #endif |
| 224 kCompilationCacheRoots, |
| 225 kHandleScopeRoots, |
| 226 kBuiltinsRoots, |
| 227 kGlobalHandlesRoots, |
| 228 kThreadManagerRoots, |
| 229 kSerializerDeserializerRoots, |
| 230 kNumberOfRootsPartitions |
| 231 }; |
| 232 |
| 233 class RootsPartitioner : public AllStatic { |
| 234 public: |
| 235 static bool Claim(RootsPartition partition) { |
| 236 return (partitions_state_[partition] == UNCLAIMED) && |
| 237 AtomicCompareAndSwap(&partitions_state_[partition], UNCLAIMED, CLAIMED); |
| 238 } |
| 239 |
| 240 static void Reset() { |
| 241 for (int i = 0; i < kNumberOfRootsPartitions; i++) { |
| 242 partitions_state_[i] = UNCLAIMED; |
| 243 } |
| 244 } |
| 245 |
| 246 private: |
| 247 static const Atomic32 CLAIMED = 0; |
| 248 static const Atomic32 UNCLAIMED = 1; |
| 249 |
| 250 static Atomic32 partitions_state_[kNumberOfRootsPartitions]; |
| 251 }; |
| 252 |
| 216 | 253 |
| 217 // The all static Heap captures the interface to the global object heap. | 254 // The all static Heap captures the interface to the global object heap. |
| 218 // All JavaScript contexts by this process share the same object heap. | 255 // All JavaScript contexts by this process share the same object heap. |
| 219 | 256 |
| 220 class Heap : public AllStatic { | 257 class Heap : public AllStatic { |
| 221 public: | 258 public: |
| 222 // Configure heap size before setup. Return false if the heap has been | 259 // Configure heap size before setup. Return false if the heap has been |
| 223 // setup already. | 260 // setup already. |
| 224 static bool ConfigureHeap(int max_semispace_size, int max_old_gen_size); | 261 static bool ConfigureHeap(int max_semispace_size, int max_old_gen_size); |
| 225 static bool ConfigureHeapDefault(); | 262 static bool ConfigureHeapDefault(); |
| (...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 764 #undef SYMBOL_ACCESSOR | 801 #undef SYMBOL_ACCESSOR |
| 765 | 802 |
| 766 // The hidden_symbol is special because it is the empty string, but does | 803 // The hidden_symbol is special because it is the empty string, but does |
| 767 // not match the empty string. | 804 // not match the empty string. |
| 768 static String* hidden_symbol() { return hidden_symbol_; } | 805 static String* hidden_symbol() { return hidden_symbol_; } |
| 769 | 806 |
| 770 // Iterates over all roots in the heap. | 807 // Iterates over all roots in the heap. |
| 771 static void IterateRoots(ObjectVisitor* v, VisitMode mode); | 808 static void IterateRoots(ObjectVisitor* v, VisitMode mode); |
| 772 // Iterates over all strong roots in the heap. | 809 // Iterates over all strong roots in the heap. |
| 773 static void IterateStrongRoots(ObjectVisitor* v, VisitMode mode); | 810 static void IterateStrongRoots(ObjectVisitor* v, VisitMode mode); |
| 811 |
| 812 static void ClaimAndIterateStrongRootsGroup(ObjectVisitor* v, |
| 813 VisitMode mode, |
| 814 RootsPartition partition); |
| 815 |
| 774 // Iterates over all the other roots in the heap. | 816 // Iterates over all the other roots in the heap. |
| 775 static void IterateWeakRoots(ObjectVisitor* v, VisitMode mode); | 817 static void IterateWeakRoots(ObjectVisitor* v, VisitMode mode); |
| 776 | 818 |
| 777 enum ExpectedPageWatermarkState { | 819 enum ExpectedPageWatermarkState { |
| 778 WATERMARK_SHOULD_BE_VALID, | 820 WATERMARK_SHOULD_BE_VALID, |
| 779 WATERMARK_CAN_BE_INVALID | 821 WATERMARK_CAN_BE_INVALID |
| 780 }; | 822 }; |
| 781 | 823 |
| 782 // For each dirty region on a page in use from an old space call | 824 // For each dirty region on a page in use from an old space call |
| 783 // visit_dirty_region callback. | 825 // visit_dirty_region callback. |
| (...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1652 struct Key { | 1694 struct Key { |
| 1653 DescriptorArray* array; | 1695 DescriptorArray* array; |
| 1654 String* name; | 1696 String* name; |
| 1655 }; | 1697 }; |
| 1656 | 1698 |
| 1657 static Key keys_[kLength]; | 1699 static Key keys_[kLength]; |
| 1658 static int results_[kLength]; | 1700 static int results_[kLength]; |
| 1659 }; | 1701 }; |
| 1660 | 1702 |
| 1661 | 1703 |
| 1662 // ---------------------------------------------------------------------------- | |
| 1663 // Marking stack for tracing live objects. | |
| 1664 | |
| 1665 class MarkingStack { | |
| 1666 public: | |
| 1667 void Initialize(Address low, Address high) { | |
| 1668 top_ = low_ = reinterpret_cast<HeapObject**>(low); | |
| 1669 high_ = reinterpret_cast<HeapObject**>(high); | |
| 1670 overflowed_ = false; | |
| 1671 } | |
| 1672 | |
| 1673 bool is_full() { return top_ >= high_; } | |
| 1674 | |
| 1675 bool is_empty() { return top_ <= low_; } | |
| 1676 | |
| 1677 bool overflowed() { return overflowed_; } | |
| 1678 | |
| 1679 void clear_overflowed() { overflowed_ = false; } | |
| 1680 | |
| 1681 // Push the (marked) object on the marking stack if there is room, | |
| 1682 // otherwise mark the object as overflowed and wait for a rescan of the | |
| 1683 // heap. | |
| 1684 void Push(HeapObject* object) { | |
| 1685 CHECK(object->IsHeapObject()); | |
| 1686 if (is_full()) { | |
| 1687 object->SetOverflow(); | |
| 1688 overflowed_ = true; | |
| 1689 } else { | |
| 1690 *(top_++) = object; | |
| 1691 } | |
| 1692 } | |
| 1693 | |
| 1694 HeapObject* Pop() { | |
| 1695 ASSERT(!is_empty()); | |
| 1696 HeapObject* object = *(--top_); | |
| 1697 CHECK(object->IsHeapObject()); | |
| 1698 return object; | |
| 1699 } | |
| 1700 | |
| 1701 private: | |
| 1702 HeapObject** low_; | |
| 1703 HeapObject** top_; | |
| 1704 HeapObject** high_; | |
| 1705 bool overflowed_; | |
| 1706 }; | |
| 1707 | |
| 1708 | |
| 1709 // A helper class to document/test C++ scopes where we do not | 1704 // A helper class to document/test C++ scopes where we do not |
| 1710 // expect a GC. Usage: | 1705 // expect a GC. Usage: |
| 1711 // | 1706 // |
| 1712 // /* Allocation not allowed: we cannot handle a GC in this scope. */ | 1707 // /* Allocation not allowed: we cannot handle a GC in this scope. */ |
| 1713 // { AssertNoAllocation nogc; | 1708 // { AssertNoAllocation nogc; |
| 1714 // ... | 1709 // ... |
| 1715 // } | 1710 // } |
| 1716 | 1711 |
| 1717 #ifdef DEBUG | 1712 #ifdef DEBUG |
| 1718 | 1713 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1816 // Sets the GC count. | 1811 // Sets the GC count. |
| 1817 void set_gc_count(int count) { gc_count_ = count; } | 1812 void set_gc_count(int count) { gc_count_ = count; } |
| 1818 | 1813 |
| 1819 // Sets the full GC count. | 1814 // Sets the full GC count. |
| 1820 void set_full_gc_count(int count) { full_gc_count_ = count; } | 1815 void set_full_gc_count(int count) { full_gc_count_ = count; } |
| 1821 | 1816 |
| 1822 // Sets the flag that this is a compacting full GC. | 1817 // Sets the flag that this is a compacting full GC. |
| 1823 void set_is_compacting() { is_compacting_ = true; } | 1818 void set_is_compacting() { is_compacting_ = true; } |
| 1824 bool is_compacting() const { return is_compacting_; } | 1819 bool is_compacting() const { return is_compacting_; } |
| 1825 | 1820 |
| 1821 #ifdef DEBUG |
| 1826 // Increment and decrement the count of marked objects. | 1822 // Increment and decrement the count of marked objects. |
| 1827 void increment_marked_count() { ++marked_count_; } | 1823 void increment_marked_count() { AtomicAdd(&marked_count_, 1); } |
| 1828 void decrement_marked_count() { --marked_count_; } | 1824 void decrement_marked_count() { --marked_count_; } |
| 1829 | 1825 |
| 1830 int marked_count() { return marked_count_; } | 1826 int marked_count() { return marked_count_; } |
| 1827 #endif |
| 1831 | 1828 |
| 1832 void increment_promoted_objects_size(int object_size) { | 1829 void increment_promoted_objects_size(int object_size) { |
| 1833 promoted_objects_size_ += object_size; | 1830 promoted_objects_size_ += object_size; |
| 1834 } | 1831 } |
| 1835 | 1832 |
| 1836 // Returns maximum GC pause. | 1833 // Returns maximum GC pause. |
| 1837 static int get_max_gc_pause() { return max_gc_pause_; } | 1834 static int get_max_gc_pause() { return max_gc_pause_; } |
| 1838 | 1835 |
| 1839 // Returns maximum size of objects alive after GC. | 1836 // Returns maximum size of objects alive after GC. |
| 1840 static intptr_t get_max_alive_after_gc() { return max_alive_after_gc_; } | 1837 static intptr_t get_max_alive_after_gc() { return max_alive_after_gc_; } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1863 int full_gc_count_; | 1860 int full_gc_count_; |
| 1864 | 1861 |
| 1865 // True if the current GC is a compacting full collection, false | 1862 // True if the current GC is a compacting full collection, false |
| 1866 // otherwise. | 1863 // otherwise. |
| 1867 bool is_compacting_; | 1864 bool is_compacting_; |
| 1868 | 1865 |
| 1869 // True if the *previous* full GC cwas a compacting collection (will be | 1866 // True if the *previous* full GC cwas a compacting collection (will be |
| 1870 // false if there has not been a previous full GC). | 1867 // false if there has not been a previous full GC). |
| 1871 bool previous_has_compacted_; | 1868 bool previous_has_compacted_; |
| 1872 | 1869 |
| 1870 #ifdef DEBUG |
| 1873 // On a full GC, a count of the number of marked objects. Incremented | 1871 // On a full GC, a count of the number of marked objects. Incremented |
| 1874 // when an object is marked and decremented when an object's mark bit is | 1872 // when an object is marked and decremented when an object's mark bit is |
| 1875 // cleared. Will be zero on a scavenge collection. | 1873 // cleared. Will be zero on a scavenge collection. |
| 1876 int marked_count_; | 1874 int marked_count_; |
| 1877 | 1875 #endif |
| 1878 // The count from the end of the previous full GC. Will be zero if there | |
| 1879 // was no previous full GC. | |
| 1880 int previous_marked_count_; | |
| 1881 | 1876 |
| 1882 // Amounts of time spent in different scopes during GC. | 1877 // Amounts of time spent in different scopes during GC. |
| 1883 double scopes_[Scope::kNumberOfScopes]; | 1878 double scopes_[Scope::kNumberOfScopes]; |
| 1884 | 1879 |
| 1885 // Total amount of space either wasted or contained in one of free lists | 1880 // Total amount of space either wasted or contained in one of free lists |
| 1886 // before the current GC. | 1881 // before the current GC. |
| 1887 intptr_t in_free_list_or_wasted_before_gc_; | 1882 intptr_t in_free_list_or_wasted_before_gc_; |
| 1888 | 1883 |
| 1889 // Difference between space used in the heap at the beginning of the current | 1884 // Difference between space used in the heap at the beginning of the current |
| 1890 // collection and the end of the previous collection. | 1885 // collection and the end of the previous collection. |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2039 | 2034 |
| 2040 // To speed up scavenge collections new space string are kept | 2035 // To speed up scavenge collections new space string are kept |
| 2041 // separate from old space strings. | 2036 // separate from old space strings. |
| 2042 static List<Object*> new_space_strings_; | 2037 static List<Object*> new_space_strings_; |
| 2043 static List<Object*> old_space_strings_; | 2038 static List<Object*> old_space_strings_; |
| 2044 }; | 2039 }; |
| 2045 | 2040 |
| 2046 } } // namespace v8::internal | 2041 } } // namespace v8::internal |
| 2047 | 2042 |
| 2048 #endif // V8_HEAP_H_ | 2043 #endif // V8_HEAP_H_ |
| OLD | NEW |