| 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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 ASSERT(owner == HEAP->old_pointer_space() || | 72 ASSERT(owner == HEAP->old_pointer_space() || |
| 73 owner == HEAP->old_data_space() || | 73 owner == HEAP->old_data_space() || |
| 74 owner == HEAP->map_space() || | 74 owner == HEAP->map_space() || |
| 75 owner == HEAP->cell_space() || | 75 owner == HEAP->cell_space() || |
| 76 owner == HEAP->code_space()); | 76 owner == HEAP->code_space()); |
| 77 Initialize(reinterpret_cast<PagedSpace*>(owner), | 77 Initialize(reinterpret_cast<PagedSpace*>(owner), |
| 78 page->ObjectAreaStart(), | 78 page->ObjectAreaStart(), |
| 79 page->ObjectAreaEnd(), | 79 page->ObjectAreaEnd(), |
| 80 kOnePageOnly, | 80 kOnePageOnly, |
| 81 size_func); | 81 size_func); |
| 82 ASSERT(!page->IsFlagSet(Page::WAS_SWEPT_CONSERVATIVELY)); | 82 ASSERT(page->WasSweptPrecisely()); |
| 83 } | 83 } |
| 84 | 84 |
| 85 | 85 |
| 86 void HeapObjectIterator::Initialize(PagedSpace* space, | 86 void HeapObjectIterator::Initialize(PagedSpace* space, |
| 87 Address cur, Address end, | 87 Address cur, Address end, |
| 88 HeapObjectIterator::PageMode mode, | 88 HeapObjectIterator::PageMode mode, |
| 89 HeapObjectCallback size_f) { | 89 HeapObjectCallback size_f) { |
| 90 // Check that we actually can iterate this space. | 90 // Check that we actually can iterate this space. |
| 91 ASSERT(!space->was_swept_conservatively()); | 91 ASSERT(!space->was_swept_conservatively()); |
| 92 | 92 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 111 if (cur_addr_ == NULL) { | 111 if (cur_addr_ == NULL) { |
| 112 cur_page = space_->anchor(); | 112 cur_page = space_->anchor(); |
| 113 } else { | 113 } else { |
| 114 cur_page = Page::FromAddress(cur_addr_ - 1); | 114 cur_page = Page::FromAddress(cur_addr_ - 1); |
| 115 ASSERT(cur_addr_ == cur_page->ObjectAreaEnd()); | 115 ASSERT(cur_addr_ == cur_page->ObjectAreaEnd()); |
| 116 } | 116 } |
| 117 cur_page = cur_page->next_page(); | 117 cur_page = cur_page->next_page(); |
| 118 if (cur_page == space_->anchor()) return false; | 118 if (cur_page == space_->anchor()) return false; |
| 119 cur_addr_ = cur_page->ObjectAreaStart(); | 119 cur_addr_ = cur_page->ObjectAreaStart(); |
| 120 cur_end_ = cur_page->ObjectAreaEnd(); | 120 cur_end_ = cur_page->ObjectAreaEnd(); |
| 121 ASSERT(!cur_page->IsFlagSet(Page::WAS_SWEPT_CONSERVATIVELY)); | 121 ASSERT(cur_page->WasSweptPrecisely()); |
| 122 return true; | 122 return true; |
| 123 } | 123 } |
| 124 | 124 |
| 125 | 125 |
| 126 #ifdef DEBUG | 126 #ifdef DEBUG |
| 127 void HeapObjectIterator::Verify() { | 127 void HeapObjectIterator::Verify() { |
| 128 // TODO(gc): We should do something here. | 128 // TODO(gc): We should do something here. |
| 129 } | 129 } |
| 130 #endif | 130 #endif |
| 131 | 131 |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 | 443 |
| 444 ASSERT(base == chunk->address()); | 444 ASSERT(base == chunk->address()); |
| 445 | 445 |
| 446 chunk->heap_ = heap; | 446 chunk->heap_ = heap; |
| 447 chunk->size_ = size; | 447 chunk->size_ = size; |
| 448 chunk->flags_ = 0; | 448 chunk->flags_ = 0; |
| 449 chunk->set_owner(owner); | 449 chunk->set_owner(owner); |
| 450 chunk->slots_buffer_ = NULL; | 450 chunk->slots_buffer_ = NULL; |
| 451 Bitmap::Clear(chunk); | 451 Bitmap::Clear(chunk); |
| 452 chunk->initialize_scan_on_scavenge(false); | 452 chunk->initialize_scan_on_scavenge(false); |
| 453 chunk->SetFlag(WAS_SWEPT_PRECISELY); |
| 453 | 454 |
| 454 ASSERT(OFFSET_OF(MemoryChunk, flags_) == kFlagsOffset); | 455 ASSERT(OFFSET_OF(MemoryChunk, flags_) == kFlagsOffset); |
| 455 | 456 |
| 456 if (executable == EXECUTABLE) chunk->SetFlag(IS_EXECUTABLE); | 457 if (executable == EXECUTABLE) chunk->SetFlag(IS_EXECUTABLE); |
| 457 | 458 |
| 458 if (owner == heap->old_data_space()) chunk->SetFlag(CONTAINS_ONLY_DATA); | 459 if (owner == heap->old_data_space()) chunk->SetFlag(CONTAINS_ONLY_DATA); |
| 459 | 460 |
| 460 return chunk; | 461 return chunk; |
| 461 } | 462 } |
| 462 | 463 |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 | 784 |
| 784 bool allocation_pointer_found_in_space = | 785 bool allocation_pointer_found_in_space = |
| 785 (allocation_info_.top != allocation_info_.limit); | 786 (allocation_info_.top != allocation_info_.limit); |
| 786 PageIterator page_iterator(this); | 787 PageIterator page_iterator(this); |
| 787 while (page_iterator.has_next()) { | 788 while (page_iterator.has_next()) { |
| 788 Page* page = page_iterator.next(); | 789 Page* page = page_iterator.next(); |
| 789 ASSERT(page->owner() == this); | 790 ASSERT(page->owner() == this); |
| 790 if (page == Page::FromAllocationTop(allocation_info_.top)) { | 791 if (page == Page::FromAllocationTop(allocation_info_.top)) { |
| 791 allocation_pointer_found_in_space = true; | 792 allocation_pointer_found_in_space = true; |
| 792 } | 793 } |
| 793 ASSERT(!page->IsFlagSet(MemoryChunk::WAS_SWEPT_CONSERVATIVELY)); | 794 ASSERT(page->WasSweptPrecisely()); |
| 794 HeapObjectIterator it(page, NULL); | 795 HeapObjectIterator it(page, NULL); |
| 795 Address end_of_previous_object = page->ObjectAreaStart(); | 796 Address end_of_previous_object = page->ObjectAreaStart(); |
| 796 Address top = page->ObjectAreaEnd(); | 797 Address top = page->ObjectAreaEnd(); |
| 797 int black_size = 0; | 798 int black_size = 0; |
| 798 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { | 799 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { |
| 799 ASSERT(end_of_previous_object <= object->address()); | 800 ASSERT(end_of_previous_object <= object->address()); |
| 800 | 801 |
| 801 // The first word should be a map, and we expect all map pointers to | 802 // The first word should be a map, and we expect all map pointers to |
| 802 // be in map space. | 803 // be in map space. |
| 803 Map* map = object->map(); | 804 Map* map = object->map(); |
| (...skipping 1119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1923 | 1924 |
| 1924 void PagedSpace::PrepareForMarkCompact() { | 1925 void PagedSpace::PrepareForMarkCompact() { |
| 1925 // We don't have a linear allocation area while sweeping. It will be restored | 1926 // We don't have a linear allocation area while sweeping. It will be restored |
| 1926 // on the first allocation after the sweep. | 1927 // on the first allocation after the sweep. |
| 1927 // Mark the old linear allocation area with a free space map so it can be | 1928 // Mark the old linear allocation area with a free space map so it can be |
| 1928 // skipped when scanning the heap. | 1929 // skipped when scanning the heap. |
| 1929 int old_linear_size = static_cast<int>(limit() - top()); | 1930 int old_linear_size = static_cast<int>(limit() - top()); |
| 1930 Free(top(), old_linear_size); | 1931 Free(top(), old_linear_size); |
| 1931 SetTop(NULL, NULL); | 1932 SetTop(NULL, NULL); |
| 1932 | 1933 |
| 1933 // Stop lazy sweeping and clear marking bits for the space. | 1934 // Stop lazy sweeping and clear marking bits for unswept pages. |
| 1934 if (first_unswept_page_ != NULL) { | 1935 if (first_unswept_page_ != NULL) { |
| 1935 int pages = 0; | |
| 1936 Page* last = last_unswept_page_->next_page(); | 1936 Page* last = last_unswept_page_->next_page(); |
| 1937 Page* p = first_unswept_page_; | 1937 Page* p = first_unswept_page_; |
| 1938 do { | 1938 do { |
| 1939 pages++; | 1939 if (ShouldBeSweptLazily(p)) { |
| 1940 Bitmap::Clear(p); | 1940 ASSERT(!p->WasSwept()); |
| 1941 Bitmap::Clear(p); |
| 1942 if (FLAG_gc_verbose) { |
| 1943 PrintF("Sweeping 0x%" V8PRIxPTR " lazily abandoned.\n", |
| 1944 reinterpret_cast<intptr_t>(p)); |
| 1945 } |
| 1946 } |
| 1941 p = p->next_page(); | 1947 p = p->next_page(); |
| 1942 } while (p != last); | 1948 } while (p != last); |
| 1943 if (FLAG_trace_gc) { | |
| 1944 PrintF("Abandoned %d unswept pages\n", pages); | |
| 1945 } | |
| 1946 } | 1949 } |
| 1947 first_unswept_page_ = last_unswept_page_ = Page::FromAddress(NULL); | 1950 first_unswept_page_ = last_unswept_page_ = Page::FromAddress(NULL); |
| 1948 | 1951 |
| 1949 // Clear the free list before a full GC---it will be rebuilt afterward. | 1952 // Clear the free list before a full GC---it will be rebuilt afterward. |
| 1950 free_list_.Reset(); | 1953 free_list_.Reset(); |
| 1951 | |
| 1952 // Clear WAS_SWEPT and WAS_SWEPT_CONSERVATIVELY flags from all pages. | |
| 1953 PageIterator it(this); | |
| 1954 while (it.has_next()) { | |
| 1955 Page* page = it.next(); | |
| 1956 page->ClearSwept(); | |
| 1957 page->ClearFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY); | |
| 1958 } | |
| 1959 } | 1954 } |
| 1960 | 1955 |
| 1961 | 1956 |
| 1962 bool PagedSpace::ReserveSpace(int size_in_bytes) { | 1957 bool PagedSpace::ReserveSpace(int size_in_bytes) { |
| 1963 ASSERT(size_in_bytes <= Page::kMaxHeapObjectSize); | 1958 ASSERT(size_in_bytes <= Page::kMaxHeapObjectSize); |
| 1964 ASSERT(size_in_bytes == RoundSizeDownToObjectAlignment(size_in_bytes)); | 1959 ASSERT(size_in_bytes == RoundSizeDownToObjectAlignment(size_in_bytes)); |
| 1965 Address current_top = allocation_info_.top; | 1960 Address current_top = allocation_info_.top; |
| 1966 Address new_top = current_top + size_in_bytes; | 1961 Address new_top = current_top + size_in_bytes; |
| 1967 if (new_top <= allocation_info_.limit) return true; | 1962 if (new_top <= allocation_info_.limit) return true; |
| 1968 | 1963 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1990 | 1985 |
| 1991 | 1986 |
| 1992 bool PagedSpace::AdvanceSweeper(intptr_t bytes_to_sweep) { | 1987 bool PagedSpace::AdvanceSweeper(intptr_t bytes_to_sweep) { |
| 1993 if (IsSweepingComplete()) return true; | 1988 if (IsSweepingComplete()) return true; |
| 1994 | 1989 |
| 1995 intptr_t freed_bytes = 0; | 1990 intptr_t freed_bytes = 0; |
| 1996 Page* last = last_unswept_page_->next_page(); | 1991 Page* last = last_unswept_page_->next_page(); |
| 1997 Page* p = first_unswept_page_; | 1992 Page* p = first_unswept_page_; |
| 1998 do { | 1993 do { |
| 1999 Page* next_page = p->next_page(); | 1994 Page* next_page = p->next_page(); |
| 2000 // Evacuation candidates were swept by evacuator. | 1995 if (ShouldBeSweptLazily(p)) { |
| 2001 if (!p->IsEvacuationCandidate() && | 1996 if (FLAG_gc_verbose) { |
| 2002 !p->IsFlagSet(Page::RESCAN_ON_EVACUATION) && | 1997 PrintF("Sweeping 0x%" V8PRIxPTR " lazily advanced.\n", |
| 2003 !p->WasSwept()) { | 1998 reinterpret_cast<intptr_t>(p)); |
| 1999 } |
| 2004 freed_bytes += MarkCompactCollector::SweepConservatively(this, p); | 2000 freed_bytes += MarkCompactCollector::SweepConservatively(this, p); |
| 2005 } | 2001 } |
| 2006 p = next_page; | 2002 p = next_page; |
| 2007 } while (p != last && freed_bytes < bytes_to_sweep); | 2003 } while (p != last && freed_bytes < bytes_to_sweep); |
| 2008 | 2004 |
| 2009 if (p == last) { | 2005 if (p == last) { |
| 2010 last_unswept_page_ = first_unswept_page_ = Page::FromAddress(NULL); | 2006 last_unswept_page_ = first_unswept_page_ = Page::FromAddress(NULL); |
| 2011 } else { | 2007 } else { |
| 2012 first_unswept_page_ = p; | 2008 first_unswept_page_ = p; |
| 2013 } | 2009 } |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2504 for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) { | 2500 for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) { |
| 2505 if (obj->IsCode()) { | 2501 if (obj->IsCode()) { |
| 2506 Code* code = Code::cast(obj); | 2502 Code* code = Code::cast(obj); |
| 2507 isolate->code_kind_statistics()[code->kind()] += code->Size(); | 2503 isolate->code_kind_statistics()[code->kind()] += code->Size(); |
| 2508 } | 2504 } |
| 2509 } | 2505 } |
| 2510 } | 2506 } |
| 2511 #endif // DEBUG | 2507 #endif // DEBUG |
| 2512 | 2508 |
| 2513 } } // namespace v8::internal | 2509 } } // namespace v8::internal |
| OLD | NEW |