| 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 920 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 931 // page dirty marks. Therefore, we only replace the string with its left | 931 // page dirty marks. Therefore, we only replace the string with its left |
| 932 // substring when page dirty marks do not change. | 932 // substring when page dirty marks do not change. |
| 933 Object* first = reinterpret_cast<ConsString*>(object)->unchecked_first(); | 933 Object* first = reinterpret_cast<ConsString*>(object)->unchecked_first(); |
| 934 if (!heap->InNewSpace(object) && heap->InNewSpace(first)) return object; | 934 if (!heap->InNewSpace(object) && heap->InNewSpace(first)) return object; |
| 935 | 935 |
| 936 *p = first; | 936 *p = first; |
| 937 return HeapObject::cast(first); | 937 return HeapObject::cast(first); |
| 938 } | 938 } |
| 939 | 939 |
| 940 | 940 |
| 941 class StaticMarkingVisitor : public StaticVisitorBase { | 941 class MarkCompactMarkingVisitor |
| 942 : public StaticMarkingVisitor<MarkCompactMarkingVisitor> { |
| 942 public: | 943 public: |
| 943 static inline void IterateBody(Map* map, HeapObject* obj) { | |
| 944 table_.GetVisitor(map)(map, obj); | |
| 945 } | |
| 946 | |
| 947 template<int id> | |
| 948 class ObjectStatsTracker { | |
| 949 public: | |
| 950 static inline void Visit(Map* map, HeapObject* obj); | |
| 951 }; | |
| 952 | |
| 953 static void Initialize(); | 944 static void Initialize(); |
| 954 | 945 |
| 955 INLINE(static void VisitPointer(Heap* heap, Object** p)) { | 946 INLINE(static void VisitPointer(Heap* heap, Object** p)) { |
| 956 MarkObjectByPointer(heap->mark_compact_collector(), p, p); | 947 MarkObjectByPointer(heap->mark_compact_collector(), p, p); |
| 957 } | 948 } |
| 958 | 949 |
| 959 INLINE(static void VisitPointers(Heap* heap, Object** start, Object** end)) { | 950 INLINE(static void VisitPointers(Heap* heap, Object** start, Object** end)) { |
| 960 // Mark all objects pointed to in [start, end). | 951 // Mark all objects pointed to in [start, end). |
| 961 const int kMinRangeForMarkingRecursion = 64; | 952 const int kMinRangeForMarkingRecursion = 64; |
| 962 if (end - start >= kMinRangeForMarkingRecursion) { | 953 if (end - start >= kMinRangeForMarkingRecursion) { |
| 963 if (VisitUnmarkedObjects(heap, start, end)) return; | 954 if (VisitUnmarkedObjects(heap, start, end)) return; |
| 964 // We are close to a stack overflow, so just mark the objects. | 955 // We are close to a stack overflow, so just mark the objects. |
| 965 } | 956 } |
| 966 MarkCompactCollector* collector = heap->mark_compact_collector(); | 957 MarkCompactCollector* collector = heap->mark_compact_collector(); |
| 967 for (Object** p = start; p < end; p++) { | 958 for (Object** p = start; p < end; p++) { |
| 968 MarkObjectByPointer(collector, start, p); | 959 MarkObjectByPointer(collector, start, p); |
| 969 } | 960 } |
| 970 } | 961 } |
| 971 | 962 |
| 972 static void VisitGlobalPropertyCell(Heap* heap, RelocInfo* rinfo) { | 963 INLINE(static void MarkObject(Heap* heap, HeapObject* object)) { |
| 973 ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL); | 964 MarkBit mark = Marking::MarkBitFrom(object); |
| 974 JSGlobalPropertyCell* cell = | 965 heap->mark_compact_collector()->MarkObject(object, mark); |
| 975 JSGlobalPropertyCell::cast(rinfo->target_cell()); | |
| 976 MarkBit mark = Marking::MarkBitFrom(cell); | |
| 977 heap->mark_compact_collector()->MarkObject(cell, mark); | |
| 978 } | 966 } |
| 979 | 967 |
| 980 static inline void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo) { | 968 static inline void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo) { |
| 981 ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); | 969 ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); |
| 982 // TODO(mstarzinger): We do not short-circuit cons strings here, verify | 970 // TODO(mstarzinger): We do not short-circuit cons strings here, verify |
| 983 // that there can be no such embedded pointers and add assertion here. | 971 // that there can be no such embedded pointers and add assertion here. |
| 984 HeapObject* object = HeapObject::cast(rinfo->target_object()); | 972 HeapObject* object = HeapObject::cast(rinfo->target_object()); |
| 985 heap->mark_compact_collector()->RecordRelocSlot(rinfo, object); | 973 heap->mark_compact_collector()->RecordRelocSlot(rinfo, object); |
| 986 MarkBit mark = Marking::MarkBitFrom(object); | 974 MarkObject(heap, object); |
| 987 heap->mark_compact_collector()->MarkObject(object, mark); | |
| 988 } | 975 } |
| 989 | 976 |
| 990 static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) { | 977 static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) { |
| 991 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); | 978 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); |
| 992 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 979 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
| 993 if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub() | 980 if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub() |
| 994 && (target->ic_state() == MEGAMORPHIC || | 981 && (target->ic_state() == MEGAMORPHIC || |
| 995 heap->mark_compact_collector()->flush_monomorphic_ics_ || | 982 heap->mark_compact_collector()->flush_monomorphic_ics_ || |
| 996 target->ic_age() != heap->global_ic_age())) { | 983 target->ic_age() != heap->global_ic_age())) { |
| 997 IC::Clear(rinfo->pc()); | 984 IC::Clear(rinfo->pc()); |
| 998 target = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 985 target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
| 999 } | 986 } |
| 1000 MarkBit code_mark = Marking::MarkBitFrom(target); | |
| 1001 heap->mark_compact_collector()->MarkObject(target, code_mark); | |
| 1002 heap->mark_compact_collector()->RecordRelocSlot(rinfo, target); | 987 heap->mark_compact_collector()->RecordRelocSlot(rinfo, target); |
| 1003 } | 988 MarkObject(heap, target); |
| 1004 | |
| 1005 static inline void VisitDebugTarget(Heap* heap, RelocInfo* rinfo) { | |
| 1006 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && | |
| 1007 rinfo->IsPatchedReturnSequence()) || | |
| 1008 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && | |
| 1009 rinfo->IsPatchedDebugBreakSlotSequence())); | |
| 1010 Code* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); | |
| 1011 MarkBit code_mark = Marking::MarkBitFrom(target); | |
| 1012 heap->mark_compact_collector()->MarkObject(target, code_mark); | |
| 1013 heap->mark_compact_collector()->RecordRelocSlot(rinfo, target); | |
| 1014 } | 989 } |
| 1015 | 990 |
| 1016 // Mark object pointed to by p. | 991 // Mark object pointed to by p. |
| 1017 INLINE(static void MarkObjectByPointer(MarkCompactCollector* collector, | 992 INLINE(static void MarkObjectByPointer(MarkCompactCollector* collector, |
| 1018 Object** anchor_slot, | 993 Object** anchor_slot, |
| 1019 Object** p)) { | 994 Object** p)) { |
| 1020 if (!(*p)->IsHeapObject()) return; | 995 if (!(*p)->IsHeapObject()) return; |
| 1021 HeapObject* object = ShortCircuitConsString(p); | 996 HeapObject* object = ShortCircuitConsString(p); |
| 1022 collector->RecordSlot(anchor_slot, p, object); | 997 collector->RecordSlot(anchor_slot, p, object); |
| 1023 MarkBit mark = Marking::MarkBitFrom(object); | 998 MarkBit mark = Marking::MarkBitFrom(object); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1058 if (!o->IsHeapObject()) continue; | 1033 if (!o->IsHeapObject()) continue; |
| 1059 collector->RecordSlot(start, p, o); | 1034 collector->RecordSlot(start, p, o); |
| 1060 HeapObject* obj = HeapObject::cast(o); | 1035 HeapObject* obj = HeapObject::cast(o); |
| 1061 MarkBit mark = Marking::MarkBitFrom(obj); | 1036 MarkBit mark = Marking::MarkBitFrom(obj); |
| 1062 if (mark.Get()) continue; | 1037 if (mark.Get()) continue; |
| 1063 VisitUnmarkedObject(collector, obj); | 1038 VisitUnmarkedObject(collector, obj); |
| 1064 } | 1039 } |
| 1065 return true; | 1040 return true; |
| 1066 } | 1041 } |
| 1067 | 1042 |
| 1068 static inline void VisitExternalReference(Address* p) { } | 1043 static void VisitCode(Map* map, HeapObject* object) { |
| 1069 static inline void VisitExternalReference(RelocInfo* rinfo) { } | 1044 Heap* heap = map->GetHeap(); |
| 1070 static inline void VisitRuntimeEntry(RelocInfo* rinfo) { } | 1045 Code* code = reinterpret_cast<Code*>(object); |
| 1071 | 1046 if (FLAG_cleanup_code_caches_at_gc) { |
| 1072 private: | 1047 code->ClearTypeFeedbackCells(heap); |
| 1073 class DataObjectVisitor { | |
| 1074 public: | |
| 1075 template<int size> | |
| 1076 static void VisitSpecialized(Map* map, HeapObject* object) { | |
| 1077 } | 1048 } |
| 1078 | 1049 code->CodeIterateBody<MarkCompactMarkingVisitor>(heap); |
| 1079 static void Visit(Map* map, HeapObject* object) { | 1050 } |
| 1080 } | |
| 1081 }; | |
| 1082 | |
| 1083 typedef FlexibleBodyVisitor<StaticMarkingVisitor, | |
| 1084 JSObject::BodyDescriptor, | |
| 1085 void> JSObjectVisitor; | |
| 1086 | |
| 1087 typedef FlexibleBodyVisitor<StaticMarkingVisitor, | |
| 1088 StructBodyDescriptor, | |
| 1089 void> StructObjectVisitor; | |
| 1090 | 1051 |
| 1091 static void VisitJSWeakMap(Map* map, HeapObject* object) { | 1052 static void VisitJSWeakMap(Map* map, HeapObject* object) { |
| 1092 MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector(); | 1053 MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector(); |
| 1093 JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(object); | 1054 JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(object); |
| 1094 | 1055 |
| 1095 // Enqueue weak map in linked list of encountered weak maps. | 1056 // Enqueue weak map in linked list of encountered weak maps. |
| 1096 if (weak_map->next() == Smi::FromInt(0)) { | 1057 if (weak_map->next() == Smi::FromInt(0)) { |
| 1097 weak_map->set_next(collector->encountered_weak_maps()); | 1058 weak_map->set_next(collector->encountered_weak_maps()); |
| 1098 collector->set_encountered_weak_maps(weak_map); | 1059 collector->set_encountered_weak_maps(weak_map); |
| 1099 } | 1060 } |
| 1100 | 1061 |
| 1101 // Skip visiting the backing hash table containing the mappings. | 1062 // Skip visiting the backing hash table containing the mappings. |
| 1102 int object_size = JSWeakMap::BodyDescriptor::SizeOf(map, object); | 1063 int object_size = JSWeakMap::BodyDescriptor::SizeOf(map, object); |
| 1103 BodyVisitorBase<StaticMarkingVisitor>::IteratePointers( | 1064 BodyVisitorBase<MarkCompactMarkingVisitor>::IteratePointers( |
| 1104 map->GetHeap(), | 1065 map->GetHeap(), |
| 1105 object, | 1066 object, |
| 1106 JSWeakMap::BodyDescriptor::kStartOffset, | 1067 JSWeakMap::BodyDescriptor::kStartOffset, |
| 1107 JSWeakMap::kTableOffset); | 1068 JSWeakMap::kTableOffset); |
| 1108 BodyVisitorBase<StaticMarkingVisitor>::IteratePointers( | 1069 BodyVisitorBase<MarkCompactMarkingVisitor>::IteratePointers( |
| 1109 map->GetHeap(), | 1070 map->GetHeap(), |
| 1110 object, | 1071 object, |
| 1111 JSWeakMap::kTableOffset + kPointerSize, | 1072 JSWeakMap::kTableOffset + kPointerSize, |
| 1112 object_size); | 1073 object_size); |
| 1113 | 1074 |
| 1114 // Mark the backing hash table without pushing it on the marking stack. | 1075 // Mark the backing hash table without pushing it on the marking stack. |
| 1115 Object* table_object = weak_map->table(); | 1076 Object* table_object = weak_map->table(); |
| 1116 if (!table_object->IsHashTable()) return; | 1077 if (!table_object->IsHashTable()) return; |
| 1117 ObjectHashTable* table = ObjectHashTable::cast(table_object); | 1078 ObjectHashTable* table = ObjectHashTable::cast(table_object); |
| 1118 Object** table_slot = | 1079 Object** table_slot = |
| 1119 HeapObject::RawField(weak_map, JSWeakMap::kTableOffset); | 1080 HeapObject::RawField(weak_map, JSWeakMap::kTableOffset); |
| 1120 MarkBit table_mark = Marking::MarkBitFrom(table); | 1081 MarkBit table_mark = Marking::MarkBitFrom(table); |
| 1121 collector->RecordSlot(table_slot, table_slot, table); | 1082 collector->RecordSlot(table_slot, table_slot, table); |
| 1122 if (!table_mark.Get()) collector->SetMark(table, table_mark); | 1083 if (!table_mark.Get()) collector->SetMark(table, table_mark); |
| 1123 // Recording the map slot can be skipped, because maps are not compacted. | 1084 // Recording the map slot can be skipped, because maps are not compacted. |
| 1124 collector->MarkObject(table->map(), Marking::MarkBitFrom(table->map())); | 1085 collector->MarkObject(table->map(), Marking::MarkBitFrom(table->map())); |
| 1125 ASSERT(MarkCompactCollector::IsMarked(table->map())); | 1086 ASSERT(MarkCompactCollector::IsMarked(table->map())); |
| 1126 } | 1087 } |
| 1127 | 1088 |
| 1128 static void VisitCode(Map* map, HeapObject* object) { | 1089 private: |
| 1129 Heap* heap = map->GetHeap(); | 1090 template<int id> |
| 1130 Code* code = reinterpret_cast<Code*>(object); | 1091 static inline void TrackObjectStatsAndVisit(Map* map, HeapObject* obj); |
| 1131 if (FLAG_cleanup_code_caches_at_gc) { | |
| 1132 code->ClearTypeFeedbackCells(heap); | |
| 1133 } | |
| 1134 code->CodeIterateBody<StaticMarkingVisitor>(heap); | |
| 1135 } | |
| 1136 | 1092 |
| 1137 // Code flushing support. | 1093 // Code flushing support. |
| 1138 | 1094 |
| 1139 // How many collections newly compiled code object will survive before being | 1095 // How many collections newly compiled code object will survive before being |
| 1140 // flushed. | 1096 // flushed. |
| 1141 static const int kCodeAgeThreshold = 5; | 1097 static const int kCodeAgeThreshold = 5; |
| 1142 | 1098 |
| 1143 static const int kRegExpCodeThreshold = 5; | 1099 static const int kRegExpCodeThreshold = 5; |
| 1144 | 1100 |
| 1145 inline static bool HasSourceCode(Heap* heap, SharedFunctionInfo* info) { | 1101 inline static bool HasSourceCode(Heap* heap, SharedFunctionInfo* info) { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1240 | 1196 |
| 1241 static inline bool IsValidNotBuiltinContext(Object* ctx) { | 1197 static inline bool IsValidNotBuiltinContext(Object* ctx) { |
| 1242 return ctx->IsContext() && | 1198 return ctx->IsContext() && |
| 1243 !Context::cast(ctx)->global()->IsJSBuiltinsObject(); | 1199 !Context::cast(ctx)->global()->IsJSBuiltinsObject(); |
| 1244 } | 1200 } |
| 1245 | 1201 |
| 1246 | 1202 |
| 1247 static void VisitSharedFunctionInfoGeneric(Map* map, HeapObject* object) { | 1203 static void VisitSharedFunctionInfoGeneric(Map* map, HeapObject* object) { |
| 1248 SharedFunctionInfo::cast(object)->BeforeVisitingPointers(); | 1204 SharedFunctionInfo::cast(object)->BeforeVisitingPointers(); |
| 1249 | 1205 |
| 1250 FixedBodyVisitor<StaticMarkingVisitor, | 1206 FixedBodyVisitor<MarkCompactMarkingVisitor, |
| 1251 SharedFunctionInfo::BodyDescriptor, | 1207 SharedFunctionInfo::BodyDescriptor, |
| 1252 void>::Visit(map, object); | 1208 void>::Visit(map, object); |
| 1253 } | 1209 } |
| 1254 | 1210 |
| 1255 | 1211 |
| 1256 static void UpdateRegExpCodeAgeAndFlush(Heap* heap, | 1212 static void UpdateRegExpCodeAgeAndFlush(Heap* heap, |
| 1257 JSRegExp* re, | 1213 JSRegExp* re, |
| 1258 bool is_ascii) { | 1214 bool is_ascii) { |
| 1259 // Make sure that the fixed array is in fact initialized on the RegExp. | 1215 // Make sure that the fixed array is in fact initialized on the RegExp. |
| 1260 // We could potentially trigger a GC when initializing the RegExp. | 1216 // We could potentially trigger a GC when initializing the RegExp. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1308 | 1264 |
| 1309 // Works by setting the current sweep_generation (as a smi) in the | 1265 // Works by setting the current sweep_generation (as a smi) in the |
| 1310 // code object place in the data array of the RegExp and keeps a copy | 1266 // code object place in the data array of the RegExp and keeps a copy |
| 1311 // around that can be reinstated if we reuse the RegExp before flushing. | 1267 // around that can be reinstated if we reuse the RegExp before flushing. |
| 1312 // If we did not use the code for kRegExpCodeThreshold mark sweep GCs | 1268 // If we did not use the code for kRegExpCodeThreshold mark sweep GCs |
| 1313 // we flush the code. | 1269 // we flush the code. |
| 1314 static void VisitRegExpAndFlushCode(Map* map, HeapObject* object) { | 1270 static void VisitRegExpAndFlushCode(Map* map, HeapObject* object) { |
| 1315 Heap* heap = map->GetHeap(); | 1271 Heap* heap = map->GetHeap(); |
| 1316 MarkCompactCollector* collector = heap->mark_compact_collector(); | 1272 MarkCompactCollector* collector = heap->mark_compact_collector(); |
| 1317 if (!collector->is_code_flushing_enabled()) { | 1273 if (!collector->is_code_flushing_enabled()) { |
| 1318 VisitJSRegExpFields(map, object); | 1274 VisitJSRegExp(map, object); |
| 1319 return; | 1275 return; |
| 1320 } | 1276 } |
| 1321 JSRegExp* re = reinterpret_cast<JSRegExp*>(object); | 1277 JSRegExp* re = reinterpret_cast<JSRegExp*>(object); |
| 1322 // Flush code or set age on both ASCII and two byte code. | 1278 // Flush code or set age on both ASCII and two byte code. |
| 1323 UpdateRegExpCodeAgeAndFlush(heap, re, true); | 1279 UpdateRegExpCodeAgeAndFlush(heap, re, true); |
| 1324 UpdateRegExpCodeAgeAndFlush(heap, re, false); | 1280 UpdateRegExpCodeAgeAndFlush(heap, re, false); |
| 1325 // Visit the fields of the RegExp, including the updated FixedArray. | 1281 // Visit the fields of the RegExp, including the updated FixedArray. |
| 1326 VisitJSRegExpFields(map, object); | 1282 VisitJSRegExp(map, object); |
| 1327 } | 1283 } |
| 1328 | 1284 |
| 1329 | 1285 |
| 1330 static void VisitSharedFunctionInfoAndFlushCode(Map* map, | 1286 static void VisitSharedFunctionInfoAndFlushCode(Map* map, |
| 1331 HeapObject* object) { | 1287 HeapObject* object) { |
| 1332 Heap* heap = map->GetHeap(); | 1288 Heap* heap = map->GetHeap(); |
| 1333 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(object); | 1289 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(object); |
| 1334 if (shared->ic_age() != heap->global_ic_age()) { | 1290 if (shared->ic_age() != heap->global_ic_age()) { |
| 1335 shared->ResetForNewContext(heap->global_ic_age()); | 1291 shared->ResetForNewContext(heap->global_ic_age()); |
| 1336 } | 1292 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1355 known_flush_code_candidate = IsFlushable(heap, shared); | 1311 known_flush_code_candidate = IsFlushable(heap, shared); |
| 1356 if (known_flush_code_candidate) { | 1312 if (known_flush_code_candidate) { |
| 1357 heap->mark_compact_collector()->code_flusher()->AddCandidate(shared); | 1313 heap->mark_compact_collector()->code_flusher()->AddCandidate(shared); |
| 1358 } | 1314 } |
| 1359 } | 1315 } |
| 1360 | 1316 |
| 1361 VisitSharedFunctionInfoFields(heap, object, known_flush_code_candidate); | 1317 VisitSharedFunctionInfoFields(heap, object, known_flush_code_candidate); |
| 1362 } | 1318 } |
| 1363 | 1319 |
| 1364 | 1320 |
| 1365 static void VisitCodeEntry(Heap* heap, Address entry_address) { | |
| 1366 Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address)); | |
| 1367 MarkBit mark = Marking::MarkBitFrom(code); | |
| 1368 heap->mark_compact_collector()->MarkObject(code, mark); | |
| 1369 heap->mark_compact_collector()-> | |
| 1370 RecordCodeEntrySlot(entry_address, code); | |
| 1371 } | |
| 1372 | |
| 1373 static void VisitGlobalContext(Map* map, HeapObject* object) { | |
| 1374 FixedBodyVisitor<StaticMarkingVisitor, | |
| 1375 Context::MarkCompactBodyDescriptor, | |
| 1376 void>::Visit(map, object); | |
| 1377 | |
| 1378 MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector(); | |
| 1379 for (int idx = Context::FIRST_WEAK_SLOT; | |
| 1380 idx < Context::GLOBAL_CONTEXT_SLOTS; | |
| 1381 ++idx) { | |
| 1382 Object** slot = | |
| 1383 HeapObject::RawField(object, FixedArray::OffsetOfElementAt(idx)); | |
| 1384 collector->RecordSlot(slot, slot, *slot); | |
| 1385 } | |
| 1386 } | |
| 1387 | |
| 1388 static void VisitJSFunctionAndFlushCode(Map* map, HeapObject* object) { | 1321 static void VisitJSFunctionAndFlushCode(Map* map, HeapObject* object) { |
| 1389 Heap* heap = map->GetHeap(); | 1322 Heap* heap = map->GetHeap(); |
| 1390 MarkCompactCollector* collector = heap->mark_compact_collector(); | 1323 MarkCompactCollector* collector = heap->mark_compact_collector(); |
| 1391 if (!collector->is_code_flushing_enabled()) { | 1324 if (!collector->is_code_flushing_enabled()) { |
| 1392 VisitJSFunction(map, object); | 1325 VisitJSFunction(map, object); |
| 1393 return; | 1326 return; |
| 1394 } | 1327 } |
| 1395 | 1328 |
| 1396 JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object); | 1329 JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object); |
| 1397 // The function must have a valid context and not be a builtin. | 1330 // The function must have a valid context and not be a builtin. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1459 } | 1392 } |
| 1460 | 1393 |
| 1461 VisitPointers( | 1394 VisitPointers( |
| 1462 heap, | 1395 heap, |
| 1463 HeapObject::RawField(object, | 1396 HeapObject::RawField(object, |
| 1464 JSFunction::kCodeEntryOffset + kPointerSize), | 1397 JSFunction::kCodeEntryOffset + kPointerSize), |
| 1465 HeapObject::RawField(object, | 1398 HeapObject::RawField(object, |
| 1466 JSFunction::kNonWeakFieldsEndOffset)); | 1399 JSFunction::kNonWeakFieldsEndOffset)); |
| 1467 } | 1400 } |
| 1468 | 1401 |
| 1469 static inline void VisitJSRegExpFields(Map* map, | |
| 1470 HeapObject* object) { | |
| 1471 int last_property_offset = | |
| 1472 JSRegExp::kSize + kPointerSize * map->inobject_properties(); | |
| 1473 VisitPointers(map->GetHeap(), | |
| 1474 SLOT_ADDR(object, JSRegExp::kPropertiesOffset), | |
| 1475 SLOT_ADDR(object, last_property_offset)); | |
| 1476 } | |
| 1477 | |
| 1478 | 1402 |
| 1479 static void VisitSharedFunctionInfoFields(Heap* heap, | 1403 static void VisitSharedFunctionInfoFields(Heap* heap, |
| 1480 HeapObject* object, | 1404 HeapObject* object, |
| 1481 bool flush_code_candidate) { | 1405 bool flush_code_candidate) { |
| 1482 VisitPointer(heap, SLOT_ADDR(object, SharedFunctionInfo::kNameOffset)); | 1406 VisitPointer(heap, SLOT_ADDR(object, SharedFunctionInfo::kNameOffset)); |
| 1483 | 1407 |
| 1484 if (!flush_code_candidate) { | 1408 if (!flush_code_candidate) { |
| 1485 VisitPointer(heap, SLOT_ADDR(object, SharedFunctionInfo::kCodeOffset)); | 1409 VisitPointer(heap, SLOT_ADDR(object, SharedFunctionInfo::kCodeOffset)); |
| 1486 } | 1410 } |
| 1487 | 1411 |
| 1488 VisitPointers(heap, | 1412 VisitPointers(heap, |
| 1489 SLOT_ADDR(object, SharedFunctionInfo::kOptimizedCodeMapOffset), | 1413 SLOT_ADDR(object, SharedFunctionInfo::kOptimizedCodeMapOffset), |
| 1490 SLOT_ADDR(object, SharedFunctionInfo::kSize)); | 1414 SLOT_ADDR(object, SharedFunctionInfo::kSize)); |
| 1491 } | 1415 } |
| 1492 | 1416 |
| 1493 #undef SLOT_ADDR | 1417 #undef SLOT_ADDR |
| 1494 | 1418 |
| 1495 typedef void (*Callback)(Map* map, HeapObject* object); | |
| 1496 | |
| 1497 static VisitorDispatchTable<Callback> table_; | |
| 1498 static VisitorDispatchTable<Callback> non_count_table_; | 1419 static VisitorDispatchTable<Callback> non_count_table_; |
| 1499 }; | 1420 }; |
| 1500 | 1421 |
| 1501 | 1422 |
| 1502 template<int id> | 1423 template<int id> |
| 1503 void StaticMarkingVisitor::ObjectStatsTracker<id>::Visit( | 1424 void MarkCompactMarkingVisitor::TrackObjectStatsAndVisit(Map* map, |
| 1504 Map* map, HeapObject* obj) { | 1425 HeapObject* obj) { |
| 1505 Heap* heap = map->GetHeap(); | 1426 Heap* heap = map->GetHeap(); |
| 1506 int object_size = obj->Size(); | 1427 int object_size = obj->Size(); |
| 1507 heap->RecordObjectStats(map->instance_type(), -1, object_size); | 1428 heap->RecordObjectStats(map->instance_type(), -1, object_size); |
| 1508 non_count_table_.GetVisitorById(static_cast<VisitorId>(id))(map, obj); | 1429 non_count_table_.GetVisitorById(static_cast<VisitorId>(id))(map, obj); |
| 1509 } | 1430 } |
| 1510 | 1431 |
| 1511 | 1432 |
| 1512 template<> | 1433 template<> |
| 1513 class StaticMarkingVisitor::ObjectStatsTracker< | 1434 void MarkCompactMarkingVisitor::TrackObjectStatsAndVisit< |
| 1514 StaticMarkingVisitor::kVisitCode> { | 1435 MarkCompactMarkingVisitor::kVisitCode>(Map* map, HeapObject* obj) { |
| 1515 public: | 1436 Heap* heap = map->GetHeap(); |
| 1516 static inline void Visit(Map* map, HeapObject* obj) { | 1437 int object_size = obj->Size(); |
| 1517 Heap* heap = map->GetHeap(); | 1438 ASSERT(map->instance_type() == CODE_TYPE); |
| 1518 int object_size = obj->Size(); | 1439 heap->RecordObjectStats(CODE_TYPE, -1, object_size); |
| 1519 ASSERT(map->instance_type() == CODE_TYPE); | 1440 heap->RecordObjectStats(CODE_TYPE, Code::cast(obj)->kind(), object_size); |
| 1520 heap->RecordObjectStats(CODE_TYPE, -1, object_size); | 1441 non_count_table_.GetVisitorById(static_cast<VisitorId>(kVisitCode))(map, obj); |
| 1521 heap->RecordObjectStats(CODE_TYPE, Code::cast(obj)->kind(), object_size); | 1442 } |
| 1522 non_count_table_.GetVisitorById( | |
| 1523 static_cast<VisitorId>(kVisitCode))(map, obj); | |
| 1524 } | |
| 1525 }; | |
| 1526 | 1443 |
| 1527 | 1444 |
| 1528 void StaticMarkingVisitor::Initialize() { | 1445 void MarkCompactMarkingVisitor::Initialize() { |
| 1529 table_.Register(kVisitShortcutCandidate, | 1446 StaticMarkingVisitor<MarkCompactMarkingVisitor>::Initialize(); |
| 1530 &FixedBodyVisitor<StaticMarkingVisitor, | |
| 1531 ConsString::BodyDescriptor, | |
| 1532 void>::Visit); | |
| 1533 | |
| 1534 table_.Register(kVisitConsString, | |
| 1535 &FixedBodyVisitor<StaticMarkingVisitor, | |
| 1536 ConsString::BodyDescriptor, | |
| 1537 void>::Visit); | |
| 1538 | |
| 1539 table_.Register(kVisitSlicedString, | |
| 1540 &FixedBodyVisitor<StaticMarkingVisitor, | |
| 1541 SlicedString::BodyDescriptor, | |
| 1542 void>::Visit); | |
| 1543 | |
| 1544 table_.Register(kVisitFixedArray, | |
| 1545 &FlexibleBodyVisitor<StaticMarkingVisitor, | |
| 1546 FixedArray::BodyDescriptor, | |
| 1547 void>::Visit); | |
| 1548 | |
| 1549 table_.Register(kVisitGlobalContext, &VisitGlobalContext); | |
| 1550 | |
| 1551 table_.Register(kVisitFixedDoubleArray, DataObjectVisitor::Visit); | |
| 1552 | |
| 1553 table_.Register(kVisitByteArray, &DataObjectVisitor::Visit); | |
| 1554 table_.Register(kVisitFreeSpace, &DataObjectVisitor::Visit); | |
| 1555 table_.Register(kVisitSeqAsciiString, &DataObjectVisitor::Visit); | |
| 1556 table_.Register(kVisitSeqTwoByteString, &DataObjectVisitor::Visit); | |
| 1557 | |
| 1558 table_.Register(kVisitJSWeakMap, &VisitJSWeakMap); | |
| 1559 | |
| 1560 table_.Register(kVisitOddball, | |
| 1561 &FixedBodyVisitor<StaticMarkingVisitor, | |
| 1562 Oddball::BodyDescriptor, | |
| 1563 void>::Visit); | |
| 1564 table_.Register(kVisitMap, | |
| 1565 &FixedBodyVisitor<StaticMarkingVisitor, | |
| 1566 Map::BodyDescriptor, | |
| 1567 void>::Visit); | |
| 1568 | |
| 1569 table_.Register(kVisitCode, &VisitCode); | |
| 1570 | 1447 |
| 1571 table_.Register(kVisitSharedFunctionInfo, | 1448 table_.Register(kVisitSharedFunctionInfo, |
| 1572 &VisitSharedFunctionInfoAndFlushCode); | 1449 &VisitSharedFunctionInfoAndFlushCode); |
| 1573 | 1450 |
| 1574 table_.Register(kVisitJSFunction, | 1451 table_.Register(kVisitJSFunction, |
| 1575 &VisitJSFunctionAndFlushCode); | 1452 &VisitJSFunctionAndFlushCode); |
| 1576 | 1453 |
| 1577 table_.Register(kVisitJSRegExp, | 1454 table_.Register(kVisitJSRegExp, |
| 1578 &VisitRegExpAndFlushCode); | 1455 &VisitRegExpAndFlushCode); |
| 1579 | 1456 |
| 1580 table_.Register(kVisitPropertyCell, | |
| 1581 &FixedBodyVisitor<StaticMarkingVisitor, | |
| 1582 JSGlobalPropertyCell::BodyDescriptor, | |
| 1583 void>::Visit); | |
| 1584 | |
| 1585 table_.RegisterSpecializations<DataObjectVisitor, | |
| 1586 kVisitDataObject, | |
| 1587 kVisitDataObjectGeneric>(); | |
| 1588 | |
| 1589 table_.RegisterSpecializations<JSObjectVisitor, | |
| 1590 kVisitJSObject, | |
| 1591 kVisitJSObjectGeneric>(); | |
| 1592 | |
| 1593 table_.RegisterSpecializations<StructObjectVisitor, | |
| 1594 kVisitStruct, | |
| 1595 kVisitStructGeneric>(); | |
| 1596 | |
| 1597 if (FLAG_track_gc_object_stats) { | 1457 if (FLAG_track_gc_object_stats) { |
| 1598 // Copy the visitor table to make call-through possible. | 1458 // Copy the visitor table to make call-through possible. |
| 1599 non_count_table_.CopyFrom(&table_); | 1459 non_count_table_.CopyFrom(&table_); |
| 1600 #define VISITOR_ID_COUNT_FUNCTION(id) \ | 1460 #define VISITOR_ID_COUNT_FUNCTION(id) \ |
| 1601 table_.Register(kVisit##id, ObjectStatsTracker<kVisit##id>::Visit); | 1461 table_.Register(kVisit##id, TrackObjectStatsAndVisit<kVisit##id>); |
| 1602 VISITOR_ID_LIST(VISITOR_ID_COUNT_FUNCTION) | 1462 VISITOR_ID_LIST(VISITOR_ID_COUNT_FUNCTION) |
| 1603 #undef VISITOR_ID_COUNT_FUNCTION | 1463 #undef VISITOR_ID_COUNT_FUNCTION |
| 1604 } | 1464 } |
| 1605 } | 1465 } |
| 1606 | 1466 |
| 1607 | 1467 |
| 1608 VisitorDispatchTable<StaticMarkingVisitor::Callback> | 1468 VisitorDispatchTable<MarkCompactMarkingVisitor::Callback> |
| 1609 StaticMarkingVisitor::table_; | 1469 MarkCompactMarkingVisitor::non_count_table_; |
| 1610 VisitorDispatchTable<StaticMarkingVisitor::Callback> | |
| 1611 StaticMarkingVisitor::non_count_table_; | |
| 1612 | 1470 |
| 1613 | 1471 |
| 1614 class MarkingVisitor : public ObjectVisitor { | 1472 class MarkingVisitor : public ObjectVisitor { |
| 1615 public: | 1473 public: |
| 1616 explicit MarkingVisitor(Heap* heap) : heap_(heap) { } | 1474 explicit MarkingVisitor(Heap* heap) : heap_(heap) { } |
| 1617 | 1475 |
| 1618 void VisitPointer(Object** p) { | 1476 void VisitPointer(Object** p) { |
| 1619 StaticMarkingVisitor::VisitPointer(heap_, p); | 1477 MarkCompactMarkingVisitor::VisitPointer(heap_, p); |
| 1620 } | 1478 } |
| 1621 | 1479 |
| 1622 void VisitPointers(Object** start, Object** end) { | 1480 void VisitPointers(Object** start, Object** end) { |
| 1623 StaticMarkingVisitor::VisitPointers(heap_, start, end); | 1481 MarkCompactMarkingVisitor::VisitPointers(heap_, start, end); |
| 1624 } | 1482 } |
| 1625 | 1483 |
| 1626 private: | 1484 private: |
| 1627 Heap* heap_; | 1485 Heap* heap_; |
| 1628 }; | 1486 }; |
| 1629 | 1487 |
| 1630 | 1488 |
| 1631 class CodeMarkingVisitor : public ThreadVisitor { | 1489 class CodeMarkingVisitor : public ThreadVisitor { |
| 1632 public: | 1490 public: |
| 1633 explicit CodeMarkingVisitor(MarkCompactCollector* collector) | 1491 explicit CodeMarkingVisitor(MarkCompactCollector* collector) |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1772 MarkBit mark_bit = Marking::MarkBitFrom(object); | 1630 MarkBit mark_bit = Marking::MarkBitFrom(object); |
| 1773 if (mark_bit.Get()) return; | 1631 if (mark_bit.Get()) return; |
| 1774 | 1632 |
| 1775 Map* map = object->map(); | 1633 Map* map = object->map(); |
| 1776 // Mark the object. | 1634 // Mark the object. |
| 1777 collector_->SetMark(object, mark_bit); | 1635 collector_->SetMark(object, mark_bit); |
| 1778 | 1636 |
| 1779 // Mark the map pointer and body, and push them on the marking stack. | 1637 // Mark the map pointer and body, and push them on the marking stack. |
| 1780 MarkBit map_mark = Marking::MarkBitFrom(map); | 1638 MarkBit map_mark = Marking::MarkBitFrom(map); |
| 1781 collector_->MarkObject(map, map_mark); | 1639 collector_->MarkObject(map, map_mark); |
| 1782 StaticMarkingVisitor::IterateBody(map, object); | 1640 MarkCompactMarkingVisitor::IterateBody(map, object); |
| 1783 | 1641 |
| 1784 // Mark all the objects reachable from the map and body. May leave | 1642 // Mark all the objects reachable from the map and body. May leave |
| 1785 // overflowed objects in the heap. | 1643 // overflowed objects in the heap. |
| 1786 collector_->EmptyMarkingDeque(); | 1644 collector_->EmptyMarkingDeque(); |
| 1787 } | 1645 } |
| 1788 | 1646 |
| 1789 MarkCompactCollector* collector_; | 1647 MarkCompactCollector* collector_; |
| 1790 }; | 1648 }; |
| 1791 | 1649 |
| 1792 | 1650 |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2242 while (!marking_deque_.IsEmpty()) { | 2100 while (!marking_deque_.IsEmpty()) { |
| 2243 HeapObject* object = marking_deque_.Pop(); | 2101 HeapObject* object = marking_deque_.Pop(); |
| 2244 ASSERT(object->IsHeapObject()); | 2102 ASSERT(object->IsHeapObject()); |
| 2245 ASSERT(heap()->Contains(object)); | 2103 ASSERT(heap()->Contains(object)); |
| 2246 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object))); | 2104 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object))); |
| 2247 | 2105 |
| 2248 Map* map = object->map(); | 2106 Map* map = object->map(); |
| 2249 MarkBit map_mark = Marking::MarkBitFrom(map); | 2107 MarkBit map_mark = Marking::MarkBitFrom(map); |
| 2250 MarkObject(map, map_mark); | 2108 MarkObject(map, map_mark); |
| 2251 | 2109 |
| 2252 StaticMarkingVisitor::IterateBody(map, object); | 2110 MarkCompactMarkingVisitor::IterateBody(map, object); |
| 2253 } | 2111 } |
| 2254 | 2112 |
| 2255 // Process encountered weak maps, mark objects only reachable by those | 2113 // Process encountered weak maps, mark objects only reachable by those |
| 2256 // weak maps and repeat until fix-point is reached. | 2114 // weak maps and repeat until fix-point is reached. |
| 2257 ProcessWeakMaps(); | 2115 ProcessWeakMaps(); |
| 2258 } | 2116 } |
| 2259 } | 2117 } |
| 2260 | 2118 |
| 2261 | 2119 |
| 2262 // Sweep the heap for overflowed objects, clear their overflow bits, and | 2120 // Sweep the heap for overflowed objects, clear their overflow bits, and |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2381 if (was_marked_incrementally_) { | 2239 if (was_marked_incrementally_) { |
| 2382 // There is no write barrier on cells so we have to scan them now at the end | 2240 // There is no write barrier on cells so we have to scan them now at the end |
| 2383 // of the incremental marking. | 2241 // of the incremental marking. |
| 2384 { | 2242 { |
| 2385 HeapObjectIterator cell_iterator(heap()->cell_space()); | 2243 HeapObjectIterator cell_iterator(heap()->cell_space()); |
| 2386 HeapObject* cell; | 2244 HeapObject* cell; |
| 2387 while ((cell = cell_iterator.Next()) != NULL) { | 2245 while ((cell = cell_iterator.Next()) != NULL) { |
| 2388 ASSERT(cell->IsJSGlobalPropertyCell()); | 2246 ASSERT(cell->IsJSGlobalPropertyCell()); |
| 2389 if (IsMarked(cell)) { | 2247 if (IsMarked(cell)) { |
| 2390 int offset = JSGlobalPropertyCell::kValueOffset; | 2248 int offset = JSGlobalPropertyCell::kValueOffset; |
| 2391 StaticMarkingVisitor::VisitPointer( | 2249 MarkCompactMarkingVisitor::VisitPointer( |
| 2392 heap(), | 2250 heap(), |
| 2393 reinterpret_cast<Object**>(cell->address() + offset)); | 2251 reinterpret_cast<Object**>(cell->address() + offset)); |
| 2394 } | 2252 } |
| 2395 } | 2253 } |
| 2396 } | 2254 } |
| 2397 } | 2255 } |
| 2398 | 2256 |
| 2399 RootMarkingVisitor root_visitor(heap()); | 2257 RootMarkingVisitor root_visitor(heap()); |
| 2400 MarkRoots(&root_visitor); | 2258 MarkRoots(&root_visitor); |
| 2401 | 2259 |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2640 Object** anchor = reinterpret_cast<Object**>(table->address()); | 2498 Object** anchor = reinterpret_cast<Object**>(table->address()); |
| 2641 for (int i = 0; i < table->Capacity(); i++) { | 2499 for (int i = 0; i < table->Capacity(); i++) { |
| 2642 if (MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) { | 2500 if (MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) { |
| 2643 Object** key_slot = | 2501 Object** key_slot = |
| 2644 HeapObject::RawField(table, FixedArray::OffsetOfElementAt( | 2502 HeapObject::RawField(table, FixedArray::OffsetOfElementAt( |
| 2645 ObjectHashTable::EntryToIndex(i))); | 2503 ObjectHashTable::EntryToIndex(i))); |
| 2646 RecordSlot(anchor, key_slot, *key_slot); | 2504 RecordSlot(anchor, key_slot, *key_slot); |
| 2647 Object** value_slot = | 2505 Object** value_slot = |
| 2648 HeapObject::RawField(table, FixedArray::OffsetOfElementAt( | 2506 HeapObject::RawField(table, FixedArray::OffsetOfElementAt( |
| 2649 ObjectHashTable::EntryToValueIndex(i))); | 2507 ObjectHashTable::EntryToValueIndex(i))); |
| 2650 StaticMarkingVisitor::MarkObjectByPointer(this, anchor, value_slot); | 2508 MarkCompactMarkingVisitor::MarkObjectByPointer(this, anchor, value_slot)
; |
| 2651 } | 2509 } |
| 2652 } | 2510 } |
| 2653 weak_map_obj = weak_map->next(); | 2511 weak_map_obj = weak_map->next(); |
| 2654 } | 2512 } |
| 2655 } | 2513 } |
| 2656 | 2514 |
| 2657 | 2515 |
| 2658 void MarkCompactCollector::ClearWeakMaps() { | 2516 void MarkCompactCollector::ClearWeakMaps() { |
| 2659 Object* weak_map_obj = encountered_weak_maps(); | 2517 Object* weak_map_obj = encountered_weak_maps(); |
| 2660 while (weak_map_obj != Smi::FromInt(0)) { | 2518 while (weak_map_obj != Smi::FromInt(0)) { |
| (...skipping 1378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4039 GDBJITInterface::RemoveCode(reinterpret_cast<Code*>(obj)); | 3897 GDBJITInterface::RemoveCode(reinterpret_cast<Code*>(obj)); |
| 4040 } | 3898 } |
| 4041 #endif | 3899 #endif |
| 4042 if (obj->IsCode()) { | 3900 if (obj->IsCode()) { |
| 4043 PROFILE(isolate, CodeDeleteEvent(obj->address())); | 3901 PROFILE(isolate, CodeDeleteEvent(obj->address())); |
| 4044 } | 3902 } |
| 4045 } | 3903 } |
| 4046 | 3904 |
| 4047 | 3905 |
| 4048 void MarkCompactCollector::Initialize() { | 3906 void MarkCompactCollector::Initialize() { |
| 4049 StaticMarkingVisitor::Initialize(); | 3907 MarkCompactMarkingVisitor::Initialize(); |
| 3908 IncrementalMarking::Initialize(); |
| 4050 } | 3909 } |
| 4051 | 3910 |
| 4052 | 3911 |
| 4053 bool SlotsBuffer::IsTypedSlot(ObjectSlot slot) { | 3912 bool SlotsBuffer::IsTypedSlot(ObjectSlot slot) { |
| 4054 return reinterpret_cast<uintptr_t>(slot) < NUMBER_OF_SLOT_TYPES; | 3913 return reinterpret_cast<uintptr_t>(slot) < NUMBER_OF_SLOT_TYPES; |
| 4055 } | 3914 } |
| 4056 | 3915 |
| 4057 | 3916 |
| 4058 bool SlotsBuffer::AddTo(SlotsBufferAllocator* allocator, | 3917 bool SlotsBuffer::AddTo(SlotsBufferAllocator* allocator, |
| 4059 SlotsBuffer** buffer_address, | 3918 SlotsBuffer** buffer_address, |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4184 while (buffer != NULL) { | 4043 while (buffer != NULL) { |
| 4185 SlotsBuffer* next_buffer = buffer->next(); | 4044 SlotsBuffer* next_buffer = buffer->next(); |
| 4186 DeallocateBuffer(buffer); | 4045 DeallocateBuffer(buffer); |
| 4187 buffer = next_buffer; | 4046 buffer = next_buffer; |
| 4188 } | 4047 } |
| 4189 *buffer_address = NULL; | 4048 *buffer_address = NULL; |
| 4190 } | 4049 } |
| 4191 | 4050 |
| 4192 | 4051 |
| 4193 } } // namespace v8::internal | 4052 } } // namespace v8::internal |
| OLD | NEW |