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 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
489 | 489 |
490 | 490 |
491 void StoreBuffer::FindPointersToNewSpaceInMapsRegion( | 491 void StoreBuffer::FindPointersToNewSpaceInMapsRegion( |
492 Address start, | 492 Address start, |
493 Address end, | 493 Address end, |
494 ObjectSlotCallback slot_callback) { | 494 ObjectSlotCallback slot_callback) { |
495 Address map_aligned_start = MapStartAlign(start); | 495 Address map_aligned_start = MapStartAlign(start); |
496 Address map_aligned_end = MapEndAlign(end); | 496 Address map_aligned_end = MapEndAlign(end); |
497 | 497 |
498 ASSERT(map_aligned_start == start); | 498 ASSERT(map_aligned_start == start); |
499 ASSERT(map_aligned_end == end); | |
500 | 499 |
501 FindPointersToNewSpaceInMaps(map_aligned_start, | 500 FindPointersToNewSpaceInMaps(map_aligned_start, |
502 map_aligned_end, | 501 map_aligned_end, |
503 slot_callback); | 502 slot_callback); |
504 } | 503 } |
505 | 504 |
506 | 505 |
507 // This function iterates over all the pointers in a paged space in the heap, | 506 // This function iterates over all the pointers in a paged space in the heap, |
508 // looking for pointers into new space. Within the pages there may be dead | 507 // looking for pointers into new space. Within the pages there may be dead |
509 // objects that have not been overwritten by free spaces or fillers because of | 508 // objects that have not been overwritten by free spaces or fillers because of |
510 // lazy sweeping. These dead objects may not contain pointers to new space. | 509 // lazy sweeping. These dead objects may not contain pointers to new space. |
511 // The garbage areas that have been swept properly (these will normally be the | 510 // The garbage areas that have been swept properly (these will normally be the |
512 // large ones) will be marked with free space and filler map words. In | 511 // large ones) will be marked with free space and filler map words. In |
513 // addition any area that has never been used at all for object allocation must | 512 // addition any area that has never been used at all for object allocation must |
514 // be marked with a free space or filler. Because the free space and filler | 513 // be marked with a free space or filler. Because the free space and filler |
515 // maps do not move we can always recognize these even after a compaction. | 514 // maps do not move we can always recognize these even after a compaction. |
516 // Normal objects like FixedArrays and JSObjects should not contain references | 515 // Normal objects like FixedArrays and JSObjects should not contain references |
517 // to these maps. The special garbage section (see comment in spaces.h) is | 516 // to these maps. The special garbage section (see comment in spaces.h) is |
518 // skipped since it can contain absolutely anything. Any objects that are | 517 // skipped since it can contain absolutely anything. Any objects that are |
519 // allocated during iteration may or may not be visited by the iteration, but | 518 // allocated during iteration may or may not be visited by the iteration, but |
520 // they will not be partially visited. | 519 // they will not be partially visited. |
521 void StoreBuffer::FindPointersToNewSpaceOnPage( | 520 void StoreBuffer::FindPointersToNewSpaceOnPage( |
522 PagedSpace* space, | 521 PagedSpace* space, |
523 Page* page, | 522 Page* page, |
524 RegionCallback region_callback, | 523 RegionCallback region_callback, |
525 ObjectSlotCallback slot_callback) { | 524 ObjectSlotCallback slot_callback) { |
526 Address visitable_start = page->ObjectAreaStart(); | 525 Address visitable_start = page->ObjectAreaStart(); |
527 Address end_of_page = page->ObjectAreaEnd(); | |
528 | 526 |
529 Address visitable_end = visitable_start; | 527 Address visitable_end = visitable_start; |
530 | 528 |
531 Object* free_space_map = heap_->free_space_map(); | 529 Object* free_space_map = heap_->free_space_map(); |
532 Object* two_pointer_filler_map = heap_->two_pointer_filler_map(); | 530 Object* two_pointer_filler_map = heap_->two_pointer_filler_map(); |
533 | 531 |
534 while (visitable_end < end_of_page) { | 532 while (true) { // While the page grows (doesn't normally happen). |
535 Object* o = *reinterpret_cast<Object**>(visitable_end); | 533 Address end_of_page = page->ObjectAreaEnd(); |
536 // Skip fillers but not things that look like fillers in the special | 534 while (visitable_end < end_of_page) { |
537 // garbage section which can contain anything. | 535 Object* o = *reinterpret_cast<Object**>(visitable_end); |
538 if (o == free_space_map || | 536 // Skip fillers but not things that look like fillers in the special |
539 o == two_pointer_filler_map || | 537 // garbage section which can contain anything. |
540 (visitable_end == space->top() && visitable_end != space->limit())) { | 538 if (o == free_space_map || |
541 if (visitable_start != visitable_end) { | 539 o == two_pointer_filler_map || |
542 // After calling this the special garbage section may have moved. | 540 (visitable_end == space->top() && visitable_end != space->limit())) { |
543 (this->*region_callback)(visitable_start, | 541 if (visitable_start != visitable_end) { |
544 visitable_end, | 542 // After calling this the special garbage section may have moved. |
545 slot_callback); | 543 (this->*region_callback)(visitable_start, |
546 if (visitable_end >= space->top() && visitable_end < space->limit()) { | 544 visitable_end, |
547 visitable_end = space->limit(); | 545 slot_callback); |
548 visitable_start = visitable_end; | 546 if (visitable_end >= space->top() && visitable_end < space->limit()) { |
549 continue; | 547 visitable_end = space->limit(); |
548 visitable_start = visitable_end; | |
549 continue; | |
550 } | |
550 } | 551 } |
552 if (visitable_end == space->top() && visitable_end != space->limit()) { | |
553 visitable_start = visitable_end = space->limit(); | |
554 } else { | |
555 // At this point we are either at the start of a filler or we are at | |
556 // the point where the space->top() used to be before the | |
557 // visit_pointer_region call above. Either way we can skip the | |
558 // object at the current spot: We don't promise to visit objects | |
559 // allocated during heap traversal, and if space->top() moved then it | |
560 // must be because an object was allocated at this point. | |
561 visitable_start = | |
562 visitable_end + HeapObject::FromAddress(visitable_end)->Size(); | |
563 intptr_t start_integer = reinterpret_cast<intptr_t>(visitable_start); | |
564 if ((start_integer & (Page::kGrowthUnit - 1)) == 0 && | |
Erik Corry
2012/01/31 10:44:44
This 'if' and its contents are new.
| |
565 visitable_start != page->ObjectAreaEnd()) { | |
566 // Sometimes there is a little free-space object left at what used | |
567 // to be the end of the page. Due to object alignment restrictions | |
568 // (this is primarily an issue for maps on 64 bit) they never | |
569 // contain pointers. We skip them because the scanning logic on | |
570 // pages in FixedSpace spaces does not scan partial objects. | |
571 visitable_start = page->RoundUpToObjectAlignment(visitable_start); | |
572 } | |
573 visitable_end = visitable_start; | |
574 } | |
575 } else { | |
576 ASSERT(o != free_space_map); | |
577 ASSERT(o != two_pointer_filler_map); | |
578 ASSERT(visitable_end < space->top() || visitable_end >= space->limit()); | |
579 visitable_end += kPointerSize; | |
551 } | 580 } |
552 if (visitable_end == space->top() && visitable_end != space->limit()) { | |
553 visitable_start = visitable_end = space->limit(); | |
554 } else { | |
555 // At this point we are either at the start of a filler or we are at | |
556 // the point where the space->top() used to be before the | |
557 // visit_pointer_region call above. Either way we can skip the | |
558 // object at the current spot: We don't promise to visit objects | |
559 // allocated during heap traversal, and if space->top() moved then it | |
560 // must be because an object was allocated at this point. | |
561 visitable_start = | |
562 visitable_end + HeapObject::FromAddress(visitable_end)->Size(); | |
563 visitable_end = visitable_start; | |
564 } | |
565 } else { | |
566 ASSERT(o != free_space_map); | |
567 ASSERT(o != two_pointer_filler_map); | |
568 ASSERT(visitable_end < space->top() || visitable_end >= space->limit()); | |
569 visitable_end += kPointerSize; | |
570 } | 581 } |
582 ASSERT(visitable_end >= end_of_page); | |
583 // If the page did not grow we are done. | |
584 if (end_of_page == page->ObjectAreaEnd()) break; | |
571 } | 585 } |
572 ASSERT(visitable_end == end_of_page); | 586 ASSERT(visitable_end == page->ObjectAreaEnd()); |
573 if (visitable_start != visitable_end) { | 587 if (visitable_start != visitable_end) { |
574 (this->*region_callback)(visitable_start, | 588 (this->*region_callback)(visitable_start, |
575 visitable_end, | 589 visitable_end, |
576 slot_callback); | 590 slot_callback); |
577 } | 591 } |
578 } | 592 } |
579 | 593 |
580 | 594 |
581 void StoreBuffer::IteratePointersInStoreBuffer( | 595 void StoreBuffer::IteratePointersInStoreBuffer( |
582 ObjectSlotCallback slot_callback) { | 596 ObjectSlotCallback slot_callback) { |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
710 heap_->isolate()->counters()->store_buffer_compactions()->Increment(); | 724 heap_->isolate()->counters()->store_buffer_compactions()->Increment(); |
711 CheckForFullBuffer(); | 725 CheckForFullBuffer(); |
712 } | 726 } |
713 | 727 |
714 | 728 |
715 void StoreBuffer::CheckForFullBuffer() { | 729 void StoreBuffer::CheckForFullBuffer() { |
716 EnsureSpace(kStoreBufferSize * 2); | 730 EnsureSpace(kStoreBufferSize * 2); |
717 } | 731 } |
718 | 732 |
719 } } // namespace v8::internal | 733 } } // namespace v8::internal |
OLD | NEW |