Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: src/store-buffer.cc

Issue 285733003: Remove a race between sweepers and the free space skipping code (while iterating new space pointers) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/store-buffer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "store-buffer.h" 5 #include "store-buffer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "v8.h" 9 #include "v8.h"
10 #include "counters.h" 10 #include "counters.h"
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 } 325 }
326 326
327 327
328 void StoreBuffer::GCPrologue() { 328 void StoreBuffer::GCPrologue() {
329 ClearFilteringHashSets(); 329 ClearFilteringHashSets();
330 during_gc_ = true; 330 during_gc_ = true;
331 } 331 }
332 332
333 333
334 #ifdef VERIFY_HEAP 334 #ifdef VERIFY_HEAP
335 static void DummyScavengePointer(HeapObject** p, HeapObject* o) {
336 // Do nothing.
337 }
338
339
340 void StoreBuffer::VerifyPointers(PagedSpace* space,
341 RegionCallback region_callback) {
342 PageIterator it(space);
343
344 while (it.has_next()) {
345 Page* page = it.next();
346 FindPointersToNewSpaceOnPage(
347 reinterpret_cast<PagedSpace*>(page->owner()),
348 page,
349 region_callback,
350 &DummyScavengePointer,
351 false);
352 }
353 }
354
355
356 void StoreBuffer::VerifyPointers(LargeObjectSpace* space) { 335 void StoreBuffer::VerifyPointers(LargeObjectSpace* space) {
357 LargeObjectIterator it(space); 336 LargeObjectIterator it(space);
358 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { 337 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) {
359 if (object->IsFixedArray()) { 338 if (object->IsFixedArray()) {
360 Address slot_address = object->address(); 339 Address slot_address = object->address();
361 Address end = object->address() + object->Size(); 340 Address end = object->address() + object->Size();
362 341
363 while (slot_address < end) { 342 while (slot_address < end) {
364 HeapObject** slot = reinterpret_cast<HeapObject**>(slot_address); 343 HeapObject** slot = reinterpret_cast<HeapObject**>(slot_address);
365 // When we are not in GC the Heap::InNewSpace() predicate 344 // When we are not in GC the Heap::InNewSpace() predicate
366 // checks that pointers which satisfy predicate point into 345 // checks that pointers which satisfy predicate point into
367 // the active semispace. 346 // the active semispace.
368 Object* object = reinterpret_cast<Object*>( 347 Object* object = reinterpret_cast<Object*>(
369 NoBarrier_Load(reinterpret_cast<AtomicWord*>(slot))); 348 NoBarrier_Load(reinterpret_cast<AtomicWord*>(slot)));
370 heap_->InNewSpace(object); 349 heap_->InNewSpace(object);
371 slot_address += kPointerSize; 350 slot_address += kPointerSize;
372 } 351 }
373 } 352 }
374 } 353 }
375 } 354 }
376 #endif 355 #endif
377 356
378 357
379 void StoreBuffer::Verify() { 358 void StoreBuffer::Verify() {
380 #ifdef VERIFY_HEAP 359 #ifdef VERIFY_HEAP
381 VerifyPointers(heap_->old_pointer_space(),
382 &StoreBuffer::FindPointersToNewSpaceInRegion);
383 VerifyPointers(heap_->map_space(),
384 &StoreBuffer::FindPointersToNewSpaceInMapsRegion);
385 VerifyPointers(heap_->lo_space()); 360 VerifyPointers(heap_->lo_space());
386 #endif 361 #endif
387 } 362 }
388 363
389 364
390 void StoreBuffer::GCEpilogue() { 365 void StoreBuffer::GCEpilogue() {
391 during_gc_ = false; 366 during_gc_ = false;
392 #ifdef VERIFY_HEAP 367 #ifdef VERIFY_HEAP
393 if (FLAG_verify_heap) { 368 if (FLAG_verify_heap) {
394 Verify(); 369 Verify();
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 ASSERT(map_aligned_start == start); 450 ASSERT(map_aligned_start == start);
476 ASSERT(map_aligned_end == end); 451 ASSERT(map_aligned_end == end);
477 452
478 FindPointersToNewSpaceInMaps(map_aligned_start, 453 FindPointersToNewSpaceInMaps(map_aligned_start,
479 map_aligned_end, 454 map_aligned_end,
480 slot_callback, 455 slot_callback,
481 clear_maps); 456 clear_maps);
482 } 457 }
483 458
484 459
485 // This function iterates over all the pointers in a paged space in the heap,
486 // looking for pointers into new space. Within the pages there may be dead
487 // objects that have not been overwritten by free spaces or fillers because of
488 // concurrent sweeping. These dead objects may not contain pointers to new
489 // space. The garbage areas that have been swept properly (these will normally
490 // be the large ones) will be marked with free space and filler map words. In
491 // addition any area that has never been used at all for object allocation must
492 // be marked with a free space or filler. Because the free space and filler
493 // maps do not move we can always recognize these even after a compaction.
494 // Normal objects like FixedArrays and JSObjects should not contain references
495 // to these maps. Constant pool array objects may contain references to these
496 // maps, however, constant pool arrays cannot contain pointers to new space
497 // objects, therefore they are skipped. The special garbage section (see
498 // comment in spaces.h) is skipped since it can contain absolutely anything.
499 // Any objects that are allocated during iteration may or may not be visited by
500 // the iteration, but they will not be partially visited.
501 void StoreBuffer::FindPointersToNewSpaceOnPage(
502 PagedSpace* space,
503 Page* page,
504 RegionCallback region_callback,
505 ObjectSlotCallback slot_callback,
506 bool clear_maps) {
507 Address visitable_start = page->area_start();
508 Address end_of_page = page->area_end();
509
510 Address visitable_end = visitable_start;
511
512 Object* free_space_map = heap_->free_space_map();
513 Object* two_pointer_filler_map = heap_->two_pointer_filler_map();
514 Object* constant_pool_array_map = heap_->constant_pool_array_map();
515
516 while (visitable_end < end_of_page) {
517 // The sweeper thread concurrently may write free space maps and size to
518 // this page. We need acquire load here to make sure that we get a
519 // consistent view of maps and their sizes.
520 Object* o = reinterpret_cast<Object*>(
521 Acquire_Load(reinterpret_cast<AtomicWord*>(visitable_end)));
522 // Skip fillers or constant pool arrays (which never contain new-space
523 // pointers but can contain pointers which can be confused for fillers)
524 // but not things that look like fillers in the special garbage section
525 // which can contain anything.
526 if (o == free_space_map ||
527 o == two_pointer_filler_map ||
528 o == constant_pool_array_map ||
529 (visitable_end == space->top() && visitable_end != space->limit())) {
530 if (visitable_start != visitable_end) {
531 // After calling this the special garbage section may have moved.
532 (this->*region_callback)(visitable_start,
533 visitable_end,
534 slot_callback,
535 clear_maps);
536 if (visitable_end >= space->top() && visitable_end < space->limit()) {
537 visitable_end = space->limit();
538 visitable_start = visitable_end;
539 continue;
540 }
541 }
542 if (visitable_end == space->top() && visitable_end != space->limit()) {
543 visitable_start = visitable_end = space->limit();
544 } else {
545 // At this point we are either at the start of a filler, a
546 // constant pool array, or we are at the point where the space->top()
547 // used to be before the visit_pointer_region call above. Either way we
548 // can skip the object at the current spot: We don't promise to visit
549 // objects allocated during heap traversal, and if space->top() moved
550 // then it must be because an object was allocated at this point.
551 visitable_start =
552 visitable_end + HeapObject::FromAddress(visitable_end)->Size();
553 visitable_end = visitable_start;
554 }
555 } else {
556 ASSERT(o != free_space_map);
557 ASSERT(o != two_pointer_filler_map);
558 ASSERT(o != constant_pool_array_map);
559 ASSERT(visitable_end < space->top() || visitable_end >= space->limit());
560 visitable_end += kPointerSize;
561 }
562 }
563 ASSERT(visitable_end == end_of_page);
564 if (visitable_start != visitable_end) {
565 (this->*region_callback)(visitable_start,
566 visitable_end,
567 slot_callback,
568 clear_maps);
569 }
570 }
571
572
573 void StoreBuffer::IteratePointersInStoreBuffer( 460 void StoreBuffer::IteratePointersInStoreBuffer(
574 ObjectSlotCallback slot_callback, 461 ObjectSlotCallback slot_callback,
575 bool clear_maps) { 462 bool clear_maps) {
576 Address* limit = old_top_; 463 Address* limit = old_top_;
577 old_top_ = old_start_; 464 old_top_ = old_start_;
578 { 465 {
579 DontMoveStoreBufferEntriesScope scope(this); 466 DontMoveStoreBufferEntriesScope scope(this);
580 for (Address* current = old_start_; current < limit; current++) { 467 for (Address* current = old_start_; current < limit; current++) {
581 #ifdef DEBUG 468 #ifdef DEBUG
582 Address* saved_top = old_top_; 469 Address* saved_top = old_top_;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 if (chunk->owner() == heap_->lo_space()) { 536 if (chunk->owner() == heap_->lo_space()) {
650 LargePage* large_page = reinterpret_cast<LargePage*>(chunk); 537 LargePage* large_page = reinterpret_cast<LargePage*>(chunk);
651 HeapObject* array = large_page->GetObject(); 538 HeapObject* array = large_page->GetObject();
652 ASSERT(array->IsFixedArray()); 539 ASSERT(array->IsFixedArray());
653 Address start = array->address(); 540 Address start = array->address();
654 Address end = start + array->Size(); 541 Address end = start + array->Size();
655 FindPointersToNewSpaceInRegion(start, end, slot_callback, clear_maps); 542 FindPointersToNewSpaceInRegion(start, end, slot_callback, clear_maps);
656 } else { 543 } else {
657 Page* page = reinterpret_cast<Page*>(chunk); 544 Page* page = reinterpret_cast<Page*>(chunk);
658 PagedSpace* owner = reinterpret_cast<PagedSpace*>(page->owner()); 545 PagedSpace* owner = reinterpret_cast<PagedSpace*>(page->owner());
659 FindPointersToNewSpaceOnPage( 546 Address start = page->area_start();
660 owner, 547 Address end = page->area_end();
661 page, 548 if (owner == heap_->map_space()) {
662 (owner == heap_->map_space() ? 549 FindPointersToNewSpaceInMapsRegion(
663 &StoreBuffer::FindPointersToNewSpaceInMapsRegion : 550 start, end, slot_callback, clear_maps);
664 &StoreBuffer::FindPointersToNewSpaceInRegion), 551 } else {
665 slot_callback, 552 FindPointersToNewSpaceInRegion(
666 clear_maps); 553 start, end, slot_callback, clear_maps);
554 }
667 } 555 }
668 } 556 }
669 } 557 }
670 if (callback_ != NULL) { 558 if (callback_ != NULL) {
671 (*callback_)(heap_, NULL, kStoreBufferScanningPageEvent); 559 (*callback_)(heap_, NULL, kStoreBufferScanningPageEvent);
672 } 560 }
673 } 561 }
674 } 562 }
675 563
676 564
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 } 609 }
722 old_buffer_is_sorted_ = false; 610 old_buffer_is_sorted_ = false;
723 old_buffer_is_filtered_ = false; 611 old_buffer_is_filtered_ = false;
724 *old_top_++ = reinterpret_cast<Address>(int_addr << kPointerSizeLog2); 612 *old_top_++ = reinterpret_cast<Address>(int_addr << kPointerSizeLog2);
725 ASSERT(old_top_ <= old_limit_); 613 ASSERT(old_top_ <= old_limit_);
726 } 614 }
727 heap_->isolate()->counters()->store_buffer_compactions()->Increment(); 615 heap_->isolate()->counters()->store_buffer_compactions()->Increment();
728 } 616 }
729 617
730 } } // namespace v8::internal 618 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/store-buffer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698