OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 1021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 } else { | 1032 } else { |
1033 // Unless this is the last page in the space containing allocated | 1033 // Unless this is the last page in the space containing allocated |
1034 // objects, the allocation top should be at a constant offset from the | 1034 // objects, the allocation top should be at a constant offset from the |
1035 // object area end. | 1035 // object area end. |
1036 Address top = current_page->AllocationTop(); | 1036 Address top = current_page->AllocationTop(); |
1037 if (current_page == top_page) { | 1037 if (current_page == top_page) { |
1038 ASSERT(top == allocation_info_.top); | 1038 ASSERT(top == allocation_info_.top); |
1039 // The next page will be above the allocation top. | 1039 // The next page will be above the allocation top. |
1040 above_allocation_top = true; | 1040 above_allocation_top = true; |
1041 } else { | 1041 } else { |
1042 ASSERT(top == current_page->ObjectAreaEnd() - page_extra_); | 1042 ASSERT(top == PageAllocationLimit(current_page)); |
1043 } | 1043 } |
1044 | 1044 |
1045 // It should be packed with objects from the bottom to the top. | 1045 // It should be packed with objects from the bottom to the top. |
1046 Address current = current_page->ObjectAreaStart(); | 1046 Address current = current_page->ObjectAreaStart(); |
1047 while (current < top) { | 1047 while (current < top) { |
1048 HeapObject* object = HeapObject::FromAddress(current); | 1048 HeapObject* object = HeapObject::FromAddress(current); |
1049 | 1049 |
1050 // The first word should be a map, and we expect all map pointers to | 1050 // The first word should be a map, and we expect all map pointers to |
1051 // be in map space. | 1051 // be in map space. |
1052 Map* map = object->map(); | 1052 Map* map = object->map(); |
(...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1970 // Order of pages in this space might no longer be consistent with | 1970 // Order of pages in this space might no longer be consistent with |
1971 // order of pages in chunks. | 1971 // order of pages in chunks. |
1972 page_list_is_chunk_ordered_ = false; | 1972 page_list_is_chunk_ordered_ = false; |
1973 } | 1973 } |
1974 | 1974 |
1975 | 1975 |
1976 void PagedSpace::PrepareForMarkCompact(bool will_compact) { | 1976 void PagedSpace::PrepareForMarkCompact(bool will_compact) { |
1977 if (will_compact) { | 1977 if (will_compact) { |
1978 // MarkCompact collector relies on WAS_IN_USE_BEFORE_MC page flag | 1978 // MarkCompact collector relies on WAS_IN_USE_BEFORE_MC page flag |
1979 // to skip unused pages. Update flag value for all pages in space. | 1979 // to skip unused pages. Update flag value for all pages in space. |
1980 PageIterator it(this, PageIterator::ALL_PAGES); | 1980 PageIterator all_pages_iterator(this, PageIterator::ALL_PAGES); |
1981 Page* last_in_use = AllocationTopPage(); | 1981 Page* last_in_use = AllocationTopPage(); |
1982 bool in_use = true; | 1982 bool in_use = true; |
1983 | 1983 |
1984 while (it.has_next()) { | 1984 while (all_pages_iterator.has_next()) { |
1985 Page* p = it.next(); | 1985 Page* p = all_pages_iterator.next(); |
1986 p->SetWasInUseBeforeMC(in_use); | 1986 p->SetWasInUseBeforeMC(in_use); |
1987 if (p == last_in_use) { | 1987 if (p == last_in_use) { |
1988 // We passed a page containing allocation top. All consequent | 1988 // We passed a page containing allocation top. All consequent |
1989 // pages are not used. | 1989 // pages are not used. |
1990 in_use = false; | 1990 in_use = false; |
1991 } | 1991 } |
1992 } | 1992 } |
1993 | 1993 |
1994 if (!page_list_is_chunk_ordered_) { | 1994 if (!page_list_is_chunk_ordered_) { |
1995 Page* new_last_in_use = NULL; | 1995 Page* new_last_in_use = NULL; |
1996 MemoryAllocator::RelinkPageListInChunkOrder(this, | 1996 MemoryAllocator::RelinkPageListInChunkOrder(this, |
1997 &first_page_, | 1997 &first_page_, |
1998 &last_page_, | 1998 &last_page_, |
1999 &new_last_in_use); | 1999 &new_last_in_use); |
2000 ASSERT(new_last_in_use != NULL); | 2000 ASSERT(new_last_in_use != NULL); |
2001 | 2001 |
2002 if (new_last_in_use != last_in_use) { | 2002 if (new_last_in_use != last_in_use) { |
2003 // Current allocation top points to a page which is now in the middle | 2003 // Current allocation top points to a page which is now in the middle |
2004 // of page list. We should move allocation top forward to the new last | 2004 // of page list. We should move allocation top forward to the new last |
2005 // used page so various object iterators will continue to work properly. | 2005 // used page so various object iterators will continue to work properly. |
2006 | 2006 |
2007 int size_in_bytes = | 2007 int size_in_bytes = |
2008 last_in_use->ObjectAreaEnd() - last_in_use->AllocationTop(); | 2008 PageAllocationLimit(last_in_use) - last_in_use->AllocationTop(); |
2009 | 2009 |
2010 if (size_in_bytes > 0) { | 2010 if (size_in_bytes > 0) { |
2011 // There is still some space left on this page. Create a fake | 2011 // There is still some space left on this page. Create a fake |
2012 // object which will occupy all free space on this page. | 2012 // object which will occupy all free space on this page. |
2013 // Otherwise iterators would not be able to scan this page | 2013 // Otherwise iterators would not be able to scan this page |
2014 // correctly. | 2014 // correctly. |
2015 | 2015 |
2016 FreeListNode* node = | 2016 FreeListNode* node = |
2017 FreeListNode::FromAddress(last_in_use->AllocationTop()); | 2017 FreeListNode::FromAddress(last_in_use->AllocationTop()); |
2018 node->set_size(last_in_use->ObjectAreaEnd() - | 2018 node->set_size(size_in_bytes); |
2019 last_in_use->AllocationTop()); | |
2020 } | 2019 } |
2021 | 2020 |
2022 // New last in use page was in the middle of the list before | 2021 // New last in use page was in the middle of the list before |
2023 // sorting so it full. | 2022 // sorting so it full. |
2024 SetTop(new_last_in_use->AllocationTop(), | 2023 SetTop(new_last_in_use->AllocationTop()); |
2025 new_last_in_use->AllocationTop()); | |
2026 | 2024 |
2027 ASSERT(AllocationTopPage() == new_last_in_use); | 2025 ASSERT(AllocationTopPage() == new_last_in_use); |
| 2026 ASSERT(AllocationTopPage()->WasInUseBeforeMC()); |
| 2027 } |
| 2028 |
| 2029 PageIterator pages_in_use_iterator(this, PageIterator::PAGES_IN_USE); |
| 2030 while (pages_in_use_iterator.has_next()) { |
| 2031 Page* p = pages_in_use_iterator.next(); |
| 2032 if (!p->WasInUseBeforeMC()) { |
| 2033 // Empty page is in the middle of a sequence of used pages. |
| 2034 // Create a fake object which will occupy all free space on this page. |
| 2035 // Otherwise iterators would not be able to scan this page correctly. |
| 2036 FreeListNode* node = |
| 2037 FreeListNode::FromAddress(p->ObjectAreaStart()); |
| 2038 node->set_size(PageAllocationLimit(p) - p->ObjectAreaStart()); |
| 2039 } |
2028 } | 2040 } |
2029 | 2041 |
2030 page_list_is_chunk_ordered_ = true; | 2042 page_list_is_chunk_ordered_ = true; |
2031 } | 2043 } |
2032 } | 2044 } |
2033 } | 2045 } |
2034 | 2046 |
2035 | 2047 |
2036 bool PagedSpace::ReserveSpace(int bytes) { | 2048 bool PagedSpace::ReserveSpace(int bytes) { |
2037 Address limit = allocation_info_.limit; | 2049 Address limit = allocation_info_.limit; |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2537 return NULL; | 2549 return NULL; |
2538 } | 2550 } |
2539 | 2551 |
2540 | 2552 |
2541 // Move to the next page (there is assumed to be one) and allocate there. | 2553 // Move to the next page (there is assumed to be one) and allocate there. |
2542 // The top of page block is always wasted, because it is too small to hold a | 2554 // The top of page block is always wasted, because it is too small to hold a |
2543 // map. | 2555 // map. |
2544 HeapObject* FixedSpace::AllocateInNextPage(Page* current_page, | 2556 HeapObject* FixedSpace::AllocateInNextPage(Page* current_page, |
2545 int size_in_bytes) { | 2557 int size_in_bytes) { |
2546 ASSERT(current_page->next_page()->is_valid()); | 2558 ASSERT(current_page->next_page()->is_valid()); |
2547 ASSERT(current_page->ObjectAreaEnd() - allocation_info_.top == page_extra_); | 2559 ASSERT(allocation_info_.top == PageAllocationLimit(current_page)); |
2548 ASSERT_EQ(object_size_in_bytes_, size_in_bytes); | 2560 ASSERT_EQ(object_size_in_bytes_, size_in_bytes); |
2549 accounting_stats_.WasteBytes(page_extra_); | 2561 accounting_stats_.WasteBytes(page_extra_); |
2550 SetAllocationInfo(&allocation_info_, current_page->next_page()); | 2562 SetAllocationInfo(&allocation_info_, current_page->next_page()); |
2551 return AllocateLinearly(&allocation_info_, size_in_bytes); | 2563 return AllocateLinearly(&allocation_info_, size_in_bytes); |
2552 } | 2564 } |
2553 | 2565 |
2554 | 2566 |
2555 #ifdef DEBUG | 2567 #ifdef DEBUG |
2556 void FixedSpace::ReportStatistics() { | 2568 void FixedSpace::ReportStatistics() { |
2557 int pct = Available() * 100 / Capacity(); | 2569 int pct = Available() * 100 / Capacity(); |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3057 reinterpret_cast<Object**>(object->address() | 3069 reinterpret_cast<Object**>(object->address() |
3058 + Page::kObjectAreaSize), | 3070 + Page::kObjectAreaSize), |
3059 allocation_top); | 3071 allocation_top); |
3060 PrintF("\n"); | 3072 PrintF("\n"); |
3061 } | 3073 } |
3062 } | 3074 } |
3063 } | 3075 } |
3064 #endif // DEBUG | 3076 #endif // DEBUG |
3065 | 3077 |
3066 } } // namespace v8::internal | 3078 } } // namespace v8::internal |
OLD | NEW |