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 1183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1194 | 1194 |
1195 | 1195 |
1196 MarkCompactCollector::~MarkCompactCollector() { | 1196 MarkCompactCollector::~MarkCompactCollector() { |
1197 if (code_flusher_ != NULL) { | 1197 if (code_flusher_ != NULL) { |
1198 delete code_flusher_; | 1198 delete code_flusher_; |
1199 code_flusher_ = NULL; | 1199 code_flusher_ = NULL; |
1200 } | 1200 } |
1201 } | 1201 } |
1202 | 1202 |
1203 | 1203 |
1204 static inline HeapObject* ShortCircuitConsString(Object** p) { | |
1205 // Optimization: If the heap object pointed to by p is a non-internalized | |
1206 // cons string whose right substring is HEAP->empty_string, update | |
1207 // it in place to its left substring. Return the updated value. | |
1208 // | |
1209 // Here we assume that if we change *p, we replace it with a heap object | |
1210 // (i.e., the left substring of a cons string is always a heap object). | |
1211 // | |
1212 // The check performed is: | |
1213 // object->IsConsString() && !object->IsInternalizedString() && | |
1214 // (ConsString::cast(object)->second() == HEAP->empty_string()) | |
1215 // except the maps for the object and its possible substrings might be | |
1216 // marked. | |
1217 HeapObject* object = HeapObject::cast(*p); | |
1218 Map* map = object->map(); | |
1219 InstanceType type = map->instance_type(); | |
1220 if (!IsShortcutCandidate(type)) return object; | |
1221 | |
1222 Object* second = reinterpret_cast<ConsString*>(object)->second(); | |
1223 Heap* heap = map->GetHeap(); | |
1224 if (second != heap->empty_string()) { | |
1225 return object; | |
1226 } | |
1227 | |
1228 // Since we don't have the object's start, it is impossible to update the | |
1229 // page dirty marks. Therefore, we only replace the string with its left | |
1230 // substring when page dirty marks do not change. | |
1231 Object* first = reinterpret_cast<ConsString*>(object)->first(); | |
1232 if (!heap->InNewSpace(object) && heap->InNewSpace(first)) return object; | |
1233 | |
1234 *p = first; | |
1235 return HeapObject::cast(first); | |
1236 } | |
1237 | |
1238 | |
1239 class MarkCompactMarkingVisitor | 1204 class MarkCompactMarkingVisitor |
1240 : public StaticMarkingVisitor<MarkCompactMarkingVisitor> { | 1205 : public StaticMarkingVisitor<MarkCompactMarkingVisitor> { |
1241 public: | 1206 public: |
1242 static void ObjectStatsVisitBase(StaticVisitorBase::VisitorId id, Map* map, | 1207 static void ObjectStatsVisitBase(StaticVisitorBase::VisitorId id, Map* map, |
1243 HeapObject* obj); | 1208 HeapObject* obj); |
1244 | 1209 |
1245 static void ObjectStatsCountFixedArray( | 1210 static void ObjectStatsCountFixedArray( |
1246 FixedArrayBase* fixed_array, FixedArraySubInstanceType fast_type, | 1211 FixedArrayBase* fixed_array, FixedArraySubInstanceType fast_type, |
1247 FixedArraySubInstanceType dictionary_type); | 1212 FixedArraySubInstanceType dictionary_type); |
1248 | 1213 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1286 heap->mark_compact_collector()->SetMark(object, mark_bit); | 1251 heap->mark_compact_collector()->SetMark(object, mark_bit); |
1287 return true; | 1252 return true; |
1288 } | 1253 } |
1289 return false; | 1254 return false; |
1290 } | 1255 } |
1291 | 1256 |
1292 // Mark object pointed to by p. | 1257 // Mark object pointed to by p. |
1293 INLINE(static void MarkObjectByPointer(MarkCompactCollector* collector, | 1258 INLINE(static void MarkObjectByPointer(MarkCompactCollector* collector, |
1294 HeapObject* object, Object** p)) { | 1259 HeapObject* object, Object** p)) { |
1295 if (!(*p)->IsHeapObject()) return; | 1260 if (!(*p)->IsHeapObject()) return; |
1296 HeapObject* target_object = ShortCircuitConsString(p); | 1261 HeapObject* target_object = HeapObject::cast(*p); |
1297 collector->RecordSlot(object, p, target_object); | 1262 collector->RecordSlot(object, p, target_object); |
1298 MarkBit mark = Marking::MarkBitFrom(target_object); | 1263 MarkBit mark = Marking::MarkBitFrom(target_object); |
1299 collector->MarkObject(target_object, mark); | 1264 collector->MarkObject(target_object, mark); |
1300 } | 1265 } |
1301 | 1266 |
1302 | 1267 |
1303 // Visit an unmarked object. | 1268 // Visit an unmarked object. |
1304 INLINE(static void VisitUnmarkedObject(MarkCompactCollector* collector, | 1269 INLINE(static void VisitUnmarkedObject(MarkCompactCollector* collector, |
1305 HeapObject* obj)) { | 1270 HeapObject* obj)) { |
1306 #ifdef DEBUG | 1271 #ifdef DEBUG |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1664 | 1629 |
1665 // Skip the weak next code link in a code object, which is visited in | 1630 // Skip the weak next code link in a code object, which is visited in |
1666 // ProcessTopOptimizedFrame. | 1631 // ProcessTopOptimizedFrame. |
1667 void VisitNextCodeLink(Object** p) {} | 1632 void VisitNextCodeLink(Object** p) {} |
1668 | 1633 |
1669 private: | 1634 private: |
1670 void MarkObjectByPointer(Object** p) { | 1635 void MarkObjectByPointer(Object** p) { |
1671 if (!(*p)->IsHeapObject()) return; | 1636 if (!(*p)->IsHeapObject()) return; |
1672 | 1637 |
1673 // Replace flat cons strings in place. | 1638 // Replace flat cons strings in place. |
1674 HeapObject* object = ShortCircuitConsString(p); | 1639 HeapObject* object = HeapObject::cast(*p); |
1675 MarkBit mark_bit = Marking::MarkBitFrom(object); | 1640 MarkBit mark_bit = Marking::MarkBitFrom(object); |
1676 if (Marking::IsBlackOrGrey(mark_bit)) return; | 1641 if (Marking::IsBlackOrGrey(mark_bit)) return; |
1677 | 1642 |
1678 Map* map = object->map(); | 1643 Map* map = object->map(); |
1679 // Mark the object. | 1644 // Mark the object. |
1680 collector_->SetMark(object, mark_bit); | 1645 collector_->SetMark(object, mark_bit); |
1681 | 1646 |
1682 // Mark the map pointer and body, and push them on the marking stack. | 1647 // Mark the map pointer and body, and push them on the marking stack. |
1683 MarkBit map_mark = Marking::MarkBitFrom(map); | 1648 MarkBit map_mark = Marking::MarkBitFrom(map); |
1684 collector_->MarkObject(map, map_mark); | 1649 collector_->MarkObject(map, map_mark); |
(...skipping 3116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4801 SlotsBuffer* buffer = *buffer_address; | 4766 SlotsBuffer* buffer = *buffer_address; |
4802 while (buffer != NULL) { | 4767 while (buffer != NULL) { |
4803 SlotsBuffer* next_buffer = buffer->next(); | 4768 SlotsBuffer* next_buffer = buffer->next(); |
4804 DeallocateBuffer(buffer); | 4769 DeallocateBuffer(buffer); |
4805 buffer = next_buffer; | 4770 buffer = next_buffer; |
4806 } | 4771 } |
4807 *buffer_address = NULL; | 4772 *buffer_address = NULL; |
4808 } | 4773 } |
4809 } // namespace internal | 4774 } // namespace internal |
4810 } // namespace v8 | 4775 } // namespace v8 |
OLD | NEW |