| 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/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/api.h" | 8 #include "src/api.h" |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
| (...skipping 2066 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2077 } | 2077 } |
| 2078 #if V8_DOUBLE_FIELDS_UNBOXING | 2078 #if V8_DOUBLE_FIELDS_UNBOXING |
| 2079 LayoutDescriptorHelper helper(target->map()); | 2079 LayoutDescriptorHelper helper(target->map()); |
| 2080 bool has_only_tagged_fields = helper.all_fields_tagged(); | 2080 bool has_only_tagged_fields = helper.all_fields_tagged(); |
| 2081 | 2081 |
| 2082 if (!has_only_tagged_fields) { | 2082 if (!has_only_tagged_fields) { |
| 2083 for (int offset = 0; offset < size;) { | 2083 for (int offset = 0; offset < size;) { |
| 2084 int end_of_region_offset; | 2084 int end_of_region_offset; |
| 2085 if (helper.IsTagged(offset, size, &end_of_region_offset)) { | 2085 if (helper.IsTagged(offset, size, &end_of_region_offset)) { |
| 2086 IterateAndMarkPointersToFromSpace( | 2086 IterateAndMarkPointersToFromSpace( |
| 2087 record_slots, obj_address + offset, | 2087 target, obj_address + offset, |
| 2088 obj_address + end_of_region_offset, &ScavengeObject); | 2088 obj_address + end_of_region_offset, record_slots, |
| 2089 &ScavengeObject); |
| 2089 } | 2090 } |
| 2090 offset = end_of_region_offset; | 2091 offset = end_of_region_offset; |
| 2091 } | 2092 } |
| 2092 } else { | 2093 } else { |
| 2093 #endif | 2094 #endif |
| 2094 IterateAndMarkPointersToFromSpace( | 2095 IterateAndMarkPointersToFromSpace(target, obj_address, |
| 2095 record_slots, obj_address, obj_address + size, &ScavengeObject); | 2096 obj_address + size, record_slots, |
| 2097 &ScavengeObject); |
| 2096 #if V8_DOUBLE_FIELDS_UNBOXING | 2098 #if V8_DOUBLE_FIELDS_UNBOXING |
| 2097 } | 2099 } |
| 2098 #endif | 2100 #endif |
| 2099 } | 2101 } |
| 2100 } | 2102 } |
| 2101 | 2103 |
| 2102 // Take another spin if there are now unswept objects in new space | 2104 // Take another spin if there are now unswept objects in new space |
| 2103 // (there are currently no more unswept promoted objects). | 2105 // (there are currently no more unswept promoted objects). |
| 2104 } while (new_space_front != new_space_.top()); | 2106 } while (new_space_front != new_space_.top()); |
| 2105 | 2107 |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2411 MarkBit mark_bit = Marking::MarkBitFrom(target); | 2413 MarkBit mark_bit = Marking::MarkBitFrom(target); |
| 2412 if (Marking::IsBlack(mark_bit)) { | 2414 if (Marking::IsBlack(mark_bit)) { |
| 2413 // This object is black and it might not be rescanned by marker. | 2415 // This object is black and it might not be rescanned by marker. |
| 2414 // We should explicitly record code entry slot for compaction because | 2416 // We should explicitly record code entry slot for compaction because |
| 2415 // promotion queue processing (IterateAndMarkPointersToFromSpace) will | 2417 // promotion queue processing (IterateAndMarkPointersToFromSpace) will |
| 2416 // miss it as it is not HeapObject-tagged. | 2418 // miss it as it is not HeapObject-tagged. |
| 2417 Address code_entry_slot = | 2419 Address code_entry_slot = |
| 2418 target->address() + JSFunction::kCodeEntryOffset; | 2420 target->address() + JSFunction::kCodeEntryOffset; |
| 2419 Code* code = Code::cast(Code::GetObjectFromEntryAddress(code_entry_slot)); | 2421 Code* code = Code::cast(Code::GetObjectFromEntryAddress(code_entry_slot)); |
| 2420 map->GetHeap()->mark_compact_collector()->RecordCodeEntrySlot( | 2422 map->GetHeap()->mark_compact_collector()->RecordCodeEntrySlot( |
| 2421 code_entry_slot, code); | 2423 target, code_entry_slot, code); |
| 2422 } | 2424 } |
| 2423 } | 2425 } |
| 2424 | 2426 |
| 2425 | 2427 |
| 2426 static inline void EvacuateFixedArray(Map* map, HeapObject** slot, | 2428 static inline void EvacuateFixedArray(Map* map, HeapObject** slot, |
| 2427 HeapObject* object) { | 2429 HeapObject* object) { |
| 2428 int object_size = FixedArray::BodyDescriptor::SizeOf(map, object); | 2430 int object_size = FixedArray::BodyDescriptor::SizeOf(map, object); |
| 2429 EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, | 2431 EvacuateObject<POINTER_OBJECT, kWordAligned>(map, slot, object, |
| 2430 object_size); | 2432 object_size); |
| 2431 } | 2433 } |
| (...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3575 allocation_sites_scratchpad()->set(allocation_sites_scratchpad_length_, | 3577 allocation_sites_scratchpad()->set(allocation_sites_scratchpad_length_, |
| 3576 site, SKIP_WRITE_BARRIER); | 3578 site, SKIP_WRITE_BARRIER); |
| 3577 Object** slot = allocation_sites_scratchpad()->RawFieldOfElementAt( | 3579 Object** slot = allocation_sites_scratchpad()->RawFieldOfElementAt( |
| 3578 allocation_sites_scratchpad_length_); | 3580 allocation_sites_scratchpad_length_); |
| 3579 | 3581 |
| 3580 if (mode == RECORD_SCRATCHPAD_SLOT) { | 3582 if (mode == RECORD_SCRATCHPAD_SLOT) { |
| 3581 // We need to allow slots buffer overflow here since the evacuation | 3583 // We need to allow slots buffer overflow here since the evacuation |
| 3582 // candidates are not part of the global list of old space pages and | 3584 // candidates are not part of the global list of old space pages and |
| 3583 // releasing an evacuation candidate due to a slots buffer overflow | 3585 // releasing an evacuation candidate due to a slots buffer overflow |
| 3584 // results in lost pages. | 3586 // results in lost pages. |
| 3585 mark_compact_collector()->RecordSlot(slot, slot, *slot, | 3587 mark_compact_collector()->RecordSlot(allocation_sites_scratchpad(), slot, |
| 3586 SlotsBuffer::IGNORE_OVERFLOW); | 3588 *slot, SlotsBuffer::IGNORE_OVERFLOW); |
| 3587 } | 3589 } |
| 3588 allocation_sites_scratchpad_length_++; | 3590 allocation_sites_scratchpad_length_++; |
| 3589 } | 3591 } |
| 3590 } | 3592 } |
| 3591 | 3593 |
| 3592 | 3594 |
| 3593 | 3595 |
| 3594 Map* Heap::MapForFixedTypedArray(ExternalArrayType array_type) { | 3596 Map* Heap::MapForFixedTypedArray(ExternalArrayType array_type) { |
| 3595 return Map::cast(roots_[RootIndexForFixedTypedArray(array_type)]); | 3597 return Map::cast(roots_[RootIndexForFixedTypedArray(array_type)]); |
| 3596 } | 3598 } |
| (...skipping 1528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5125 while (it.has_next()) { | 5127 while (it.has_next()) { |
| 5126 NewSpacePage* page = it.next(); | 5128 NewSpacePage* page = it.next(); |
| 5127 for (Address cursor = page->area_start(), limit = page->area_end(); | 5129 for (Address cursor = page->area_start(), limit = page->area_end(); |
| 5128 cursor < limit; cursor += kPointerSize) { | 5130 cursor < limit; cursor += kPointerSize) { |
| 5129 Memory::Address_at(cursor) = kFromSpaceZapValue; | 5131 Memory::Address_at(cursor) = kFromSpaceZapValue; |
| 5130 } | 5132 } |
| 5131 } | 5133 } |
| 5132 } | 5134 } |
| 5133 | 5135 |
| 5134 | 5136 |
| 5135 void Heap::IterateAndMarkPointersToFromSpace(bool record_slots, Address start, | 5137 void Heap::IterateAndMarkPointersToFromSpace(HeapObject* object, Address start, |
| 5136 Address end, | 5138 Address end, bool record_slots, |
| 5137 ObjectSlotCallback callback) { | 5139 ObjectSlotCallback callback) { |
| 5138 Address slot_address = start; | 5140 Address slot_address = start; |
| 5139 | 5141 |
| 5140 while (slot_address < end) { | 5142 while (slot_address < end) { |
| 5141 Object** slot = reinterpret_cast<Object**>(slot_address); | 5143 Object** slot = reinterpret_cast<Object**>(slot_address); |
| 5142 Object* object = *slot; | 5144 Object* target = *slot; |
| 5143 // If the store buffer becomes overfull we mark pages as being exempt from | 5145 // If the store buffer becomes overfull we mark pages as being exempt from |
| 5144 // the store buffer. These pages are scanned to find pointers that point | 5146 // the store buffer. These pages are scanned to find pointers that point |
| 5145 // to the new space. In that case we may hit newly promoted objects and | 5147 // to the new space. In that case we may hit newly promoted objects and |
| 5146 // fix the pointers before the promotion queue gets to them. Thus the 'if'. | 5148 // fix the pointers before the promotion queue gets to them. Thus the 'if'. |
| 5147 if (object->IsHeapObject()) { | 5149 if (target->IsHeapObject()) { |
| 5148 if (Heap::InFromSpace(object)) { | 5150 if (Heap::InFromSpace(target)) { |
| 5149 callback(reinterpret_cast<HeapObject**>(slot), | 5151 callback(reinterpret_cast<HeapObject**>(slot), |
| 5150 HeapObject::cast(object)); | 5152 HeapObject::cast(target)); |
| 5151 Object* new_object = *slot; | 5153 Object* new_target = *slot; |
| 5152 if (InNewSpace(new_object)) { | 5154 if (InNewSpace(new_target)) { |
| 5153 SLOW_DCHECK(Heap::InToSpace(new_object)); | 5155 SLOW_DCHECK(Heap::InToSpace(new_target)); |
| 5154 SLOW_DCHECK(new_object->IsHeapObject()); | 5156 SLOW_DCHECK(new_target->IsHeapObject()); |
| 5155 store_buffer_.EnterDirectlyIntoStoreBuffer( | 5157 store_buffer_.EnterDirectlyIntoStoreBuffer( |
| 5156 reinterpret_cast<Address>(slot)); | 5158 reinterpret_cast<Address>(slot)); |
| 5157 } | 5159 } |
| 5158 SLOW_DCHECK(!MarkCompactCollector::IsOnEvacuationCandidate(new_object)); | 5160 SLOW_DCHECK(!MarkCompactCollector::IsOnEvacuationCandidate(new_target)); |
| 5159 } else if (record_slots && | 5161 } else if (record_slots && |
| 5160 MarkCompactCollector::IsOnEvacuationCandidate(object)) { | 5162 MarkCompactCollector::IsOnEvacuationCandidate(target)) { |
| 5161 mark_compact_collector()->RecordSlot(slot, slot, object); | 5163 mark_compact_collector()->RecordSlot(object, slot, target); |
| 5162 } | 5164 } |
| 5163 } | 5165 } |
| 5164 slot_address += kPointerSize; | 5166 slot_address += kPointerSize; |
| 5165 } | 5167 } |
| 5166 } | 5168 } |
| 5167 | 5169 |
| 5168 | 5170 |
| 5169 void Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) { | 5171 void Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) { |
| 5170 IterateStrongRoots(v, mode); | 5172 IterateStrongRoots(v, mode); |
| 5171 IterateWeakRoots(v, mode); | 5173 IterateWeakRoots(v, mode); |
| (...skipping 1690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6862 *object_type = "CODE_TYPE"; \ | 6864 *object_type = "CODE_TYPE"; \ |
| 6863 *object_sub_type = "CODE_AGE/" #name; \ | 6865 *object_sub_type = "CODE_AGE/" #name; \ |
| 6864 return true; | 6866 return true; |
| 6865 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) | 6867 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) |
| 6866 #undef COMPARE_AND_RETURN_NAME | 6868 #undef COMPARE_AND_RETURN_NAME |
| 6867 } | 6869 } |
| 6868 return false; | 6870 return false; |
| 6869 } | 6871 } |
| 6870 } // namespace internal | 6872 } // namespace internal |
| 6871 } // namespace v8 | 6873 } // namespace v8 |
| OLD | NEW |