Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1932 | 1932 |
| 1933 | 1933 |
| 1934 static void DiscoverGreyObjectsOnPage(MarkingDeque* marking_deque, | 1934 static void DiscoverGreyObjectsOnPage(MarkingDeque* marking_deque, |
| 1935 MemoryChunk* p) { | 1935 MemoryChunk* p) { |
| 1936 ASSERT(!marking_deque->IsFull()); | 1936 ASSERT(!marking_deque->IsFull()); |
| 1937 ASSERT(strcmp(Marking::kWhiteBitPattern, "00") == 0); | 1937 ASSERT(strcmp(Marking::kWhiteBitPattern, "00") == 0); |
| 1938 ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); | 1938 ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); |
| 1939 ASSERT(strcmp(Marking::kGreyBitPattern, "11") == 0); | 1939 ASSERT(strcmp(Marking::kGreyBitPattern, "11") == 0); |
| 1940 ASSERT(strcmp(Marking::kImpossibleBitPattern, "01") == 0); | 1940 ASSERT(strcmp(Marking::kImpossibleBitPattern, "01") == 0); |
| 1941 | 1941 |
| 1942 MarkBit::CellType* cells = p->markbits()->cells(); | 1942 Address cell_base; |
|
titzer
2013/07/15 13:42:06
Can be in the loop, no? And also below.
Hannes Payer (out of office)
2013/07/16 12:13:00
Done.
| |
| 1943 MarkBit::CellType* cell; | |
|
Michael Starzinger
2013/07/15 14:01:46
nit: Lets move the declaration of the variables in
Hannes Payer (out of office)
2013/07/16 12:13:00
Done.
| |
| 1944 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { | |
| 1945 cell_base = it.CurrentCellBase(); | |
| 1946 cell = it.CurrentCell(); | |
| 1943 | 1947 |
| 1944 int last_cell_index = | 1948 const MarkBit::CellType current_cell = *cell; |
| 1945 Bitmap::IndexToCell( | |
| 1946 Bitmap::CellAlignIndex( | |
| 1947 p->AddressToMarkbitIndex(p->area_end()))); | |
| 1948 | |
| 1949 Address cell_base = p->area_start(); | |
| 1950 int cell_index = Bitmap::IndexToCell( | |
| 1951 Bitmap::CellAlignIndex( | |
| 1952 p->AddressToMarkbitIndex(cell_base))); | |
| 1953 | |
| 1954 | |
| 1955 for (; | |
| 1956 cell_index < last_cell_index; | |
| 1957 cell_index++, cell_base += 32 * kPointerSize) { | |
| 1958 ASSERT(static_cast<unsigned>(cell_index) == | |
| 1959 Bitmap::IndexToCell( | |
| 1960 Bitmap::CellAlignIndex( | |
| 1961 p->AddressToMarkbitIndex(cell_base)))); | |
| 1962 | |
| 1963 const MarkBit::CellType current_cell = cells[cell_index]; | |
| 1964 if (current_cell == 0) continue; | 1949 if (current_cell == 0) continue; |
| 1965 | 1950 |
| 1966 const MarkBit::CellType next_cell = cells[cell_index + 1]; | 1951 MarkBit::CellType grey_objects; |
| 1967 MarkBit::CellType grey_objects = current_cell & | 1952 if (it.HasNext()) { |
| 1968 ((current_cell >> 1) | (next_cell << (Bitmap::kBitsPerCell - 1))); | 1953 const MarkBit::CellType next_cell = *(cell+1); |
| 1954 grey_objects = current_cell & | |
| 1955 ((current_cell >> 1) | (next_cell << (Bitmap::kBitsPerCell - 1))); | |
| 1956 } else { | |
| 1957 grey_objects = current_cell & (current_cell >> 1); | |
| 1958 } | |
| 1969 | 1959 |
| 1970 int offset = 0; | 1960 int offset = 0; |
| 1971 while (grey_objects != 0) { | 1961 while (grey_objects != 0) { |
| 1972 int trailing_zeros = CompilerIntrinsics::CountTrailingZeros(grey_objects); | 1962 int trailing_zeros = CompilerIntrinsics::CountTrailingZeros(grey_objects); |
| 1973 grey_objects >>= trailing_zeros; | 1963 grey_objects >>= trailing_zeros; |
| 1974 offset += trailing_zeros; | 1964 offset += trailing_zeros; |
| 1975 MarkBit markbit(&cells[cell_index], 1 << offset, false); | 1965 MarkBit markbit(cell, 1 << offset, false); |
| 1976 ASSERT(Marking::IsGrey(markbit)); | 1966 ASSERT(Marking::IsGrey(markbit)); |
| 1977 Marking::GreyToBlack(markbit); | 1967 Marking::GreyToBlack(markbit); |
| 1978 Address addr = cell_base + offset * kPointerSize; | 1968 Address addr = cell_base + offset * kPointerSize; |
| 1979 HeapObject* object = HeapObject::FromAddress(addr); | 1969 HeapObject* object = HeapObject::FromAddress(addr); |
| 1980 MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size()); | 1970 MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size()); |
| 1981 marking_deque->PushBlack(object); | 1971 marking_deque->PushBlack(object); |
| 1982 if (marking_deque->IsFull()) return; | 1972 if (marking_deque->IsFull()) return; |
| 1983 offset += 2; | 1973 offset += 2; |
| 1984 grey_objects >>= 2; | 1974 grey_objects >>= 2; |
| 1985 } | 1975 } |
| 1986 | 1976 |
| 1987 grey_objects >>= (Bitmap::kBitsPerCell - 1); | 1977 grey_objects >>= (Bitmap::kBitsPerCell - 1); |
| 1988 } | 1978 } |
| 1989 } | 1979 } |
| 1990 | 1980 |
| 1991 | 1981 |
| 1992 int MarkCompactCollector::DiscoverAndPromoteBlackObjectsOnPage( | 1982 int MarkCompactCollector::DiscoverAndPromoteBlackObjectsOnPage( |
| 1993 NewSpace* new_space, | 1983 NewSpace* new_space, |
| 1994 NewSpacePage* p) { | 1984 NewSpacePage* p) { |
| 1995 ASSERT(strcmp(Marking::kWhiteBitPattern, "00") == 0); | 1985 ASSERT(strcmp(Marking::kWhiteBitPattern, "00") == 0); |
| 1996 ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); | 1986 ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); |
| 1997 ASSERT(strcmp(Marking::kGreyBitPattern, "11") == 0); | 1987 ASSERT(strcmp(Marking::kGreyBitPattern, "11") == 0); |
| 1998 ASSERT(strcmp(Marking::kImpossibleBitPattern, "01") == 0); | 1988 ASSERT(strcmp(Marking::kImpossibleBitPattern, "01") == 0); |
| 1999 | 1989 |
| 2000 MarkBit::CellType* cells = p->markbits()->cells(); | 1990 MarkBit::CellType* cells = p->markbits()->cells(); |
| 2001 int survivors_size = 0; | 1991 int survivors_size = 0; |
| 2002 | 1992 |
| 2003 int last_cell_index = | 1993 Address cell_base; |
| 2004 Bitmap::IndexToCell( | 1994 MarkBit::CellType* cell; |
|
Michael Starzinger
2013/07/15 14:01:46
nit: Likewise.
Hannes Payer (out of office)
2013/07/16 12:13:00
Done.
| |
| 2005 Bitmap::CellAlignIndex( | 1995 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { |
| 2006 p->AddressToMarkbitIndex(p->area_end()))); | 1996 cell_base = it.CurrentCellBase(); |
| 1997 cell = it.CurrentCell(); | |
| 2007 | 1998 |
| 2008 Address cell_base = p->area_start(); | 1999 MarkBit::CellType current_cell = *cell; |
| 2009 int cell_index = Bitmap::IndexToCell( | |
| 2010 Bitmap::CellAlignIndex( | |
| 2011 p->AddressToMarkbitIndex(cell_base))); | |
| 2012 | |
| 2013 for (; | |
| 2014 cell_index < last_cell_index; | |
| 2015 cell_index++, cell_base += 32 * kPointerSize) { | |
| 2016 ASSERT(static_cast<unsigned>(cell_index) == | |
| 2017 Bitmap::IndexToCell( | |
| 2018 Bitmap::CellAlignIndex( | |
| 2019 p->AddressToMarkbitIndex(cell_base)))); | |
| 2020 | |
| 2021 MarkBit::CellType current_cell = cells[cell_index]; | |
| 2022 if (current_cell == 0) continue; | 2000 if (current_cell == 0) continue; |
| 2023 | 2001 |
| 2024 int offset = 0; | 2002 int offset = 0; |
| 2025 while (current_cell != 0) { | 2003 while (current_cell != 0) { |
| 2026 int trailing_zeros = CompilerIntrinsics::CountTrailingZeros(current_cell); | 2004 int trailing_zeros = CompilerIntrinsics::CountTrailingZeros(current_cell); |
| 2027 current_cell >>= trailing_zeros; | 2005 current_cell >>= trailing_zeros; |
| 2028 offset += trailing_zeros; | 2006 offset += trailing_zeros; |
| 2029 Address address = cell_base + offset * kPointerSize; | 2007 Address address = cell_base + offset * kPointerSize; |
| 2030 HeapObject* object = HeapObject::FromAddress(address); | 2008 HeapObject* object = HeapObject::FromAddress(address); |
| 2031 | 2009 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 2051 allocation = new_space->AllocateRaw(size); | 2029 allocation = new_space->AllocateRaw(size); |
| 2052 ASSERT(!allocation->IsFailure()); | 2030 ASSERT(!allocation->IsFailure()); |
| 2053 } | 2031 } |
| 2054 Object* target = allocation->ToObjectUnchecked(); | 2032 Object* target = allocation->ToObjectUnchecked(); |
| 2055 | 2033 |
| 2056 MigrateObject(HeapObject::cast(target)->address(), | 2034 MigrateObject(HeapObject::cast(target)->address(), |
| 2057 object->address(), | 2035 object->address(), |
| 2058 size, | 2036 size, |
| 2059 NEW_SPACE); | 2037 NEW_SPACE); |
| 2060 } | 2038 } |
| 2061 cells[cell_index] = 0; | 2039 *cells = 0; |
| 2062 } | 2040 } |
| 2063 return survivors_size; | 2041 return survivors_size; |
| 2064 } | 2042 } |
| 2065 | 2043 |
| 2066 | 2044 |
| 2067 static void DiscoverGreyObjectsInSpace(Heap* heap, | 2045 static void DiscoverGreyObjectsInSpace(Heap* heap, |
| 2068 MarkingDeque* marking_deque, | 2046 MarkingDeque* marking_deque, |
| 2069 PagedSpace* space) { | 2047 PagedSpace* space) { |
| 2070 if (!space->was_swept_conservatively()) { | 2048 if (!space->was_swept_conservatively()) { |
| 2071 HeapObjectIterator it(space); | 2049 HeapObjectIterator it(space); |
| (...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2978 | 2956 |
| 2979 heap_->IncrementYoungSurvivorsCounter(survivors_size); | 2957 heap_->IncrementYoungSurvivorsCounter(survivors_size); |
| 2980 new_space->set_age_mark(new_space->top()); | 2958 new_space->set_age_mark(new_space->top()); |
| 2981 } | 2959 } |
| 2982 | 2960 |
| 2983 | 2961 |
| 2984 void MarkCompactCollector::EvacuateLiveObjectsFromPage(Page* p) { | 2962 void MarkCompactCollector::EvacuateLiveObjectsFromPage(Page* p) { |
| 2985 AlwaysAllocateScope always_allocate; | 2963 AlwaysAllocateScope always_allocate; |
| 2986 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); | 2964 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); |
| 2987 ASSERT(p->IsEvacuationCandidate() && !p->WasSwept()); | 2965 ASSERT(p->IsEvacuationCandidate() && !p->WasSwept()); |
| 2988 MarkBit::CellType* cells = p->markbits()->cells(); | |
| 2989 p->MarkSweptPrecisely(); | 2966 p->MarkSweptPrecisely(); |
| 2990 | 2967 |
| 2991 int last_cell_index = | |
| 2992 Bitmap::IndexToCell( | |
| 2993 Bitmap::CellAlignIndex( | |
| 2994 p->AddressToMarkbitIndex(p->area_end()))); | |
| 2995 | |
| 2996 Address cell_base = p->area_start(); | |
| 2997 int cell_index = Bitmap::IndexToCell( | |
| 2998 Bitmap::CellAlignIndex( | |
| 2999 p->AddressToMarkbitIndex(cell_base))); | |
| 3000 | |
| 3001 int offsets[16]; | 2968 int offsets[16]; |
| 3002 | 2969 |
| 3003 for (; | 2970 Address cell_base; |
| 3004 cell_index < last_cell_index; | 2971 MarkBit::CellType* cell; |
|
Michael Starzinger
2013/07/15 14:01:46
nit: Likewise.
Hannes Payer (out of office)
2013/07/16 12:13:00
Done.
| |
| 3005 cell_index++, cell_base += 32 * kPointerSize) { | 2972 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { |
| 3006 ASSERT(static_cast<unsigned>(cell_index) == | 2973 cell_base = it.CurrentCellBase(); |
| 3007 Bitmap::IndexToCell( | 2974 cell = it.CurrentCell(); |
| 3008 Bitmap::CellAlignIndex( | |
| 3009 p->AddressToMarkbitIndex(cell_base)))); | |
| 3010 if (cells[cell_index] == 0) continue; | |
| 3011 | 2975 |
| 3012 int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets); | 2976 if (*cell == 0) continue; |
| 2977 | |
| 2978 int live_objects = MarkWordToObjectStarts(*cell, offsets); | |
| 3013 for (int i = 0; i < live_objects; i++) { | 2979 for (int i = 0; i < live_objects; i++) { |
| 3014 Address object_addr = cell_base + offsets[i] * kPointerSize; | 2980 Address object_addr = cell_base + offsets[i] * kPointerSize; |
| 3015 HeapObject* object = HeapObject::FromAddress(object_addr); | 2981 HeapObject* object = HeapObject::FromAddress(object_addr); |
| 3016 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object))); | 2982 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object))); |
| 3017 | 2983 |
| 3018 int size = object->Size(); | 2984 int size = object->Size(); |
| 3019 | 2985 |
| 3020 MaybeObject* target = space->AllocateRaw(size); | 2986 MaybeObject* target = space->AllocateRaw(size); |
| 3021 if (target->IsFailure()) { | 2987 if (target->IsFailure()) { |
| 3022 // OS refused to give us memory. | 2988 // OS refused to give us memory. |
| 3023 V8::FatalProcessOutOfMemory("Evacuation"); | 2989 V8::FatalProcessOutOfMemory("Evacuation"); |
| 3024 return; | 2990 return; |
| 3025 } | 2991 } |
| 3026 | 2992 |
| 3027 Object* target_object = target->ToObjectUnchecked(); | 2993 Object* target_object = target->ToObjectUnchecked(); |
| 3028 | 2994 |
| 3029 MigrateObject(HeapObject::cast(target_object)->address(), | 2995 MigrateObject(HeapObject::cast(target_object)->address(), |
| 3030 object_addr, | 2996 object_addr, |
| 3031 size, | 2997 size, |
| 3032 space->identity()); | 2998 space->identity()); |
| 3033 ASSERT(object->map_word().IsForwardingAddress()); | 2999 ASSERT(object->map_word().IsForwardingAddress()); |
| 3034 } | 3000 } |
| 3035 | 3001 |
| 3036 // Clear marking bits for current cell. | 3002 // Clear marking bits for current cell. |
| 3037 cells[cell_index] = 0; | 3003 *cell = 0; |
| 3038 } | 3004 } |
| 3039 p->ResetLiveBytes(); | 3005 p->ResetLiveBytes(); |
| 3040 } | 3006 } |
| 3041 | 3007 |
| 3042 | 3008 |
| 3043 void MarkCompactCollector::EvacuatePages() { | 3009 void MarkCompactCollector::EvacuatePages() { |
| 3044 int npages = evacuation_candidates_.length(); | 3010 int npages = evacuation_candidates_.length(); |
| 3045 for (int i = 0; i < npages; i++) { | 3011 for (int i = 0; i < npages; i++) { |
| 3046 Page* p = evacuation_candidates_[i]; | 3012 Page* p = evacuation_candidates_[i]; |
| 3047 ASSERT(p->IsEvacuationCandidate() || | 3013 ASSERT(p->IsEvacuationCandidate() || |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3148 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); | 3114 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); |
| 3149 ASSERT_EQ(skip_list_mode == REBUILD_SKIP_LIST, | 3115 ASSERT_EQ(skip_list_mode == REBUILD_SKIP_LIST, |
| 3150 space->identity() == CODE_SPACE); | 3116 space->identity() == CODE_SPACE); |
| 3151 ASSERT((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); | 3117 ASSERT((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); |
| 3152 | 3118 |
| 3153 double start_time = 0.0; | 3119 double start_time = 0.0; |
| 3154 if (FLAG_print_cumulative_gc_stat) { | 3120 if (FLAG_print_cumulative_gc_stat) { |
| 3155 start_time = OS::TimeCurrentMillis(); | 3121 start_time = OS::TimeCurrentMillis(); |
| 3156 } | 3122 } |
| 3157 | 3123 |
| 3158 MarkBit::CellType* cells = p->markbits()->cells(); | |
| 3159 p->MarkSweptPrecisely(); | 3124 p->MarkSweptPrecisely(); |
| 3160 | 3125 |
| 3161 int last_cell_index = | |
| 3162 Bitmap::IndexToCell( | |
| 3163 Bitmap::CellAlignIndex( | |
| 3164 p->AddressToMarkbitIndex(p->area_end()))); | |
| 3165 | |
| 3166 Address free_start = p->area_start(); | 3126 Address free_start = p->area_start(); |
| 3167 int cell_index = | |
| 3168 Bitmap::IndexToCell( | |
| 3169 Bitmap::CellAlignIndex( | |
| 3170 p->AddressToMarkbitIndex(free_start))); | |
| 3171 | |
| 3172 ASSERT(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); | 3127 ASSERT(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); |
| 3173 Address object_address = free_start; | |
| 3174 int offsets[16]; | 3128 int offsets[16]; |
| 3175 | 3129 |
| 3176 SkipList* skip_list = p->skip_list(); | 3130 SkipList* skip_list = p->skip_list(); |
| 3177 int curr_region = -1; | 3131 int curr_region = -1; |
| 3178 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list) { | 3132 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list) { |
| 3179 skip_list->Clear(); | 3133 skip_list->Clear(); |
| 3180 } | 3134 } |
| 3181 | 3135 |
| 3182 for (; | 3136 MarkBit::CellType* cell; |
| 3183 cell_index < last_cell_index; | 3137 Address cell_base; |
| 3184 cell_index++, object_address += 32 * kPointerSize) { | 3138 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { |
| 3185 ASSERT(static_cast<unsigned>(cell_index) == | 3139 cell = it.CurrentCell(); |
| 3186 Bitmap::IndexToCell( | 3140 cell_base = it.CurrentCellBase(); |
| 3187 Bitmap::CellAlignIndex( | 3141 int live_objects = MarkWordToObjectStarts(*cell, offsets); |
| 3188 p->AddressToMarkbitIndex(object_address)))); | |
| 3189 int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets); | |
| 3190 int live_index = 0; | 3142 int live_index = 0; |
| 3191 for ( ; live_objects != 0; live_objects--) { | 3143 for ( ; live_objects != 0; live_objects--) { |
| 3192 Address free_end = object_address + offsets[live_index++] * kPointerSize; | 3144 Address free_end = cell_base + offsets[live_index++] * kPointerSize; |
| 3193 if (free_end != free_start) { | 3145 if (free_end != free_start) { |
| 3194 space->Free(free_start, static_cast<int>(free_end - free_start)); | 3146 space->Free(free_start, static_cast<int>(free_end - free_start)); |
| 3195 #ifdef ENABLE_GDB_JIT_INTERFACE | 3147 #ifdef ENABLE_GDB_JIT_INTERFACE |
| 3196 if (FLAG_gdbjit && space->identity() == CODE_SPACE) { | 3148 if (FLAG_gdbjit && space->identity() == CODE_SPACE) { |
| 3197 GDBJITInterface::RemoveCodeRange(free_start, free_end); | 3149 GDBJITInterface::RemoveCodeRange(free_start, free_end); |
| 3198 } | 3150 } |
| 3199 #endif | 3151 #endif |
| 3200 } | 3152 } |
| 3201 HeapObject* live_object = HeapObject::FromAddress(free_end); | 3153 HeapObject* live_object = HeapObject::FromAddress(free_end); |
| 3202 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object))); | 3154 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(live_object))); |
| 3203 Map* map = live_object->map(); | 3155 Map* map = live_object->map(); |
| 3204 int size = live_object->SizeFromMap(map); | 3156 int size = live_object->SizeFromMap(map); |
| 3205 if (sweeping_mode == SWEEP_AND_VISIT_LIVE_OBJECTS) { | 3157 if (sweeping_mode == SWEEP_AND_VISIT_LIVE_OBJECTS) { |
| 3206 live_object->IterateBody(map->instance_type(), size, v); | 3158 live_object->IterateBody(map->instance_type(), size, v); |
| 3207 } | 3159 } |
| 3208 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list != NULL) { | 3160 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list != NULL) { |
| 3209 int new_region_start = | 3161 int new_region_start = |
| 3210 SkipList::RegionNumber(free_end); | 3162 SkipList::RegionNumber(free_end); |
| 3211 int new_region_end = | 3163 int new_region_end = |
| 3212 SkipList::RegionNumber(free_end + size - kPointerSize); | 3164 SkipList::RegionNumber(free_end + size - kPointerSize); |
| 3213 if (new_region_start != curr_region || | 3165 if (new_region_start != curr_region || |
| 3214 new_region_end != curr_region) { | 3166 new_region_end != curr_region) { |
| 3215 skip_list->AddObject(free_end, size); | 3167 skip_list->AddObject(free_end, size); |
| 3216 curr_region = new_region_end; | 3168 curr_region = new_region_end; |
| 3217 } | 3169 } |
| 3218 } | 3170 } |
| 3219 free_start = free_end + size; | 3171 free_start = free_end + size; |
| 3220 } | 3172 } |
| 3221 // Clear marking bits for current cell. | 3173 // Clear marking bits for current cell. |
| 3222 cells[cell_index] = 0; | 3174 *cell = 0; |
| 3223 } | 3175 } |
| 3224 if (free_start != p->area_end()) { | 3176 if (free_start != p->area_end()) { |
| 3225 space->Free(free_start, static_cast<int>(p->area_end() - free_start)); | 3177 space->Free(free_start, static_cast<int>(p->area_end() - free_start)); |
| 3226 #ifdef ENABLE_GDB_JIT_INTERFACE | 3178 #ifdef ENABLE_GDB_JIT_INTERFACE |
| 3227 if (FLAG_gdbjit && space->identity() == CODE_SPACE) { | 3179 if (FLAG_gdbjit && space->identity() == CODE_SPACE) { |
| 3228 GDBJITInterface::RemoveCodeRange(free_start, p->area_end()); | 3180 GDBJITInterface::RemoveCodeRange(free_start, p->area_end()); |
| 3229 } | 3181 } |
| 3230 #endif | 3182 #endif |
| 3231 } | 3183 } |
| 3232 p->ResetLiveBytes(); | 3184 p->ResetLiveBytes(); |
| (...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3879 template<MarkCompactCollector::SweepingParallelism mode> | 3831 template<MarkCompactCollector::SweepingParallelism mode> |
| 3880 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, | 3832 intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, |
| 3881 FreeList* free_list, | 3833 FreeList* free_list, |
| 3882 Page* p) { | 3834 Page* p) { |
| 3883 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); | 3835 ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept()); |
| 3884 ASSERT((mode == MarkCompactCollector::SWEEP_IN_PARALLEL && | 3836 ASSERT((mode == MarkCompactCollector::SWEEP_IN_PARALLEL && |
| 3885 free_list != NULL) || | 3837 free_list != NULL) || |
| 3886 (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY && | 3838 (mode == MarkCompactCollector::SWEEP_SEQUENTIALLY && |
| 3887 free_list == NULL)); | 3839 free_list == NULL)); |
| 3888 | 3840 |
| 3889 MarkBit::CellType* cells = p->markbits()->cells(); | |
| 3890 p->MarkSweptConservatively(); | 3841 p->MarkSweptConservatively(); |
| 3891 | 3842 |
| 3892 int last_cell_index = | |
| 3893 Bitmap::IndexToCell( | |
| 3894 Bitmap::CellAlignIndex( | |
| 3895 p->AddressToMarkbitIndex(p->area_end()))); | |
| 3896 | |
| 3897 int cell_index = | |
| 3898 Bitmap::IndexToCell( | |
| 3899 Bitmap::CellAlignIndex( | |
| 3900 p->AddressToMarkbitIndex(p->area_start()))); | |
| 3901 | |
| 3902 intptr_t freed_bytes = 0; | 3843 intptr_t freed_bytes = 0; |
| 3903 | 3844 size_t size = 0; |
| 3904 // This is the start of the 32 word block that we are currently looking at. | |
| 3905 Address block_address = p->area_start(); | |
| 3906 | 3845 |
| 3907 // Skip over all the dead objects at the start of the page and mark them free. | 3846 // Skip over all the dead objects at the start of the page and mark them free. |
| 3908 for (; | 3847 Address cell_base = 0; |
| 3909 cell_index < last_cell_index; | 3848 MarkBit::CellType* cell = NULL; |
| 3910 cell_index++, block_address += 32 * kPointerSize) { | 3849 MarkBitCellIterator it(p); |
| 3911 if (cells[cell_index] != 0) break; | 3850 for (; !it.Done(); it.Advance()) { |
| 3851 cell_base = it.CurrentCellBase(); | |
| 3852 cell = it.CurrentCell(); | |
| 3853 if (*cell != 0) break; | |
| 3912 } | 3854 } |
| 3913 size_t size = block_address - p->area_start(); | 3855 |
| 3914 if (cell_index == last_cell_index) { | 3856 if (it.Done()) { |
| 3857 size = p->area_end() - p->area_start(); | |
| 3915 freed_bytes += Free<mode>(space, free_list, p->area_start(), | 3858 freed_bytes += Free<mode>(space, free_list, p->area_start(), |
| 3916 static_cast<int>(size)); | 3859 static_cast<int>(size)); |
| 3917 ASSERT_EQ(0, p->LiveBytes()); | 3860 ASSERT_EQ(0, p->LiveBytes()); |
| 3918 return freed_bytes; | 3861 return freed_bytes; |
| 3919 } | 3862 } |
| 3863 | |
| 3920 // Grow the size of the start-of-page free space a little to get up to the | 3864 // Grow the size of the start-of-page free space a little to get up to the |
| 3921 // first live object. | 3865 // first live object. |
| 3922 Address free_end = StartOfLiveObject(block_address, cells[cell_index]); | 3866 Address free_end = StartOfLiveObject(cell_base, *cell); |
| 3923 // Free the first free space. | 3867 // Free the first free space. |
| 3924 size = free_end - p->area_start(); | 3868 size = free_end - p->area_start(); |
| 3925 freed_bytes += Free<mode>(space, free_list, p->area_start(), | 3869 freed_bytes += Free<mode>(space, free_list, p->area_start(), |
| 3926 static_cast<int>(size)); | 3870 static_cast<int>(size)); |
| 3927 | 3871 |
| 3928 // The start of the current free area is represented in undigested form by | 3872 // The start of the current free area is represented in undigested form by |
| 3929 // the address of the last 32-word section that contained a live object and | 3873 // the address of the last 32-word section that contained a live object and |
| 3930 // the marking bitmap for that cell, which describes where the live object | 3874 // the marking bitmap for that cell, which describes where the live object |
| 3931 // started. Unless we find a large free space in the bitmap we will not | 3875 // started. Unless we find a large free space in the bitmap we will not |
| 3932 // digest this pair into a real address. We start the iteration here at the | 3876 // digest this pair into a real address. We start the iteration here at the |
| 3933 // first word in the marking bit map that indicates a live object. | 3877 // first word in the marking bit map that indicates a live object. |
| 3934 Address free_start = block_address; | 3878 Address free_start = cell_base; |
| 3935 uint32_t free_start_cell = cells[cell_index]; | 3879 MarkBit::CellType free_start_cell = *cell; |
| 3936 | 3880 |
| 3937 for ( ; | 3881 for (; !it.Done(); it.Advance()) { |
| 3938 cell_index < last_cell_index; | 3882 cell_base = it.CurrentCellBase(); |
| 3939 cell_index++, block_address += 32 * kPointerSize) { | 3883 cell = it.CurrentCell(); |
| 3940 ASSERT((unsigned)cell_index == | 3884 if (*cell != 0) { |
| 3941 Bitmap::IndexToCell( | |
| 3942 Bitmap::CellAlignIndex( | |
| 3943 p->AddressToMarkbitIndex(block_address)))); | |
| 3944 uint32_t cell = cells[cell_index]; | |
| 3945 if (cell != 0) { | |
| 3946 // We have a live object. Check approximately whether it is more than 32 | 3885 // We have a live object. Check approximately whether it is more than 32 |
| 3947 // words since the last live object. | 3886 // words since the last live object. |
| 3948 if (block_address - free_start > 32 * kPointerSize) { | 3887 if (cell_base - free_start > 32 * kPointerSize) { |
| 3949 free_start = DigestFreeStart(free_start, free_start_cell); | 3888 free_start = DigestFreeStart(free_start, free_start_cell); |
| 3950 if (block_address - free_start > 32 * kPointerSize) { | 3889 if (cell_base - free_start > 32 * kPointerSize) { |
| 3951 // Now that we know the exact start of the free space it still looks | 3890 // Now that we know the exact start of the free space it still looks |
| 3952 // like we have a large enough free space to be worth bothering with. | 3891 // like we have a large enough free space to be worth bothering with. |
| 3953 // so now we need to find the start of the first live object at the | 3892 // so now we need to find the start of the first live object at the |
| 3954 // end of the free space. | 3893 // end of the free space. |
| 3955 free_end = StartOfLiveObject(block_address, cell); | 3894 free_end = StartOfLiveObject(cell_base, *cell); |
| 3956 freed_bytes += Free<mode>(space, free_list, free_start, | 3895 freed_bytes += Free<mode>(space, free_list, free_start, |
| 3957 static_cast<int>(free_end - free_start)); | 3896 static_cast<int>(free_end - free_start)); |
| 3958 } | 3897 } |
| 3959 } | 3898 } |
| 3960 // Update our undigested record of where the current free area started. | 3899 // Update our undigested record of where the current free area started. |
| 3961 free_start = block_address; | 3900 free_start = cell_base; |
| 3962 free_start_cell = cell; | 3901 free_start_cell = *cell; |
| 3963 // Clear marking bits for current cell. | 3902 // Clear marking bits for current cell. |
| 3964 cells[cell_index] = 0; | 3903 *cell = 0; |
| 3965 } | 3904 } |
| 3966 } | 3905 } |
| 3967 | 3906 |
| 3968 // Handle the free space at the end of the page. | 3907 // Handle the free space at the end of the page. |
| 3969 if (block_address - free_start > 32 * kPointerSize) { | 3908 if (cell_base - free_start > 32 * kPointerSize) { |
| 3970 free_start = DigestFreeStart(free_start, free_start_cell); | 3909 free_start = DigestFreeStart(free_start, free_start_cell); |
| 3971 freed_bytes += Free<mode>(space, free_list, free_start, | 3910 freed_bytes += Free<mode>(space, free_list, free_start, |
| 3972 static_cast<int>(block_address - free_start)); | 3911 static_cast<int>(p->area_end() - free_start)); |
| 3973 } | 3912 } |
| 3974 | 3913 |
| 3975 p->ResetLiveBytes(); | 3914 p->ResetLiveBytes(); |
| 3976 return freed_bytes; | 3915 return freed_bytes; |
| 3977 } | 3916 } |
| 3978 | 3917 |
| 3979 | 3918 |
| 3980 void MarkCompactCollector::SweepInParallel(PagedSpace* space, | 3919 void MarkCompactCollector::SweepInParallel(PagedSpace* space, |
| 3981 FreeList* private_free_list, | 3920 FreeList* private_free_list, |
| 3982 FreeList* free_list) { | 3921 FreeList* free_list) { |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4372 while (buffer != NULL) { | 4311 while (buffer != NULL) { |
| 4373 SlotsBuffer* next_buffer = buffer->next(); | 4312 SlotsBuffer* next_buffer = buffer->next(); |
| 4374 DeallocateBuffer(buffer); | 4313 DeallocateBuffer(buffer); |
| 4375 buffer = next_buffer; | 4314 buffer = next_buffer; |
| 4376 } | 4315 } |
| 4377 *buffer_address = NULL; | 4316 *buffer_address = NULL; |
| 4378 } | 4317 } |
| 4379 | 4318 |
| 4380 | 4319 |
| 4381 } } // namespace v8::internal | 4320 } } // namespace v8::internal |
| OLD | NEW |