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

Side by Side Diff: src/spaces.cc

Issue 9634005: Implement a hash based look-up to speed up containing address check in large (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 8 years, 9 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
« src/spaces.h ('K') | « src/spaces.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 2502 matching lines...) Expand 10 before | Expand all | Expand 10 after
2513 if (current_ == NULL) return NULL; 2513 if (current_ == NULL) return NULL;
2514 2514
2515 HeapObject* object = current_->GetObject(); 2515 HeapObject* object = current_->GetObject();
2516 current_ = current_->next_page(); 2516 current_ = current_->next_page();
2517 return object; 2517 return object;
2518 } 2518 }
2519 2519
2520 2520
2521 // ----------------------------------------------------------------------------- 2521 // -----------------------------------------------------------------------------
2522 // LargeObjectSpace 2522 // LargeObjectSpace
2523 static bool match(void* key1, void* key2) {
Vyacheslav Egorov (Chromium) 2012/03/08 11:41:23 Please give this function a more meaningful name,
kewpie.w.zp 2012/03/12 02:00:40 Done.
2524 return key1 == key2;
2525 }
2523 2526
Vyacheslav Egorov (Chromium) 2012/03/08 11:41:23 one additional empty line
kewpie.w.zp 2012/03/12 02:00:40 Done.
2524 LargeObjectSpace::LargeObjectSpace(Heap* heap, 2527 LargeObjectSpace::LargeObjectSpace(Heap* heap,
2525 intptr_t max_capacity, 2528 intptr_t max_capacity,
2526 AllocationSpace id) 2529 AllocationSpace id)
2527 : Space(heap, id, NOT_EXECUTABLE), // Managed on a per-allocation basis 2530 : Space(heap, id, NOT_EXECUTABLE), // Managed on a per-allocation basis
2528 max_capacity_(max_capacity), 2531 max_capacity_(max_capacity),
2529 first_page_(NULL), 2532 first_page_(NULL),
2530 size_(0), 2533 size_(0),
2531 page_count_(0), 2534 page_count_(0),
2532 objects_size_(0) {} 2535 objects_size_(0),
2536 map_(match, 1024) {}
2533 2537
2534 2538
2535 bool LargeObjectSpace::SetUp() { 2539 bool LargeObjectSpace::SetUp() {
2536 first_page_ = NULL; 2540 first_page_ = NULL;
2537 size_ = 0; 2541 size_ = 0;
2538 page_count_ = 0; 2542 page_count_ = 0;
2539 objects_size_ = 0; 2543 objects_size_ = 0;
2544 map_.Clear();
2540 return true; 2545 return true;
2541 } 2546 }
2542 2547
2543 2548
2544 void LargeObjectSpace::TearDown() { 2549 void LargeObjectSpace::TearDown() {
2545 while (first_page_ != NULL) { 2550 while (first_page_ != NULL) {
2546 LargePage* page = first_page_; 2551 LargePage* page = first_page_;
2547 first_page_ = first_page_->next_page(); 2552 first_page_ = first_page_->next_page();
2548 LOG(heap()->isolate(), DeleteEvent("LargeObjectChunk", page->address())); 2553 LOG(heap()->isolate(), DeleteEvent("LargeObjectChunk", page->address()));
2549 2554
(...skipping 23 matching lines...) Expand all
2573 AllocateLargePage(object_size, executable, this); 2578 AllocateLargePage(object_size, executable, this);
2574 if (page == NULL) return Failure::RetryAfterGC(identity()); 2579 if (page == NULL) return Failure::RetryAfterGC(identity());
2575 ASSERT(page->area_size() >= object_size); 2580 ASSERT(page->area_size() >= object_size);
2576 2581
2577 size_ += static_cast<int>(page->size()); 2582 size_ += static_cast<int>(page->size());
2578 objects_size_ += object_size; 2583 objects_size_ += object_size;
2579 page_count_++; 2584 page_count_++;
2580 page->set_next_page(first_page_); 2585 page->set_next_page(first_page_);
2581 first_page_ = page; 2586 first_page_ = page;
2582 2587
2588 // map following entries to this page object, in which keys are
Vyacheslav Egorov (Chromium) 2012/03/08 11:41:23 comments should start with a capital letter and en
Vyacheslav Egorov (Chromium) 2012/03/08 11:41:23 I would rephrase this comment, for example: // Re
kewpie.w.zp 2012/03/12 02:00:40 Done.
2589 // MemoryChunk::kAlignment-aligned addresses in this page, and
2590 // hash is key/MemoryChunk::kAlignment to reduce hash conflict
2591 uint32_t key = reinterpret_cast<uint32_t>(page);
2592 uint32_t limit = key + page->size();
2593 for (uint32_t hash = key/MemoryChunk::kAlignment;
2594 key < limit;
2595 key += MemoryChunk::kAlignment, hash++) {
Vyacheslav Egorov (Chromium) 2012/03/08 11:41:23 I think you can just unify hash and key (make key
kewpie.w.zp 2012/03/12 02:00:40 Done.
2596 (map_.Lookup(reinterpret_cast<void*>(key), hash, true))->value = page;
Vyacheslav Egorov (Chromium) 2012/03/08 11:41:23 I would prefer this is done in two lines instead o
kewpie.w.zp 2012/03/12 02:00:40 Done.
2597 }
2598
2583 HeapObject* object = page->GetObject(); 2599 HeapObject* object = page->GetObject();
2584 2600
2585 #ifdef DEBUG 2601 #ifdef DEBUG
2586 // Make the object consistent so the heap can be vefified in OldSpaceStep. 2602 // Make the object consistent so the heap can be vefified in OldSpaceStep.
2587 reinterpret_cast<Object**>(object->address())[0] = 2603 reinterpret_cast<Object**>(object->address())[0] =
2588 heap()->fixed_array_map(); 2604 heap()->fixed_array_map();
2589 reinterpret_cast<Object**>(object->address())[1] = Smi::FromInt(0); 2605 reinterpret_cast<Object**>(object->address())[1] = Smi::FromInt(0);
2590 #endif 2606 #endif
2591 2607
2592 heap()->incremental_marking()->OldSpaceStep(object_size); 2608 heap()->incremental_marking()->OldSpaceStep(object_size);
2593 return object; 2609 return object;
2594 } 2610 }
2595 2611
2596 2612
2597 // GC support 2613 // GC support
2598 MaybeObject* LargeObjectSpace::FindObject(Address a) { 2614 MaybeObject* LargeObjectSpace::FindObject(Address a) {
2599 for (LargePage* page = first_page_; 2615 uint32_t key = reinterpret_cast<uint32_t>(a);
2600 page != NULL; 2616 key -= key % MemoryChunk::kAlignment;
2601 page = page->next_page()) { 2617 uint32_t hash = key / MemoryChunk::kAlignment;
2618 HashMap::Entry* e = map_.Lookup(reinterpret_cast<void*>(key), hash, false);
2619 if ( e != NULL ) {
2620 ASSERT(e->value != NULL);
2621 LargePage* page = reinterpret_cast<LargePage*>(e->value);
2622 ASSERT(page->is_valid());
2602 Address page_address = page->address(); 2623 Address page_address = page->address();
2603 if (page_address <= a && a < page_address + page->size()) { 2624 if ( page_address <= a && a < page_address + page->size() ) {
Vyacheslav Egorov (Chromium) 2012/03/08 11:41:23 accidental edit? please revert.
kewpie.w.zp 2012/03/12 02:00:40 Done.
2604 return page->GetObject(); 2625 return page->GetObject();
2605 } 2626 }
2606 } 2627 }
2607 return Failure::Exception(); 2628 return Failure::Exception();
2608 } 2629 }
2609 2630
2610
2611 LargePage* LargeObjectSpace::FindPageContainingPc(Address pc) { 2631 LargePage* LargeObjectSpace::FindPageContainingPc(Address pc) {
2612 // TODO(853): Change this implementation to only find executable 2632 uint32_t key = reinterpret_cast<uint32_t>(pc);
2613 // chunks and use some kind of hash-based approach to speed it up. 2633 key -= key % MemoryChunk::kAlignment;
2614 for (LargePage* chunk = first_page_; 2634 uint32_t hash = key / MemoryChunk::kAlignment;
2615 chunk != NULL; 2635 HashMap::Entry* e = map_.Lookup(reinterpret_cast<void*>(key), hash, false);
2616 chunk = chunk->next_page()) { 2636 if ( e != NULL ) {
2617 Address chunk_address = chunk->address(); 2637 ASSERT(e->value != NULL);
2618 if (chunk_address <= pc && pc < chunk_address + chunk->size()) { 2638 LargePage* page = reinterpret_cast<LargePage*>(e->value);
2619 return chunk; 2639 ASSERT(page->is_valid());
2640 Address page_address = page->address();
2641 if ( page_address <= pc && pc < page_address + page->size() ) {
2642 return page;
Vyacheslav Egorov (Chromium) 2012/03/08 11:41:23 This code is duplicated in two places. Please move
kewpie.w.zp 2012/03/12 02:00:40 Accepted, will reduce FindObject(a) size by callin
2620 } 2643 }
2621 } 2644 }
2622 return NULL; 2645 return NULL;
2623 } 2646 }
2624 2647
2625
Vyacheslav Egorov (Chromium) 2012/03/08 11:41:23 accidental edit? please revert.
kewpie.w.zp 2012/03/12 02:00:40 Done.
2626 void LargeObjectSpace::FreeUnmarkedObjects() { 2648 void LargeObjectSpace::FreeUnmarkedObjects() {
2627 LargePage* previous = NULL; 2649 LargePage* previous = NULL;
2628 LargePage* current = first_page_; 2650 LargePage* current = first_page_;
2629 while (current != NULL) { 2651 while (current != NULL) {
2630 HeapObject* object = current->GetObject(); 2652 HeapObject* object = current->GetObject();
2631 // Can this large page contain pointers to non-trivial objects. No other 2653 // Can this large page contain pointers to non-trivial objects. No other
2632 // pointer object is this big. 2654 // pointer object is this big.
2633 bool is_pointer_object = object->IsFixedArray(); 2655 bool is_pointer_object = object->IsFixedArray();
2634 MarkBit mark_bit = Marking::MarkBitFrom(object); 2656 MarkBit mark_bit = Marking::MarkBitFrom(object);
2635 if (mark_bit.Get()) { 2657 if (mark_bit.Get()) {
(...skipping 11 matching lines...) Expand all
2647 previous->set_next_page(current); 2669 previous->set_next_page(current);
2648 } 2670 }
2649 2671
2650 // Free the chunk. 2672 // Free the chunk.
2651 heap()->mark_compact_collector()->ReportDeleteIfNeeded( 2673 heap()->mark_compact_collector()->ReportDeleteIfNeeded(
2652 object, heap()->isolate()); 2674 object, heap()->isolate());
2653 size_ -= static_cast<int>(page->size()); 2675 size_ -= static_cast<int>(page->size());
2654 objects_size_ -= object->Size(); 2676 objects_size_ -= object->Size();
2655 page_count_--; 2677 page_count_--;
2656 2678
2679 // remove entries belonging to this page
Vyacheslav Egorov (Chromium) 2012/03/08 11:41:23 comments should start with a capital letter and en
kewpie.w.zp 2012/03/12 02:00:40 Done.
2680 uint32_t key = reinterpret_cast<uint32_t>(page);
2681 uint32_t limit = key + page->size();
2682 for (uint32_t hash = key/MemoryChunk::kAlignment;
2683 key < limit;
2684 key += MemoryChunk::kAlignment, hash++) {
2685 map_.Remove(reinterpret_cast<void*>(key), hash);
2686 }
2687
2657 if (is_pointer_object) { 2688 if (is_pointer_object) {
2658 heap()->QueueMemoryChunkForFree(page); 2689 heap()->QueueMemoryChunkForFree(page);
2659 } else { 2690 } else {
2660 heap()->isolate()->memory_allocator()->Free(page); 2691 heap()->isolate()->memory_allocator()->Free(page);
2661 } 2692 }
2662 } 2693 }
2663 } 2694 }
2664 heap()->FreeQueuedChunks(); 2695 heap()->FreeQueuedChunks();
2665 } 2696 }
2666 2697
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
2782 object->ShortPrint(); 2813 object->ShortPrint();
2783 PrintF("\n"); 2814 PrintF("\n");
2784 } 2815 }
2785 printf(" --------------------------------------\n"); 2816 printf(" --------------------------------------\n");
2786 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); 2817 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes());
2787 } 2818 }
2788 2819
2789 #endif // DEBUG 2820 #endif // DEBUG
2790 2821
2791 } } // namespace v8::internal 2822 } } // namespace v8::internal
OLDNEW
« src/spaces.h ('K') | « src/spaces.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698