| 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 |