| 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); |
| 499 | 500 |
| 500 FindPointersToNewSpaceInMaps(map_aligned_start, | 501 FindPointersToNewSpaceInMaps(map_aligned_start, |
| 501 map_aligned_end, | 502 map_aligned_end, |
| 502 slot_callback); | 503 slot_callback); |
| 503 } | 504 } |
| 504 | 505 |
| 505 | 506 |
| 506 // This function iterates over all the pointers in a paged space in the heap, | 507 // This function iterates over all the pointers in a paged space in the heap, |
| 507 // looking for pointers into new space. Within the pages there may be dead | 508 // looking for pointers into new space. Within the pages there may be dead |
| 508 // objects that have not been overwritten by free spaces or fillers because of | 509 // objects that have not been overwritten by free spaces or fillers because of |
| 509 // lazy sweeping. These dead objects may not contain pointers to new space. | 510 // lazy sweeping. These dead objects may not contain pointers to new space. |
| 510 // The garbage areas that have been swept properly (these will normally be the | 511 // The garbage areas that have been swept properly (these will normally be the |
| 511 // large ones) will be marked with free space and filler map words. In | 512 // large ones) will be marked with free space and filler map words. In |
| 512 // addition any area that has never been used at all for object allocation must | 513 // addition any area that has never been used at all for object allocation must |
| 513 // be marked with a free space or filler. Because the free space and filler | 514 // be marked with a free space or filler. Because the free space and filler |
| 514 // maps do not move we can always recognize these even after a compaction. | 515 // maps do not move we can always recognize these even after a compaction. |
| 515 // Normal objects like FixedArrays and JSObjects should not contain references | 516 // Normal objects like FixedArrays and JSObjects should not contain references |
| 516 // to these maps. The special garbage section (see comment in spaces.h) is | 517 // to these maps. The special garbage section (see comment in spaces.h) is |
| 517 // skipped since it can contain absolutely anything. Any objects that are | 518 // skipped since it can contain absolutely anything. Any objects that are |
| 518 // allocated during iteration may or may not be visited by the iteration, but | 519 // allocated during iteration may or may not be visited by the iteration, but |
| 519 // they will not be partially visited. | 520 // they will not be partially visited. |
| 520 void StoreBuffer::FindPointersToNewSpaceOnPage( | 521 void StoreBuffer::FindPointersToNewSpaceOnPage( |
| 521 PagedSpace* space, | 522 PagedSpace* space, |
| 522 Page* page, | 523 Page* page, |
| 523 RegionCallback region_callback, | 524 RegionCallback region_callback, |
| 524 ObjectSlotCallback slot_callback) { | 525 ObjectSlotCallback slot_callback) { |
| 525 Address visitable_start = page->ObjectAreaStart(); | 526 Address visitable_start = page->ObjectAreaStart(); |
| 527 Address end_of_page = page->ObjectAreaEnd(); |
| 526 | 528 |
| 527 Address visitable_end = visitable_start; | 529 Address visitable_end = visitable_start; |
| 528 | 530 |
| 529 Object* free_space_map = heap_->free_space_map(); | 531 Object* free_space_map = heap_->free_space_map(); |
| 530 Object* two_pointer_filler_map = heap_->two_pointer_filler_map(); | 532 Object* two_pointer_filler_map = heap_->two_pointer_filler_map(); |
| 531 | 533 |
| 532 while (true) { // While the page grows (doesn't normally happen). | 534 while (visitable_end < end_of_page) { |
| 533 Address end_of_page = page->ObjectAreaEnd(); | 535 Object* o = *reinterpret_cast<Object**>(visitable_end); |
| 534 while (visitable_end < end_of_page) { | 536 // Skip fillers but not things that look like fillers in the special |
| 535 Object* o = *reinterpret_cast<Object**>(visitable_end); | 537 // garbage section which can contain anything. |
| 536 // Skip fillers but not things that look like fillers in the special | 538 if (o == free_space_map || |
| 537 // garbage section which can contain anything. | 539 o == two_pointer_filler_map || |
| 538 if (o == free_space_map || | 540 (visitable_end == space->top() && visitable_end != space->limit())) { |
| 539 o == two_pointer_filler_map || | 541 if (visitable_start != visitable_end) { |
| 540 (visitable_end == space->top() && visitable_end != space->limit())) { | 542 // After calling this the special garbage section may have moved. |
| 541 if (visitable_start != visitable_end) { | 543 (this->*region_callback)(visitable_start, |
| 542 // After calling this the special garbage section may have moved. | 544 visitable_end, |
| 543 (this->*region_callback)(visitable_start, | 545 slot_callback); |
| 544 visitable_end, | 546 if (visitable_end >= space->top() && visitable_end < space->limit()) { |
| 545 slot_callback); | 547 visitable_end = space->limit(); |
| 546 if (visitable_end >= space->top() && visitable_end < space->limit()) { | 548 visitable_start = visitable_end; |
| 547 visitable_end = space->limit(); | 549 continue; |
| 548 visitable_start = visitable_end; | |
| 549 continue; | |
| 550 } | |
| 551 } | 550 } |
| 552 if (visitable_end == space->top() && visitable_end != space->limit()) { | 551 } |
| 553 visitable_start = visitable_end = space->limit(); | 552 if (visitable_end == space->top() && visitable_end != space->limit()) { |
| 554 } else { | 553 visitable_start = visitable_end = space->limit(); |
| 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 { | 554 } else { |
| 566 ASSERT(o != free_space_map); | 555 // At this point we are either at the start of a filler or we are at |
| 567 ASSERT(o != two_pointer_filler_map); | 556 // the point where the space->top() used to be before the |
| 568 ASSERT(visitable_end < space->top() || visitable_end >= space->limit()); | 557 // visit_pointer_region call above. Either way we can skip the |
| 569 visitable_end += kPointerSize; | 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; |
| 570 } | 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; |
| 571 } | 570 } |
| 572 ASSERT(visitable_end >= end_of_page); | |
| 573 // If the page did not grow we are done. | |
| 574 if (end_of_page == page->ObjectAreaEnd()) break; | |
| 575 } | 571 } |
| 576 ASSERT(visitable_end == page->ObjectAreaEnd()); | 572 ASSERT(visitable_end == end_of_page); |
| 577 if (visitable_start != visitable_end) { | 573 if (visitable_start != visitable_end) { |
| 578 (this->*region_callback)(visitable_start, | 574 (this->*region_callback)(visitable_start, |
| 579 visitable_end, | 575 visitable_end, |
| 580 slot_callback); | 576 slot_callback); |
| 581 } | 577 } |
| 582 } | 578 } |
| 583 | 579 |
| 584 | 580 |
| 585 void StoreBuffer::IteratePointersInStoreBuffer( | 581 void StoreBuffer::IteratePointersInStoreBuffer( |
| 586 ObjectSlotCallback slot_callback) { | 582 ObjectSlotCallback slot_callback) { |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 heap_->isolate()->counters()->store_buffer_compactions()->Increment(); | 710 heap_->isolate()->counters()->store_buffer_compactions()->Increment(); |
| 715 CheckForFullBuffer(); | 711 CheckForFullBuffer(); |
| 716 } | 712 } |
| 717 | 713 |
| 718 | 714 |
| 719 void StoreBuffer::CheckForFullBuffer() { | 715 void StoreBuffer::CheckForFullBuffer() { |
| 720 EnsureSpace(kStoreBufferSize * 2); | 716 EnsureSpace(kStoreBufferSize * 2); |
| 721 } | 717 } |
| 722 | 718 |
| 723 } } // namespace v8::internal | 719 } } // namespace v8::internal |
| OLD | NEW |