OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
(...skipping 1839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1850 if (current_cell == 0) continue; | 1850 if (current_cell == 0) continue; |
1851 | 1851 |
1852 int offset = 0; | 1852 int offset = 0; |
1853 while (current_cell != 0) { | 1853 while (current_cell != 0) { |
1854 int trailing_zeros = base::bits::CountTrailingZeros32(current_cell); | 1854 int trailing_zeros = base::bits::CountTrailingZeros32(current_cell); |
1855 current_cell >>= trailing_zeros; | 1855 current_cell >>= trailing_zeros; |
1856 offset += trailing_zeros; | 1856 offset += trailing_zeros; |
1857 Address address = cell_base + offset * kPointerSize; | 1857 Address address = cell_base + offset * kPointerSize; |
1858 HeapObject* object = HeapObject::FromAddress(address); | 1858 HeapObject* object = HeapObject::FromAddress(address); |
1859 | 1859 |
| 1860 offset++; |
| 1861 current_cell >>= 1; |
| 1862 |
| 1863 MapWord map_word = object->map_word(); |
| 1864 if (map_word.IsForwardingAddress()) { |
| 1865 printf("forwarded object found %p\n", address); |
| 1866 continue; |
| 1867 } |
| 1868 |
1860 int size = object->Size(); | 1869 int size = object->Size(); |
1861 survivors_size += size; | 1870 survivors_size += size; |
1862 | 1871 |
1863 Heap::UpdateAllocationSiteFeedback(object, Heap::RECORD_SCRATCHPAD_SLOT); | 1872 Heap::UpdateAllocationSiteFeedback(object, Heap::RECORD_SCRATCHPAD_SLOT); |
1864 | 1873 |
1865 offset++; | |
1866 current_cell >>= 1; | |
1867 | |
1868 // TODO(hpayer): Refactor EvacuateObject and call this function instead. | 1874 // TODO(hpayer): Refactor EvacuateObject and call this function instead. |
1869 if (heap()->ShouldBePromoted(object->address(), size) && | 1875 if (heap()->ShouldBePromoted(object->address(), size) && |
1870 TryPromoteObject(object, size)) { | 1876 TryPromoteObject(object, size)) { |
1871 continue; | 1877 continue; |
1872 } | 1878 } |
1873 | 1879 |
1874 AllocationResult allocation = new_space->AllocateRaw(size); | 1880 AllocationResult allocation = new_space->AllocateRaw(size); |
1875 if (allocation.IsRetry()) { | 1881 if (allocation.IsRetry()) { |
1876 if (!new_space->AddFreshPage()) { | 1882 if (!new_space->AddFreshPage()) { |
1877 // Shouldn't happen. We are sweeping linearly, and to-space | 1883 // Shouldn't happen. We are sweeping linearly, and to-space |
(...skipping 1055 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2933 // update garbage memory which was concurrently accessed by the sweeper. | 2939 // update garbage memory which was concurrently accessed by the sweeper. |
2934 if (new_addr != NULL) { | 2940 if (new_addr != NULL) { |
2935 base::NoBarrier_CompareAndSwap( | 2941 base::NoBarrier_CompareAndSwap( |
2936 reinterpret_cast<base::AtomicWord*>(address), | 2942 reinterpret_cast<base::AtomicWord*>(address), |
2937 reinterpret_cast<base::AtomicWord>(object), | 2943 reinterpret_cast<base::AtomicWord>(object), |
2938 reinterpret_cast<base::AtomicWord>(HeapObject::FromAddress(new_addr))); | 2944 reinterpret_cast<base::AtomicWord>(HeapObject::FromAddress(new_addr))); |
2939 } | 2945 } |
2940 } | 2946 } |
2941 | 2947 |
2942 | 2948 |
| 2949 static void PromoteObjectReferencedFromStoreBuffer(HeapObject** address, |
| 2950 HeapObject* object) { |
| 2951 Heap* heap = object->GetIsolate()->heap(); |
| 2952 DCHECK(heap->InFromSpace(object)); |
| 2953 |
| 2954 // We use the first word (where the map pointer usually is) of a heap |
| 2955 // object to record the forwarding pointer. A forwarding pointer can |
| 2956 // point to an old space, the code space, or the to space of the new |
| 2957 // generation. |
| 2958 MapWord first_word = object->map_word(); |
| 2959 |
| 2960 // If the first word is a forwarding address, the object has already been |
| 2961 // promoted to the old generation. There must have been a duplicate store |
| 2962 // buffer entry. |
| 2963 if (first_word.IsForwardingAddress()) { |
| 2964 DCHECK(!heap->InNewSpace(first_word.ToForwardingAddress())); |
| 2965 return; |
| 2966 } |
| 2967 |
| 2968 if (!heap->mark_compact_collector()->TryPromoteObject(object, |
| 2969 object->Size())) { |
| 2970 V8::FatalProcessOutOfMemory("Store buffer promotion"); |
| 2971 } |
| 2972 } |
| 2973 |
| 2974 |
2943 static String* UpdateReferenceInExternalStringTableEntry(Heap* heap, | 2975 static String* UpdateReferenceInExternalStringTableEntry(Heap* heap, |
2944 Object** p) { | 2976 Object** p) { |
2945 MapWord map_word = HeapObject::cast(*p)->map_word(); | 2977 MapWord map_word = HeapObject::cast(*p)->map_word(); |
2946 | 2978 |
2947 if (map_word.IsForwardingAddress()) { | 2979 if (map_word.IsForwardingAddress()) { |
2948 return String::cast(map_word.ToForwardingAddress()); | 2980 return String::cast(map_word.ToForwardingAddress()); |
2949 } | 2981 } |
2950 | 2982 |
2951 return String::cast(*p); | 2983 return String::cast(*p); |
2952 } | 2984 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2984 Address from_bottom = new_space->bottom(); | 3016 Address from_bottom = new_space->bottom(); |
2985 Address from_top = new_space->top(); | 3017 Address from_top = new_space->top(); |
2986 | 3018 |
2987 // Flip the semispaces. After flipping, to space is empty, from space has | 3019 // Flip the semispaces. After flipping, to space is empty, from space has |
2988 // live objects. | 3020 // live objects. |
2989 new_space->Flip(); | 3021 new_space->Flip(); |
2990 new_space->ResetAllocationInfo(); | 3022 new_space->ResetAllocationInfo(); |
2991 | 3023 |
2992 int survivors_size = 0; | 3024 int survivors_size = 0; |
2993 | 3025 |
| 3026 { |
| 3027 StoreBufferRebuildScope scope(heap_, heap_->store_buffer(), |
| 3028 &Heap::ScavengeStoreBufferCallback); |
| 3029 heap_->store_buffer()->IteratePointersToNewSpace( |
| 3030 &PromoteObjectReferencedFromStoreBuffer); |
| 3031 } |
| 3032 |
2994 // First pass: traverse all objects in inactive semispace, remove marks, | 3033 // First pass: traverse all objects in inactive semispace, remove marks, |
2995 // migrate live objects and write forwarding addresses. This stage puts | 3034 // migrate live objects and write forwarding addresses. This stage puts |
2996 // new entries in the store buffer and may cause some pages to be marked | 3035 // new entries in the store buffer and may cause some pages to be marked |
2997 // scan-on-scavenge. | 3036 // scan-on-scavenge. |
2998 NewSpacePageIterator it(from_bottom, from_top); | 3037 NewSpacePageIterator it(from_bottom, from_top); |
2999 while (it.has_next()) { | 3038 while (it.has_next()) { |
3000 NewSpacePage* p = it.next(); | 3039 NewSpacePage* p = it.next(); |
3001 survivors_size += DiscoverAndEvacuateBlackObjectsOnPage(new_space, p); | 3040 survivors_size += DiscoverAndEvacuateBlackObjectsOnPage(new_space, p); |
3002 } | 3041 } |
3003 | 3042 |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3394 } | 3433 } |
3395 } | 3434 } |
3396 invalidated_code_.Rewind(0); | 3435 invalidated_code_.Rewind(0); |
3397 } | 3436 } |
3398 | 3437 |
3399 | 3438 |
3400 void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { | 3439 void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { |
3401 Heap::RelocationLock relocation_lock(heap()); | 3440 Heap::RelocationLock relocation_lock(heap()); |
3402 | 3441 |
3403 bool code_slots_filtering_required; | 3442 bool code_slots_filtering_required; |
| 3443 |
3404 { | 3444 { |
3405 GCTracer::Scope gc_scope(heap()->tracer(), | 3445 GCTracer::Scope gc_scope(heap()->tracer(), |
3406 GCTracer::Scope::MC_SWEEP_NEWSPACE); | 3446 GCTracer::Scope::MC_SWEEP_NEWSPACE); |
3407 code_slots_filtering_required = MarkInvalidatedCode(); | 3447 code_slots_filtering_required = MarkInvalidatedCode(); |
3408 EvacuateNewSpace(); | 3448 EvacuateNewSpace(); |
3409 } | 3449 } |
3410 | 3450 |
3411 { | 3451 { |
3412 GCTracer::Scope gc_scope(heap()->tracer(), | 3452 GCTracer::Scope gc_scope(heap()->tracer(), |
3413 GCTracer::Scope::MC_EVACUATE_PAGES); | 3453 GCTracer::Scope::MC_EVACUATE_PAGES); |
(...skipping 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4430 SlotsBuffer* buffer = *buffer_address; | 4470 SlotsBuffer* buffer = *buffer_address; |
4431 while (buffer != NULL) { | 4471 while (buffer != NULL) { |
4432 SlotsBuffer* next_buffer = buffer->next(); | 4472 SlotsBuffer* next_buffer = buffer->next(); |
4433 DeallocateBuffer(buffer); | 4473 DeallocateBuffer(buffer); |
4434 buffer = next_buffer; | 4474 buffer = next_buffer; |
4435 } | 4475 } |
4436 *buffer_address = NULL; | 4476 *buffer_address = NULL; |
4437 } | 4477 } |
4438 } | 4478 } |
4439 } // namespace v8::internal | 4479 } // namespace v8::internal |
OLD | NEW |