OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1148 | 1148 |
1149 MarkCompactCollector::~MarkCompactCollector() { | 1149 MarkCompactCollector::~MarkCompactCollector() { |
1150 if (code_flusher_ != NULL) { | 1150 if (code_flusher_ != NULL) { |
1151 delete code_flusher_; | 1151 delete code_flusher_; |
1152 code_flusher_ = NULL; | 1152 code_flusher_ = NULL; |
1153 } | 1153 } |
1154 } | 1154 } |
1155 | 1155 |
1156 | 1156 |
1157 static inline HeapObject* ShortCircuitConsString(Object** p) { | 1157 static inline HeapObject* ShortCircuitConsString(Object** p) { |
1158 // Optimization: If the heap object pointed to by p is a non-symbol | 1158 // Optimization: If the heap object pointed to by p is a non-internalized |
1159 // cons string whose right substring is HEAP->empty_string, update | 1159 // cons string whose right substring is HEAP->empty_string, update |
1160 // it in place to its left substring. Return the updated value. | 1160 // it in place to its left substring. Return the updated value. |
1161 // | 1161 // |
1162 // Here we assume that if we change *p, we replace it with a heap object | 1162 // Here we assume that if we change *p, we replace it with a heap object |
1163 // (i.e., the left substring of a cons string is always a heap object). | 1163 // (i.e., the left substring of a cons string is always a heap object). |
1164 // | 1164 // |
1165 // The check performed is: | 1165 // The check performed is: |
1166 // object->IsConsString() && !object->IsSymbol() && | 1166 // object->IsConsString() && !object->IsInternalizedString() && |
1167 // (ConsString::cast(object)->second() == HEAP->empty_string()) | 1167 // (ConsString::cast(object)->second() == HEAP->empty_string()) |
1168 // except the maps for the object and its possible substrings might be | 1168 // except the maps for the object and its possible substrings might be |
1169 // marked. | 1169 // marked. |
1170 HeapObject* object = HeapObject::cast(*p); | 1170 HeapObject* object = HeapObject::cast(*p); |
1171 if (!FLAG_clever_optimizations) return object; | 1171 if (!FLAG_clever_optimizations) return object; |
1172 Map* map = object->map(); | 1172 Map* map = object->map(); |
1173 InstanceType type = map->instance_type(); | 1173 InstanceType type = map->instance_type(); |
1174 if ((type & kShortcutTypeMask) != kShortcutTypeTag) return object; | 1174 if ((type & kShortcutTypeMask) != kShortcutTypeTag) return object; |
1175 | 1175 |
1176 Object* second = reinterpret_cast<ConsString*>(object)->unchecked_second(); | 1176 Object* second = reinterpret_cast<ConsString*>(object)->unchecked_second(); |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1533 }; | 1533 }; |
1534 | 1534 |
1535 | 1535 |
1536 template<> | 1536 template<> |
1537 class MarkCompactMarkingVisitor::ObjectStatsTracker< | 1537 class MarkCompactMarkingVisitor::ObjectStatsTracker< |
1538 MarkCompactMarkingVisitor::kVisitFixedArray> { | 1538 MarkCompactMarkingVisitor::kVisitFixedArray> { |
1539 public: | 1539 public: |
1540 static inline void Visit(Map* map, HeapObject* obj) { | 1540 static inline void Visit(Map* map, HeapObject* obj) { |
1541 Heap* heap = map->GetHeap(); | 1541 Heap* heap = map->GetHeap(); |
1542 FixedArray* fixed_array = FixedArray::cast(obj); | 1542 FixedArray* fixed_array = FixedArray::cast(obj); |
1543 if (fixed_array == heap->symbol_table()) { | 1543 if (fixed_array == heap->string_table()) { |
1544 heap->RecordObjectStats( | 1544 heap->RecordObjectStats( |
1545 FIXED_ARRAY_TYPE, | 1545 FIXED_ARRAY_TYPE, |
1546 SYMBOL_TABLE_SUB_TYPE, | 1546 STRING_TABLE_SUB_TYPE, |
1547 fixed_array->Size()); | 1547 fixed_array->Size()); |
1548 } | 1548 } |
1549 ObjectStatsVisitBase(kVisitFixedArray, map, obj); | 1549 ObjectStatsVisitBase(kVisitFixedArray, map, obj); |
1550 } | 1550 } |
1551 }; | 1551 }; |
1552 | 1552 |
1553 | 1553 |
1554 void MarkCompactMarkingVisitor::Initialize() { | 1554 void MarkCompactMarkingVisitor::Initialize() { |
1555 StaticMarkingVisitor<MarkCompactMarkingVisitor>::Initialize(); | 1555 StaticMarkingVisitor<MarkCompactMarkingVisitor>::Initialize(); |
1556 | 1556 |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1717 | 1717 |
1718 // Mark all the objects reachable from the map and body. May leave | 1718 // Mark all the objects reachable from the map and body. May leave |
1719 // overflowed objects in the heap. | 1719 // overflowed objects in the heap. |
1720 collector_->EmptyMarkingDeque(); | 1720 collector_->EmptyMarkingDeque(); |
1721 } | 1721 } |
1722 | 1722 |
1723 MarkCompactCollector* collector_; | 1723 MarkCompactCollector* collector_; |
1724 }; | 1724 }; |
1725 | 1725 |
1726 | 1726 |
1727 // Helper class for pruning the symbol table. | 1727 // Helper class for pruning the string table. |
1728 class SymbolTableCleaner : public ObjectVisitor { | 1728 class StringTableCleaner : public ObjectVisitor { |
1729 public: | 1729 public: |
1730 explicit SymbolTableCleaner(Heap* heap) | 1730 explicit StringTableCleaner(Heap* heap) |
1731 : heap_(heap), pointers_removed_(0) { } | 1731 : heap_(heap), pointers_removed_(0) { } |
1732 | 1732 |
1733 virtual void VisitPointers(Object** start, Object** end) { | 1733 virtual void VisitPointers(Object** start, Object** end) { |
1734 // Visit all HeapObject pointers in [start, end). | 1734 // Visit all HeapObject pointers in [start, end). |
1735 for (Object** p = start; p < end; p++) { | 1735 for (Object** p = start; p < end; p++) { |
1736 Object* o = *p; | 1736 Object* o = *p; |
1737 if (o->IsHeapObject() && | 1737 if (o->IsHeapObject() && |
1738 !Marking::MarkBitFrom(HeapObject::cast(o)).Get()) { | 1738 !Marking::MarkBitFrom(HeapObject::cast(o)).Get()) { |
1739 // Check if the symbol being pruned is an external symbol. We need to | 1739 // Check if the internalized string being pruned is external. We need to |
1740 // delete the associated external data as this symbol is going away. | 1740 // delete the associated external data as this string is going away. |
1741 | 1741 |
1742 // Since no objects have yet been moved we can safely access the map of | 1742 // Since no objects have yet been moved we can safely access the map of |
1743 // the object. | 1743 // the object. |
1744 if (o->IsExternalString()) { | 1744 if (o->IsExternalString()) { |
1745 heap_->FinalizeExternalString(String::cast(*p)); | 1745 heap_->FinalizeExternalString(String::cast(*p)); |
1746 } | 1746 } |
1747 // Set the entry to the_hole_value (as deleted). | 1747 // Set the entry to the_hole_value (as deleted). |
1748 *p = heap_->the_hole_value(); | 1748 *p = heap_->the_hole_value(); |
1749 pointers_removed_++; | 1749 pointers_removed_++; |
1750 } | 1750 } |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1890 bool MarkCompactCollector::IsUnmarkedHeapObjectWithHeap(Heap* heap, | 1890 bool MarkCompactCollector::IsUnmarkedHeapObjectWithHeap(Heap* heap, |
1891 Object** p) { | 1891 Object** p) { |
1892 Object* o = *p; | 1892 Object* o = *p; |
1893 ASSERT(o->IsHeapObject()); | 1893 ASSERT(o->IsHeapObject()); |
1894 HeapObject* heap_object = HeapObject::cast(o); | 1894 HeapObject* heap_object = HeapObject::cast(o); |
1895 MarkBit mark = Marking::MarkBitFrom(heap_object); | 1895 MarkBit mark = Marking::MarkBitFrom(heap_object); |
1896 return !mark.Get(); | 1896 return !mark.Get(); |
1897 } | 1897 } |
1898 | 1898 |
1899 | 1899 |
1900 void MarkCompactCollector::MarkSymbolTable() { | 1900 void MarkCompactCollector::MarkStringTable() { |
1901 SymbolTable* symbol_table = heap()->symbol_table(); | 1901 StringTable* string_table = heap()->string_table(); |
1902 // Mark the symbol table itself. | 1902 // Mark the string table itself. |
1903 MarkBit symbol_table_mark = Marking::MarkBitFrom(symbol_table); | 1903 MarkBit string_table_mark = Marking::MarkBitFrom(string_table); |
1904 SetMark(symbol_table, symbol_table_mark); | 1904 SetMark(string_table, string_table_mark); |
1905 // Explicitly mark the prefix. | 1905 // Explicitly mark the prefix. |
1906 MarkingVisitor marker(heap()); | 1906 MarkingVisitor marker(heap()); |
1907 symbol_table->IteratePrefix(&marker); | 1907 string_table->IteratePrefix(&marker); |
1908 ProcessMarkingDeque(); | 1908 ProcessMarkingDeque(); |
1909 } | 1909 } |
1910 | 1910 |
1911 | 1911 |
1912 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { | 1912 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { |
1913 // Mark the heap roots including global variables, stack variables, | 1913 // Mark the heap roots including global variables, stack variables, |
1914 // etc., and all objects reachable from them. | 1914 // etc., and all objects reachable from them. |
1915 heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG); | 1915 heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG); |
1916 | 1916 |
1917 // Handle the symbol table specially. | 1917 // Handle the string table specially. |
1918 MarkSymbolTable(); | 1918 MarkStringTable(); |
1919 | 1919 |
1920 // There may be overflowed objects in the heap. Visit them now. | 1920 // There may be overflowed objects in the heap. Visit them now. |
1921 while (marking_deque_.overflowed()) { | 1921 while (marking_deque_.overflowed()) { |
1922 RefillMarkingDeque(); | 1922 RefillMarkingDeque(); |
1923 EmptyMarkingDeque(); | 1923 EmptyMarkingDeque(); |
1924 } | 1924 } |
1925 } | 1925 } |
1926 | 1926 |
1927 | 1927 |
1928 void MarkCompactCollector::MarkImplicitRefGroups() { | 1928 void MarkCompactCollector::MarkImplicitRefGroups() { |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2146 | 2146 |
2147 // Repeat host application specific marking to mark unmarked objects | 2147 // Repeat host application specific marking to mark unmarked objects |
2148 // reachable from the weak roots. | 2148 // reachable from the weak roots. |
2149 ProcessExternalMarking(&root_visitor); | 2149 ProcessExternalMarking(&root_visitor); |
2150 | 2150 |
2151 AfterMarking(); | 2151 AfterMarking(); |
2152 } | 2152 } |
2153 | 2153 |
2154 | 2154 |
2155 void MarkCompactCollector::AfterMarking() { | 2155 void MarkCompactCollector::AfterMarking() { |
2156 // Object literal map caches reference symbols (cache keys) and maps | 2156 // Object literal map caches reference strings (cache keys) and maps |
2157 // (cache values). At this point still useful maps have already been | 2157 // (cache values). At this point still useful maps have already been |
2158 // marked. Mark the keys for the alive values before we process the | 2158 // marked. Mark the keys for the alive values before we process the |
2159 // symbol table. | 2159 // string table. |
2160 ProcessMapCaches(); | 2160 ProcessMapCaches(); |
2161 | 2161 |
2162 // Prune the symbol table removing all symbols only pointed to by the | 2162 // Prune the string table removing all strings only pointed to by the |
2163 // symbol table. Cannot use symbol_table() here because the symbol | 2163 // string table. Cannot use string_table() here because the string |
2164 // table is marked. | 2164 // table is marked. |
2165 SymbolTable* symbol_table = heap()->symbol_table(); | 2165 StringTable* string_table = heap()->string_table(); |
2166 SymbolTableCleaner v(heap()); | 2166 StringTableCleaner v(heap()); |
2167 symbol_table->IterateElements(&v); | 2167 string_table->IterateElements(&v); |
2168 symbol_table->ElementsRemoved(v.PointersRemoved()); | 2168 string_table->ElementsRemoved(v.PointersRemoved()); |
2169 heap()->external_string_table_.Iterate(&v); | 2169 heap()->external_string_table_.Iterate(&v); |
2170 heap()->external_string_table_.CleanUp(); | 2170 heap()->external_string_table_.CleanUp(); |
2171 heap()->error_object_list_.RemoveUnmarked(heap()); | 2171 heap()->error_object_list_.RemoveUnmarked(heap()); |
2172 | 2172 |
2173 // Process the weak references. | 2173 // Process the weak references. |
2174 MarkCompactWeakObjectRetainer mark_compact_object_retainer; | 2174 MarkCompactWeakObjectRetainer mark_compact_object_retainer; |
2175 heap()->ProcessWeakReferences(&mark_compact_object_retainer); | 2175 heap()->ProcessWeakReferences(&mark_compact_object_retainer); |
2176 | 2176 |
2177 // Remove object groups after marking phase. | 2177 // Remove object groups after marking phase. |
2178 heap()->isolate()->global_handles()->RemoveObjectGroups(); | 2178 heap()->isolate()->global_handles()->RemoveObjectGroups(); |
(...skipping 1064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3243 Address value_address = | 3243 Address value_address = |
3244 reinterpret_cast<Address>(cell) + | 3244 reinterpret_cast<Address>(cell) + |
3245 (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag); | 3245 (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag); |
3246 updating_visitor.VisitPointer(reinterpret_cast<Object**>(value_address)); | 3246 updating_visitor.VisitPointer(reinterpret_cast<Object**>(value_address)); |
3247 } | 3247 } |
3248 } | 3248 } |
3249 | 3249 |
3250 // Update pointer from the native contexts list. | 3250 // Update pointer from the native contexts list. |
3251 updating_visitor.VisitPointer(heap_->native_contexts_list_address()); | 3251 updating_visitor.VisitPointer(heap_->native_contexts_list_address()); |
3252 | 3252 |
3253 heap_->symbol_table()->Iterate(&updating_visitor); | 3253 heap_->string_table()->Iterate(&updating_visitor); |
3254 | 3254 |
3255 // Update pointers from external string table. | 3255 // Update pointers from external string table. |
3256 heap_->UpdateReferencesInExternalStringTable( | 3256 heap_->UpdateReferencesInExternalStringTable( |
3257 &UpdateReferenceInExternalStringTableEntry); | 3257 &UpdateReferenceInExternalStringTableEntry); |
3258 | 3258 |
3259 // Update pointers in the new error object list. | 3259 // Update pointers in the new error object list. |
3260 heap_->error_object_list()->UpdateReferences(); | 3260 heap_->error_object_list()->UpdateReferences(); |
3261 | 3261 |
3262 if (!FLAG_watch_ic_patching) { | 3262 if (!FLAG_watch_ic_patching) { |
3263 // Update JSFunction pointers from the runtime profiler. | 3263 // Update JSFunction pointers from the runtime profiler. |
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4072 while (buffer != NULL) { | 4072 while (buffer != NULL) { |
4073 SlotsBuffer* next_buffer = buffer->next(); | 4073 SlotsBuffer* next_buffer = buffer->next(); |
4074 DeallocateBuffer(buffer); | 4074 DeallocateBuffer(buffer); |
4075 buffer = next_buffer; | 4075 buffer = next_buffer; |
4076 } | 4076 } |
4077 *buffer_address = NULL; | 4077 *buffer_address = NULL; |
4078 } | 4078 } |
4079 | 4079 |
4080 | 4080 |
4081 } } // namespace v8::internal | 4081 } } // namespace v8::internal |
OLD | NEW |