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

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

Issue 7247004: Make the store buffer smaller and handle store buffer (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 6 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 // 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 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 } 388 }
389 } 389 }
390 } 390 }
391 } 391 }
392 #endif 392 #endif
393 393
394 394
395 void StoreBuffer::Verify() { 395 void StoreBuffer::Verify() {
396 #ifdef DEBUG 396 #ifdef DEBUG
397 VerifyPointers(heap_->old_pointer_space(), 397 VerifyPointers(heap_->old_pointer_space(),
398 &StoreBuffer::FindPointersToNewSpaceInRegion); 398 &StoreBuffer::FindPointersToNewSpaceInRegionDontRecord);
399 VerifyPointers(heap_->map_space(), 399 VerifyPointers(heap_->map_space(),
400 &StoreBuffer::FindPointersToNewSpaceInMapsRegion); 400 &StoreBuffer::FindPointersToNewSpaceInMapsRegion);
401 VerifyPointers(heap_->lo_space()); 401 VerifyPointers(heap_->lo_space());
402 #endif 402 #endif
403 } 403 }
404 404
405 405
406 void StoreBuffer::GCEpilogue(GCType type, GCCallbackFlags flags) { 406 void StoreBuffer::GCEpilogue(GCType type, GCCallbackFlags flags) {
407 // TODO(gc) ISOLATES MERGE 407 // TODO(gc) ISOLATES MERGE
408 HEAP->store_buffer()->during_gc_ = false; 408 HEAP->store_buffer()->during_gc_ = false;
409 HEAP->store_buffer()->Verify(); 409 HEAP->store_buffer()->Verify();
410 } 410 }
411 411
412 412
413 template<StoreBuffer::RecordNewSpacePointers record>
413 void StoreBuffer::FindPointersToNewSpaceInRegion( 414 void StoreBuffer::FindPointersToNewSpaceInRegion(
414 Address start, Address end, ObjectSlotCallback slot_callback) { 415 Address start, Address end, ObjectSlotCallback slot_callback) {
415 for (Address slot_address = start; 416 for (Address slot_address = start;
416 slot_address < end; 417 slot_address < end;
417 slot_address += kPointerSize) { 418 slot_address += kPointerSize) {
418 Object** slot = reinterpret_cast<Object**>(slot_address); 419 Object** slot = reinterpret_cast<Object**>(slot_address);
419 if (heap_->InNewSpace(*slot)) { 420 if (heap_->InNewSpace(*slot)) {
420 HeapObject* object = reinterpret_cast<HeapObject*>(*slot); 421 HeapObject* object = reinterpret_cast<HeapObject*>(*slot);
421 ASSERT(object->IsHeapObject()); 422 ASSERT(object->IsHeapObject());
422 slot_callback(reinterpret_cast<HeapObject**>(slot), object); 423 slot_callback(reinterpret_cast<HeapObject**>(slot), object);
423 if (heap_->InNewSpace(*slot)) { 424 if (record == kRecord) {
424 EnterDirectlyIntoStoreBuffer(slot_address); 425 if (heap_->InNewSpace(*slot)) {
426 EnterDirectlyIntoStoreBuffer(slot_address);
427 }
425 } 428 }
426 } 429 }
427 } 430 }
428 } 431 }
429 432
430 433
434 void StoreBuffer::FindPointersToNewSpaceInRegionRecord(
435 StoreBuffer* store_buffer,
436 Address start,
437 Address end,
438 ObjectSlotCallback slot_callback) {
439 store_buffer->FindPointersToNewSpaceInRegion<kRecord>(
440 start, end, slot_callback);
441 }
442
443
444 void StoreBuffer::FindPointersToNewSpaceInRegionDontRecord(
445 StoreBuffer* store_buffer,
446 Address start,
447 Address end,
448 ObjectSlotCallback slot_callback) {
449 store_buffer->FindPointersToNewSpaceInRegion<kDontRecord>(
450 start, end, slot_callback);
451 }
452
453
431 // Compute start address of the first map following given addr. 454 // Compute start address of the first map following given addr.
432 static inline Address MapStartAlign(Address addr) { 455 static inline Address MapStartAlign(Address addr) {
433 Address page = Page::FromAddress(addr)->ObjectAreaStart(); 456 Address page = Page::FromAddress(addr)->ObjectAreaStart();
434 return page + (((addr - page) + (Map::kSize - 1)) / Map::kSize * Map::kSize); 457 return page + (((addr - page) + (Map::kSize - 1)) / Map::kSize * Map::kSize);
435 } 458 }
436 459
437 460
438 // Compute end address of the first map preceding given addr. 461 // Compute end address of the first map preceding given addr.
439 static inline Address MapEndAlign(Address addr) { 462 static inline Address MapEndAlign(Address addr) {
440 Address page = Page::FromAllocationTop(addr)->ObjectAreaStart(); 463 Address page = Page::FromAllocationTop(addr)->ObjectAreaStart();
441 return page + ((addr - page) / Map::kSize * Map::kSize); 464 return page + ((addr - page) / Map::kSize * Map::kSize);
442 } 465 }
443 466
444 467
445 void StoreBuffer::FindPointersToNewSpaceInMaps( 468 void StoreBuffer::FindPointersToNewSpaceInMaps(
446 Address start, 469 Address start,
447 Address end, 470 Address end,
448 ObjectSlotCallback slot_callback) { 471 ObjectSlotCallback slot_callback) {
449 ASSERT(MapStartAlign(start) == start); 472 ASSERT(MapStartAlign(start) == start);
450 ASSERT(MapEndAlign(end) == end); 473 ASSERT(MapEndAlign(end) == end);
451 474
452 Address map_address = start; 475 Address map_address = start;
453 while (map_address < end) { 476 while (map_address < end) {
454 ASSERT(!heap_->InNewSpace(Memory::Object_at(map_address))); 477 ASSERT(!heap_->InNewSpace(Memory::Object_at(map_address)));
455 ASSERT(Memory::Object_at(map_address)->IsMap()); 478 ASSERT(Memory::Object_at(map_address)->IsMap());
456 479
457 Address pointer_fields_start = map_address + Map::kPointerFieldsBeginOffset; 480 Address pointer_fields_start = map_address + Map::kPointerFieldsBeginOffset;
458 Address pointer_fields_end = map_address + Map::kPointerFieldsEndOffset; 481 Address pointer_fields_end = map_address + Map::kPointerFieldsEndOffset;
459 482
460 FindPointersToNewSpaceInRegion(pointer_fields_start, 483 FindPointersToNewSpaceInRegion<kRecord>(pointer_fields_start,
461 pointer_fields_end, 484 pointer_fields_end,
462 slot_callback); 485 slot_callback);
463 map_address += Map::kSize; 486 map_address += Map::kSize;
464 } 487 }
465 } 488 }
466 489
467 490
468 void StoreBuffer::FindPointersToNewSpaceInMapsRegion( 491 void StoreBuffer::FindPointersToNewSpaceInMapsRegion(
492 StoreBuffer* store_buffer,
469 Address start, 493 Address start,
470 Address end, 494 Address end,
471 ObjectSlotCallback slot_callback) { 495 ObjectSlotCallback slot_callback) {
472 Address map_aligned_start = MapStartAlign(start); 496 Address map_aligned_start = MapStartAlign(start);
473 Address map_aligned_end = MapEndAlign(end); 497 Address map_aligned_end = MapEndAlign(end);
474 498
475 ASSERT(map_aligned_start == start); 499 ASSERT(map_aligned_start == start);
476 ASSERT(map_aligned_end == end); 500 ASSERT(map_aligned_end == end);
477 501
478 FindPointersToNewSpaceInMaps(map_aligned_start, 502 store_buffer->FindPointersToNewSpaceInMaps(map_aligned_start,
479 map_aligned_end, 503 map_aligned_end,
480 slot_callback); 504 slot_callback);
481 } 505 }
482 506
483 507
484 // This function iterates over all the pointers in a paged space in the heap, 508 // This function iterates over all the pointers in a paged space in the heap,
485 // looking for pointers into new space. Within the pages there may be dead 509 // looking for pointers into new space. Within the pages there may be dead
486 // objects that have not been overwritten by free spaces or fillers because of 510 // objects that have not been overwritten by free spaces or fillers because of
487 // lazy sweeping. These dead objects may not contain pointers to new space. 511 // lazy sweeping. These dead objects may not contain pointers to new space.
488 // The garbage areas that have been swept properly (these will normally be the 512 // The garbage areas that have been swept properly (these will normally be the
489 // large ones) will be marked with free space and filler map words. In 513 // large ones) will be marked with free space and filler map words. In
490 // addition any area that has never been used at all for object allocation must 514 // addition any area that has never been used at all for object allocation must
(...skipping 19 matching lines...) Expand all
510 534
511 while (visitable_end < end_of_page) { 535 while (visitable_end < end_of_page) {
512 Object* o = *reinterpret_cast<Object**>(visitable_end); 536 Object* o = *reinterpret_cast<Object**>(visitable_end);
513 // Skip fillers but not things that look like fillers in the special 537 // Skip fillers but not things that look like fillers in the special
514 // garbage section which can contain anything. 538 // garbage section which can contain anything.
515 if (o == free_space_map || 539 if (o == free_space_map ||
516 o == two_pointer_filler_map || 540 o == two_pointer_filler_map ||
517 visitable_end == space->top()) { 541 visitable_end == space->top()) {
518 if (visitable_start != visitable_end) { 542 if (visitable_start != visitable_end) {
519 // After calling this the special garbage section may have moved. 543 // After calling this the special garbage section may have moved.
520 (this->*region_callback)(visitable_start, 544 (*region_callback)(this,
521 visitable_end, 545 visitable_start,
522 slot_callback); 546 visitable_end,
547 slot_callback);
523 if (visitable_end >= space->top() && visitable_end < space->limit()) { 548 if (visitable_end >= space->top() && visitable_end < space->limit()) {
524 visitable_end = space->limit(); 549 visitable_end = space->limit();
525 visitable_start = visitable_end; 550 visitable_start = visitable_end;
526 continue; 551 continue;
527 } 552 }
528 } 553 }
529 if (visitable_end == space->top() && visitable_end != space->limit()) { 554 if (visitable_end == space->top() && visitable_end != space->limit()) {
530 visitable_start = visitable_end = space->limit(); 555 visitable_start = visitable_end = space->limit();
531 } else { 556 } else {
532 // At this point we are either at the start of a filler or we are at 557 // At this point we are either at the start of a filler or we are at
533 // the point where the space->top() used to be before the 558 // the point where the space->top() used to be before the
534 // visit_pointer_region call above. Either way we can skip the 559 // visit_pointer_region call above. Either way we can skip the
535 // object at the current spot: We don't promise to visit objects 560 // object at the current spot: We don't promise to visit objects
536 // allocated during heap traversal, and if space->top() moved then it 561 // allocated during heap traversal, and if space->top() moved then it
537 // must be because an object was allocated at this point. 562 // must be because an object was allocated at this point.
538 visitable_start = 563 visitable_start =
539 visitable_end + HeapObject::FromAddress(visitable_end)->Size(); 564 visitable_end + HeapObject::FromAddress(visitable_end)->Size();
540 visitable_end = visitable_start; 565 visitable_end = visitable_start;
541 } 566 }
542 } else { 567 } else {
543 ASSERT(o != free_space_map); 568 ASSERT(o != free_space_map);
544 ASSERT(o != two_pointer_filler_map); 569 ASSERT(o != two_pointer_filler_map);
545 ASSERT(visitable_end < space->top() || visitable_end >= space->limit()); 570 ASSERT(visitable_end < space->top() || visitable_end >= space->limit());
546 visitable_end += kPointerSize; 571 visitable_end += kPointerSize;
547 } 572 }
548 } 573 }
549 ASSERT(visitable_end == end_of_page); 574 ASSERT(visitable_end == end_of_page);
550 if (visitable_start != visitable_end) { 575 if (visitable_start != visitable_end) {
551 (this->*region_callback)(visitable_start, 576 (*region_callback)(this,
552 visitable_end, 577 visitable_start,
553 slot_callback); 578 visitable_end,
579 slot_callback);
554 } 580 }
555 } 581 }
556 582
557 583
558 void StoreBuffer::IteratePointersInStoreBuffer( 584 void StoreBuffer::IteratePointersInStoreBuffer(
559 ObjectSlotCallback slot_callback) { 585 ObjectSlotCallback slot_callback) {
560 Address* limit = old_top_; 586 Address* limit = old_top_;
561 old_top_ = old_start_; 587 old_top_ = old_start_;
562 { 588 {
563 DontMoveStoreBufferEntriesScope scope(this); 589 DontMoveStoreBufferEntriesScope scope(this);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 chunk->set_scan_on_scavenge(false); 637 chunk->set_scan_on_scavenge(false);
612 if (callback_ != NULL) { 638 if (callback_ != NULL) {
613 (*callback_)(heap_, chunk, kStoreBufferScanningPageEvent); 639 (*callback_)(heap_, chunk, kStoreBufferScanningPageEvent);
614 } 640 }
615 if (chunk->owner() == heap_->lo_space()) { 641 if (chunk->owner() == heap_->lo_space()) {
616 LargePage* large_page = reinterpret_cast<LargePage*>(chunk); 642 LargePage* large_page = reinterpret_cast<LargePage*>(chunk);
617 HeapObject* array = large_page->GetObject(); 643 HeapObject* array = large_page->GetObject();
618 ASSERT(array->IsFixedArray()); 644 ASSERT(array->IsFixedArray());
619 Address start = array->address(); 645 Address start = array->address();
620 Address end = start + array->Size(); 646 Address end = start + array->Size();
621 FindPointersToNewSpaceInRegion(start, end, slot_callback); 647 const int kLump = 10000;
648 for (Address current = start; current < end; current += kLump) {
649 if (chunk->scan_on_scavenge()) {
650 FindPointersToNewSpaceInRegion<kDontRecord>(
651 current,
652 Min(end, current + kLump),
653 slot_callback);
654 } else {
655 FindPointersToNewSpaceInRegion<kRecord>(
656 current,
657 Min(end, current + kLump),
658 slot_callback);
659 }
660 }
622 } else { 661 } else {
623 Page* page = reinterpret_cast<Page*>(chunk); 662 Page* page = reinterpret_cast<Page*>(chunk);
624 PagedSpace* owner = reinterpret_cast<PagedSpace*>(page->owner()); 663 PagedSpace* owner = reinterpret_cast<PagedSpace*>(page->owner());
625 FindPointersToNewSpaceOnPage( 664 FindPointersToNewSpaceOnPage(
626 owner, 665 owner,
627 page, 666 page,
628 (owner == heap_->map_space() ? 667 (owner == heap_->map_space() ?
629 &StoreBuffer::FindPointersToNewSpaceInMapsRegion : 668 &StoreBuffer::FindPointersToNewSpaceInMapsRegion :
630 &StoreBuffer::FindPointersToNewSpaceInRegion), 669 &StoreBuffer::FindPointersToNewSpaceInRegionRecord),
631 slot_callback); 670 slot_callback);
632 } 671 }
633 } 672 }
634 } 673 }
635 (*callback_)(heap_, NULL, kStoreBufferScanningPageEvent); 674 (*callback_)(heap_, NULL, kStoreBufferScanningPageEvent);
636 } 675 }
637 } 676 }
638 677
639 678
640 void StoreBuffer::Compact() { 679 void StoreBuffer::Compact() {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
688 } 727 }
689 728
690 729
691 void StoreBuffer::CheckForFullBuffer() { 730 void StoreBuffer::CheckForFullBuffer() {
692 if (old_limit_ - old_top_ < kStoreBufferSize * 2) { 731 if (old_limit_ - old_top_ < kStoreBufferSize * 2) {
693 HandleFullness(); 732 HandleFullness();
694 } 733 }
695 } 734 }
696 735
697 } } // namespace v8::internal 736 } } // 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