Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Side by Side Diff: src/mark-compact.cc

Issue 7607031: Update gc branch to bleeding_edge revision 8862. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Fix bug in weak-map merge Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mark-compact.h ('k') | src/messages.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 live_young_objects_size_(0), 66 live_young_objects_size_(0),
67 live_old_pointer_objects_size_(0), 67 live_old_pointer_objects_size_(0),
68 live_old_data_objects_size_(0), 68 live_old_data_objects_size_(0),
69 live_code_objects_size_(0), 69 live_code_objects_size_(0),
70 live_map_objects_size_(0), 70 live_map_objects_size_(0),
71 live_cell_objects_size_(0), 71 live_cell_objects_size_(0),
72 live_lo_objects_size_(0), 72 live_lo_objects_size_(0),
73 live_bytes_(0), 73 live_bytes_(0),
74 #endif 74 #endif
75 heap_(NULL), 75 heap_(NULL),
76 code_flusher_(NULL) { } 76 code_flusher_(NULL),
77 encountered_weak_maps_(NULL) { }
77 78
78 79
79 #ifdef DEBUG 80 #ifdef DEBUG
80 class VerifyMarkingVisitor: public ObjectVisitor { 81 class VerifyMarkingVisitor: public ObjectVisitor {
81 public: 82 public:
82 void VisitPointers(Object** start, Object** end) { 83 void VisitPointers(Object** start, Object** end) {
83 for (Object** current = start; current < end; current++) { 84 for (Object** current = start; current < end; current++) {
84 if ((*current)->IsHeapObject()) { 85 if ((*current)->IsHeapObject()) {
85 HeapObject* object = HeapObject::cast(*current); 86 HeapObject* object = HeapObject::cast(*current);
86 ASSERT(HEAP->mark_compact_collector()->IsMarked(object)); 87 ASSERT(HEAP->mark_compact_collector()->IsMarked(object));
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 } 245 }
245 246
246 return compacting_; 247 return compacting_;
247 } 248 }
248 249
249 250
250 void MarkCompactCollector::CollectGarbage() { 251 void MarkCompactCollector::CollectGarbage() {
251 // Make sure that Prepare() has been called. The individual steps below will 252 // Make sure that Prepare() has been called. The individual steps below will
252 // update the state as they proceed. 253 // update the state as they proceed.
253 ASSERT(state_ == PREPARE_GC); 254 ASSERT(state_ == PREPARE_GC);
255 ASSERT(encountered_weak_maps_ == Smi::FromInt(0));
254 256
255 MarkLiveObjects(); 257 MarkLiveObjects();
256 ASSERT(heap_->incremental_marking()->IsStopped()); 258 ASSERT(heap_->incremental_marking()->IsStopped());
257 259
258 if (collect_maps_) ClearNonLiveTransitions(); 260 if (collect_maps_) ClearNonLiveTransitions();
259 261
262 ClearWeakMaps();
263
260 #ifdef DEBUG 264 #ifdef DEBUG
261 if (FLAG_verify_heap) { 265 if (FLAG_verify_heap) {
262 VerifyMarking(heap_); 266 VerifyMarking(heap_);
263 } 267 }
264 #endif 268 #endif
265 269
266 SweepSpaces(); 270 SweepSpaces();
267 271
268 if (!collect_maps_) ReattachInitialMaps(); 272 if (!collect_maps_) ReattachInitialMaps();
269 273
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
684 688
685 table_.Register(kVisitGlobalContext, &VisitGlobalContext); 689 table_.Register(kVisitGlobalContext, &VisitGlobalContext);
686 690
687 table_.Register(kVisitFixedDoubleArray, DataObjectVisitor::Visit); 691 table_.Register(kVisitFixedDoubleArray, DataObjectVisitor::Visit);
688 692
689 table_.Register(kVisitByteArray, &DataObjectVisitor::Visit); 693 table_.Register(kVisitByteArray, &DataObjectVisitor::Visit);
690 table_.Register(kVisitFreeSpace, &DataObjectVisitor::Visit); 694 table_.Register(kVisitFreeSpace, &DataObjectVisitor::Visit);
691 table_.Register(kVisitSeqAsciiString, &DataObjectVisitor::Visit); 695 table_.Register(kVisitSeqAsciiString, &DataObjectVisitor::Visit);
692 table_.Register(kVisitSeqTwoByteString, &DataObjectVisitor::Visit); 696 table_.Register(kVisitSeqTwoByteString, &DataObjectVisitor::Visit);
693 697
698 table_.Register(kVisitJSWeakMap, &VisitJSWeakMap);
699
694 table_.Register(kVisitOddball, 700 table_.Register(kVisitOddball,
695 &FixedBodyVisitor<StaticMarkingVisitor, 701 &FixedBodyVisitor<StaticMarkingVisitor,
696 Oddball::BodyDescriptor, 702 Oddball::BodyDescriptor,
697 void>::Visit); 703 void>::Visit);
698 table_.Register(kVisitMap, 704 table_.Register(kVisitMap,
699 &FixedBodyVisitor<StaticMarkingVisitor, 705 &FixedBodyVisitor<StaticMarkingVisitor,
700 Map::BodyDescriptor, 706 Map::BodyDescriptor,
701 void>::Visit); 707 void>::Visit);
702 708
703 table_.Register(kVisitCode, &VisitCode); 709 table_.Register(kVisitCode, &VisitCode);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 }; 853 };
848 854
849 typedef FlexibleBodyVisitor<StaticMarkingVisitor, 855 typedef FlexibleBodyVisitor<StaticMarkingVisitor,
850 JSObject::BodyDescriptor, 856 JSObject::BodyDescriptor,
851 void> JSObjectVisitor; 857 void> JSObjectVisitor;
852 858
853 typedef FlexibleBodyVisitor<StaticMarkingVisitor, 859 typedef FlexibleBodyVisitor<StaticMarkingVisitor,
854 StructBodyDescriptor, 860 StructBodyDescriptor,
855 void> StructObjectVisitor; 861 void> StructObjectVisitor;
856 862
863 static void VisitJSWeakMap(Map* map, HeapObject* object) {
864 MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector();
865 JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(object);
866
867 // Enqueue weak map in linked list of encountered weak maps.
868 ASSERT(weak_map->next() == Smi::FromInt(0));
869 weak_map->set_next(collector->encountered_weak_maps());
870 collector->set_encountered_weak_maps(weak_map);
871
872 // Skip visiting the backing hash table containing the mappings.
873 int object_size = JSWeakMap::BodyDescriptor::SizeOf(map, object);
874 BodyVisitorBase<StaticMarkingVisitor>::IteratePointers(
875 map->GetHeap(),
876 object,
877 JSWeakMap::BodyDescriptor::kStartOffset,
878 JSWeakMap::kTableOffset);
879 BodyVisitorBase<StaticMarkingVisitor>::IteratePointers(
880 map->GetHeap(),
881 object,
882 JSWeakMap::kTableOffset + kPointerSize,
883 object_size);
884
885 // Mark the backing hash table without pushing it on the marking stack.
886 ASSERT(!MarkCompactCollector::IsMarked(weak_map->unchecked_table()));
887 ASSERT(MarkCompactCollector::IsMarked(weak_map->unchecked_table()->map()));
888
889 HeapObject* unchecked_table = weak_map->unchecked_table();
890 MarkBit mark_bit = Marking::MarkBitFrom(unchecked_table);
891 collector->SetMark(unchecked_table, mark_bit);
892 }
893
857 static void VisitCode(Map* map, HeapObject* object) { 894 static void VisitCode(Map* map, HeapObject* object) {
858 reinterpret_cast<Code*>(object)->CodeIterateBody<StaticMarkingVisitor>( 895 reinterpret_cast<Code*>(object)->CodeIterateBody<StaticMarkingVisitor>(
859 map->GetHeap()); 896 map->GetHeap());
860 } 897 }
861 898
862 // Code flushing support. 899 // Code flushing support.
863 900
864 // How many collections newly compiled code object will survive before being 901 // How many collections newly compiled code object will survive before being
865 // flushed. 902 // flushed.
866 static const int kCodeAgeThreshold = 5; 903 static const int kCodeAgeThreshold = 5;
(...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after
1760 ref_groups->Rewind(last); 1797 ref_groups->Rewind(last);
1761 } 1798 }
1762 1799
1763 1800
1764 // Mark all objects reachable from the objects on the marking stack. 1801 // Mark all objects reachable from the objects on the marking stack.
1765 // Before: the marking stack contains zero or more heap object pointers. 1802 // Before: the marking stack contains zero or more heap object pointers.
1766 // After: the marking stack is empty, and all objects reachable from the 1803 // After: the marking stack is empty, and all objects reachable from the
1767 // marking stack have been marked, or are overflowed in the heap. 1804 // marking stack have been marked, or are overflowed in the heap.
1768 void MarkCompactCollector::EmptyMarkingDeque() { 1805 void MarkCompactCollector::EmptyMarkingDeque() {
1769 while (!marking_deque_.IsEmpty()) { 1806 while (!marking_deque_.IsEmpty()) {
1770 HeapObject* object = marking_deque_.Pop(); 1807 while (!marking_deque_.IsEmpty()) {
1771 ASSERT(object->IsHeapObject()); 1808 HeapObject* object = marking_deque_.Pop();
1772 ASSERT(heap()->Contains(object)); 1809 ASSERT(object->IsHeapObject());
1773 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object))); 1810 ASSERT(heap()->Contains(object));
1811 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object)));
1774 1812
1775 Map* map = object->map(); 1813 Map* map = object->map();
1776 MarkBit map_mark = Marking::MarkBitFrom(map); 1814 MarkBit map_mark = Marking::MarkBitFrom(map);
1777 MarkObject(map, map_mark); 1815 MarkObject(map, map_mark);
1778 1816
1779 StaticMarkingVisitor::IterateBody(map, object); 1817 StaticMarkingVisitor::IterateBody(map, object);
1818 }
1819
1820 // Process encountered weak maps, mark objects only reachable by those
1821 // weak maps and repeat until fix-point is reached.
1822 ProcessWeakMaps();
1780 } 1823 }
1781 } 1824 }
1782 1825
1783 1826
1784 // Sweep the heap for overflowed objects, clear their overflow bits, and 1827 // Sweep the heap for overflowed objects, clear their overflow bits, and
1785 // push them on the marking stack. Stop early if the marking stack fills 1828 // push them on the marking stack. Stop early if the marking stack fills
1786 // before sweeping completes. If sweeping completes, there are no remaining 1829 // before sweeping completes. If sweeping completes, there are no remaining
1787 // overflowed objects in the heap so the overflow flag on the markings stack 1830 // overflowed objects in the heap so the overflow flag on the markings stack
1788 // is cleared. 1831 // is cleared.
1789 void MarkCompactCollector::RefillMarkingDeque() { 1832 void MarkCompactCollector::RefillMarkingDeque() {
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
2171 if (is_alive) { 2214 if (is_alive) {
2172 Object** slot = HeapObject::RawField(current, Map::kPrototypeOffset); 2215 Object** slot = HeapObject::RawField(current, Map::kPrototypeOffset);
2173 RecordSlot(slot, slot, real_prototype); 2216 RecordSlot(slot, slot, real_prototype);
2174 } 2217 }
2175 current = reinterpret_cast<Map*>(next); 2218 current = reinterpret_cast<Map*>(next);
2176 } 2219 }
2177 } 2220 }
2178 } 2221 }
2179 2222
2180 2223
2224 void MarkCompactCollector::ProcessWeakMaps() {
2225 Object* weak_map_obj = encountered_weak_maps();
2226 while (weak_map_obj != Smi::FromInt(0)) {
2227 ASSERT(MarkCompactCollector::IsMarked(HeapObject::cast(weak_map_obj)));
2228 JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(weak_map_obj);
2229 ObjectHashTable* table = weak_map->unchecked_table();
2230 for (int i = 0; i < table->Capacity(); i++) {
2231 if (MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) {
2232 Object* value = table->get(table->EntryToValueIndex(i));
2233 StaticMarkingVisitor::VisitPointer(heap(), &value);
2234 table->set_unchecked(heap(),
2235 table->EntryToValueIndex(i),
2236 value,
2237 UPDATE_WRITE_BARRIER);
2238 }
2239 }
2240 weak_map_obj = weak_map->next();
2241 }
2242 }
2243
2244
2245 void MarkCompactCollector::ClearWeakMaps() {
2246 Object* weak_map_obj = encountered_weak_maps();
2247 while (weak_map_obj != Smi::FromInt(0)) {
2248 ASSERT(MarkCompactCollector::IsMarked(HeapObject::cast(weak_map_obj)));
2249 JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(weak_map_obj);
2250 ObjectHashTable* table = weak_map->unchecked_table();
2251 for (int i = 0; i < table->Capacity(); i++) {
2252 if (!MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) {
2253 table->RemoveEntry(i, heap());
2254 }
2255 }
2256 weak_map_obj = weak_map->next();
2257 weak_map->set_next(Smi::FromInt(0));
2258 }
2259 set_encountered_weak_maps(Smi::FromInt(0));
2260 }
2261
2262
2181 // We scavange new space simultaneously with sweeping. This is done in two 2263 // We scavange new space simultaneously with sweeping. This is done in two
2182 // passes. 2264 // passes.
2183 // 2265 //
2184 // The first pass migrates all alive objects from one semispace to another or 2266 // The first pass migrates all alive objects from one semispace to another or
2185 // promotes them to old space. Forwarding address is written directly into 2267 // promotes them to old space. Forwarding address is written directly into
2186 // first word of object without any encoding. If object is dead we write 2268 // first word of object without any encoding. If object is dead we write
2187 // NULL as a forwarding address. 2269 // NULL as a forwarding address.
2188 // 2270 //
2189 // The second pass updates pointers to new space in all spaces. It is possible 2271 // The second pass updates pointers to new space in all spaces. It is possible
2190 // to encounter pointers to dead new space objects during traversal of pointers 2272 // to encounter pointers to dead new space objects during traversal of pointers
(...skipping 1154 matching lines...) Expand 10 before | Expand all | Expand 10 after
3345 while (buffer != NULL) { 3427 while (buffer != NULL) {
3346 SlotsBuffer* next_buffer = buffer->next(); 3428 SlotsBuffer* next_buffer = buffer->next();
3347 DeallocateBuffer(buffer); 3429 DeallocateBuffer(buffer);
3348 buffer = next_buffer; 3430 buffer = next_buffer;
3349 } 3431 }
3350 *buffer_address = NULL; 3432 *buffer_address = NULL;
3351 } 3433 }
3352 3434
3353 3435
3354 } } // namespace v8::internal 3436 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mark-compact.h ('k') | src/messages.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698