Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 278 VerifyMarkbitsAreClean(heap->map_space()); | 278 VerifyMarkbitsAreClean(heap->map_space()); |
| 279 VerifyMarkbitsAreClean(heap->new_space()); | 279 VerifyMarkbitsAreClean(heap->new_space()); |
| 280 } | 280 } |
| 281 #endif | 281 #endif |
| 282 | 282 |
| 283 | 283 |
| 284 static void ClearMarkbits(PagedSpace* space) { | 284 static void ClearMarkbits(PagedSpace* space) { |
| 285 PageIterator it(space); | 285 PageIterator it(space); |
| 286 | 286 |
| 287 while (it.has_next()) { | 287 while (it.has_next()) { |
| 288 Page* p = it.next(); | 288 Bitmap::Clear(it.next()); |
| 289 p->markbits()->Clear(); | |
| 290 } | 289 } |
| 291 } | 290 } |
| 292 | 291 |
| 293 | 292 |
| 294 static void ClearMarkbits(NewSpace* space) { | 293 static void ClearMarkbits(NewSpace* space) { |
| 295 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd()); | 294 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd()); |
| 296 | 295 |
| 297 while (it.has_next()) { | 296 while (it.has_next()) { |
| 298 NewSpacePage* p = it.next(); | 297 Bitmap::Clear(it.next()); |
| 299 p->markbits()->Clear(); | |
| 300 } | 298 } |
| 301 } | 299 } |
| 302 | 300 |
| 303 | 301 |
| 304 static void ClearMarkbits(Heap* heap) { | 302 static void ClearMarkbits(Heap* heap) { |
| 305 // TODO(gc): Clean the mark bits while sweeping. | 303 // TODO(gc): Clean the mark bits while sweeping. |
| 306 ClearMarkbits(heap->code_space()); | 304 ClearMarkbits(heap->code_space()); |
| 307 ClearMarkbits(heap->map_space()); | 305 ClearMarkbits(heap->map_space()); |
| 308 ClearMarkbits(heap->old_pointer_space()); | 306 ClearMarkbits(heap->old_pointer_space()); |
| 309 ClearMarkbits(heap->old_data_space()); | 307 ClearMarkbits(heap->old_data_space()); |
| 310 ClearMarkbits(heap->cell_space()); | 308 ClearMarkbits(heap->cell_space()); |
| 311 ClearMarkbits(heap->new_space()); | 309 ClearMarkbits(heap->new_space()); |
| 312 } | 310 } |
| 313 | 311 |
| 314 | 312 |
| 315 void Marking::TransferMark(Address old_start, Address new_start) { | 313 bool Marking::TransferMark(Address old_start, Address new_start) { |
| 316 if (old_start == new_start) return; | 314 // This is only used when resizing an object. |
| 315 ASSERT(MemoryChunk::FromAddress(old_start) == | |
| 316 MemoryChunk::FromAddress(new_start)); | |
| 317 if (old_start == new_start) return false; | |
|
Erik Corry
2011/06/24 09:46:17
A comment to the effect that the return value does
Lasse Reichstein
2011/06/24 11:09:08
done.
| |
| 317 | 318 |
| 318 MarkBit new_mark_bit = MarkBitFrom(new_start); | 319 MarkBit new_mark_bit = MarkBitFrom(new_start); |
| 319 | 320 |
| 320 if (heap_->incremental_marking()->IsMarking()) { | 321 if (heap_->incremental_marking()->IsMarking()) { |
| 321 MarkBit old_mark_bit = MarkBitFrom(old_start); | 322 MarkBit old_mark_bit = MarkBitFrom(old_start); |
| 322 #ifdef DEBUG | 323 #ifdef DEBUG |
| 323 ObjectColor old_color = Color(old_mark_bit); | 324 ObjectColor old_color = Color(old_mark_bit); |
| 324 #endif | 325 #endif |
| 325 if (Marking::IsBlack(old_mark_bit)) { | 326 if (Marking::IsBlack(old_mark_bit)) { |
| 326 Marking::MarkBlack(new_mark_bit); | 327 Marking::MarkBlack(new_mark_bit); |
| 327 old_mark_bit.Clear(); | 328 old_mark_bit.Clear(); |
| 329 return true; | |
| 328 } else if (Marking::IsGrey(old_mark_bit)) { | 330 } else if (Marking::IsGrey(old_mark_bit)) { |
| 329 old_mark_bit.Next().Clear(); | 331 old_mark_bit.Next().Clear(); |
| 330 heap_->incremental_marking()->WhiteToGreyAndPush( | 332 heap_->incremental_marking()->WhiteToGreyAndPush( |
| 331 HeapObject::FromAddress(new_start), new_mark_bit); | 333 HeapObject::FromAddress(new_start), new_mark_bit); |
| 332 heap_->incremental_marking()->RestartIfNotMarking(); | 334 heap_->incremental_marking()->RestartIfNotMarking(); |
| 333 // TODO(gc): if we shift huge array in the loop we might end up pushing | 335 // TODO(gc): if we shift huge array in the loop we might end up pushing |
| 334 // too much into the marking deque. Maybe we should check one or two | 336 // too much into the marking deque. Maybe we should check one or two |
| 335 // elements on top/bottom of the marking deque to see whether they are | 337 // elements on top/bottom of the marking deque to see whether they are |
| 336 // equal to old_start. | 338 // equal to old_start. |
| 337 } | 339 } |
| 338 | 340 |
| 339 #ifdef DEBUG | 341 #ifdef DEBUG |
| 340 ObjectColor new_color = Color(new_mark_bit); | 342 ObjectColor new_color = Color(new_mark_bit); |
| 341 ASSERT(new_color == old_color); | 343 ASSERT(new_color == old_color); |
| 342 #endif | 344 #endif |
| 343 } else { | 345 return false; |
| 344 if (heap_->InNewSpace(old_start)) { | |
| 345 return; | |
| 346 } else { | |
| 347 MarkBit old_mark_bit = MarkBitFrom(old_start); | |
| 348 if (!old_mark_bit.Get()) { | |
| 349 return; | |
| 350 } | |
| 351 } | |
| 352 new_mark_bit.Set(); | |
| 353 } | 346 } |
| 347 MarkBit old_mark_bit = MarkBitFrom(old_start); | |
| 348 if (!old_mark_bit.Get()) { | |
| 349 return false; | |
| 350 } | |
| 351 new_mark_bit.Set(); | |
| 352 return true; | |
| 354 } | 353 } |
| 355 | 354 |
| 356 | 355 |
| 357 void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { | 356 void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { |
| 358 ASSERT(space->identity() == OLD_POINTER_SPACE || | 357 ASSERT(space->identity() == OLD_POINTER_SPACE || |
| 359 space->identity() == OLD_DATA_SPACE); | 358 space->identity() == OLD_DATA_SPACE); |
| 360 | 359 |
| 361 PageIterator it(space); | 360 PageIterator it(space); |
| 362 while (it.has_next()) { | 361 while (it.has_next()) { |
| 363 Page* p = it.next(); | 362 Page* p = it.next(); |
| (...skipping 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1373 } | 1372 } |
| 1374 } | 1373 } |
| 1375 | 1374 |
| 1376 | 1375 |
| 1377 void MarkCompactCollector::MarkMapContents(Map* map) { | 1376 void MarkCompactCollector::MarkMapContents(Map* map) { |
| 1378 // Mark prototype transitions array but don't push it into marking stack. | 1377 // Mark prototype transitions array but don't push it into marking stack. |
| 1379 // This will make references from it weak. We will clean dead prototype | 1378 // This will make references from it weak. We will clean dead prototype |
| 1380 // transitions in ClearNonLiveTransitions. | 1379 // transitions in ClearNonLiveTransitions. |
| 1381 FixedArray* prototype_transitions = map->prototype_transitions(); | 1380 FixedArray* prototype_transitions = map->prototype_transitions(); |
| 1382 MarkBit mark = Marking::MarkBitFrom(prototype_transitions); | 1381 MarkBit mark = Marking::MarkBitFrom(prototype_transitions); |
| 1383 if (!mark.Get()) mark.Set(); | 1382 if (!mark.Get()) { |
| 1383 mark.Set(); | |
| 1384 MemoryChunk::IncrementLiveBytes(prototype_transitions->address(), | |
| 1385 prototype_transitions->Size()); | |
| 1386 } | |
| 1384 | 1387 |
| 1385 Object** raw_descriptor_array_slot = | 1388 Object** raw_descriptor_array_slot = |
| 1386 HeapObject::RawField(map, Map::kInstanceDescriptorsOrBitField3Offset); | 1389 HeapObject::RawField(map, Map::kInstanceDescriptorsOrBitField3Offset); |
| 1387 Object* raw_descriptor_array = *raw_descriptor_array_slot; | 1390 Object* raw_descriptor_array = *raw_descriptor_array_slot; |
| 1388 if (!raw_descriptor_array->IsSmi()) { | 1391 if (!raw_descriptor_array->IsSmi()) { |
| 1389 MarkDescriptorArray( | 1392 MarkDescriptorArray( |
| 1390 reinterpret_cast<DescriptorArray*>(raw_descriptor_array)); | 1393 reinterpret_cast<DescriptorArray*>(raw_descriptor_array)); |
| 1391 } | 1394 } |
| 1392 | 1395 |
| 1393 // Mark the Object* fields of the Map. | 1396 // Mark the Object* fields of the Map. |
| (...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2211 // migrate live objects and write forwarding addresses. This stage puts | 2214 // migrate live objects and write forwarding addresses. This stage puts |
| 2212 // new entries in the store buffer and may cause some pages to be marked | 2215 // new entries in the store buffer and may cause some pages to be marked |
| 2213 // scan-on-scavenge. | 2216 // scan-on-scavenge. |
| 2214 SemiSpaceIterator from_it(from_bottom, from_top); | 2217 SemiSpaceIterator from_it(from_bottom, from_top); |
| 2215 for (HeapObject* object = from_it.Next(); | 2218 for (HeapObject* object = from_it.Next(); |
| 2216 object != NULL; | 2219 object != NULL; |
| 2217 object = from_it.Next()) { | 2220 object = from_it.Next()) { |
| 2218 MarkBit mark_bit = Marking::MarkBitFrom(object); | 2221 MarkBit mark_bit = Marking::MarkBitFrom(object); |
| 2219 if (mark_bit.Get()) { | 2222 if (mark_bit.Get()) { |
| 2220 mark_bit.Clear(); | 2223 mark_bit.Clear(); |
| 2221 | |
| 2222 int size = object->Size(); | 2224 int size = object->Size(); |
| 2223 survivors_size += size; | 2225 survivors_size += size; |
| 2226 MemoryChunk::IncrementLiveBytes(object->address(), -size); | |
| 2224 | 2227 |
| 2225 // Aggressively promote young survivors to the old space. | 2228 // Aggressively promote young survivors to the old space. |
| 2226 if (TryPromoteObject(object, size)) { | 2229 if (TryPromoteObject(object, size)) { |
| 2227 continue; | 2230 continue; |
| 2228 } | 2231 } |
| 2229 | 2232 |
| 2230 // Promotion failed. Just migrate object to another semispace. | 2233 // Promotion failed. Just migrate object to another semispace. |
| 2231 MaybeObject* allocation = new_space->AllocateRaw(size); | 2234 MaybeObject* allocation = new_space->AllocateRaw(size); |
| 2232 if (allocation->IsFailure()) { | 2235 if (allocation->IsFailure()) { |
| 2233 if (!new_space->AddFreshPage()) { | 2236 if (!new_space->AddFreshPage()) { |
| (...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3073 visitor->VisitPointer(last_buffer[slot_idx]); | 3076 visitor->VisitPointer(last_buffer[slot_idx]); |
| 3074 } | 3077 } |
| 3075 } | 3078 } |
| 3076 | 3079 |
| 3077 | 3080 |
| 3078 void SlotsBuffer::Report() { | 3081 void SlotsBuffer::Report() { |
| 3079 } | 3082 } |
| 3080 | 3083 |
| 3081 | 3084 |
| 3082 } } // namespace v8::internal | 3085 } } // namespace v8::internal |
| OLD | NEW |