| OLD | NEW |
| 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 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 next_gc_likely_to_collect_more = | 504 next_gc_likely_to_collect_more = |
| 505 PerformGarbageCollection(collector, &tracer); | 505 PerformGarbageCollection(collector, &tracer); |
| 506 rate->Stop(); | 506 rate->Stop(); |
| 507 | 507 |
| 508 GarbageCollectionEpilogue(); | 508 GarbageCollectionEpilogue(); |
| 509 } | 509 } |
| 510 | 510 |
| 511 | 511 |
| 512 #ifdef ENABLE_LOGGING_AND_PROFILING | 512 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 513 if (FLAG_log_gc) HeapProfiler::WriteSample(); | 513 if (FLAG_log_gc) HeapProfiler::WriteSample(); |
| 514 if (CpuProfiler::is_profiling()) CpuProfiler::ProcessMovedFunctions(); | |
| 515 #endif | 514 #endif |
| 516 | 515 |
| 517 return next_gc_likely_to_collect_more; | 516 return next_gc_likely_to_collect_more; |
| 518 } | 517 } |
| 519 | 518 |
| 520 | 519 |
| 521 void Heap::PerformScavenge() { | 520 void Heap::PerformScavenge() { |
| 522 GCTracer tracer(this); | 521 GCTracer tracer(this); |
| 523 PerformGarbageCollection(SCAVENGER, &tracer); | 522 PerformGarbageCollection(SCAVENGER, &tracer); |
| 524 } | 523 } |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 836 } | 835 } |
| 837 | 836 |
| 838 | 837 |
| 839 void Heap::MarkCompactPrologue(bool is_compacting) { | 838 void Heap::MarkCompactPrologue(bool is_compacting) { |
| 840 // At any old GC clear the keyed lookup cache to enable collection of unused | 839 // At any old GC clear the keyed lookup cache to enable collection of unused |
| 841 // maps. | 840 // maps. |
| 842 isolate_->keyed_lookup_cache()->Clear(); | 841 isolate_->keyed_lookup_cache()->Clear(); |
| 843 isolate_->context_slot_cache()->Clear(); | 842 isolate_->context_slot_cache()->Clear(); |
| 844 isolate_->descriptor_lookup_cache()->Clear(); | 843 isolate_->descriptor_lookup_cache()->Clear(); |
| 845 | 844 |
| 846 isolate_->runtime_profiler()->MarkCompactPrologue(is_compacting); | |
| 847 | |
| 848 isolate_->compilation_cache()->MarkCompactPrologue(); | 845 isolate_->compilation_cache()->MarkCompactPrologue(); |
| 849 | 846 |
| 850 CompletelyClearInstanceofCache(); | 847 CompletelyClearInstanceofCache(); |
| 851 | 848 |
| 852 if (is_compacting) FlushNumberStringCache(); | 849 if (is_compacting) FlushNumberStringCache(); |
| 853 | 850 |
| 854 ClearNormalizedMapCaches(); | 851 ClearNormalizedMapCaches(); |
| 855 } | 852 } |
| 856 | 853 |
| 857 | 854 |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1017 Address value_address = | 1014 Address value_address = |
| 1018 reinterpret_cast<Address>(cell) + | 1015 reinterpret_cast<Address>(cell) + |
| 1019 (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag); | 1016 (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag); |
| 1020 scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address)); | 1017 scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address)); |
| 1021 } | 1018 } |
| 1022 } | 1019 } |
| 1023 | 1020 |
| 1024 // Scavenge object reachable from the global contexts list directly. | 1021 // Scavenge object reachable from the global contexts list directly. |
| 1025 scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_)); | 1022 scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_)); |
| 1026 | 1023 |
| 1027 // Scavenge objects reachable from the runtime-profiler sampler | |
| 1028 // window directly. | |
| 1029 RuntimeProfiler* runtime_profiler = isolate_->runtime_profiler(); | |
| 1030 Object** sampler_window_address = runtime_profiler->SamplerWindowAddress(); | |
| 1031 int sampler_window_size = runtime_profiler->SamplerWindowSize(); | |
| 1032 scavenge_visitor.VisitPointers( | |
| 1033 sampler_window_address, | |
| 1034 sampler_window_address + sampler_window_size); | |
| 1035 | |
| 1036 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); | 1024 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
| 1037 | 1025 |
| 1038 UpdateNewSpaceReferencesInExternalStringTable( | 1026 UpdateNewSpaceReferencesInExternalStringTable( |
| 1039 &UpdateNewSpaceReferenceInExternalStringTableEntry); | 1027 &UpdateNewSpaceReferenceInExternalStringTableEntry); |
| 1040 | 1028 |
| 1041 LiveObjectList::UpdateReferencesForScavengeGC(); | 1029 LiveObjectList::UpdateReferencesForScavengeGC(); |
| 1030 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge(); |
| 1042 | 1031 |
| 1043 ASSERT(new_space_front == new_space_.top()); | 1032 ASSERT(new_space_front == new_space_.top()); |
| 1044 | 1033 |
| 1045 is_safe_to_read_maps_ = true; | 1034 is_safe_to_read_maps_ = true; |
| 1046 | 1035 |
| 1047 // Set age mark. | 1036 // Set age mark. |
| 1048 new_space_.set_age_mark(new_space_.top()); | 1037 new_space_.set_age_mark(new_space_.top()); |
| 1049 | 1038 |
| 1050 // Update how much has survived scavenge. | 1039 // Update how much has survived scavenge. |
| 1051 IncrementYoungSurvivorsCounter(static_cast<int>( | 1040 IncrementYoungSurvivorsCounter(static_cast<int>( |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1322 | 1311 |
| 1323 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) | 1312 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) |
| 1324 // Update NewSpace stats if necessary. | 1313 // Update NewSpace stats if necessary. |
| 1325 RecordCopiedObject(heap, target); | 1314 RecordCopiedObject(heap, target); |
| 1326 #endif | 1315 #endif |
| 1327 HEAP_PROFILE(heap, ObjectMoveEvent(source->address(), target->address())); | 1316 HEAP_PROFILE(heap, ObjectMoveEvent(source->address(), target->address())); |
| 1328 #if defined(ENABLE_LOGGING_AND_PROFILING) | 1317 #if defined(ENABLE_LOGGING_AND_PROFILING) |
| 1329 Isolate* isolate = heap->isolate(); | 1318 Isolate* isolate = heap->isolate(); |
| 1330 if (isolate->logger()->is_logging() || | 1319 if (isolate->logger()->is_logging() || |
| 1331 isolate->cpu_profiler()->is_profiling()) { | 1320 isolate->cpu_profiler()->is_profiling()) { |
| 1332 if (target->IsJSFunction()) { | 1321 if (target->IsSharedFunctionInfo()) { |
| 1333 PROFILE(FunctionMoveEvent(heap, source->address(), target->address())); | 1322 PROFILE(SFIMoveEvent(source->address(), target->address())); |
| 1334 PROFILE(FunctionCreateEventFromMove(heap, JSFunction::cast(target))); | |
| 1335 } | 1323 } |
| 1336 } | 1324 } |
| 1337 #endif | 1325 #endif |
| 1338 return target; | 1326 return target; |
| 1339 } | 1327 } |
| 1340 | 1328 |
| 1341 | 1329 |
| 1342 template<ObjectContents object_contents, SizeRestriction size_restriction> | 1330 template<ObjectContents object_contents, SizeRestriction size_restriction> |
| 1343 static inline void EvacuateObject(Map* map, | 1331 static inline void EvacuateObject(Map* map, |
| 1344 HeapObject** slot, | 1332 HeapObject** slot, |
| (...skipping 1567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2912 JSFunction* object_function = | 2900 JSFunction* object_function = |
| 2913 function->context()->global_context()->object_function(); | 2901 function->context()->global_context()->object_function(); |
| 2914 Object* prototype; | 2902 Object* prototype; |
| 2915 { MaybeObject* maybe_prototype = AllocateJSObject(object_function); | 2903 { MaybeObject* maybe_prototype = AllocateJSObject(object_function); |
| 2916 if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype; | 2904 if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype; |
| 2917 } | 2905 } |
| 2918 // When creating the prototype for the function we must set its | 2906 // When creating the prototype for the function we must set its |
| 2919 // constructor to the function. | 2907 // constructor to the function. |
| 2920 Object* result; | 2908 Object* result; |
| 2921 { MaybeObject* maybe_result = | 2909 { MaybeObject* maybe_result = |
| 2922 JSObject::cast(prototype)->SetProperty(constructor_symbol(), | 2910 JSObject::cast(prototype)->SetLocalPropertyIgnoreAttributes( |
| 2923 function, | 2911 constructor_symbol(), function, DONT_ENUM); |
| 2924 DONT_ENUM); | |
| 2925 if (!maybe_result->ToObject(&result)) return maybe_result; | 2912 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 2926 } | 2913 } |
| 2927 return prototype; | 2914 return prototype; |
| 2928 } | 2915 } |
| 2929 | 2916 |
| 2930 | 2917 |
| 2931 MaybeObject* Heap::AllocateFunction(Map* function_map, | 2918 MaybeObject* Heap::AllocateFunction(Map* function_map, |
| 2932 SharedFunctionInfo* shared, | 2919 SharedFunctionInfo* shared, |
| 2933 Object* prototype, | 2920 Object* prototype, |
| 2934 PretenureFlag pretenure) { | 2921 PretenureFlag pretenure) { |
| (...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3804 Struct::cast(result)->InitializeBody(size); | 3791 Struct::cast(result)->InitializeBody(size); |
| 3805 return result; | 3792 return result; |
| 3806 } | 3793 } |
| 3807 | 3794 |
| 3808 | 3795 |
| 3809 bool Heap::IdleNotification() { | 3796 bool Heap::IdleNotification() { |
| 3810 static const int kIdlesBeforeScavenge = 4; | 3797 static const int kIdlesBeforeScavenge = 4; |
| 3811 static const int kIdlesBeforeMarkSweep = 7; | 3798 static const int kIdlesBeforeMarkSweep = 7; |
| 3812 static const int kIdlesBeforeMarkCompact = 8; | 3799 static const int kIdlesBeforeMarkCompact = 8; |
| 3813 static const int kMaxIdleCount = kIdlesBeforeMarkCompact + 1; | 3800 static const int kMaxIdleCount = kIdlesBeforeMarkCompact + 1; |
| 3814 static const int kGCsBetweenCleanup = 4; | 3801 static const unsigned int kGCsBetweenCleanup = 4; |
| 3815 | 3802 |
| 3816 if (!last_idle_notification_gc_count_init_) { | 3803 if (!last_idle_notification_gc_count_init_) { |
| 3817 last_idle_notification_gc_count_ = gc_count_; | 3804 last_idle_notification_gc_count_ = gc_count_; |
| 3818 last_idle_notification_gc_count_init_ = true; | 3805 last_idle_notification_gc_count_init_ = true; |
| 3819 } | 3806 } |
| 3820 | 3807 |
| 3821 bool uncommit = true; | 3808 bool uncommit = true; |
| 3822 bool finished = false; | 3809 bool finished = false; |
| 3823 | 3810 |
| 3824 // Reset the number of idle notifications received when a number of | 3811 // Reset the number of idle notifications received when a number of |
| 3825 // GCs have taken place. This allows another round of cleanup based | 3812 // GCs have taken place. This allows another round of cleanup based |
| 3826 // on idle notifications if enough work has been carried out to | 3813 // on idle notifications if enough work has been carried out to |
| 3827 // provoke a number of garbage collections. | 3814 // provoke a number of garbage collections. |
| 3828 if (gc_count_ < last_idle_notification_gc_count_ + kGCsBetweenCleanup) { | 3815 if (gc_count_ - last_idle_notification_gc_count_ < kGCsBetweenCleanup) { |
| 3829 number_idle_notifications_ = | 3816 number_idle_notifications_ = |
| 3830 Min(number_idle_notifications_ + 1, kMaxIdleCount); | 3817 Min(number_idle_notifications_ + 1, kMaxIdleCount); |
| 3831 } else { | 3818 } else { |
| 3832 number_idle_notifications_ = 0; | 3819 number_idle_notifications_ = 0; |
| 3833 last_idle_notification_gc_count_ = gc_count_; | 3820 last_idle_notification_gc_count_ = gc_count_; |
| 3834 } | 3821 } |
| 3835 | 3822 |
| 3836 if (number_idle_notifications_ == kIdlesBeforeScavenge) { | 3823 if (number_idle_notifications_ == kIdlesBeforeScavenge) { |
| 3837 if (contexts_disposed_ > 0) { | 3824 if (contexts_disposed_ > 0) { |
| 3838 HistogramTimerScope scope(isolate_->counters()->gc_context()); | 3825 HistogramTimerScope scope(isolate_->counters()->gc_context()); |
| (...skipping 1551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5390 } | 5377 } |
| 5391 | 5378 |
| 5392 | 5379 |
| 5393 void HeapIterator::reset() { | 5380 void HeapIterator::reset() { |
| 5394 // Restart the iterator. | 5381 // Restart the iterator. |
| 5395 Shutdown(); | 5382 Shutdown(); |
| 5396 Init(); | 5383 Init(); |
| 5397 } | 5384 } |
| 5398 | 5385 |
| 5399 | 5386 |
| 5387 #if defined(DEBUG) || defined(LIVE_OBJECT_LIST) |
| 5388 |
| 5389 Object* const PathTracer::kAnyGlobalObject = reinterpret_cast<Object*>(NULL); |
| 5390 |
| 5391 class PathTracer::MarkVisitor: public ObjectVisitor { |
| 5392 public: |
| 5393 explicit MarkVisitor(PathTracer* tracer) : tracer_(tracer) {} |
| 5394 void VisitPointers(Object** start, Object** end) { |
| 5395 // Scan all HeapObject pointers in [start, end) |
| 5396 for (Object** p = start; !tracer_->found() && (p < end); p++) { |
| 5397 if ((*p)->IsHeapObject()) |
| 5398 tracer_->MarkRecursively(p, this); |
| 5399 } |
| 5400 } |
| 5401 |
| 5402 private: |
| 5403 PathTracer* tracer_; |
| 5404 }; |
| 5405 |
| 5406 |
| 5407 class PathTracer::UnmarkVisitor: public ObjectVisitor { |
| 5408 public: |
| 5409 explicit UnmarkVisitor(PathTracer* tracer) : tracer_(tracer) {} |
| 5410 void VisitPointers(Object** start, Object** end) { |
| 5411 // Scan all HeapObject pointers in [start, end) |
| 5412 for (Object** p = start; p < end; p++) { |
| 5413 if ((*p)->IsHeapObject()) |
| 5414 tracer_->UnmarkRecursively(p, this); |
| 5415 } |
| 5416 } |
| 5417 |
| 5418 private: |
| 5419 PathTracer* tracer_; |
| 5420 }; |
| 5421 |
| 5422 |
| 5423 void PathTracer::VisitPointers(Object** start, Object** end) { |
| 5424 bool done = ((what_to_find_ == FIND_FIRST) && found_target_); |
| 5425 // Visit all HeapObject pointers in [start, end) |
| 5426 for (Object** p = start; !done && (p < end); p++) { |
| 5427 if ((*p)->IsHeapObject()) { |
| 5428 TracePathFrom(p); |
| 5429 done = ((what_to_find_ == FIND_FIRST) && found_target_); |
| 5430 } |
| 5431 } |
| 5432 } |
| 5433 |
| 5434 |
| 5435 void PathTracer::Reset() { |
| 5436 found_target_ = false; |
| 5437 object_stack_.Clear(); |
| 5438 } |
| 5439 |
| 5440 |
| 5441 void PathTracer::TracePathFrom(Object** root) { |
| 5442 ASSERT((search_target_ == kAnyGlobalObject) || |
| 5443 search_target_->IsHeapObject()); |
| 5444 found_target_in_trace_ = false; |
| 5445 object_stack_.Clear(); |
| 5446 |
| 5447 MarkVisitor mark_visitor(this); |
| 5448 MarkRecursively(root, &mark_visitor); |
| 5449 |
| 5450 UnmarkVisitor unmark_visitor(this); |
| 5451 UnmarkRecursively(root, &unmark_visitor); |
| 5452 |
| 5453 ProcessResults(); |
| 5454 } |
| 5455 |
| 5456 |
| 5457 void PathTracer::MarkRecursively(Object** p, MarkVisitor* mark_visitor) { |
| 5458 if (!(*p)->IsHeapObject()) return; |
| 5459 |
| 5460 HeapObject* obj = HeapObject::cast(*p); |
| 5461 |
| 5462 Object* map = obj->map(); |
| 5463 |
| 5464 if (!map->IsHeapObject()) return; // visited before |
| 5465 |
| 5466 if (found_target_in_trace_) return; // stop if target found |
| 5467 object_stack_.Add(obj); |
| 5468 if (((search_target_ == kAnyGlobalObject) && obj->IsJSGlobalObject()) || |
| 5469 (obj == search_target_)) { |
| 5470 found_target_in_trace_ = true; |
| 5471 found_target_ = true; |
| 5472 return; |
| 5473 } |
| 5474 |
| 5475 bool is_global_context = obj->IsGlobalContext(); |
| 5476 |
| 5477 // not visited yet |
| 5478 Map* map_p = reinterpret_cast<Map*>(HeapObject::cast(map)); |
| 5479 |
| 5480 Address map_addr = map_p->address(); |
| 5481 |
| 5482 obj->set_map(reinterpret_cast<Map*>(map_addr + kMarkTag)); |
| 5483 |
| 5484 // Scan the object body. |
| 5485 if (is_global_context && (visit_mode_ == VISIT_ONLY_STRONG)) { |
| 5486 // This is specialized to scan Context's properly. |
| 5487 Object** start = reinterpret_cast<Object**>(obj->address() + |
| 5488 Context::kHeaderSize); |
| 5489 Object** end = reinterpret_cast<Object**>(obj->address() + |
| 5490 Context::kHeaderSize + Context::FIRST_WEAK_SLOT * kPointerSize); |
| 5491 mark_visitor->VisitPointers(start, end); |
| 5492 } else { |
| 5493 obj->IterateBody(map_p->instance_type(), |
| 5494 obj->SizeFromMap(map_p), |
| 5495 mark_visitor); |
| 5496 } |
| 5497 |
| 5498 // Scan the map after the body because the body is a lot more interesting |
| 5499 // when doing leak detection. |
| 5500 MarkRecursively(&map, mark_visitor); |
| 5501 |
| 5502 if (!found_target_in_trace_) // don't pop if found the target |
| 5503 object_stack_.RemoveLast(); |
| 5504 } |
| 5505 |
| 5506 |
| 5507 void PathTracer::UnmarkRecursively(Object** p, UnmarkVisitor* unmark_visitor) { |
| 5508 if (!(*p)->IsHeapObject()) return; |
| 5509 |
| 5510 HeapObject* obj = HeapObject::cast(*p); |
| 5511 |
| 5512 Object* map = obj->map(); |
| 5513 |
| 5514 if (map->IsHeapObject()) return; // unmarked already |
| 5515 |
| 5516 Address map_addr = reinterpret_cast<Address>(map); |
| 5517 |
| 5518 map_addr -= kMarkTag; |
| 5519 |
| 5520 ASSERT_TAG_ALIGNED(map_addr); |
| 5521 |
| 5522 HeapObject* map_p = HeapObject::FromAddress(map_addr); |
| 5523 |
| 5524 obj->set_map(reinterpret_cast<Map*>(map_p)); |
| 5525 |
| 5526 UnmarkRecursively(reinterpret_cast<Object**>(&map_p), unmark_visitor); |
| 5527 |
| 5528 obj->IterateBody(Map::cast(map_p)->instance_type(), |
| 5529 obj->SizeFromMap(Map::cast(map_p)), |
| 5530 unmark_visitor); |
| 5531 } |
| 5532 |
| 5533 |
| 5534 void PathTracer::ProcessResults() { |
| 5535 if (found_target_) { |
| 5536 PrintF("=====================================\n"); |
| 5537 PrintF("==== Path to object ====\n"); |
| 5538 PrintF("=====================================\n\n"); |
| 5539 |
| 5540 ASSERT(!object_stack_.is_empty()); |
| 5541 for (int i = 0; i < object_stack_.length(); i++) { |
| 5542 if (i > 0) PrintF("\n |\n |\n V\n\n"); |
| 5543 Object* obj = object_stack_[i]; |
| 5544 #ifdef OBJECT_PRINT |
| 5545 obj->Print(); |
| 5546 #else |
| 5547 obj->ShortPrint(); |
| 5548 #endif |
| 5549 } |
| 5550 PrintF("=====================================\n"); |
| 5551 } |
| 5552 } |
| 5553 #endif // DEBUG || LIVE_OBJECT_LIST |
| 5554 |
| 5555 |
| 5400 #ifdef DEBUG | 5556 #ifdef DEBUG |
| 5401 // Triggers a depth-first traversal of reachable objects from roots | 5557 // Triggers a depth-first traversal of reachable objects from roots |
| 5402 // and finds a path to a specific heap object and prints it. | 5558 // and finds a path to a specific heap object and prints it. |
| 5403 void Heap::TracePathToObject(Object* target) { | 5559 void Heap::TracePathToObject(Object* target) { |
| 5404 debug_utils_->search_target_ = target; | 5560 PathTracer tracer(target, PathTracer::FIND_ALL, VISIT_ALL); |
| 5405 debug_utils_->search_for_any_global_ = false; | 5561 IterateRoots(&tracer, VISIT_ONLY_STRONG); |
| 5406 | |
| 5407 HeapDebugUtils::MarkRootVisitor root_visitor(debug_utils_); | |
| 5408 IterateRoots(&root_visitor, VISIT_ONLY_STRONG); | |
| 5409 } | 5562 } |
| 5410 | 5563 |
| 5411 | 5564 |
| 5412 // Triggers a depth-first traversal of reachable objects from roots | 5565 // Triggers a depth-first traversal of reachable objects from roots |
| 5413 // and finds a path to any global object and prints it. Useful for | 5566 // and finds a path to any global object and prints it. Useful for |
| 5414 // determining the source for leaks of global objects. | 5567 // determining the source for leaks of global objects. |
| 5415 void Heap::TracePathToGlobal() { | 5568 void Heap::TracePathToGlobal() { |
| 5416 debug_utils_->search_target_ = NULL; | 5569 PathTracer tracer(PathTracer::kAnyGlobalObject, |
| 5417 debug_utils_->search_for_any_global_ = true; | 5570 PathTracer::FIND_ALL, |
| 5418 | 5571 VISIT_ALL); |
| 5419 HeapDebugUtils::MarkRootVisitor root_visitor(debug_utils_); | 5572 IterateRoots(&tracer, VISIT_ONLY_STRONG); |
| 5420 IterateRoots(&root_visitor, VISIT_ONLY_STRONG); | |
| 5421 } | 5573 } |
| 5422 #endif | 5574 #endif |
| 5423 | 5575 |
| 5424 | 5576 |
| 5425 static intptr_t CountTotalHolesSize() { | 5577 static intptr_t CountTotalHolesSize() { |
| 5426 intptr_t holes_size = 0; | 5578 intptr_t holes_size = 0; |
| 5427 OldSpaces spaces; | 5579 OldSpaces spaces; |
| 5428 for (OldSpace* space = spaces.next(); | 5580 for (OldSpace* space = spaces.next(); |
| 5429 space != NULL; | 5581 space != NULL; |
| 5430 space = spaces.next()) { | 5582 space = spaces.next()) { |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5651 } | 5803 } |
| 5652 | 5804 |
| 5653 | 5805 |
| 5654 void ExternalStringTable::TearDown() { | 5806 void ExternalStringTable::TearDown() { |
| 5655 new_space_strings_.Free(); | 5807 new_space_strings_.Free(); |
| 5656 old_space_strings_.Free(); | 5808 old_space_strings_.Free(); |
| 5657 } | 5809 } |
| 5658 | 5810 |
| 5659 | 5811 |
| 5660 } } // namespace v8::internal | 5812 } } // namespace v8::internal |
| OLD | NEW |