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

Side by Side Diff: src/heap.cc

Issue 6777011: Specialize ScavengingVisitor for the case when all logging and profiling is disabled. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: use AtomicWord in VisitorDispatchTable instead of Callback Created 9 years, 8 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/heap.h ('k') | src/objects-visiting.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 923 matching lines...) Expand 10 before | Expand all | Expand 10 after
934 } 934 }
935 935
936 936
937 void Heap::Scavenge() { 937 void Heap::Scavenge() {
938 #ifdef DEBUG 938 #ifdef DEBUG
939 if (FLAG_enable_slow_asserts) VerifyNonPointerSpacePointers(); 939 if (FLAG_enable_slow_asserts) VerifyNonPointerSpacePointers();
940 #endif 940 #endif
941 941
942 gc_state_ = SCAVENGE; 942 gc_state_ = SCAVENGE;
943 943
944 SwitchScavengingVisitorsTableIfProfilingWasEnabled();
945
944 Page::FlipMeaningOfInvalidatedWatermarkFlag(this); 946 Page::FlipMeaningOfInvalidatedWatermarkFlag(this);
945 #ifdef DEBUG 947 #ifdef DEBUG
946 VerifyPageWatermarkValidity(old_pointer_space_, ALL_VALID); 948 VerifyPageWatermarkValidity(old_pointer_space_, ALL_VALID);
947 VerifyPageWatermarkValidity(map_space_, ALL_VALID); 949 VerifyPageWatermarkValidity(map_space_, ALL_VALID);
948 #endif 950 #endif
949 951
950 // We do not update an allocation watermark of the top page during linear 952 // We do not update an allocation watermark of the top page during linear
951 // allocation to avoid overhead. So to maintain the watermark invariant 953 // allocation to avoid overhead. So to maintain the watermark invariant
952 // we have to manually cache the watermark and mark the top page as having an 954 // we have to manually cache the watermark and mark the top page as having an
953 // invalid watermark. This guarantees that dirty regions iteration will use a 955 // invalid watermark. This guarantees that dirty regions iteration will use a
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
1225 } 1227 }
1226 1228
1227 // Take another spin if there are now unswept objects in new space 1229 // Take another spin if there are now unswept objects in new space
1228 // (there are currently no more unswept promoted objects). 1230 // (there are currently no more unswept promoted objects).
1229 } while (new_space_front < new_space_.top()); 1231 } while (new_space_front < new_space_.top());
1230 1232
1231 return new_space_front; 1233 return new_space_front;
1232 } 1234 }
1233 1235
1234 1236
1237 enum LoggingAndProfiling {
1238 LOGGING_AND_PROFILING_ENABLED,
1239 LOGGING_AND_PROFILING_DISABLED
1240 };
1241
1242
1243 typedef void (*ScavengingCallback)(Map* map,
1244 HeapObject** slot,
1245 HeapObject* object);
1246
1247
1248 static Atomic32 scavenging_visitors_table_mode_;
1249 static VisitorDispatchTable<ScavengingCallback> scavenging_visitors_table_;
1250
1251
1252 static inline void DoScavengeObject(Map* map,
Vitaly Repeshko 2011/03/30 15:11:04 This probably needs INLINE to prevent surprises wi
1253 HeapObject** slot,
1254 HeapObject* obj) {
1255 scavenging_visitors_table_.GetVisitor(map)(map, slot, obj);
1256 }
1257
1258
1259 template<LoggingAndProfiling logging_and_profiling_mode>
1235 class ScavengingVisitor : public StaticVisitorBase { 1260 class ScavengingVisitor : public StaticVisitorBase {
1236 public: 1261 public:
1237 static void Initialize() { 1262 static void Initialize() {
1238 table_.Register(kVisitSeqAsciiString, &EvacuateSeqAsciiString); 1263 table_.Register(kVisitSeqAsciiString, &EvacuateSeqAsciiString);
1239 table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString); 1264 table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString);
1240 table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate); 1265 table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate);
1241 table_.Register(kVisitByteArray, &EvacuateByteArray); 1266 table_.Register(kVisitByteArray, &EvacuateByteArray);
1242 table_.Register(kVisitFixedArray, &EvacuateFixedArray); 1267 table_.Register(kVisitFixedArray, &EvacuateFixedArray);
1268
1243 table_.Register(kVisitGlobalContext, 1269 table_.Register(kVisitGlobalContext,
1244 &ObjectEvacuationStrategy<POINTER_OBJECT>:: 1270 &ObjectEvacuationStrategy<POINTER_OBJECT>::
1245 VisitSpecialized<Context::kSize>); 1271 template VisitSpecialized<Context::kSize>);
1246
1247 typedef ObjectEvacuationStrategy<POINTER_OBJECT> PointerObject;
1248 1272
1249 table_.Register(kVisitConsString, 1273 table_.Register(kVisitConsString,
1250 &ObjectEvacuationStrategy<POINTER_OBJECT>:: 1274 &ObjectEvacuationStrategy<POINTER_OBJECT>::
1251 VisitSpecialized<ConsString::kSize>); 1275 template VisitSpecialized<ConsString::kSize>);
1252 1276
1253 table_.Register(kVisitSharedFunctionInfo, 1277 table_.Register(kVisitSharedFunctionInfo,
1254 &ObjectEvacuationStrategy<POINTER_OBJECT>:: 1278 &ObjectEvacuationStrategy<POINTER_OBJECT>::
1255 VisitSpecialized<SharedFunctionInfo::kSize>); 1279 template VisitSpecialized<SharedFunctionInfo::kSize>);
1256 1280
1257 table_.Register(kVisitJSFunction, 1281 table_.Register(kVisitJSFunction,
1258 &ObjectEvacuationStrategy<POINTER_OBJECT>:: 1282 &ObjectEvacuationStrategy<POINTER_OBJECT>::
1259 VisitSpecialized<JSFunction::kSize>); 1283 template VisitSpecialized<JSFunction::kSize>);
1260 1284
1261 table_.RegisterSpecializations<ObjectEvacuationStrategy<DATA_OBJECT>, 1285 table_.RegisterSpecializations<ObjectEvacuationStrategy<DATA_OBJECT>,
1262 kVisitDataObject, 1286 kVisitDataObject,
1263 kVisitDataObjectGeneric>(); 1287 kVisitDataObjectGeneric>();
1264 1288
1265 table_.RegisterSpecializations<ObjectEvacuationStrategy<POINTER_OBJECT>, 1289 table_.RegisterSpecializations<ObjectEvacuationStrategy<POINTER_OBJECT>,
1266 kVisitJSObject, 1290 kVisitJSObject,
1267 kVisitJSObjectGeneric>(); 1291 kVisitJSObjectGeneric>();
1268 1292
1269 table_.RegisterSpecializations<ObjectEvacuationStrategy<POINTER_OBJECT>, 1293 table_.RegisterSpecializations<ObjectEvacuationStrategy<POINTER_OBJECT>,
1270 kVisitStruct, 1294 kVisitStruct,
1271 kVisitStructGeneric>(); 1295 kVisitStructGeneric>();
1272 } 1296 }
1273 1297
1274 1298 static VisitorDispatchTable<ScavengingCallback>* GetTable() {
1275 static inline void Scavenge(Map* map, HeapObject** slot, HeapObject* obj) { 1299 return &table_;
1276 table_.GetVisitor(map)(map, slot, obj);
1277 } 1300 }
1278 1301
1279
1280 private: 1302 private:
1281 enum ObjectContents { DATA_OBJECT, POINTER_OBJECT }; 1303 enum ObjectContents { DATA_OBJECT, POINTER_OBJECT };
1282 enum SizeRestriction { SMALL, UNKNOWN_SIZE }; 1304 enum SizeRestriction { SMALL, UNKNOWN_SIZE };
1283 1305
1284 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) 1306 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
1285 static void RecordCopiedObject(Heap* heap, HeapObject* obj) { 1307 static void RecordCopiedObject(Heap* heap, HeapObject* obj) {
1286 bool should_record = false; 1308 bool should_record = false;
1287 #ifdef DEBUG 1309 #ifdef DEBUG
1288 should_record = FLAG_heap_stats; 1310 should_record = FLAG_heap_stats;
1289 #endif 1311 #endif
(...skipping 16 matching lines...) Expand all
1306 INLINE(static HeapObject* MigrateObject(Heap* heap, 1328 INLINE(static HeapObject* MigrateObject(Heap* heap,
1307 HeapObject* source, 1329 HeapObject* source,
1308 HeapObject* target, 1330 HeapObject* target,
1309 int size)) { 1331 int size)) {
1310 // Copy the content of source to target. 1332 // Copy the content of source to target.
1311 heap->CopyBlock(target->address(), source->address(), size); 1333 heap->CopyBlock(target->address(), source->address(), size);
1312 1334
1313 // Set the forwarding address. 1335 // Set the forwarding address.
1314 source->set_map_word(MapWord::FromForwardingAddress(target)); 1336 source->set_map_word(MapWord::FromForwardingAddress(target));
1315 1337
1338 if (logging_and_profiling_mode == LOGGING_AND_PROFILING_ENABLED) {
1316 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) 1339 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
1317 // Update NewSpace stats if necessary. 1340 // Update NewSpace stats if necessary.
1318 RecordCopiedObject(heap, target); 1341 RecordCopiedObject(heap, target);
1319 #endif 1342 #endif
1320 HEAP_PROFILE(heap, ObjectMoveEvent(source->address(), target->address())); 1343 HEAP_PROFILE(heap, ObjectMoveEvent(source->address(), target->address()));
1321 #if defined(ENABLE_LOGGING_AND_PROFILING) 1344 #if defined(ENABLE_LOGGING_AND_PROFILING)
1322 Isolate* isolate = heap->isolate(); 1345 Isolate* isolate = heap->isolate();
1323 if (isolate->logger()->is_logging() || 1346 if (isolate->logger()->is_logging() ||
1324 isolate->cpu_profiler()->is_profiling()) { 1347 isolate->cpu_profiler()->is_profiling()) {
1325 if (target->IsSharedFunctionInfo()) { 1348 if (target->IsSharedFunctionInfo()) {
1326 PROFILE(isolate, SharedFunctionInfoMoveEvent( 1349 PROFILE(isolate, SharedFunctionInfoMoveEvent(
1327 source->address(), target->address())); 1350 source->address(), target->address()));
1351 }
1328 } 1352 }
1353 #endif
1329 } 1354 }
1330 #endif 1355
1331 return target; 1356 return target;
1332 } 1357 }
1333 1358
1334 1359
1335 template<ObjectContents object_contents, SizeRestriction size_restriction> 1360 template<ObjectContents object_contents, SizeRestriction size_restriction>
1336 static inline void EvacuateObject(Map* map, 1361 static inline void EvacuateObject(Map* map,
1337 HeapObject** slot, 1362 HeapObject** slot,
1338 HeapObject* object, 1363 HeapObject* object,
1339 int object_size) { 1364 int object_size) {
1340 ASSERT((size_restriction != SMALL) || 1365 ASSERT((size_restriction != SMALL) ||
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1436 1461
1437 MapWord first_word = first->map_word(); 1462 MapWord first_word = first->map_word();
1438 if (first_word.IsForwardingAddress()) { 1463 if (first_word.IsForwardingAddress()) {
1439 HeapObject* target = first_word.ToForwardingAddress(); 1464 HeapObject* target = first_word.ToForwardingAddress();
1440 1465
1441 *slot = target; 1466 *slot = target;
1442 object->set_map_word(MapWord::FromForwardingAddress(target)); 1467 object->set_map_word(MapWord::FromForwardingAddress(target));
1443 return; 1468 return;
1444 } 1469 }
1445 1470
1446 Scavenge(first->map(), slot, first); 1471 DoScavengeObject(first->map(), slot, first);
1447 object->set_map_word(MapWord::FromForwardingAddress(*slot)); 1472 object->set_map_word(MapWord::FromForwardingAddress(*slot));
1448 return; 1473 return;
1449 } 1474 }
1450 1475
1451 int object_size = ConsString::kSize; 1476 int object_size = ConsString::kSize;
1452 EvacuateObject<POINTER_OBJECT, SMALL>(map, slot, object, object_size); 1477 EvacuateObject<POINTER_OBJECT, SMALL>(map, slot, object, object_size);
1453 } 1478 }
1454 1479
1455 template<ObjectContents object_contents> 1480 template<ObjectContents object_contents>
1456 class ObjectEvacuationStrategy { 1481 class ObjectEvacuationStrategy {
1457 public: 1482 public:
1458 template<int object_size> 1483 template<int object_size>
1459 static inline void VisitSpecialized(Map* map, 1484 static inline void VisitSpecialized(Map* map,
1460 HeapObject** slot, 1485 HeapObject** slot,
1461 HeapObject* object) { 1486 HeapObject* object) {
1462 EvacuateObject<object_contents, SMALL>(map, slot, object, object_size); 1487 EvacuateObject<object_contents, SMALL>(map, slot, object, object_size);
1463 } 1488 }
1464 1489
1465 static inline void Visit(Map* map, 1490 static inline void Visit(Map* map,
1466 HeapObject** slot, 1491 HeapObject** slot,
1467 HeapObject* object) { 1492 HeapObject* object) {
1468 int object_size = map->instance_size(); 1493 int object_size = map->instance_size();
1469 EvacuateObject<object_contents, SMALL>(map, slot, object, object_size); 1494 EvacuateObject<object_contents, SMALL>(map, slot, object, object_size);
1470 } 1495 }
1471 }; 1496 };
1472 1497
1473 typedef void (*Callback)(Map* map, HeapObject** slot, HeapObject* object); 1498 static VisitorDispatchTable<ScavengingCallback> table_;
1474
1475 static VisitorDispatchTable<Callback> table_;
1476 }; 1499 };
1477 1500
1478 1501
1479 VisitorDispatchTable<ScavengingVisitor::Callback> ScavengingVisitor::table_; 1502 template<LoggingAndProfiling logging_and_profiling_mode>
1503 VisitorDispatchTable<ScavengingCallback>
1504 ScavengingVisitor<logging_and_profiling_mode>::table_;
1505
1506
1507 static void InitializeScavengingVisitorsTables() {
1508 ScavengingVisitor<LOGGING_AND_PROFILING_DISABLED>::Initialize();
1509 ScavengingVisitor<LOGGING_AND_PROFILING_ENABLED>::Initialize();
1510 scavenging_visitors_table_.CopyFrom(
1511 ScavengingVisitor<LOGGING_AND_PROFILING_DISABLED>::GetTable());
1512 scavenging_visitors_table_mode_ = LOGGING_AND_PROFILING_DISABLED;
1513 }
1514
1515
1516 void Heap::SwitchScavengingVisitorsTableIfProfilingWasEnabled() {
1517 if (scavenging_visitors_table_mode_ == LOGGING_AND_PROFILING_ENABLED) {
1518 // Table was already updated by some isolate.
1519 return;
1520 }
1521
1522 if (isolate()->logger()->is_logging() ||
1523 isolate()->cpu_profiler()->is_profiling() ||
1524 (isolate()->heap_profiler() != NULL &&
1525 isolate()->heap_profiler()->is_profiling())) {
1526 // If one of the isolates is doing scavenge at this moment of time
1527 // it might see this table in an inconsitent state when
1528 // some of the callbacks point to
1529 // ScavengingVisitor<LOGGING_AND_PROFILING_ENABLED> and others
1530 // to ScavengingVisitor<LOGGING_AND_PROFILING_DISABLED>.
1531 // However this does not lead any bugs as such isolate does not have
Vitaly Repeshko 2011/03/30 15:11:04 "lead to"
1532 // profiling enabled and any isolate with enabled profiling is guaranteed
1533 // to see table it in the consistent state.
Vitaly Repeshko 2011/03/30 15:11:04 "table it" -> "the table"
1534 scavenging_visitors_table_.CopyFrom(
1535 ScavengingVisitor<LOGGING_AND_PROFILING_ENABLED>::GetTable());
1536
1537 // We use Release_Store to prevent reordering of this write before writes
1538 // to the table.
1539 Release_Store(&scavenging_visitors_table_mode_,
1540 LOGGING_AND_PROFILING_ENABLED);
1541 }
1542 }
1480 1543
1481 1544
1482 void Heap::ScavengeObjectSlow(HeapObject** p, HeapObject* object) { 1545 void Heap::ScavengeObjectSlow(HeapObject** p, HeapObject* object) {
1483 ASSERT(HEAP->InFromSpace(object)); 1546 ASSERT(HEAP->InFromSpace(object));
1484 MapWord first_word = object->map_word(); 1547 MapWord first_word = object->map_word();
1485 ASSERT(!first_word.IsForwardingAddress()); 1548 ASSERT(!first_word.IsForwardingAddress());
1486 Map* map = first_word.ToMap(); 1549 Map* map = first_word.ToMap();
1487 ScavengingVisitor::Scavenge(map, p, object); 1550 DoScavengeObject(map, p, object);
1488 } 1551 }
1489 1552
1490 1553
1491 MaybeObject* Heap::AllocatePartialMap(InstanceType instance_type, 1554 MaybeObject* Heap::AllocatePartialMap(InstanceType instance_type,
1492 int instance_size) { 1555 int instance_size) {
1493 Object* result; 1556 Object* result;
1494 { MaybeObject* maybe_result = AllocateRawMap(); 1557 { MaybeObject* maybe_result = AllocateRawMap();
1495 if (!maybe_result->ToObject(&result)) return maybe_result; 1558 if (!maybe_result->ToObject(&result)) return maybe_result;
1496 } 1559 }
1497 1560
(...skipping 3252 matching lines...) Expand 10 before | Expand all | Expand 10 after
4750 // Configuration is based on the flags new-space-size (really the semispace 4813 // Configuration is based on the flags new-space-size (really the semispace
4751 // size) and old-space-size if set or the initial values of semispace_size_ 4814 // size) and old-space-size if set or the initial values of semispace_size_
4752 // and old_generation_size_ otherwise. 4815 // and old_generation_size_ otherwise.
4753 if (!configured_) { 4816 if (!configured_) {
4754 if (!ConfigureHeapDefault()) return false; 4817 if (!ConfigureHeapDefault()) return false;
4755 } 4818 }
4756 4819
4757 gc_initializer_mutex->Lock(); 4820 gc_initializer_mutex->Lock();
4758 static bool initialized_gc = false; 4821 static bool initialized_gc = false;
4759 if (!initialized_gc) { 4822 if (!initialized_gc) {
4760 initialized_gc = true; 4823 initialized_gc = true;
Vitaly Repeshko 2011/03/30 15:11:04 nit: Is indentation off here?
4761 ScavengingVisitor::Initialize(); 4824 InitializeScavengingVisitorsTables();
4762 NewSpaceScavenger::Initialize(); 4825 NewSpaceScavenger::Initialize();
4763 MarkCompactCollector::Initialize(); 4826 MarkCompactCollector::Initialize();
4764 } 4827 }
4765 gc_initializer_mutex->Unlock(); 4828 gc_initializer_mutex->Unlock();
4766 4829
4767 MarkMapPointersAsEncoded(false); 4830 MarkMapPointersAsEncoded(false);
4768 4831
4769 // Setup memory allocator and reserve a chunk of memory for new 4832 // Setup memory allocator and reserve a chunk of memory for new
4770 // space. The chunk is double the size of the requested reserved 4833 // space. The chunk is double the size of the requested reserved
4771 // new space size to ensure that we can find a pair of semispaces that 4834 // new space size to ensure that we can find a pair of semispaces that
(...skipping 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after
5781 } 5844 }
5782 5845
5783 5846
5784 void ExternalStringTable::TearDown() { 5847 void ExternalStringTable::TearDown() {
5785 new_space_strings_.Free(); 5848 new_space_strings_.Free();
5786 old_space_strings_.Free(); 5849 old_space_strings_.Free();
5787 } 5850 }
5788 5851
5789 5852
5790 } } // namespace v8::internal 5853 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap.h ('k') | src/objects-visiting.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698