| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_HEAP_HEAP_H_ | 5 #ifndef V8_HEAP_HEAP_H_ |
| 6 #define V8_HEAP_HEAP_H_ | 6 #define V8_HEAP_HEAP_H_ |
| 7 | 7 |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <map> | 9 #include <map> |
| 10 | 10 |
| (...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 888 void RemoveGCPrologueCallback(v8::Isolate::GCPrologueCallback callback); | 888 void RemoveGCPrologueCallback(v8::Isolate::GCPrologueCallback callback); |
| 889 | 889 |
| 890 void AddGCEpilogueCallback(v8::Isolate::GCEpilogueCallback callback, | 890 void AddGCEpilogueCallback(v8::Isolate::GCEpilogueCallback callback, |
| 891 GCType gc_type_filter, bool pass_isolate = true); | 891 GCType gc_type_filter, bool pass_isolate = true); |
| 892 void RemoveGCEpilogueCallback(v8::Isolate::GCEpilogueCallback callback); | 892 void RemoveGCEpilogueCallback(v8::Isolate::GCEpilogueCallback callback); |
| 893 | 893 |
| 894 // Heap root getters. We have versions with and without type::cast() here. | 894 // Heap root getters. We have versions with and without type::cast() here. |
| 895 // You can't use type::cast during GC because the assert fails. | 895 // You can't use type::cast during GC because the assert fails. |
| 896 // TODO(1490): Try removing the unchecked accessors, now that GC marking does | 896 // TODO(1490): Try removing the unchecked accessors, now that GC marking does |
| 897 // not corrupt the map. | 897 // not corrupt the map. |
| 898 #define ROOT_ACCESSOR(type, name, camel_name) \ | 898 #define ROOT_ACCESSOR(type, name, camel_name) \ |
| 899 type* name() { return type::cast(roots_[k##camel_name##RootIndex]); } \ | 899 inline type* name(); \ |
| 900 type* raw_unchecked_##name() { \ | 900 type* raw_unchecked_##name() { \ |
| 901 return reinterpret_cast<type*>(roots_[k##camel_name##RootIndex]); \ | 901 return reinterpret_cast<type*>(roots_[k##camel_name##RootIndex]); \ |
| 902 } | 902 } |
| 903 ROOT_LIST(ROOT_ACCESSOR) | 903 ROOT_LIST(ROOT_ACCESSOR) |
| 904 #undef ROOT_ACCESSOR | 904 #undef ROOT_ACCESSOR |
| 905 | 905 |
| 906 // Utility type maps | 906 // Utility type maps |
| 907 #define STRUCT_MAP_ACCESSOR(NAME, Name, name) \ | 907 #define STRUCT_MAP_ACCESSOR(NAME, Name, name) inline Map* name##_map(); |
| 908 Map* name##_map() { return Map::cast(roots_[k##Name##MapRootIndex]); } | |
| 909 STRUCT_LIST(STRUCT_MAP_ACCESSOR) | 908 STRUCT_LIST(STRUCT_MAP_ACCESSOR) |
| 910 #undef STRUCT_MAP_ACCESSOR | 909 #undef STRUCT_MAP_ACCESSOR |
| 911 | 910 |
| 912 #define STRING_ACCESSOR(name, str) \ | 911 #define STRING_ACCESSOR(name, str) inline String* name(); |
| 913 String* name() { return String::cast(roots_[k##name##RootIndex]); } | |
| 914 INTERNALIZED_STRING_LIST(STRING_ACCESSOR) | 912 INTERNALIZED_STRING_LIST(STRING_ACCESSOR) |
| 915 #undef STRING_ACCESSOR | 913 #undef STRING_ACCESSOR |
| 916 | 914 |
| 917 #define SYMBOL_ACCESSOR(name) \ | 915 #define SYMBOL_ACCESSOR(name) inline Symbol* name(); |
| 918 Symbol* name() { return Symbol::cast(roots_[k##name##RootIndex]); } | |
| 919 PRIVATE_SYMBOL_LIST(SYMBOL_ACCESSOR) | 916 PRIVATE_SYMBOL_LIST(SYMBOL_ACCESSOR) |
| 920 #undef SYMBOL_ACCESSOR | 917 #undef SYMBOL_ACCESSOR |
| 921 | 918 |
| 922 #define SYMBOL_ACCESSOR(name, varname, description) \ | 919 #define SYMBOL_ACCESSOR(name, varname, description) inline Symbol* name(); |
| 923 Symbol* name() { return Symbol::cast(roots_[k##name##RootIndex]); } | |
| 924 PUBLIC_SYMBOL_LIST(SYMBOL_ACCESSOR) | 920 PUBLIC_SYMBOL_LIST(SYMBOL_ACCESSOR) |
| 925 #undef SYMBOL_ACCESSOR | 921 #undef SYMBOL_ACCESSOR |
| 926 | 922 |
| 927 // The hidden_string is special because it is the empty string, but does | 923 // The hidden_string is special because it is the empty string, but does |
| 928 // not match the empty string. | 924 // not match the empty string. |
| 929 String* hidden_string() { return hidden_string_; } | 925 String* hidden_string() { return hidden_string_; } |
| 930 | 926 |
| 931 void set_native_contexts_list(Object* object) { | 927 void set_native_contexts_list(Object* object) { |
| 932 native_contexts_list_ = object; | 928 native_contexts_list_ = object; |
| 933 } | 929 } |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1095 void TracePathToGlobal(); | 1091 void TracePathToGlobal(); |
| 1096 #endif | 1092 #endif |
| 1097 | 1093 |
| 1098 // Callback function passed to Heap::Iterate etc. Copies an object if | 1094 // Callback function passed to Heap::Iterate etc. Copies an object if |
| 1099 // necessary, the object might be promoted to an old space. The caller must | 1095 // necessary, the object might be promoted to an old space. The caller must |
| 1100 // ensure the precondition that the object is (a) a heap object and (b) in | 1096 // ensure the precondition that the object is (a) a heap object and (b) in |
| 1101 // the heap's from space. | 1097 // the heap's from space. |
| 1102 static inline void ScavengePointer(HeapObject** p); | 1098 static inline void ScavengePointer(HeapObject** p); |
| 1103 static inline void ScavengeObject(HeapObject** p, HeapObject* object); | 1099 static inline void ScavengeObject(HeapObject** p, HeapObject* object); |
| 1104 | 1100 |
| 1101 // Slow part of scavenge object. |
| 1102 static void ScavengeObjectSlow(HeapObject** p, HeapObject* object); |
| 1103 |
| 1105 enum ScratchpadSlotMode { IGNORE_SCRATCHPAD_SLOT, RECORD_SCRATCHPAD_SLOT }; | 1104 enum ScratchpadSlotMode { IGNORE_SCRATCHPAD_SLOT, RECORD_SCRATCHPAD_SLOT }; |
| 1106 | 1105 |
| 1107 // If an object has an AllocationMemento trailing it, return it, otherwise | 1106 // If an object has an AllocationMemento trailing it, return it, otherwise |
| 1108 // return NULL; | 1107 // return NULL; |
| 1109 inline AllocationMemento* FindAllocationMemento(HeapObject* object); | 1108 inline AllocationMemento* FindAllocationMemento(HeapObject* object); |
| 1110 | 1109 |
| 1111 // An object may have an AllocationSite associated with it through a trailing | 1110 // An object may have an AllocationSite associated with it through a trailing |
| 1112 // AllocationMemento. Its feedback should be updated when objects are found | 1111 // AllocationMemento. Its feedback should be updated when objects are found |
| 1113 // in the heap. | 1112 // in the heap. |
| 1114 static inline void UpdateAllocationSiteFeedback(HeapObject* object, | 1113 static inline void UpdateAllocationSiteFeedback(HeapObject* object, |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1426 | 1425 |
| 1427 bool concurrent_sweeping_enabled() { return concurrent_sweeping_enabled_; } | 1426 bool concurrent_sweeping_enabled() { return concurrent_sweeping_enabled_; } |
| 1428 | 1427 |
| 1429 inline Isolate* isolate(); | 1428 inline Isolate* isolate(); |
| 1430 | 1429 |
| 1431 void CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags); | 1430 void CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags); |
| 1432 void CallGCEpilogueCallbacks(GCType gc_type, GCCallbackFlags flags); | 1431 void CallGCEpilogueCallbacks(GCType gc_type, GCCallbackFlags flags); |
| 1433 | 1432 |
| 1434 inline bool OldGenerationAllocationLimitReached(); | 1433 inline bool OldGenerationAllocationLimitReached(); |
| 1435 | 1434 |
| 1436 inline void DoScavengeObject(Map* map, HeapObject** slot, HeapObject* obj) { | |
| 1437 scavenging_visitors_table_.GetVisitor(map)(map, slot, obj); | |
| 1438 } | |
| 1439 | |
| 1440 void QueueMemoryChunkForFree(MemoryChunk* chunk); | 1435 void QueueMemoryChunkForFree(MemoryChunk* chunk); |
| 1441 void FreeQueuedChunks(); | 1436 void FreeQueuedChunks(); |
| 1442 | 1437 |
| 1443 int gc_count() const { return gc_count_; } | 1438 int gc_count() const { return gc_count_; } |
| 1444 | 1439 |
| 1445 bool RecentIdleNotificationHappened(); | 1440 bool RecentIdleNotificationHappened(); |
| 1446 | 1441 |
| 1447 // Completely clear the Instanceof cache (to stop it keeping objects alive | 1442 // Completely clear the Instanceof cache (to stop it keeping objects alive |
| 1448 // around a GC). | 1443 // around a GC). |
| 1449 inline void CompletelyClearInstanceofCache(); | 1444 inline void CompletelyClearInstanceofCache(); |
| 1450 | 1445 |
| 1451 // The roots that have an index less than this are always in old space. | 1446 // The roots that have an index less than this are always in old space. |
| 1452 static const int kOldSpaceRoots = 0x20; | 1447 static const int kOldSpaceRoots = 0x20; |
| 1453 | 1448 |
| 1454 uint32_t HashSeed() { | 1449 inline uint32_t HashSeed(); |
| 1455 uint32_t seed = static_cast<uint32_t>(hash_seed()->value()); | |
| 1456 DCHECK(FLAG_randomize_hashes || seed == 0); | |
| 1457 return seed; | |
| 1458 } | |
| 1459 | 1450 |
| 1460 Smi* NextScriptId() { | 1451 inline Smi* NextScriptId(); |
| 1461 int next_id = last_script_id()->value() + 1; | |
| 1462 if (!Smi::IsValid(next_id) || next_id < 0) next_id = 1; | |
| 1463 Smi* next_id_smi = Smi::FromInt(next_id); | |
| 1464 set_last_script_id(next_id_smi); | |
| 1465 return next_id_smi; | |
| 1466 } | |
| 1467 | 1452 |
| 1468 void SetArgumentsAdaptorDeoptPCOffset(int pc_offset) { | 1453 inline void SetArgumentsAdaptorDeoptPCOffset(int pc_offset); |
| 1469 DCHECK(arguments_adaptor_deopt_pc_offset() == Smi::FromInt(0)); | 1454 inline void SetConstructStubDeoptPCOffset(int pc_offset); |
| 1470 set_arguments_adaptor_deopt_pc_offset(Smi::FromInt(pc_offset)); | 1455 inline void SetGetterStubDeoptPCOffset(int pc_offset); |
| 1471 } | 1456 inline void SetSetterStubDeoptPCOffset(int pc_offset); |
| 1472 | |
| 1473 void SetConstructStubDeoptPCOffset(int pc_offset) { | |
| 1474 DCHECK(construct_stub_deopt_pc_offset() == Smi::FromInt(0)); | |
| 1475 set_construct_stub_deopt_pc_offset(Smi::FromInt(pc_offset)); | |
| 1476 } | |
| 1477 | |
| 1478 void SetGetterStubDeoptPCOffset(int pc_offset) { | |
| 1479 DCHECK(getter_stub_deopt_pc_offset() == Smi::FromInt(0)); | |
| 1480 set_getter_stub_deopt_pc_offset(Smi::FromInt(pc_offset)); | |
| 1481 } | |
| 1482 | |
| 1483 void SetSetterStubDeoptPCOffset(int pc_offset) { | |
| 1484 DCHECK(setter_stub_deopt_pc_offset() == Smi::FromInt(0)); | |
| 1485 set_setter_stub_deopt_pc_offset(Smi::FromInt(pc_offset)); | |
| 1486 } | |
| 1487 | 1457 |
| 1488 // For post mortem debugging. | 1458 // For post mortem debugging. |
| 1489 void RememberUnmappedPage(Address page, bool compacted); | 1459 void RememberUnmappedPage(Address page, bool compacted); |
| 1490 | 1460 |
| 1491 // Global inline caching age: it is incremented on some GCs after context | 1461 // Global inline caching age: it is incremented on some GCs after context |
| 1492 // disposal. We use it to flush inline caches. | 1462 // disposal. We use it to flush inline caches. |
| 1493 int global_ic_age() { return global_ic_age_; } | 1463 int global_ic_age() { return global_ic_age_; } |
| 1494 | 1464 |
| 1495 void AgeInlineCaches() { | 1465 void AgeInlineCaches() { |
| 1496 global_ic_age_ = (global_ic_age_ + 1) & SharedFunctionInfo::ICAgeBits::kMax; | 1466 global_ic_age_ = (global_ic_age_ + 1) & SharedFunctionInfo::ICAgeBits::kMax; |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1773 unsigned int gc_count_; | 1743 unsigned int gc_count_; |
| 1774 | 1744 |
| 1775 // For post mortem debugging. | 1745 // For post mortem debugging. |
| 1776 static const int kRememberedUnmappedPages = 128; | 1746 static const int kRememberedUnmappedPages = 128; |
| 1777 int remembered_unmapped_pages_index_; | 1747 int remembered_unmapped_pages_index_; |
| 1778 Address remembered_unmapped_pages_[kRememberedUnmappedPages]; | 1748 Address remembered_unmapped_pages_[kRememberedUnmappedPages]; |
| 1779 | 1749 |
| 1780 // Total length of the strings we failed to flatten since the last GC. | 1750 // Total length of the strings we failed to flatten since the last GC. |
| 1781 int unflattened_strings_length_; | 1751 int unflattened_strings_length_; |
| 1782 | 1752 |
| 1783 #define ROOT_ACCESSOR(type, name, camel_name) \ | 1753 #define ROOT_ACCESSOR(type, name, camel_name) \ |
| 1784 inline void set_##name(type* value) { \ | 1754 inline void set_##name(type* value); |
| 1785 /* The deserializer makes use of the fact that these common roots are */ \ | |
| 1786 /* never in new space and never on a page that is being compacted. */ \ | |
| 1787 DCHECK(!deserialization_complete() || \ | |
| 1788 RootCanBeWrittenAfterInitialization(k##camel_name##RootIndex)); \ | |
| 1789 DCHECK(k##camel_name##RootIndex >= kOldSpaceRoots || !InNewSpace(value)); \ | |
| 1790 roots_[k##camel_name##RootIndex] = value; \ | |
| 1791 } | |
| 1792 ROOT_LIST(ROOT_ACCESSOR) | 1755 ROOT_LIST(ROOT_ACCESSOR) |
| 1793 #undef ROOT_ACCESSOR | 1756 #undef ROOT_ACCESSOR |
| 1794 | 1757 |
| 1795 #ifdef DEBUG | 1758 #ifdef DEBUG |
| 1796 // If the --gc-interval flag is set to a positive value, this | 1759 // If the --gc-interval flag is set to a positive value, this |
| 1797 // variable holds the value indicating the number of allocations | 1760 // variable holds the value indicating the number of allocations |
| 1798 // remain until the next failure and garbage collection. | 1761 // remain until the next failure and garbage collection. |
| 1799 int allocation_timeout_; | 1762 int allocation_timeout_; |
| 1800 #endif // DEBUG | 1763 #endif // DEBUG |
| 1801 | 1764 |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2149 Isolate* isolate, std::map<void*, size_t>& live_buffers, | 2112 Isolate* isolate, std::map<void*, size_t>& live_buffers, |
| 2150 std::map<void*, size_t>& not_yet_discovered_buffers); | 2113 std::map<void*, size_t>& not_yet_discovered_buffers); |
| 2151 void TearDownArrayBuffersHelper( | 2114 void TearDownArrayBuffersHelper( |
| 2152 Isolate* isolate, std::map<void*, size_t>& live_buffers, | 2115 Isolate* isolate, std::map<void*, size_t>& live_buffers, |
| 2153 std::map<void*, size_t>& not_yet_discovered_buffers); | 2116 std::map<void*, size_t>& not_yet_discovered_buffers); |
| 2154 | 2117 |
| 2155 // Record statistics before and after garbage collection. | 2118 // Record statistics before and after garbage collection. |
| 2156 void ReportStatisticsBeforeGC(); | 2119 void ReportStatisticsBeforeGC(); |
| 2157 void ReportStatisticsAfterGC(); | 2120 void ReportStatisticsAfterGC(); |
| 2158 | 2121 |
| 2159 // Slow part of scavenge object. | |
| 2160 static void ScavengeObjectSlow(HeapObject** p, HeapObject* object); | |
| 2161 | |
| 2162 // Total RegExp code ever generated | 2122 // Total RegExp code ever generated |
| 2163 double total_regexp_code_generated_; | 2123 double total_regexp_code_generated_; |
| 2164 | 2124 |
| 2165 int deferred_counters_[v8::Isolate::kUseCounterFeatureCount]; | 2125 int deferred_counters_[v8::Isolate::kUseCounterFeatureCount]; |
| 2166 | 2126 |
| 2167 GCTracer tracer_; | 2127 GCTracer tracer_; |
| 2168 | 2128 |
| 2169 // Creates and installs the full-sized number string cache. | 2129 // Creates and installs the full-sized number string cache. |
| 2170 int FullSizeNumberStringCacheLength(); | 2130 int FullSizeNumberStringCacheLength(); |
| 2171 // Flush the number to string cache. | 2131 // Flush the number to string cache. |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2763 DisallowHeapAllocation no_allocation; // i.e. no gc allowed. | 2723 DisallowHeapAllocation no_allocation; // i.e. no gc allowed. |
| 2764 | 2724 |
| 2765 private: | 2725 private: |
| 2766 DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer); | 2726 DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer); |
| 2767 }; | 2727 }; |
| 2768 #endif // DEBUG | 2728 #endif // DEBUG |
| 2769 } | 2729 } |
| 2770 } // namespace v8::internal | 2730 } // namespace v8::internal |
| 2771 | 2731 |
| 2772 #endif // V8_HEAP_HEAP_H_ | 2732 #endif // V8_HEAP_HEAP_H_ |
| OLD | NEW |