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 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 ", committed: %6" V8_PTR_PREFIX "d KB\n", | 364 ", committed: %6" V8_PTR_PREFIX "d KB\n", |
365 cell_space_->SizeOfObjects() / KB, | 365 cell_space_->SizeOfObjects() / KB, |
366 cell_space_->Available() / KB, | 366 cell_space_->Available() / KB, |
367 cell_space_->CommittedMemory() / KB); | 367 cell_space_->CommittedMemory() / KB); |
368 PrintPID("Large object space, used: %6" V8_PTR_PREFIX "d KB" | 368 PrintPID("Large object space, used: %6" V8_PTR_PREFIX "d KB" |
369 ", available: %6" V8_PTR_PREFIX "d KB" | 369 ", available: %6" V8_PTR_PREFIX "d KB" |
370 ", committed: %6" V8_PTR_PREFIX "d KB\n", | 370 ", committed: %6" V8_PTR_PREFIX "d KB\n", |
371 lo_space_->SizeOfObjects() / KB, | 371 lo_space_->SizeOfObjects() / KB, |
372 lo_space_->Available() / KB, | 372 lo_space_->Available() / KB, |
373 lo_space_->CommittedMemory() / KB); | 373 lo_space_->CommittedMemory() / KB); |
374 PrintPID("All spaces, used: %6" V8_PTR_PREFIX "d KB" | |
375 ", available: %6" V8_PTR_PREFIX "d KB" | |
376 ", committed: %6" V8_PTR_PREFIX "d KB\n", | |
377 this->SizeOfObjects() / KB, | |
378 this->Available() / KB, | |
379 this->CommittedMemory() / KB); | |
380 PrintPID("Total time spent in GC : %d ms\n", total_gc_time_ms_); | 374 PrintPID("Total time spent in GC : %d ms\n", total_gc_time_ms_); |
381 } | 375 } |
382 | 376 |
383 | 377 |
384 // TODO(1238405): Combine the infrastructure for --heap-stats and | 378 // TODO(1238405): Combine the infrastructure for --heap-stats and |
385 // --log-gc to avoid the complicated preprocessor and flag testing. | 379 // --log-gc to avoid the complicated preprocessor and flag testing. |
386 void Heap::ReportStatisticsAfterGC() { | 380 void Heap::ReportStatisticsAfterGC() { |
387 // Similar to the before GC, we use some complicated logic to ensure that | 381 // Similar to the before GC, we use some complicated logic to ensure that |
388 // NewSpace statistics are logged exactly once when --log-gc is turned on. | 382 // NewSpace statistics are logged exactly once when --log-gc is turned on. |
389 #if defined(DEBUG) | 383 #if defined(DEBUG) |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 tracer.set_collector(collector); | 612 tracer.set_collector(collector); |
619 | 613 |
620 HistogramTimer* rate = (collector == SCAVENGER) | 614 HistogramTimer* rate = (collector == SCAVENGER) |
621 ? isolate_->counters()->gc_scavenger() | 615 ? isolate_->counters()->gc_scavenger() |
622 : isolate_->counters()->gc_compactor(); | 616 : isolate_->counters()->gc_compactor(); |
623 rate->Start(); | 617 rate->Start(); |
624 next_gc_likely_to_collect_more = | 618 next_gc_likely_to_collect_more = |
625 PerformGarbageCollection(collector, &tracer); | 619 PerformGarbageCollection(collector, &tracer); |
626 rate->Stop(); | 620 rate->Stop(); |
627 | 621 |
628 ASSERT(collector == SCAVENGER || incremental_marking()->IsStopped()); | |
629 | |
630 // This can do debug callbacks and restart incremental marking. | |
631 GarbageCollectionEpilogue(); | 622 GarbageCollectionEpilogue(); |
632 } | 623 } |
633 | 624 |
| 625 ASSERT(collector == SCAVENGER || incremental_marking()->IsStopped()); |
634 if (incremental_marking()->IsStopped()) { | 626 if (incremental_marking()->IsStopped()) { |
635 if (incremental_marking()->WorthActivating() && NextGCIsLikelyToBeFull()) { | 627 if (incremental_marking()->WorthActivating() && NextGCIsLikelyToBeFull()) { |
636 incremental_marking()->Start(); | 628 incremental_marking()->Start(); |
637 } | 629 } |
638 } | 630 } |
639 | 631 |
640 return next_gc_likely_to_collect_more; | 632 return next_gc_likely_to_collect_more; |
641 } | 633 } |
642 | 634 |
643 | 635 |
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1352 | 1344 |
1353 | 1345 |
1354 void Heap::UpdateNewSpaceReferencesInExternalStringTable( | 1346 void Heap::UpdateNewSpaceReferencesInExternalStringTable( |
1355 ExternalStringTableUpdaterCallback updater_func) { | 1347 ExternalStringTableUpdaterCallback updater_func) { |
1356 if (FLAG_verify_heap) { | 1348 if (FLAG_verify_heap) { |
1357 external_string_table_.Verify(); | 1349 external_string_table_.Verify(); |
1358 } | 1350 } |
1359 | 1351 |
1360 if (external_string_table_.new_space_strings_.is_empty()) return; | 1352 if (external_string_table_.new_space_strings_.is_empty()) return; |
1361 | 1353 |
1362 Object** start_slot = &external_string_table_.new_space_strings_[0]; | 1354 Object** start = &external_string_table_.new_space_strings_[0]; |
1363 Object** end_slot = | 1355 Object** end = start + external_string_table_.new_space_strings_.length(); |
1364 start_slot + external_string_table_.new_space_strings_.length(); | 1356 Object** last = start; |
1365 Object** last = start_slot; | |
1366 | 1357 |
1367 for (Object** p = start_slot; p < end_slot; ++p) { | 1358 for (Object** p = start; p < end; ++p) { |
1368 ASSERT(InFromSpace(*p)); | 1359 ASSERT(InFromSpace(*p)); |
1369 String* target = updater_func(this, p); | 1360 String* target = updater_func(this, p); |
1370 | 1361 |
1371 if (target == NULL) continue; | 1362 if (target == NULL) continue; |
1372 | 1363 |
1373 ASSERT(target->IsExternalString()); | 1364 ASSERT(target->IsExternalString()); |
1374 | 1365 |
1375 if (InNewSpace(target)) { | 1366 if (InNewSpace(target)) { |
1376 // String is still in new space. Update the table entry. | 1367 // String is still in new space. Update the table entry. |
1377 *last = target; | 1368 *last = target; |
1378 ++last; | 1369 ++last; |
1379 } else { | 1370 } else { |
1380 // String got promoted. Move it to the old string list. | 1371 // String got promoted. Move it to the old string list. |
1381 external_string_table_.AddOldString(target); | 1372 external_string_table_.AddOldString(target); |
1382 } | 1373 } |
1383 } | 1374 } |
1384 | 1375 |
1385 ASSERT(last <= end_slot); | 1376 ASSERT(last <= end); |
1386 external_string_table_.ShrinkNewStrings(static_cast<int>(last - start_slot)); | 1377 external_string_table_.ShrinkNewStrings(static_cast<int>(last - start)); |
1387 } | 1378 } |
1388 | 1379 |
1389 | 1380 |
1390 void Heap::UpdateReferencesInExternalStringTable( | 1381 void Heap::UpdateReferencesInExternalStringTable( |
1391 ExternalStringTableUpdaterCallback updater_func) { | 1382 ExternalStringTableUpdaterCallback updater_func) { |
1392 | 1383 |
1393 // Update old space string references. | 1384 // Update old space string references. |
1394 if (external_string_table_.old_space_strings_.length() > 0) { | 1385 if (external_string_table_.old_space_strings_.length() > 0) { |
1395 Object** start_slot = &external_string_table_.old_space_strings_[0]; | 1386 Object** start = &external_string_table_.old_space_strings_[0]; |
1396 Object** end_slot = | 1387 Object** end = start + external_string_table_.old_space_strings_.length(); |
1397 start_slot + external_string_table_.old_space_strings_.length(); | 1388 for (Object** p = start; p < end; ++p) *p = updater_func(this, p); |
1398 for (Object** p = start_slot; p < end_slot; ++p) *p = updater_func(this, p); | |
1399 } | 1389 } |
1400 | 1390 |
1401 UpdateNewSpaceReferencesInExternalStringTable(updater_func); | 1391 UpdateNewSpaceReferencesInExternalStringTable(updater_func); |
1402 } | 1392 } |
1403 | 1393 |
1404 | 1394 |
1405 static Object* ProcessFunctionWeakReferences(Heap* heap, | 1395 static Object* ProcessFunctionWeakReferences(Heap* heap, |
1406 Object* function, | 1396 Object* function, |
1407 WeakObjectRetainer* retainer, | 1397 WeakObjectRetainer* retainer, |
1408 bool record_slots) { | 1398 bool record_slots) { |
(...skipping 2781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4190 | 4180 |
4191 // Initial size of the backing store to avoid resize of the storage during | 4181 // Initial size of the backing store to avoid resize of the storage during |
4192 // bootstrapping. The size differs between the JS global object ad the | 4182 // bootstrapping. The size differs between the JS global object ad the |
4193 // builtins object. | 4183 // builtins object. |
4194 int initial_size = map->instance_type() == JS_GLOBAL_OBJECT_TYPE ? 64 : 512; | 4184 int initial_size = map->instance_type() == JS_GLOBAL_OBJECT_TYPE ? 64 : 512; |
4195 | 4185 |
4196 // Allocate a dictionary object for backing storage. | 4186 // Allocate a dictionary object for backing storage. |
4197 StringDictionary* dictionary; | 4187 StringDictionary* dictionary; |
4198 MaybeObject* maybe_dictionary = | 4188 MaybeObject* maybe_dictionary = |
4199 StringDictionary::Allocate( | 4189 StringDictionary::Allocate( |
4200 map->NumberOfOwnDescriptors() * 2 + initial_size); | 4190 map->NumberOfDescribedProperties() * 2 + initial_size); |
4201 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; | 4191 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; |
4202 | 4192 |
4203 // The global object might be created from an object template with accessors. | 4193 // The global object might be created from an object template with accessors. |
4204 // Fill these accessors into the dictionary. | 4194 // Fill these accessors into the dictionary. |
4205 DescriptorArray* descs = map->instance_descriptors(); | 4195 DescriptorArray* descs = map->instance_descriptors(); |
4206 for (int i = 0; i < descs->number_of_descriptors(); i++) { | 4196 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
4207 PropertyDetails details = descs->GetDetails(i); | 4197 PropertyDetails details = descs->GetDetails(i); |
4208 ASSERT(details.type() == CALLBACKS); // Only accessors are expected. | 4198 ASSERT(details.type() == CALLBACKS); // Only accessors are expected. |
4209 PropertyDetails d = PropertyDetails(details.attributes(), | 4199 PropertyDetails d = PropertyDetails(details.attributes(), |
4210 CALLBACKS, | 4200 CALLBACKS, |
(...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5128 bool Heap::IdleNotification(int hint) { | 5118 bool Heap::IdleNotification(int hint) { |
5129 // Hints greater than this value indicate that | 5119 // Hints greater than this value indicate that |
5130 // the embedder is requesting a lot of GC work. | 5120 // the embedder is requesting a lot of GC work. |
5131 const int kMaxHint = 1000; | 5121 const int kMaxHint = 1000; |
5132 // Minimal hint that allows to do full GC. | 5122 // Minimal hint that allows to do full GC. |
5133 const int kMinHintForFullGC = 100; | 5123 const int kMinHintForFullGC = 100; |
5134 intptr_t size_factor = Min(Max(hint, 20), kMaxHint) / 4; | 5124 intptr_t size_factor = Min(Max(hint, 20), kMaxHint) / 4; |
5135 // The size factor is in range [5..250]. The numbers here are chosen from | 5125 // The size factor is in range [5..250]. The numbers here are chosen from |
5136 // experiments. If you changes them, make sure to test with | 5126 // experiments. If you changes them, make sure to test with |
5137 // chrome/performance_ui_tests --gtest_filter="GeneralMixMemoryTest.* | 5127 // chrome/performance_ui_tests --gtest_filter="GeneralMixMemoryTest.* |
5138 intptr_t step_size = | 5128 intptr_t step_size = size_factor * IncrementalMarking::kAllocatedThreshold; |
5139 size_factor * IncrementalMarking::kAllocatedThreshold; | |
5140 | 5129 |
5141 if (contexts_disposed_ > 0) { | 5130 if (contexts_disposed_ > 0) { |
5142 if (hint >= kMaxHint) { | 5131 if (hint >= kMaxHint) { |
5143 // The embedder is requesting a lot of GC work after context disposal, | 5132 // The embedder is requesting a lot of GC work after context disposal, |
5144 // we age inline caches so that they don't keep objects from | 5133 // we age inline caches so that they don't keep objects from |
5145 // the old context alive. | 5134 // the old context alive. |
5146 AgeInlineCaches(); | 5135 AgeInlineCaches(); |
5147 } | 5136 } |
5148 int mark_sweep_time = Min(TimeMarkSweepWouldTakeInMs(), 1000); | 5137 int mark_sweep_time = Min(TimeMarkSweepWouldTakeInMs(), 1000); |
5149 if (hint >= mark_sweep_time && !FLAG_expose_gc && | 5138 if (hint >= mark_sweep_time && !FLAG_expose_gc && |
(...skipping 1635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6785 // not visited yet | 6774 // not visited yet |
6786 Map* map_p = reinterpret_cast<Map*>(HeapObject::cast(map)); | 6775 Map* map_p = reinterpret_cast<Map*>(HeapObject::cast(map)); |
6787 | 6776 |
6788 Address map_addr = map_p->address(); | 6777 Address map_addr = map_p->address(); |
6789 | 6778 |
6790 obj->set_map_no_write_barrier(reinterpret_cast<Map*>(map_addr + kMarkTag)); | 6779 obj->set_map_no_write_barrier(reinterpret_cast<Map*>(map_addr + kMarkTag)); |
6791 | 6780 |
6792 // Scan the object body. | 6781 // Scan the object body. |
6793 if (is_native_context && (visit_mode_ == VISIT_ONLY_STRONG)) { | 6782 if (is_native_context && (visit_mode_ == VISIT_ONLY_STRONG)) { |
6794 // This is specialized to scan Context's properly. | 6783 // This is specialized to scan Context's properly. |
6795 Object** start_slot = reinterpret_cast<Object**>(obj->address() + | 6784 Object** start = reinterpret_cast<Object**>(obj->address() + |
6796 Context::kHeaderSize); | 6785 Context::kHeaderSize); |
6797 Object** end_slot = reinterpret_cast<Object**>(obj->address() + | 6786 Object** end = reinterpret_cast<Object**>(obj->address() + |
6798 Context::kHeaderSize + Context::FIRST_WEAK_SLOT * kPointerSize); | 6787 Context::kHeaderSize + Context::FIRST_WEAK_SLOT * kPointerSize); |
6799 mark_visitor->VisitPointers(start_slot, end_slot); | 6788 mark_visitor->VisitPointers(start, end); |
6800 } else { | 6789 } else { |
6801 obj->IterateBody(map_p->instance_type(), | 6790 obj->IterateBody(map_p->instance_type(), |
6802 obj->SizeFromMap(map_p), | 6791 obj->SizeFromMap(map_p), |
6803 mark_visitor); | 6792 mark_visitor); |
6804 } | 6793 } |
6805 | 6794 |
6806 // Scan the map after the body because the body is a lot more interesting | 6795 // Scan the map after the body because the body is a lot more interesting |
6807 // when doing leak detection. | 6796 // when doing leak detection. |
6808 MarkRecursively(&map, mark_visitor); | 6797 MarkRecursively(&map, mark_visitor); |
6809 | 6798 |
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7329 static_cast<int>(object_sizes_last_time_[index])); | 7318 static_cast<int>(object_sizes_last_time_[index])); |
7330 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) | 7319 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) |
7331 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 7320 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
7332 | 7321 |
7333 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 7322 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |
7334 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 7323 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |
7335 ClearObjectStats(); | 7324 ClearObjectStats(); |
7336 } | 7325 } |
7337 | 7326 |
7338 } } // namespace v8::internal | 7327 } } // namespace v8::internal |
OLD | NEW |