OLD | NEW |
---|---|
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
83 | 83 |
84 | 84 |
85 void Marking::TearDown() { | 85 void Marking::TearDown() { |
86 if (new_space_bitmap_ != NULL) { | 86 if (new_space_bitmap_ != NULL) { |
87 BitmapStorageDescriptor::Free(new_space_bitmap_); | 87 BitmapStorageDescriptor::Free(new_space_bitmap_); |
88 new_space_bitmap_ = NULL; | 88 new_space_bitmap_ = NULL; |
89 } | 89 } |
90 } | 90 } |
91 | 91 |
92 | 92 |
93 #ifdef DEBUG | |
94 class VerifyMarkingVisitor: public ObjectVisitor { | |
95 public: | |
96 void VisitPointers(Object** start, Object** end) { | |
97 for (Object** current = start; current < end; current++) { | |
98 if ((*current)->IsHeapObject()) { | |
99 HeapObject* object = HeapObject::cast(*current); | |
100 ASSERT(Marking::IsMarked(object)); | |
101 } | |
102 } | |
103 } | |
104 }; | |
105 | |
Erik Corry
2011/02/22 12:27:19
2 blank lines here and several places.
Vyacheslav Egorov (Chromium)
2011/02/23 14:31:46
Done.
| |
106 static void VerifyMarking(Address bottom, Address top) { | |
107 VerifyMarkingVisitor visitor; | |
108 HeapObject* object; | |
109 | |
110 for (Address current = bottom; | |
111 current < top; | |
112 current += object->Size()) { | |
113 object = HeapObject::FromAddress(current); | |
114 if (Marking::IsMarked(object)) object->Iterate(&visitor); | |
115 } | |
116 | |
117 } | |
118 | |
119 static void VerifyMarking(Page* p) { | |
120 VerifyMarking(p->ObjectAreaStart(), p->AllocationTop()); | |
121 } | |
122 | |
123 static void VerifyMarking(NewSpace* space) { | |
124 VerifyMarking(space->bottom(), space->top()); | |
125 } | |
126 | |
127 static void VerifyMarking(PagedSpace* space) { | |
128 PageIterator it(space, PageIterator::PAGES_IN_USE); | |
129 | |
130 while (it.has_next()) { | |
131 VerifyMarking(it.next()); | |
132 } | |
133 } | |
134 | |
135 static void VerifyMarking() { | |
136 VerifyMarking(Heap::old_pointer_space()); | |
137 VerifyMarking(Heap::old_data_space()); | |
138 VerifyMarking(Heap::code_space()); | |
139 VerifyMarking(Heap::cell_space()); | |
140 VerifyMarking(Heap::map_space()); | |
141 VerifyMarking(Heap::new_space()); | |
142 | |
143 VerifyMarkingVisitor visitor; | |
144 Heap::IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); | |
145 } | |
146 #endif | |
147 | |
93 void MarkCompactCollector::CollectGarbage() { | 148 void MarkCompactCollector::CollectGarbage() { |
94 // Make sure that Prepare() has been called. The individual steps below will | 149 // Make sure that Prepare() has been called. The individual steps below will |
95 // update the state as they proceed. | 150 // update the state as they proceed. |
96 ASSERT(state_ == PREPARE_GC); | 151 ASSERT(state_ == PREPARE_GC); |
97 | 152 |
98 // Prepare has selected whether to compact the old generation or not. | 153 // Prepare has selected whether to compact the old generation or not. |
99 // Tell the tracer. | 154 // Tell the tracer. |
100 if (IsCompacting()) tracer_->set_is_compacting(); | 155 // if (IsCompacting()) tracer_->set_is_compacting(); |
Erik Corry
2011/02/22 12:27:19
Commented code.
Vyacheslav Egorov (Chromium)
2011/02/23 14:31:46
Done.
| |
101 | 156 |
102 MarkLiveObjects(); | 157 if (IncrementalMarking::state() == IncrementalMarking::STOPPED) { |
158 MarkLiveObjects(); | |
159 } else { | |
160 { | |
161 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK); | |
162 IncrementalMarking::Finalize(); | |
163 ASSERT(IncrementalMarking::state() == IncrementalMarking::STOPPED); | |
164 } | |
165 MarkLiveObjects(); | |
166 } | |
103 | 167 |
104 if (FLAG_collect_maps) ClearNonLiveTransitions(); | 168 #ifdef DEBUG |
169 VerifyMarking(); | |
170 #endif | |
171 // if (FLAG_collect_maps) ClearNonLiveTransitions(); | |
105 | 172 |
106 SweepSpaces(); | 173 SweepSpaces(); |
107 | 174 |
108 PcToCodeCache::FlushPcToCodeCache(); | 175 PcToCodeCache::FlushPcToCodeCache(); |
109 | 176 |
110 Finish(); | 177 Finish(); |
111 | 178 |
112 // Check that swept all marked objects and | 179 // Check that swept all marked objects and |
113 // null out the GC tracer. | 180 // null out the GC tracer. |
114 // TODO(gc) does not work with conservative sweeping. | 181 // TODO(gc) does not work with conservative sweeping. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
147 } | 214 } |
148 | 215 |
149 static void ClearMarkbits() { | 216 static void ClearMarkbits() { |
150 // We are sweeping code and map spaces precisely so clearing is not required. | 217 // We are sweeping code and map spaces precisely so clearing is not required. |
151 ClearMarkbits(Heap::old_pointer_space()); | 218 ClearMarkbits(Heap::old_pointer_space()); |
152 ClearMarkbits(Heap::old_data_space()); | 219 ClearMarkbits(Heap::old_data_space()); |
153 ClearMarkbits(Heap::cell_space()); | 220 ClearMarkbits(Heap::cell_space()); |
154 } | 221 } |
155 | 222 |
156 | 223 |
224 void Marking::TransferMark(Address old_start, Address new_start) { | |
225 if (IncrementalMarking::state() == IncrementalMarking::MARKING) { | |
226 if (IncrementalMarking::IsBlack(HeapObject::FromAddress(old_start))) { | |
227 IncrementalMarking::MarkBlack(HeapObject::FromAddress(new_start)); | |
228 } else if (IncrementalMarking::IsGrey(HeapObject::FromAddress(old_start))) { | |
229 IncrementalMarking::WhiteToGrey(HeapObject::FromAddress(new_start)); | |
230 // TODO(gc): if we shift huge array in the loop we might end up pushing | |
231 // to much to marking stack. maybe we should check one or two elements | |
232 // on top of it to see whether they are equal to old_start. | |
Erik Corry
2011/02/22 12:27:19
Or perhaps we should compact the marking stack by
Vyacheslav Egorov (Chromium)
2011/02/23 14:31:46
We will think about it.
| |
233 } | |
234 } else { | |
235 if (Heap::InNewSpace(old_start) || | |
236 Page::FromAddress(old_start)->IsFlagSet(Page::IS_CONTINUOUS) || | |
237 !IsMarked(old_start)) { | |
238 return; | |
239 } | |
240 SetMark(new_start); | |
241 } | |
242 } | |
243 | |
244 | |
157 void MarkCompactCollector::Prepare(GCTracer* tracer) { | 245 void MarkCompactCollector::Prepare(GCTracer* tracer) { |
158 FLAG_flush_code = false; | 246 FLAG_flush_code = false; |
159 FLAG_always_compact = false; | 247 FLAG_always_compact = false; |
160 FLAG_never_compact = true; | 248 FLAG_never_compact = true; |
161 | 249 |
250 // Disable collection of maps if incremental marking is enabled. | |
251 // TODO(gc) improve maps collection algorithm to work with incremental | |
252 // marking. | |
253 if (FLAG_incremental_marking) FLAG_collect_maps = false; | |
254 | |
162 // Rather than passing the tracer around we stash it in a static member | 255 // Rather than passing the tracer around we stash it in a static member |
163 // variable. | 256 // variable. |
164 tracer_ = tracer; | 257 tracer_ = tracer; |
165 | 258 |
166 #ifdef DEBUG | 259 #ifdef DEBUG |
167 ASSERT(state_ == IDLE); | 260 ASSERT(state_ == IDLE); |
168 state_ = PREPARE_GC; | 261 state_ = PREPARE_GC; |
169 #endif | 262 #endif |
170 ASSERT(!FLAG_always_compact || !FLAG_never_compact); | 263 ASSERT(!FLAG_always_compact || !FLAG_never_compact); |
171 | 264 |
172 compacting_collection_ = | 265 compacting_collection_ = |
173 FLAG_always_compact || force_compaction_ || compact_on_next_gc_; | 266 FLAG_always_compact || force_compaction_ || compact_on_next_gc_; |
174 compact_on_next_gc_ = false; | 267 compact_on_next_gc_ = false; |
175 | 268 |
176 if (FLAG_never_compact) compacting_collection_ = false; | 269 if (FLAG_never_compact) compacting_collection_ = false; |
177 if (!Heap::map_space()->MapPointersEncodable()) | 270 if (!Heap::map_space()->MapPointersEncodable()) { |
178 compacting_collection_ = false; | 271 compacting_collection_ = false; |
272 } | |
179 if (FLAG_collect_maps) CreateBackPointers(); | 273 if (FLAG_collect_maps) CreateBackPointers(); |
180 #ifdef ENABLE_GDB_JIT_INTERFACE | 274 #ifdef ENABLE_GDB_JIT_INTERFACE |
181 if (FLAG_gdbjit) { | 275 if (FLAG_gdbjit) { |
182 // If GDBJIT interface is active disable compaction. | 276 // If GDBJIT interface is active disable compaction. |
183 compacting_collection_ = false; | 277 compacting_collection_ = false; |
184 } | 278 } |
185 #endif | 279 #endif |
186 | 280 |
187 PagedSpaces spaces; | 281 PagedSpaces spaces; |
188 for (PagedSpace* space = spaces.next(); | 282 for (PagedSpace* space = spaces.next(); |
189 space != NULL; space = spaces.next()) { | 283 space != NULL; space = spaces.next()) { |
190 space->PrepareForMarkCompact(compacting_collection_); | 284 space->PrepareForMarkCompact(compacting_collection_); |
191 } | 285 } |
192 | 286 |
193 Address new_space_top = Heap::new_space()->top(); | 287 if (IncrementalMarking::state() == IncrementalMarking::STOPPED) { |
194 Address new_space_bottom = Heap::new_space()->bottom(); | 288 Address new_space_top = Heap::new_space()->top(); |
289 Address new_space_bottom = Heap::new_space()->bottom(); | |
195 | 290 |
196 Marking::ClearRange(new_space_bottom, | 291 Marking::ClearRange(new_space_bottom, |
197 static_cast<int>(new_space_top - new_space_bottom)); | 292 static_cast<int>(new_space_top - new_space_bottom)); |
198 | 293 |
199 ClearMarkbits(); | 294 ClearMarkbits(); |
295 #ifdef DEBUG | |
296 VerifyMarkbitsAreClean(); | |
297 #endif | |
298 } | |
200 | 299 |
201 #ifdef DEBUG | 300 #ifdef DEBUG |
202 VerifyMarkbitsAreClean(); | |
203 | |
204 live_bytes_ = 0; | 301 live_bytes_ = 0; |
205 live_young_objects_size_ = 0; | 302 live_young_objects_size_ = 0; |
206 live_old_pointer_objects_size_ = 0; | 303 live_old_pointer_objects_size_ = 0; |
207 live_old_data_objects_size_ = 0; | 304 live_old_data_objects_size_ = 0; |
208 live_code_objects_size_ = 0; | 305 live_code_objects_size_ = 0; |
209 live_map_objects_size_ = 0; | 306 live_map_objects_size_ = 0; |
210 live_cell_objects_size_ = 0; | 307 live_cell_objects_size_ = 0; |
211 live_lo_objects_size_ = 0; | 308 live_lo_objects_size_ = 0; |
212 #endif | 309 #endif |
213 } | 310 } |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
538 MarkCompactCollector::MarkObject(code); | 635 MarkCompactCollector::MarkObject(code); |
539 } | 636 } |
540 } | 637 } |
541 | 638 |
542 static void VisitGlobalPropertyCell(RelocInfo* rinfo) { | 639 static void VisitGlobalPropertyCell(RelocInfo* rinfo) { |
543 ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL); | 640 ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL); |
544 Object* cell = rinfo->target_cell(); | 641 Object* cell = rinfo->target_cell(); |
545 Object* old_cell = cell; | 642 Object* old_cell = cell; |
546 VisitPointer(&cell); | 643 VisitPointer(&cell); |
547 if (cell != old_cell) { | 644 if (cell != old_cell) { |
548 rinfo->set_target_cell(reinterpret_cast<JSGlobalPropertyCell*>(cell)); | 645 rinfo->set_target_cell(reinterpret_cast<JSGlobalPropertyCell*>(cell), NULL ); |
549 } | 646 } |
550 } | 647 } |
551 | 648 |
552 static inline void VisitDebugTarget(RelocInfo* rinfo) { | 649 static inline void VisitDebugTarget(RelocInfo* rinfo) { |
553 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && | 650 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && |
554 rinfo->IsPatchedReturnSequence()) || | 651 rinfo->IsPatchedReturnSequence()) || |
555 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && | 652 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && |
556 rinfo->IsPatchedDebugBreakSlotSequence())); | 653 rinfo->IsPatchedDebugBreakSlotSequence())); |
557 HeapObject* code = Code::GetCodeFromTargetAddress(rinfo->call_address()); | 654 HeapObject* code = Code::GetCodeFromTargetAddress(rinfo->call_address()); |
558 MarkCompactCollector::MarkObject(code); | 655 MarkCompactCollector::MarkObject(code); |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
785 Object* old_code = code; | 882 Object* old_code = code; |
786 VisitPointer(&code); | 883 VisitPointer(&code); |
787 if (code != old_code) { | 884 if (code != old_code) { |
788 Memory::Address_at(entry_address) = | 885 Memory::Address_at(entry_address) = |
789 reinterpret_cast<Code*>(code)->entry(); | 886 reinterpret_cast<Code*>(code)->entry(); |
790 } | 887 } |
791 } | 888 } |
792 | 889 |
793 | 890 |
794 static void VisitJSFunctionAndFlushCode(Map* map, HeapObject* object) { | 891 static void VisitJSFunctionAndFlushCode(Map* map, HeapObject* object) { |
892 UNREACHABLE(); | |
Erik Corry
2011/02/22 12:27:19
TODO?
Vyacheslav Egorov (Chromium)
2011/02/23 14:31:46
Done.
| |
893 #if 0 | |
Erik Corry
2011/02/22 12:27:19
Commented code.
Vyacheslav Egorov (Chromium)
2011/02/23 14:31:46
Done.
| |
795 JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object); | 894 JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object); |
796 // The function must have a valid context and not be a builtin. | 895 // The function must have a valid context and not be a builtin. |
797 bool flush_code_candidate = false; | 896 bool flush_code_candidate = false; |
798 if (IsValidNotBuiltinContext(jsfunction->unchecked_context())) { | 897 if (IsValidNotBuiltinContext(jsfunction->unchecked_context())) { |
799 flush_code_candidate = FlushCodeForFunction(jsfunction); | 898 flush_code_candidate = FlushCodeForFunction(jsfunction); |
800 } | 899 } |
801 | 900 |
802 if (!flush_code_candidate) { | 901 if (!flush_code_candidate) { |
803 MarkCompactCollector::MarkObject( | 902 MarkCompactCollector::MarkObject( |
804 jsfunction->unchecked_shared()->unchecked_code()); | 903 jsfunction->unchecked_shared()->unchecked_code()); |
(...skipping 14 matching lines...) Expand all Loading... | |
819 JSFunction* inlined = reinterpret_cast<JSFunction*>(literals->get(i)); | 918 JSFunction* inlined = reinterpret_cast<JSFunction*>(literals->get(i)); |
820 MarkCompactCollector::MarkObject( | 919 MarkCompactCollector::MarkObject( |
821 inlined->unchecked_shared()->unchecked_code()); | 920 inlined->unchecked_shared()->unchecked_code()); |
822 } | 921 } |
823 } | 922 } |
824 } | 923 } |
825 | 924 |
826 VisitJSFunctionFields(map, | 925 VisitJSFunctionFields(map, |
827 reinterpret_cast<JSFunction*>(object), | 926 reinterpret_cast<JSFunction*>(object), |
828 flush_code_candidate); | 927 flush_code_candidate); |
928 #endif | |
829 } | 929 } |
830 | 930 |
831 | 931 |
832 static void VisitJSFunction(Map* map, HeapObject* object) { | 932 static void VisitJSFunction(Map* map, HeapObject* object) { |
833 VisitJSFunctionFields(map, | 933 VisitJSFunctionFields(map, |
834 reinterpret_cast<JSFunction*>(object), | 934 reinterpret_cast<JSFunction*>(object), |
835 false); | 935 false); |
836 } | 936 } |
837 | 937 |
838 | 938 |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1065 | 1165 |
1066 | 1166 |
1067 void MarkCompactCollector::ProcessNewlyMarkedObject(HeapObject* object) { | 1167 void MarkCompactCollector::ProcessNewlyMarkedObject(HeapObject* object) { |
1068 ASSERT(Marking::IsMarked(object)); | 1168 ASSERT(Marking::IsMarked(object)); |
1069 ASSERT(Heap::Contains(object)); | 1169 ASSERT(Heap::Contains(object)); |
1070 if (object->IsMap()) { | 1170 if (object->IsMap()) { |
1071 Map* map = Map::cast(object); | 1171 Map* map = Map::cast(object); |
1072 if (FLAG_cleanup_caches_in_maps_at_gc) { | 1172 if (FLAG_cleanup_caches_in_maps_at_gc) { |
1073 map->ClearCodeCache(); | 1173 map->ClearCodeCache(); |
1074 } | 1174 } |
1075 if (FLAG_collect_maps && | 1175 /*if (FLAG_collect_maps && |
Erik Corry
2011/02/22 12:27:19
Commented code. TODO?
Vyacheslav Egorov (Chromium)
2011/02/23 14:31:46
Done.
| |
1076 map->instance_type() >= FIRST_JS_OBJECT_TYPE && | 1176 map->instance_type() >= FIRST_JS_OBJECT_TYPE && |
1077 map->instance_type() <= JS_FUNCTION_TYPE) { | 1177 map->instance_type() <= JS_FUNCTION_TYPE) { |
1178 UNREACHABLE(); | |
1078 MarkMapContents(map); | 1179 MarkMapContents(map); |
1079 } else { | 1180 } else {*/ |
1080 marking_stack.Push(map); | 1181 marking_stack.Push(map); |
1081 } | 1182 /*}*/ |
1082 } else { | 1183 } else { |
1083 marking_stack.Push(object); | 1184 marking_stack.Push(object); |
1084 } | 1185 } |
1085 } | 1186 } |
1086 | 1187 |
1087 | 1188 |
1088 void MarkCompactCollector::MarkMapContents(Map* map) { | 1189 void MarkCompactCollector::MarkMapContents(Map* map) { |
1089 MarkDescriptorArray(reinterpret_cast<DescriptorArray*>( | 1190 MarkDescriptorArray(reinterpret_cast<DescriptorArray*>( |
1090 *HeapObject::RawField(map, Map::kInstanceDescriptorsOffset))); | 1191 *HeapObject::RawField(map, Map::kInstanceDescriptorsOffset))); |
1091 | 1192 |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1381 GlobalHandles::IterateWeakRoots(&root_visitor); | 1482 GlobalHandles::IterateWeakRoots(&root_visitor); |
1382 while (marking_stack.overflowed()) { | 1483 while (marking_stack.overflowed()) { |
1383 RefillMarkingStack(); | 1484 RefillMarkingStack(); |
1384 EmptyMarkingStack(); | 1485 EmptyMarkingStack(); |
1385 } | 1486 } |
1386 | 1487 |
1387 // Repeat the object groups to mark unmarked groups reachable from the | 1488 // Repeat the object groups to mark unmarked groups reachable from the |
1388 // weak roots. | 1489 // weak roots. |
1389 ProcessObjectGroups(); | 1490 ProcessObjectGroups(); |
1390 | 1491 |
1492 AfterMarking(); | |
1493 } | |
1494 | |
1495 | |
1496 void MarkCompactCollector::AfterMarking() { | |
1391 // Prune the symbol table removing all symbols only pointed to by the | 1497 // Prune the symbol table removing all symbols only pointed to by the |
1392 // symbol table. Cannot use symbol_table() here because the symbol | 1498 // symbol table. Cannot use symbol_table() here because the symbol |
1393 // table is marked. | 1499 // table is marked. |
1394 SymbolTable* symbol_table = Heap::raw_unchecked_symbol_table(); | 1500 SymbolTable* symbol_table = Heap::raw_unchecked_symbol_table(); |
1395 SymbolTableCleaner v; | 1501 SymbolTableCleaner v; |
1396 symbol_table->IterateElements(&v); | 1502 symbol_table->IterateElements(&v); |
1397 symbol_table->ElementsRemoved(v.PointersRemoved()); | 1503 symbol_table->ElementsRemoved(v.PointersRemoved()); |
1398 ExternalStringTable::Iterate(&v); | 1504 ExternalStringTable::Iterate(&v); |
1399 ExternalStringTable::CleanUp(); | 1505 ExternalStringTable::CleanUp(); |
1400 | 1506 |
1401 // Process the weak references. | 1507 // Process the weak references. |
1402 MarkCompactWeakObjectRetainer mark_compact_object_retainer; | 1508 MarkCompactWeakObjectRetainer mark_compact_object_retainer; |
1403 Heap::ProcessWeakReferences(&mark_compact_object_retainer); | 1509 Heap::ProcessWeakReferences(&mark_compact_object_retainer); |
1404 | 1510 |
1405 // Remove object groups after marking phase. | 1511 // Remove object groups after marking phase. |
1406 GlobalHandles::RemoveObjectGroups(); | 1512 GlobalHandles::RemoveObjectGroups(); |
1407 | 1513 |
1408 // Flush code from collected candidates. | 1514 // Flush code from collected candidates. |
1409 FlushCode::ProcessCandidates(); | 1515 // FlushCode::ProcessCandidates(); |
Erik Corry
2011/02/22 12:27:19
Commented code and missing TODO'
Vyacheslav Egorov (Chromium)
2011/02/23 14:31:46
Done.
| |
1410 } | 1516 } |
1411 | 1517 |
1412 | 1518 |
1413 #ifdef DEBUG | 1519 #ifdef DEBUG |
1414 void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj) { | 1520 void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj) { |
1415 live_bytes_ += obj->Size(); | 1521 live_bytes_ += obj->Size(); |
1416 if (Heap::new_space()->Contains(obj)) { | 1522 if (Heap::new_space()->Contains(obj)) { |
1417 live_young_objects_size_ += obj->Size(); | 1523 live_young_objects_size_ += obj->Size(); |
1418 } else if (Heap::map_space()->Contains(obj)) { | 1524 } else if (Heap::map_space()->Contains(obj)) { |
1419 ASSERT(obj->IsMap()); | 1525 ASSERT(obj->IsMap()); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1559 void VisitPointers(Object** start, Object** end) { | 1665 void VisitPointers(Object** start, Object** end) { |
1560 for (Object** p = start; p < end; p++) { | 1666 for (Object** p = start; p < end; p++) { |
1561 StaticPointersToNewGenUpdatingVisitor::VisitPointer(p); | 1667 StaticPointersToNewGenUpdatingVisitor::VisitPointer(p); |
1562 } | 1668 } |
1563 } | 1669 } |
1564 | 1670 |
1565 void VisitCodeTarget(RelocInfo* rinfo) { | 1671 void VisitCodeTarget(RelocInfo* rinfo) { |
1566 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); | 1672 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); |
1567 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 1673 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
1568 VisitPointer(&target); | 1674 VisitPointer(&target); |
1569 rinfo->set_target_address(Code::cast(target)->instruction_start()); | 1675 rinfo->set_target_address(Code::cast(target)->instruction_start(), NULL); |
1570 } | 1676 } |
1571 | 1677 |
1572 void VisitDebugTarget(RelocInfo* rinfo) { | 1678 void VisitDebugTarget(RelocInfo* rinfo) { |
1573 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && | 1679 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && |
1574 rinfo->IsPatchedReturnSequence()) || | 1680 rinfo->IsPatchedReturnSequence()) || |
1575 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && | 1681 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && |
1576 rinfo->IsPatchedDebugBreakSlotSequence())); | 1682 rinfo->IsPatchedDebugBreakSlotSequence())); |
1577 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); | 1683 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); |
1578 VisitPointer(&target); | 1684 VisitPointer(&target); |
1579 rinfo->set_call_address(Code::cast(target)->instruction_start()); | 1685 rinfo->set_call_address(Code::cast(target)->instruction_start()); |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1889 Marking::ClearMark(object); | 1995 Marking::ClearMark(object); |
1890 MarkCompactCollector::tracer()->decrement_marked_count(); | 1996 MarkCompactCollector::tracer()->decrement_marked_count(); |
1891 | 1997 |
1892 if (!is_previous_alive) { // Transition from free to live. | 1998 if (!is_previous_alive) { // Transition from free to live. |
1893 space->DeallocateBlock(free_start, | 1999 space->DeallocateBlock(free_start, |
1894 static_cast<int>(current - free_start), | 2000 static_cast<int>(current - free_start), |
1895 true); | 2001 true); |
1896 is_previous_alive = true; | 2002 is_previous_alive = true; |
1897 } | 2003 } |
1898 } else { | 2004 } else { |
2005 ASSERT((current + kPointerSize) >= p->AllocationTop() || | |
2006 object->Size() == 4 || | |
Erik Corry
2011/02/22 12:27:19
kPointerSize?
Vyacheslav Egorov (Chromium)
2011/02/23 14:31:46
Done.
| |
2007 IncrementalMarking::IsWhite(object)); | |
1899 MarkCompactCollector::ReportDeleteIfNeeded(object); | 2008 MarkCompactCollector::ReportDeleteIfNeeded(object); |
1900 if (is_previous_alive) { // Transition from live to free. | 2009 if (is_previous_alive) { // Transition from live to free. |
1901 free_start = current; | 2010 free_start = current; |
1902 is_previous_alive = false; | 2011 is_previous_alive = false; |
1903 } | 2012 } |
1904 } | 2013 } |
1905 } | 2014 } |
1906 | 2015 |
1907 if (!is_previous_alive) *last_free_start = free_start; | 2016 if (!is_previous_alive) *last_free_start = free_start; |
1908 } | 2017 } |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2031 space->SetTop(new_allocation_top); | 2140 space->SetTop(new_allocation_top); |
2032 } | 2141 } |
2033 } | 2142 } |
2034 | 2143 |
2035 | 2144 |
2036 void MarkCompactCollector::SweepSpaces() { | 2145 void MarkCompactCollector::SweepSpaces() { |
2037 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP); | 2146 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP); |
2038 #ifdef DEBUG | 2147 #ifdef DEBUG |
2039 state_ = SWEEP_SPACES; | 2148 state_ = SWEEP_SPACES; |
2040 #endif | 2149 #endif |
2150 | |
2151 #ifndef DEBUG | |
2152 SweeperType fast_sweeper = CONSERVATIVE; | |
2153 #else | |
2154 SweeperType fast_sweeper = PRECISE; | |
2155 #endif | |
2156 | |
2041 ASSERT(!IsCompacting()); | 2157 ASSERT(!IsCompacting()); |
2042 // Noncompacting collections simply sweep the spaces to clear the mark | 2158 // Noncompacting collections simply sweep the spaces to clear the mark |
2043 // bits and free the nonlive blocks (for old and map spaces). We sweep | 2159 // bits and free the nonlive blocks (for old and map spaces). We sweep |
2044 // the map space last because freeing non-live maps overwrites them and | 2160 // the map space last because freeing non-live maps overwrites them and |
2045 // the other spaces rely on possibly non-live maps to get the sizes for | 2161 // the other spaces rely on possibly non-live maps to get the sizes for |
2046 // non-live objects. | 2162 // non-live objects. |
2047 SweepSpace(Heap::old_pointer_space(), CONSERVATIVE); | 2163 SweepSpace(Heap::old_pointer_space(), fast_sweeper); |
2048 SweepSpace(Heap::old_data_space(), CONSERVATIVE); | 2164 SweepSpace(Heap::old_data_space(), fast_sweeper); |
2049 SweepSpace(Heap::code_space(), PRECISE); | 2165 SweepSpace(Heap::code_space(), PRECISE); |
2050 // TODO(gc): implement specialized sweeper for cell space. | 2166 // TODO(gc): implement specialized sweeper for cell space. |
2051 SweepSpace(Heap::cell_space(), CONSERVATIVE); | 2167 SweepSpace(Heap::cell_space(), fast_sweeper); |
2052 { GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP_NEWSPACE); | 2168 { GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP_NEWSPACE); |
2053 SweepNewSpace(Heap::new_space()); | 2169 SweepNewSpace(Heap::new_space()); |
2054 } | 2170 } |
2055 // TODO(gc): ClearNonLiveTransitions depends on precise sweeping of | 2171 // TODO(gc): ClearNonLiveTransitions depends on precise sweeping of |
2056 // map space to detect whether unmarked map became dead in this | 2172 // map space to detect whether unmarked map became dead in this |
2057 // collection or in one of the previous ones. | 2173 // collection or in one of the previous ones. |
2058 // TODO(gc): Implement specialized sweeper for map space. | 2174 // TODO(gc): Implement specialized sweeper for map space. |
2059 SweepSpace(Heap::map_space(), PRECISE); | 2175 SweepSpace(Heap::map_space(), PRECISE); |
2060 | 2176 |
2061 ASSERT(live_map_objects_size_ <= Heap::map_space()->Size()); | 2177 ASSERT(live_map_objects_size_ <= Heap::map_space()->Size()); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2134 } | 2250 } |
2135 | 2251 |
2136 | 2252 |
2137 void MarkCompactCollector::Initialize() { | 2253 void MarkCompactCollector::Initialize() { |
2138 StaticPointersToNewGenUpdatingVisitor::Initialize(); | 2254 StaticPointersToNewGenUpdatingVisitor::Initialize(); |
2139 StaticMarkingVisitor::Initialize(); | 2255 StaticMarkingVisitor::Initialize(); |
2140 } | 2256 } |
2141 | 2257 |
2142 | 2258 |
2143 } } // namespace v8::internal | 2259 } } // namespace v8::internal |
OLD | NEW |