Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(171)

Side by Side Diff: src/mark-compact.cc

Issue 10816007: Refactor incremental marking to use static visitor. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments by Toon Verwaest. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mark-compact.h ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/mark-compact.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698