| 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 the mark doesn't move, we don't check the color of the object. |
| 318 // It doesn't matter whether the object is black, since it hasn't changed |
| 319 // size, so the adjustment to the live data count will be zero anyway. |
| 320 if (old_start == new_start) return false; |
| 317 | 321 |
| 318 MarkBit new_mark_bit = MarkBitFrom(new_start); | 322 MarkBit new_mark_bit = MarkBitFrom(new_start); |
| 319 | 323 |
| 320 if (heap_->incremental_marking()->IsMarking()) { | 324 if (heap_->incremental_marking()->IsMarking()) { |
| 321 MarkBit old_mark_bit = MarkBitFrom(old_start); | 325 MarkBit old_mark_bit = MarkBitFrom(old_start); |
| 322 #ifdef DEBUG | 326 #ifdef DEBUG |
| 323 ObjectColor old_color = Color(old_mark_bit); | 327 ObjectColor old_color = Color(old_mark_bit); |
| 324 #endif | 328 #endif |
| 325 if (Marking::IsBlack(old_mark_bit)) { | 329 if (Marking::IsBlack(old_mark_bit)) { |
| 326 Marking::MarkBlack(new_mark_bit); | 330 Marking::MarkBlack(new_mark_bit); |
| 327 old_mark_bit.Clear(); | 331 old_mark_bit.Clear(); |
| 332 return true; |
| 328 } else if (Marking::IsGrey(old_mark_bit)) { | 333 } else if (Marking::IsGrey(old_mark_bit)) { |
| 329 old_mark_bit.Next().Clear(); | 334 old_mark_bit.Next().Clear(); |
| 330 heap_->incremental_marking()->WhiteToGreyAndPush( | 335 heap_->incremental_marking()->WhiteToGreyAndPush( |
| 331 HeapObject::FromAddress(new_start), new_mark_bit); | 336 HeapObject::FromAddress(new_start), new_mark_bit); |
| 332 heap_->incremental_marking()->RestartIfNotMarking(); | 337 heap_->incremental_marking()->RestartIfNotMarking(); |
| 333 // TODO(gc): if we shift huge array in the loop we might end up pushing | 338 // 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 | 339 // 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 | 340 // elements on top/bottom of the marking deque to see whether they are |
| 336 // equal to old_start. | 341 // equal to old_start. |
| 337 } | 342 } |
| 338 | 343 |
| 339 #ifdef DEBUG | 344 #ifdef DEBUG |
| 340 ObjectColor new_color = Color(new_mark_bit); | 345 ObjectColor new_color = Color(new_mark_bit); |
| 341 ASSERT(new_color == old_color); | 346 ASSERT(new_color == old_color); |
| 342 #endif | 347 #endif |
| 343 } else { | 348 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 } | 349 } |
| 350 MarkBit old_mark_bit = MarkBitFrom(old_start); |
| 351 if (!old_mark_bit.Get()) { |
| 352 return false; |
| 353 } |
| 354 new_mark_bit.Set(); |
| 355 return true; |
| 354 } | 356 } |
| 355 | 357 |
| 356 | 358 |
| 357 void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { | 359 void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { |
| 358 ASSERT(space->identity() == OLD_POINTER_SPACE || | 360 ASSERT(space->identity() == OLD_POINTER_SPACE || |
| 359 space->identity() == OLD_DATA_SPACE); | 361 space->identity() == OLD_DATA_SPACE); |
| 360 | 362 |
| 361 PageIterator it(space); | 363 PageIterator it(space); |
| 362 while (it.has_next()) { | 364 while (it.has_next()) { |
| 363 Page* p = it.next(); | 365 Page* p = it.next(); |
| (...skipping 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1373 } | 1375 } |
| 1374 } | 1376 } |
| 1375 | 1377 |
| 1376 | 1378 |
| 1377 void MarkCompactCollector::MarkMapContents(Map* map) { | 1379 void MarkCompactCollector::MarkMapContents(Map* map) { |
| 1378 // Mark prototype transitions array but don't push it into marking stack. | 1380 // 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 | 1381 // This will make references from it weak. We will clean dead prototype |
| 1380 // transitions in ClearNonLiveTransitions. | 1382 // transitions in ClearNonLiveTransitions. |
| 1381 FixedArray* prototype_transitions = map->prototype_transitions(); | 1383 FixedArray* prototype_transitions = map->prototype_transitions(); |
| 1382 MarkBit mark = Marking::MarkBitFrom(prototype_transitions); | 1384 MarkBit mark = Marking::MarkBitFrom(prototype_transitions); |
| 1383 if (!mark.Get()) mark.Set(); | 1385 if (!mark.Get()) { |
| 1386 mark.Set(); |
| 1387 MemoryChunk::IncrementLiveBytes(prototype_transitions->address(), |
| 1388 prototype_transitions->Size()); |
| 1389 } |
| 1384 | 1390 |
| 1385 Object** raw_descriptor_array_slot = | 1391 Object** raw_descriptor_array_slot = |
| 1386 HeapObject::RawField(map, Map::kInstanceDescriptorsOrBitField3Offset); | 1392 HeapObject::RawField(map, Map::kInstanceDescriptorsOrBitField3Offset); |
| 1387 Object* raw_descriptor_array = *raw_descriptor_array_slot; | 1393 Object* raw_descriptor_array = *raw_descriptor_array_slot; |
| 1388 if (!raw_descriptor_array->IsSmi()) { | 1394 if (!raw_descriptor_array->IsSmi()) { |
| 1389 MarkDescriptorArray( | 1395 MarkDescriptorArray( |
| 1390 reinterpret_cast<DescriptorArray*>(raw_descriptor_array)); | 1396 reinterpret_cast<DescriptorArray*>(raw_descriptor_array)); |
| 1391 } | 1397 } |
| 1392 | 1398 |
| 1393 // Mark the Object* fields of the Map. | 1399 // 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 | 2217 // 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 | 2218 // new entries in the store buffer and may cause some pages to be marked |
| 2213 // scan-on-scavenge. | 2219 // scan-on-scavenge. |
| 2214 SemiSpaceIterator from_it(from_bottom, from_top); | 2220 SemiSpaceIterator from_it(from_bottom, from_top); |
| 2215 for (HeapObject* object = from_it.Next(); | 2221 for (HeapObject* object = from_it.Next(); |
| 2216 object != NULL; | 2222 object != NULL; |
| 2217 object = from_it.Next()) { | 2223 object = from_it.Next()) { |
| 2218 MarkBit mark_bit = Marking::MarkBitFrom(object); | 2224 MarkBit mark_bit = Marking::MarkBitFrom(object); |
| 2219 if (mark_bit.Get()) { | 2225 if (mark_bit.Get()) { |
| 2220 mark_bit.Clear(); | 2226 mark_bit.Clear(); |
| 2221 | |
| 2222 int size = object->Size(); | 2227 int size = object->Size(); |
| 2223 survivors_size += size; | 2228 survivors_size += size; |
| 2229 MemoryChunk::IncrementLiveBytes(object->address(), -size); |
| 2224 | 2230 |
| 2225 // Aggressively promote young survivors to the old space. | 2231 // Aggressively promote young survivors to the old space. |
| 2226 if (TryPromoteObject(object, size)) { | 2232 if (TryPromoteObject(object, size)) { |
| 2227 continue; | 2233 continue; |
| 2228 } | 2234 } |
| 2229 | 2235 |
| 2230 // Promotion failed. Just migrate object to another semispace. | 2236 // Promotion failed. Just migrate object to another semispace. |
| 2231 MaybeObject* allocation = new_space->AllocateRaw(size); | 2237 MaybeObject* allocation = new_space->AllocateRaw(size); |
| 2232 if (allocation->IsFailure()) { | 2238 if (allocation->IsFailure()) { |
| 2233 if (!new_space->AddFreshPage()) { | 2239 if (!new_space->AddFreshPage()) { |
| (...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3073 visitor->VisitPointer(last_buffer[slot_idx]); | 3079 visitor->VisitPointer(last_buffer[slot_idx]); |
| 3074 } | 3080 } |
| 3075 } | 3081 } |
| 3076 | 3082 |
| 3077 | 3083 |
| 3078 void SlotsBuffer::Report() { | 3084 void SlotsBuffer::Report() { |
| 3079 } | 3085 } |
| 3080 | 3086 |
| 3081 | 3087 |
| 3082 } } // namespace v8::internal | 3088 } } // namespace v8::internal |
| OLD | NEW |