| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 // allow at least a few allocations after a collection. The reason | 466 // allow at least a few allocations after a collection. The reason |
| 467 // for this is that we have a lot of allocation sequences and we | 467 // for this is that we have a lot of allocation sequences and we |
| 468 // assume that a garbage collection will allow the subsequent | 468 // assume that a garbage collection will allow the subsequent |
| 469 // allocation attempts to go through. | 469 // allocation attempts to go through. |
| 470 allocation_timeout_ = Max(6, FLAG_gc_interval); | 470 allocation_timeout_ = Max(6, FLAG_gc_interval); |
| 471 #endif | 471 #endif |
| 472 | 472 |
| 473 if (collector == SCAVENGER && | 473 if (collector == SCAVENGER && |
| 474 IncrementalMarking::state() != IncrementalMarking::STOPPED) { | 474 IncrementalMarking::state() != IncrementalMarking::STOPPED) { |
| 475 if (FLAG_trace_incremental_marking) { | 475 if (FLAG_trace_incremental_marking) { |
| 476 PrintF("[IncrementalMarking] SCAVENGE -> MARK-SWEEP\n"); | 476 PrintF("[IncrementalMarking] Scavenge during marking.\n"); |
| 477 } | 477 } |
| 478 collector = MARK_COMPACTOR; | 478 } |
| 479 |
| 480 if (collector == MARK_COMPACTOR && |
| 481 !MarkCompactCollector::PreciseSweepingRequired() && |
| 482 IncrementalMarking::state() == IncrementalMarking::MARKING) { |
| 483 if (FLAG_trace_incremental_marking) { |
| 484 PrintF("[IncrementalMarking] Delaying MarkSweep.\n"); |
| 485 } |
| 486 collector = SCAVENGER; |
| 479 } | 487 } |
| 480 | 488 |
| 481 bool next_gc_likely_to_collect_more = false; | 489 bool next_gc_likely_to_collect_more = false; |
| 482 | 490 |
| 483 { GCTracer tracer; | 491 { GCTracer tracer; |
| 484 GarbageCollectionPrologue(); | 492 GarbageCollectionPrologue(); |
| 485 // The GC count was incremented in the prologue. Tell the tracer about | 493 // The GC count was incremented in the prologue. Tell the tracer about |
| 486 // it. | 494 // it. |
| 487 tracer.set_gc_count(gc_count_); | 495 tracer.set_gc_count(gc_count_); |
| 488 | 496 |
| 489 // Tell the tracer which collector we've selected. | 497 // Tell the tracer which collector we've selected. |
| 490 tracer.set_collector(collector); | 498 tracer.set_collector(collector); |
| 491 | 499 |
| 492 HistogramTimer* rate = (collector == SCAVENGER) | 500 HistogramTimer* rate = (collector == SCAVENGER) |
| 493 ? &Counters::gc_scavenger | 501 ? &Counters::gc_scavenger |
| 494 : &Counters::gc_compactor; | 502 : &Counters::gc_compactor; |
| 495 rate->Start(); | 503 rate->Start(); |
| 496 next_gc_likely_to_collect_more = | 504 next_gc_likely_to_collect_more = |
| 497 PerformGarbageCollection(collector, &tracer); | 505 PerformGarbageCollection(collector, &tracer); |
| 498 rate->Stop(); | 506 rate->Stop(); |
| 499 | 507 |
| 500 GarbageCollectionEpilogue(); | 508 GarbageCollectionEpilogue(); |
| 501 } | 509 } |
| 502 | 510 |
| 503 ASSERT(IncrementalMarking::state() == IncrementalMarking::STOPPED); | 511 |
| 504 if (IncrementalMarking::WorthActivating() && NextGCIsLikelyToBeFull()) { | 512 ASSERT(collector == SCAVENGER || IncrementalMarking::IsStopped()); |
| 505 IncrementalMarking::Start(); | 513 if (IncrementalMarking::IsStopped()) { |
| 514 if (IncrementalMarking::WorthActivating() && NextGCIsLikelyToBeFull()) { |
| 515 IncrementalMarking::Start(); |
| 516 } |
| 506 } | 517 } |
| 507 | 518 |
| 508 #ifdef ENABLE_LOGGING_AND_PROFILING | 519 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 509 if (FLAG_log_gc) HeapProfiler::WriteSample(); | 520 if (FLAG_log_gc) HeapProfiler::WriteSample(); |
| 510 #endif | 521 #endif |
| 511 | 522 |
| 512 return next_gc_likely_to_collect_more; | 523 return next_gc_likely_to_collect_more; |
| 513 } | 524 } |
| 514 | 525 |
| 515 | 526 |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 950 LOG(ResourceEvent("scavenge", "begin")); | 961 LOG(ResourceEvent("scavenge", "begin")); |
| 951 | 962 |
| 952 // Clear descriptor cache. | 963 // Clear descriptor cache. |
| 953 DescriptorLookupCache::Clear(); | 964 DescriptorLookupCache::Clear(); |
| 954 | 965 |
| 955 // Used for updating survived_since_last_expansion_ at function end. | 966 // Used for updating survived_since_last_expansion_ at function end. |
| 956 intptr_t survived_watermark = PromotedSpaceSize(); | 967 intptr_t survived_watermark = PromotedSpaceSize(); |
| 957 | 968 |
| 958 CheckNewSpaceExpansionCriteria(); | 969 CheckNewSpaceExpansionCriteria(); |
| 959 | 970 |
| 971 SelectScavengingVisitorsTable(); |
| 972 |
| 973 IncrementalMarking::PrepareForScavenge(); |
| 974 |
| 960 // Flip the semispaces. After flipping, to space is empty, from space has | 975 // Flip the semispaces. After flipping, to space is empty, from space has |
| 961 // live objects. | 976 // live objects. |
| 962 new_space_.Flip(); | 977 new_space_.Flip(); |
| 963 new_space_.ResetAllocationInfo(); | 978 new_space_.ResetAllocationInfo(); |
| 964 | 979 |
| 965 // We need to sweep newly copied objects which can be either in the | 980 // We need to sweep newly copied objects which can be either in the |
| 966 // to space or promoted to the old generation. For to-space | 981 // to space or promoted to the old generation. For to-space |
| 967 // objects, we treat the bottom of the to space as a queue. Newly | 982 // objects, we treat the bottom of the to space as a queue. Newly |
| 968 // copied and unswept objects lie between a 'front' mark and the | 983 // copied and unswept objects lie between a 'front' mark and the |
| 969 // allocation pointer. | 984 // allocation pointer. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1011 // Scavenge object reachable from the global contexts list directly. | 1026 // Scavenge object reachable from the global contexts list directly. |
| 1012 scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_)); | 1027 scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_)); |
| 1013 | 1028 |
| 1014 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); | 1029 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
| 1015 | 1030 |
| 1016 UpdateNewSpaceReferencesInExternalStringTable( | 1031 UpdateNewSpaceReferencesInExternalStringTable( |
| 1017 &UpdateNewSpaceReferenceInExternalStringTableEntry); | 1032 &UpdateNewSpaceReferenceInExternalStringTableEntry); |
| 1018 | 1033 |
| 1019 LiveObjectList::UpdateReferencesForScavengeGC(); | 1034 LiveObjectList::UpdateReferencesForScavengeGC(); |
| 1020 RuntimeProfiler::UpdateSamplesAfterScavenge(); | 1035 RuntimeProfiler::UpdateSamplesAfterScavenge(); |
| 1036 IncrementalMarking::UpdateMarkingStackAfterScavenge(); |
| 1021 | 1037 |
| 1022 ASSERT(new_space_front == new_space_.top()); | 1038 ASSERT(new_space_front == new_space_.top()); |
| 1023 | 1039 |
| 1024 // Set age mark. | 1040 // Set age mark. |
| 1025 new_space_.set_age_mark(new_space_.top()); | 1041 new_space_.set_age_mark(new_space_.top()); |
| 1026 | 1042 |
| 1027 // Update how much has survived scavenge. | 1043 // Update how much has survived scavenge. |
| 1028 IncrementYoungSurvivorsCounter(static_cast<int>( | 1044 IncrementYoungSurvivorsCounter(static_cast<int>( |
| 1029 (PromotedSpaceSize() - survived_watermark) + new_space_.Size())); | 1045 (PromotedSpaceSize() - survived_watermark) + new_space_.Size())); |
| 1030 | 1046 |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1206 } | 1222 } |
| 1207 | 1223 |
| 1208 // Take another spin if there are now unswept objects in new space | 1224 // Take another spin if there are now unswept objects in new space |
| 1209 // (there are currently no more unswept promoted objects). | 1225 // (there are currently no more unswept promoted objects). |
| 1210 } while (new_space_front < new_space_.top()); | 1226 } while (new_space_front < new_space_.top()); |
| 1211 | 1227 |
| 1212 return new_space_front; | 1228 return new_space_front; |
| 1213 } | 1229 } |
| 1214 | 1230 |
| 1215 | 1231 |
| 1232 enum MarksHandling { TRANSFER_MARKS, IGNORE_MARKS }; |
| 1233 |
| 1234 typedef void (*ScavengingCallback)(Map* map, |
| 1235 HeapObject** slot, |
| 1236 HeapObject* object); |
| 1237 |
| 1238 static VisitorDispatchTable<ScavengingCallback> scavening_visitors_table_; |
| 1239 |
| 1240 static inline void DoScavengeObject(Map* map, |
| 1241 HeapObject** slot, |
| 1242 HeapObject* obj) { |
| 1243 scavening_visitors_table_.GetVisitor(map)(map, slot, obj); |
| 1244 } |
| 1245 |
| 1246 |
| 1247 template<MarksHandling marks_handling> |
| 1216 class ScavengingVisitor : public StaticVisitorBase { | 1248 class ScavengingVisitor : public StaticVisitorBase { |
| 1217 public: | 1249 public: |
| 1218 static void Initialize() { | 1250 static void Initialize() { |
| 1219 table_.Register(kVisitSeqAsciiString, &EvacuateSeqAsciiString); | 1251 table_.Register(kVisitSeqAsciiString, &EvacuateSeqAsciiString); |
| 1220 table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString); | 1252 table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString); |
| 1221 table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate); | 1253 table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate); |
| 1222 table_.Register(kVisitByteArray, &EvacuateByteArray); | 1254 table_.Register(kVisitByteArray, &EvacuateByteArray); |
| 1223 table_.Register(kVisitFixedArray, &EvacuateFixedArray); | 1255 table_.Register(kVisitFixedArray, &EvacuateFixedArray); |
| 1256 |
| 1224 table_.Register(kVisitGlobalContext, | 1257 table_.Register(kVisitGlobalContext, |
| 1225 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1258 &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
| 1226 VisitSpecialized<Context::kSize>); | 1259 template VisitSpecialized<Context::kSize>); |
| 1227 | |
| 1228 typedef ObjectEvacuationStrategy<POINTER_OBJECT> PointerObject; | |
| 1229 | 1260 |
| 1230 table_.Register(kVisitConsString, | 1261 table_.Register(kVisitConsString, |
| 1231 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1262 &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
| 1232 VisitSpecialized<ConsString::kSize>); | 1263 template VisitSpecialized<ConsString::kSize>); |
| 1233 | 1264 |
| 1234 table_.Register(kVisitSharedFunctionInfo, | 1265 table_.Register(kVisitSharedFunctionInfo, |
| 1235 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1266 &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
| 1236 VisitSpecialized<SharedFunctionInfo::kSize>); | 1267 template VisitSpecialized<SharedFunctionInfo::kSize>); |
| 1237 | 1268 |
| 1238 table_.Register(kVisitJSFunction, | 1269 table_.Register(kVisitJSFunction, |
| 1239 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1270 &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
| 1240 VisitSpecialized<JSFunction::kSize>); | 1271 template VisitSpecialized<JSFunction::kSize>); |
| 1241 | 1272 |
| 1242 table_.RegisterSpecializations<ObjectEvacuationStrategy<DATA_OBJECT>, | 1273 table_.RegisterSpecializations<ObjectEvacuationStrategy<DATA_OBJECT>, |
| 1243 kVisitDataObject, | 1274 kVisitDataObject, |
| 1244 kVisitDataObjectGeneric>(); | 1275 kVisitDataObjectGeneric>(); |
| 1245 | 1276 |
| 1246 table_.RegisterSpecializations<ObjectEvacuationStrategy<POINTER_OBJECT>, | 1277 table_.RegisterSpecializations<ObjectEvacuationStrategy<POINTER_OBJECT>, |
| 1247 kVisitJSObject, | 1278 kVisitJSObject, |
| 1248 kVisitJSObjectGeneric>(); | 1279 kVisitJSObjectGeneric>(); |
| 1249 | 1280 |
| 1250 table_.RegisterSpecializations<ObjectEvacuationStrategy<POINTER_OBJECT>, | 1281 table_.RegisterSpecializations<ObjectEvacuationStrategy<POINTER_OBJECT>, |
| 1251 kVisitStruct, | 1282 kVisitStruct, |
| 1252 kVisitStructGeneric>(); | 1283 kVisitStructGeneric>(); |
| 1253 } | 1284 } |
| 1254 | 1285 |
| 1255 | 1286 static VisitorDispatchTable<ScavengingCallback>* GetTable() { |
| 1256 static inline void Scavenge(Map* map, HeapObject** slot, HeapObject* obj) { | 1287 return &table_; |
| 1257 table_.GetVisitor(map)(map, slot, obj); | |
| 1258 } | 1288 } |
| 1259 | 1289 |
| 1260 | |
| 1261 private: | 1290 private: |
| 1262 enum ObjectContents { DATA_OBJECT, POINTER_OBJECT }; | 1291 enum ObjectContents { DATA_OBJECT, POINTER_OBJECT }; |
| 1263 enum SizeRestriction { SMALL, UNKNOWN_SIZE }; | 1292 enum SizeRestriction { SMALL, UNKNOWN_SIZE }; |
| 1264 | 1293 |
| 1265 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) | 1294 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) |
| 1266 static void RecordCopiedObject(HeapObject* obj) { | 1295 static void RecordCopiedObject(HeapObject* obj) { |
| 1267 bool should_record = false; | 1296 bool should_record = false; |
| 1268 #ifdef DEBUG | 1297 #ifdef DEBUG |
| 1269 should_record = FLAG_heap_stats; | 1298 should_record = FLAG_heap_stats; |
| 1270 #endif | 1299 #endif |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1299 #endif | 1328 #endif |
| 1300 HEAP_PROFILE(ObjectMoveEvent(source->address(), target->address())); | 1329 HEAP_PROFILE(ObjectMoveEvent(source->address(), target->address())); |
| 1301 #if defined(ENABLE_LOGGING_AND_PROFILING) | 1330 #if defined(ENABLE_LOGGING_AND_PROFILING) |
| 1302 if (Logger::is_logging() || CpuProfiler::is_profiling()) { | 1331 if (Logger::is_logging() || CpuProfiler::is_profiling()) { |
| 1303 if (target->IsSharedFunctionInfo()) { | 1332 if (target->IsSharedFunctionInfo()) { |
| 1304 PROFILE(SharedFunctionInfoMoveEvent( | 1333 PROFILE(SharedFunctionInfoMoveEvent( |
| 1305 source->address(), target->address())); | 1334 source->address(), target->address())); |
| 1306 } | 1335 } |
| 1307 } | 1336 } |
| 1308 #endif | 1337 #endif |
| 1338 |
| 1339 if (marks_handling == TRANSFER_MARKS) TransferMark(source, target); |
| 1340 |
| 1309 return target; | 1341 return target; |
| 1310 } | 1342 } |
| 1311 | 1343 |
| 1312 | 1344 |
| 1345 INLINE(static void TransferMark(HeapObject* from, HeapObject* to)) { |
| 1346 MarkBit from_mark_bit = Marking::MarkBitFrom(from); |
| 1347 if (IncrementalMarking::IsBlack(from_mark_bit)) { |
| 1348 IncrementalMarking::MarkBlack(Marking::MarkBitFrom(to)); |
| 1349 } |
| 1350 } |
| 1351 |
| 1313 template<ObjectContents object_contents, SizeRestriction size_restriction> | 1352 template<ObjectContents object_contents, SizeRestriction size_restriction> |
| 1314 static inline void EvacuateObject(Map* map, | 1353 static inline void EvacuateObject(Map* map, |
| 1315 HeapObject** slot, | 1354 HeapObject** slot, |
| 1316 HeapObject* object, | 1355 HeapObject* object, |
| 1317 int object_size) { | 1356 int object_size) { |
| 1318 ASSERT((size_restriction != SMALL) || | 1357 ASSERT((size_restriction != SMALL) || |
| 1319 (object_size <= Page::kMaxHeapObjectSize)); | 1358 (object_size <= Page::kMaxHeapObjectSize)); |
| 1320 ASSERT(object->Size() == object_size); | 1359 ASSERT(object->Size() == object_size); |
| 1321 | 1360 |
| 1322 if (Heap::ShouldBePromoted(object->address(), object_size)) { | 1361 if (Heap::ShouldBePromoted(object->address(), object_size)) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1396 | 1435 |
| 1397 static inline bool IsShortcutCandidate(int type) { | 1436 static inline bool IsShortcutCandidate(int type) { |
| 1398 return ((type & kShortcutTypeMask) == kShortcutTypeTag); | 1437 return ((type & kShortcutTypeMask) == kShortcutTypeTag); |
| 1399 } | 1438 } |
| 1400 | 1439 |
| 1401 static inline void EvacuateShortcutCandidate(Map* map, | 1440 static inline void EvacuateShortcutCandidate(Map* map, |
| 1402 HeapObject** slot, | 1441 HeapObject** slot, |
| 1403 HeapObject* object) { | 1442 HeapObject* object) { |
| 1404 ASSERT(IsShortcutCandidate(map->instance_type())); | 1443 ASSERT(IsShortcutCandidate(map->instance_type())); |
| 1405 | 1444 |
| 1406 if (ConsString::cast(object)->unchecked_second() == Heap::empty_string()) { | 1445 if (marks_handling == IGNORE_MARKS && |
| 1446 ConsString::cast(object)->unchecked_second() == Heap::empty_string()) { |
| 1407 HeapObject* first = | 1447 HeapObject* first = |
| 1408 HeapObject::cast(ConsString::cast(object)->unchecked_first()); | 1448 HeapObject::cast(ConsString::cast(object)->unchecked_first()); |
| 1409 | 1449 |
| 1410 *slot = first; | 1450 *slot = first; |
| 1411 | 1451 |
| 1412 if (!Heap::InNewSpace(first)) { | 1452 if (!Heap::InNewSpace(first)) { |
| 1413 object->set_map_word(MapWord::FromForwardingAddress(first)); | 1453 object->set_map_word(MapWord::FromForwardingAddress(first)); |
| 1414 return; | 1454 return; |
| 1415 } | 1455 } |
| 1416 | 1456 |
| 1417 MapWord first_word = first->map_word(); | 1457 MapWord first_word = first->map_word(); |
| 1418 if (first_word.IsForwardingAddress()) { | 1458 if (first_word.IsForwardingAddress()) { |
| 1419 HeapObject* target = first_word.ToForwardingAddress(); | 1459 HeapObject* target = first_word.ToForwardingAddress(); |
| 1420 | 1460 |
| 1421 *slot = target; | 1461 *slot = target; |
| 1422 object->set_map_word(MapWord::FromForwardingAddress(target)); | 1462 object->set_map_word(MapWord::FromForwardingAddress(target)); |
| 1423 return; | 1463 return; |
| 1424 } | 1464 } |
| 1425 | 1465 |
| 1426 Scavenge(first->map(), slot, first); | 1466 DoScavengeObject(first->map(), slot, first); |
| 1427 object->set_map_word(MapWord::FromForwardingAddress(*slot)); | 1467 object->set_map_word(MapWord::FromForwardingAddress(*slot)); |
| 1428 return; | 1468 return; |
| 1429 } | 1469 } |
| 1430 | 1470 |
| 1431 int object_size = ConsString::kSize; | 1471 int object_size = ConsString::kSize; |
| 1432 EvacuateObject<POINTER_OBJECT, SMALL>(map, slot, object, object_size); | 1472 EvacuateObject<POINTER_OBJECT, SMALL>(map, slot, object, object_size); |
| 1433 } | 1473 } |
| 1434 | 1474 |
| 1435 template<ObjectContents object_contents> | 1475 template<ObjectContents object_contents> |
| 1436 class ObjectEvacuationStrategy { | 1476 class ObjectEvacuationStrategy { |
| 1437 public: | 1477 public: |
| 1438 template<int object_size> | 1478 template<int object_size> |
| 1439 static inline void VisitSpecialized(Map* map, | 1479 static inline void VisitSpecialized(Map* map, |
| 1440 HeapObject** slot, | 1480 HeapObject** slot, |
| 1441 HeapObject* object) { | 1481 HeapObject* object) { |
| 1442 EvacuateObject<object_contents, SMALL>(map, slot, object, object_size); | 1482 EvacuateObject<object_contents, SMALL>(map, slot, object, object_size); |
| 1443 } | 1483 } |
| 1444 | 1484 |
| 1445 static inline void Visit(Map* map, | 1485 static inline void Visit(Map* map, |
| 1446 HeapObject** slot, | 1486 HeapObject** slot, |
| 1447 HeapObject* object) { | 1487 HeapObject* object) { |
| 1448 int object_size = map->instance_size(); | 1488 int object_size = map->instance_size(); |
| 1449 EvacuateObject<object_contents, SMALL>(map, slot, object, object_size); | 1489 EvacuateObject<object_contents, SMALL>(map, slot, object, object_size); |
| 1450 } | 1490 } |
| 1451 }; | 1491 }; |
| 1452 | 1492 |
| 1453 typedef void (*Callback)(Map* map, HeapObject** slot, HeapObject* object); | 1493 static VisitorDispatchTable<ScavengingCallback> table_; |
| 1454 | |
| 1455 static VisitorDispatchTable<Callback> table_; | |
| 1456 }; | 1494 }; |
| 1457 | 1495 |
| 1458 | 1496 |
| 1459 VisitorDispatchTable<ScavengingVisitor::Callback> ScavengingVisitor::table_; | 1497 template<MarksHandling marks_handling> |
| 1498 VisitorDispatchTable<ScavengingCallback> |
| 1499 ScavengingVisitor<marks_handling>::table_; |
| 1500 |
| 1501 |
| 1502 void Heap::SelectScavengingVisitorsTable() { |
| 1503 if (IncrementalMarking::IsStopped()) { |
| 1504 scavening_visitors_table_.CopyFrom( |
| 1505 ScavengingVisitor<IGNORE_MARKS>::GetTable()); |
| 1506 } else { |
| 1507 scavening_visitors_table_.CopyFrom( |
| 1508 ScavengingVisitor<TRANSFER_MARKS>::GetTable()); |
| 1509 } |
| 1510 } |
| 1460 | 1511 |
| 1461 | 1512 |
| 1462 void Heap::ScavengeObjectSlow(HeapObject** p, HeapObject* object) { | 1513 void Heap::ScavengeObjectSlow(HeapObject** p, HeapObject* object) { |
| 1463 ASSERT(InFromSpace(object)); | 1514 ASSERT(InFromSpace(object)); |
| 1464 MapWord first_word = object->map_word(); | 1515 MapWord first_word = object->map_word(); |
| 1465 ASSERT(!first_word.IsForwardingAddress()); | 1516 ASSERT(!first_word.IsForwardingAddress()); |
| 1466 Map* map = first_word.ToMap(); | 1517 Map* map = first_word.ToMap(); |
| 1467 ScavengingVisitor::Scavenge(map, p, object); | 1518 DoScavengeObject(map, p, object); |
| 1468 } | 1519 } |
| 1469 | 1520 |
| 1470 | 1521 |
| 1471 void Heap::ScavengePointer(HeapObject** p) { | 1522 void Heap::ScavengePointer(HeapObject** p) { |
| 1472 ScavengeObject(p, *p); | 1523 ScavengeObject(p, *p); |
| 1473 } | 1524 } |
| 1474 | 1525 |
| 1475 | 1526 |
| 1476 MaybeObject* Heap::AllocatePartialMap(InstanceType instance_type, | 1527 MaybeObject* Heap::AllocatePartialMap(InstanceType instance_type, |
| 1477 int instance_size) { | 1528 int instance_size) { |
| (...skipping 2226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3704 { MaybeObject* maybe_result = Heap::Allocate(map, space); | 3755 { MaybeObject* maybe_result = Heap::Allocate(map, space); |
| 3705 if (!maybe_result->ToObject(&result)) return maybe_result; | 3756 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3706 } | 3757 } |
| 3707 Struct::cast(result)->InitializeBody(size); | 3758 Struct::cast(result)->InitializeBody(size); |
| 3708 return result; | 3759 return result; |
| 3709 } | 3760 } |
| 3710 | 3761 |
| 3711 | 3762 |
| 3712 void Heap::EnsureHeapIsIterable() { | 3763 void Heap::EnsureHeapIsIterable() { |
| 3713 ASSERT(IsAllocationAllowed()); | 3764 ASSERT(IsAllocationAllowed()); |
| 3714 if (IncrementalMarking::state() != IncrementalMarking::STOPPED || | 3765 if (old_pointer_space()->was_swept_conservatively() || |
| 3715 old_pointer_space()->was_swept_conservatively() || | |
| 3716 old_data_space()->was_swept_conservatively()) { | 3766 old_data_space()->was_swept_conservatively()) { |
| 3717 CollectAllGarbage(kMakeHeapIterableMask); | 3767 CollectAllGarbage(kMakeHeapIterableMask); |
| 3718 } | 3768 } |
| 3719 ASSERT(!old_pointer_space()->was_swept_conservatively()); | 3769 ASSERT(!old_pointer_space()->was_swept_conservatively()); |
| 3720 ASSERT(!old_data_space()->was_swept_conservatively()); | 3770 ASSERT(!old_data_space()->was_swept_conservatively()); |
| 3721 } | 3771 } |
| 3722 | 3772 |
| 3723 | 3773 |
| 3724 bool Heap::IdleNotification() { | 3774 bool Heap::IdleNotification() { |
| 3725 static const int kIdlesBeforeScavenge = 4; | 3775 static const int kIdlesBeforeScavenge = 4; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3789 } else if (number_idle_notifications > kIdlesBeforeMarkCompact) { | 3839 } else if (number_idle_notifications > kIdlesBeforeMarkCompact) { |
| 3790 // If we have received more than kIdlesBeforeMarkCompact idle | 3840 // If we have received more than kIdlesBeforeMarkCompact idle |
| 3791 // notifications we do not perform any cleanup because we don't | 3841 // notifications we do not perform any cleanup because we don't |
| 3792 // expect to gain much by doing so. | 3842 // expect to gain much by doing so. |
| 3793 finished = true; | 3843 finished = true; |
| 3794 } | 3844 } |
| 3795 | 3845 |
| 3796 // Make sure that we have no pending context disposals and | 3846 // Make sure that we have no pending context disposals and |
| 3797 // conditionally uncommit from space. | 3847 // conditionally uncommit from space. |
| 3798 ASSERT(contexts_disposed_ == 0); | 3848 ASSERT(contexts_disposed_ == 0); |
| 3799 if (uncommit && IncrementalMarking::IsStopped()) Heap::UncommitFromSpace(); | 3849 if (uncommit) Heap::UncommitFromSpace(); |
| 3800 return finished; | 3850 return finished; |
| 3801 } | 3851 } |
| 3802 | 3852 |
| 3803 | 3853 |
| 3804 #ifdef DEBUG | 3854 #ifdef DEBUG |
| 3805 | 3855 |
| 3806 void Heap::Print() { | 3856 void Heap::Print() { |
| 3807 if (!HasBeenSetup()) return; | 3857 if (!HasBeenSetup()) return; |
| 3808 Top::PrintStack(); | 3858 Top::PrintStack(); |
| 3809 AllSpaces spaces; | 3859 AllSpaces spaces; |
| (...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4596 // call Heap::TearDown() to release allocated memory. | 4646 // call Heap::TearDown() to release allocated memory. |
| 4597 // | 4647 // |
| 4598 // If the heap is not yet configured (eg, through the API), configure it. | 4648 // If the heap is not yet configured (eg, through the API), configure it. |
| 4599 // Configuration is based on the flags new-space-size (really the semispace | 4649 // Configuration is based on the flags new-space-size (really the semispace |
| 4600 // size) and old-space-size if set or the initial values of semispace_size_ | 4650 // size) and old-space-size if set or the initial values of semispace_size_ |
| 4601 // and old_generation_size_ otherwise. | 4651 // and old_generation_size_ otherwise. |
| 4602 if (!heap_configured) { | 4652 if (!heap_configured) { |
| 4603 if (!ConfigureHeapDefault()) return false; | 4653 if (!ConfigureHeapDefault()) return false; |
| 4604 } | 4654 } |
| 4605 | 4655 |
| 4606 ScavengingVisitor::Initialize(); | 4656 ScavengingVisitor<TRANSFER_MARKS>::Initialize(); |
| 4657 ScavengingVisitor<IGNORE_MARKS>::Initialize(); |
| 4607 NewSpaceScavenger::Initialize(); | 4658 NewSpaceScavenger::Initialize(); |
| 4608 MarkCompactCollector::Initialize(); | 4659 MarkCompactCollector::Initialize(); |
| 4609 | 4660 |
| 4610 MarkMapPointersAsEncoded(false); | 4661 MarkMapPointersAsEncoded(false); |
| 4611 | 4662 |
| 4612 // Setup memory allocator. | 4663 // Setup memory allocator. |
| 4613 if (!MemoryAllocator::Setup(MaxReserved(), MaxExecutableSize())) return false; | 4664 if (!MemoryAllocator::Setup(MaxReserved(), MaxExecutableSize())) return false; |
| 4614 | 4665 |
| 4615 // Setup new space. | 4666 // Setup new space. |
| 4616 if (!new_space_.Setup(reserved_semispace_size_)) { | 4667 if (!new_space_.Setup(reserved_semispace_size_)) { |
| (...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5537 void ExternalStringTable::TearDown() { | 5588 void ExternalStringTable::TearDown() { |
| 5538 new_space_strings_.Free(); | 5589 new_space_strings_.Free(); |
| 5539 old_space_strings_.Free(); | 5590 old_space_strings_.Free(); |
| 5540 } | 5591 } |
| 5541 | 5592 |
| 5542 | 5593 |
| 5543 List<Object*> ExternalStringTable::new_space_strings_; | 5594 List<Object*> ExternalStringTable::new_space_strings_; |
| 5544 List<Object*> ExternalStringTable::old_space_strings_; | 5595 List<Object*> ExternalStringTable::old_space_strings_; |
| 5545 | 5596 |
| 5546 } } // namespace v8::internal | 5597 } } // namespace v8::internal |
| OLD | NEW |