OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/profiler/heap-snapshot-generator.h" | 5 #include "src/profiler/heap-snapshot-generator.h" |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
10 #include "src/objects-body-descriptors.h" | 10 #include "src/objects-body-descriptors.h" |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 // It may occur that some untracked object moves to an address X and there | 385 // It may occur that some untracked object moves to an address X and there |
386 // is a tracked object at that address. In this case we should remove the | 386 // is a tracked object at that address. In this case we should remove the |
387 // entry as we know that the object has died. | 387 // entry as we know that the object has died. |
388 void* to_value = entries_map_.Remove(to, ComputePointerHash(to)); | 388 void* to_value = entries_map_.Remove(to, ComputePointerHash(to)); |
389 if (to_value != NULL) { | 389 if (to_value != NULL) { |
390 int to_entry_info_index = | 390 int to_entry_info_index = |
391 static_cast<int>(reinterpret_cast<intptr_t>(to_value)); | 391 static_cast<int>(reinterpret_cast<intptr_t>(to_value)); |
392 entries_.at(to_entry_info_index).addr = NULL; | 392 entries_.at(to_entry_info_index).addr = NULL; |
393 } | 393 } |
394 } else { | 394 } else { |
395 HashMap::Entry* to_entry = | 395 base::HashMap::Entry* to_entry = |
396 entries_map_.LookupOrInsert(to, ComputePointerHash(to)); | 396 entries_map_.LookupOrInsert(to, ComputePointerHash(to)); |
397 if (to_entry->value != NULL) { | 397 if (to_entry->value != NULL) { |
398 // We found the existing entry with to address for an old object. | 398 // We found the existing entry with to address for an old object. |
399 // Without this operation we will have two EntryInfo's with the same | 399 // Without this operation we will have two EntryInfo's with the same |
400 // value in addr field. It is bad because later at RemoveDeadEntries | 400 // value in addr field. It is bad because later at RemoveDeadEntries |
401 // one of this entry will be removed with the corresponding entries_map_ | 401 // one of this entry will be removed with the corresponding entries_map_ |
402 // entry. | 402 // entry. |
403 int to_entry_info_index = | 403 int to_entry_info_index = |
404 static_cast<int>(reinterpret_cast<intptr_t>(to_entry->value)); | 404 static_cast<int>(reinterpret_cast<intptr_t>(to_entry->value)); |
405 entries_.at(to_entry_info_index).addr = NULL; | 405 entries_.at(to_entry_info_index).addr = NULL; |
(...skipping 15 matching lines...) Expand all Loading... |
421 return from_value != NULL; | 421 return from_value != NULL; |
422 } | 422 } |
423 | 423 |
424 | 424 |
425 void HeapObjectsMap::UpdateObjectSize(Address addr, int size) { | 425 void HeapObjectsMap::UpdateObjectSize(Address addr, int size) { |
426 FindOrAddEntry(addr, size, false); | 426 FindOrAddEntry(addr, size, false); |
427 } | 427 } |
428 | 428 |
429 | 429 |
430 SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) { | 430 SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) { |
431 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr)); | 431 base::HashMap::Entry* entry = |
| 432 entries_map_.Lookup(addr, ComputePointerHash(addr)); |
432 if (entry == NULL) return 0; | 433 if (entry == NULL) return 0; |
433 int entry_index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); | 434 int entry_index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); |
434 EntryInfo& entry_info = entries_.at(entry_index); | 435 EntryInfo& entry_info = entries_.at(entry_index); |
435 DCHECK(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); | 436 DCHECK(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); |
436 return entry_info.id; | 437 return entry_info.id; |
437 } | 438 } |
438 | 439 |
439 | 440 |
440 SnapshotObjectId HeapObjectsMap::FindOrAddEntry(Address addr, | 441 SnapshotObjectId HeapObjectsMap::FindOrAddEntry(Address addr, |
441 unsigned int size, | 442 unsigned int size, |
442 bool accessed) { | 443 bool accessed) { |
443 DCHECK(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); | 444 DCHECK(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); |
444 HashMap::Entry* entry = | 445 base::HashMap::Entry* entry = |
445 entries_map_.LookupOrInsert(addr, ComputePointerHash(addr)); | 446 entries_map_.LookupOrInsert(addr, ComputePointerHash(addr)); |
446 if (entry->value != NULL) { | 447 if (entry->value != NULL) { |
447 int entry_index = | 448 int entry_index = |
448 static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); | 449 static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); |
449 EntryInfo& entry_info = entries_.at(entry_index); | 450 EntryInfo& entry_info = entries_.at(entry_index); |
450 entry_info.accessed = accessed; | 451 entry_info.accessed = accessed; |
451 if (FLAG_heap_profiler_trace_objects) { | 452 if (FLAG_heap_profiler_trace_objects) { |
452 PrintF("Update object size : %p with old size %d and new size %d\n", | 453 PrintF("Update object size : %p with old size %d and new size %d\n", |
453 static_cast<void*>(addr), entry_info.size, size); | 454 static_cast<void*>(addr), entry_info.size, size); |
454 } | 455 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 | 539 |
539 | 540 |
540 int HeapObjectsMap::FindUntrackedObjects() { | 541 int HeapObjectsMap::FindUntrackedObjects() { |
541 List<HeapObjectInfo> heap_objects(1000); | 542 List<HeapObjectInfo> heap_objects(1000); |
542 | 543 |
543 HeapIterator iterator(heap_); | 544 HeapIterator iterator(heap_); |
544 int untracked = 0; | 545 int untracked = 0; |
545 for (HeapObject* obj = iterator.next(); | 546 for (HeapObject* obj = iterator.next(); |
546 obj != NULL; | 547 obj != NULL; |
547 obj = iterator.next()) { | 548 obj = iterator.next()) { |
548 HashMap::Entry* entry = | 549 base::HashMap::Entry* entry = |
549 entries_map_.Lookup(obj->address(), ComputePointerHash(obj->address())); | 550 entries_map_.Lookup(obj->address(), ComputePointerHash(obj->address())); |
550 if (entry == NULL) { | 551 if (entry == NULL) { |
551 ++untracked; | 552 ++untracked; |
552 if (FLAG_heap_profiler_trace_objects) { | 553 if (FLAG_heap_profiler_trace_objects) { |
553 heap_objects.Add(HeapObjectInfo(obj, 0)); | 554 heap_objects.Add(HeapObjectInfo(obj, 0)); |
554 } | 555 } |
555 } else { | 556 } else { |
556 int entry_index = static_cast<int>( | 557 int entry_index = static_cast<int>( |
557 reinterpret_cast<intptr_t>(entry->value)); | 558 reinterpret_cast<intptr_t>(entry->value)); |
558 EntryInfo& entry_info = entries_.at(entry_index); | 559 EntryInfo& entry_info = entries_.at(entry_index); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
658 entries_.at(0).id == 0 && | 659 entries_.at(0).id == 0 && |
659 entries_.at(0).addr == NULL); | 660 entries_.at(0).addr == NULL); |
660 int first_free_entry = 1; | 661 int first_free_entry = 1; |
661 for (int i = 1; i < entries_.length(); ++i) { | 662 for (int i = 1; i < entries_.length(); ++i) { |
662 EntryInfo& entry_info = entries_.at(i); | 663 EntryInfo& entry_info = entries_.at(i); |
663 if (entry_info.accessed) { | 664 if (entry_info.accessed) { |
664 if (first_free_entry != i) { | 665 if (first_free_entry != i) { |
665 entries_.at(first_free_entry) = entry_info; | 666 entries_.at(first_free_entry) = entry_info; |
666 } | 667 } |
667 entries_.at(first_free_entry).accessed = false; | 668 entries_.at(first_free_entry).accessed = false; |
668 HashMap::Entry* entry = entries_map_.Lookup( | 669 base::HashMap::Entry* entry = entries_map_.Lookup( |
669 entry_info.addr, ComputePointerHash(entry_info.addr)); | 670 entry_info.addr, ComputePointerHash(entry_info.addr)); |
670 DCHECK(entry); | 671 DCHECK(entry); |
671 entry->value = reinterpret_cast<void*>(first_free_entry); | 672 entry->value = reinterpret_cast<void*>(first_free_entry); |
672 ++first_free_entry; | 673 ++first_free_entry; |
673 } else { | 674 } else { |
674 if (entry_info.addr) { | 675 if (entry_info.addr) { |
675 entries_map_.Remove(entry_info.addr, | 676 entries_map_.Remove(entry_info.addr, |
676 ComputePointerHash(entry_info.addr)); | 677 ComputePointerHash(entry_info.addr)); |
677 } | 678 } |
678 } | 679 } |
(...skipping 12 matching lines...) Expand all Loading... |
691 heap_->HashSeed()); | 692 heap_->HashSeed()); |
692 intptr_t element_count = info->GetElementCount(); | 693 intptr_t element_count = info->GetElementCount(); |
693 if (element_count != -1) | 694 if (element_count != -1) |
694 id ^= ComputeIntegerHash(static_cast<uint32_t>(element_count), | 695 id ^= ComputeIntegerHash(static_cast<uint32_t>(element_count), |
695 v8::internal::kZeroHashSeed); | 696 v8::internal::kZeroHashSeed); |
696 return id << 1; | 697 return id << 1; |
697 } | 698 } |
698 | 699 |
699 | 700 |
700 size_t HeapObjectsMap::GetUsedMemorySize() const { | 701 size_t HeapObjectsMap::GetUsedMemorySize() const { |
701 return | 702 return sizeof(*this) + |
702 sizeof(*this) + | 703 sizeof(base::HashMap::Entry) * entries_map_.capacity() + |
703 sizeof(HashMap::Entry) * entries_map_.capacity() + | 704 GetMemoryUsedByList(entries_) + GetMemoryUsedByList(time_intervals_); |
704 GetMemoryUsedByList(entries_) + | |
705 GetMemoryUsedByList(time_intervals_); | |
706 } | 705 } |
707 | 706 |
708 | 707 HeapEntriesMap::HeapEntriesMap() : entries_(base::HashMap::PointersMatch) {} |
709 HeapEntriesMap::HeapEntriesMap() | |
710 : entries_(HashMap::PointersMatch) { | |
711 } | |
712 | |
713 | 708 |
714 int HeapEntriesMap::Map(HeapThing thing) { | 709 int HeapEntriesMap::Map(HeapThing thing) { |
715 HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing)); | 710 base::HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing)); |
716 if (cache_entry == NULL) return HeapEntry::kNoEntry; | 711 if (cache_entry == NULL) return HeapEntry::kNoEntry; |
717 return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value)); | 712 return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value)); |
718 } | 713 } |
719 | 714 |
720 | 715 |
721 void HeapEntriesMap::Pair(HeapThing thing, int entry) { | 716 void HeapEntriesMap::Pair(HeapThing thing, int entry) { |
722 HashMap::Entry* cache_entry = entries_.LookupOrInsert(thing, Hash(thing)); | 717 base::HashMap::Entry* cache_entry = |
| 718 entries_.LookupOrInsert(thing, Hash(thing)); |
723 DCHECK(cache_entry->value == NULL); | 719 DCHECK(cache_entry->value == NULL); |
724 cache_entry->value = reinterpret_cast<void*>(static_cast<intptr_t>(entry)); | 720 cache_entry->value = reinterpret_cast<void*>(static_cast<intptr_t>(entry)); |
725 } | 721 } |
726 | 722 |
727 | 723 HeapObjectsSet::HeapObjectsSet() : entries_(base::HashMap::PointersMatch) {} |
728 HeapObjectsSet::HeapObjectsSet() | |
729 : entries_(HashMap::PointersMatch) { | |
730 } | |
731 | |
732 | 724 |
733 void HeapObjectsSet::Clear() { | 725 void HeapObjectsSet::Clear() { |
734 entries_.Clear(); | 726 entries_.Clear(); |
735 } | 727 } |
736 | 728 |
737 | 729 |
738 bool HeapObjectsSet::Contains(Object* obj) { | 730 bool HeapObjectsSet::Contains(Object* obj) { |
739 if (!obj->IsHeapObject()) return false; | 731 if (!obj->IsHeapObject()) return false; |
740 HeapObject* object = HeapObject::cast(obj); | 732 HeapObject* object = HeapObject::cast(obj); |
741 return entries_.Lookup(object, HeapEntriesMap::Hash(object)) != NULL; | 733 return entries_.Lookup(object, HeapEntriesMap::Hash(object)) != NULL; |
742 } | 734 } |
743 | 735 |
744 | 736 |
745 void HeapObjectsSet::Insert(Object* obj) { | 737 void HeapObjectsSet::Insert(Object* obj) { |
746 if (!obj->IsHeapObject()) return; | 738 if (!obj->IsHeapObject()) return; |
747 HeapObject* object = HeapObject::cast(obj); | 739 HeapObject* object = HeapObject::cast(obj); |
748 entries_.LookupOrInsert(object, HeapEntriesMap::Hash(object)); | 740 entries_.LookupOrInsert(object, HeapEntriesMap::Hash(object)); |
749 } | 741 } |
750 | 742 |
751 | 743 |
752 const char* HeapObjectsSet::GetTag(Object* obj) { | 744 const char* HeapObjectsSet::GetTag(Object* obj) { |
753 HeapObject* object = HeapObject::cast(obj); | 745 HeapObject* object = HeapObject::cast(obj); |
754 HashMap::Entry* cache_entry = | 746 base::HashMap::Entry* cache_entry = |
755 entries_.Lookup(object, HeapEntriesMap::Hash(object)); | 747 entries_.Lookup(object, HeapEntriesMap::Hash(object)); |
756 return cache_entry != NULL | 748 return cache_entry != NULL |
757 ? reinterpret_cast<const char*>(cache_entry->value) | 749 ? reinterpret_cast<const char*>(cache_entry->value) |
758 : NULL; | 750 : NULL; |
759 } | 751 } |
760 | 752 |
761 | 753 |
762 void HeapObjectsSet::SetTag(Object* obj, const char* tag) { | 754 void HeapObjectsSet::SetTag(Object* obj, const char* tag) { |
763 if (!obj->IsHeapObject()) return; | 755 if (!obj->IsHeapObject()) return; |
764 HeapObject* object = HeapObject::cast(obj); | 756 HeapObject* object = HeapObject::cast(obj); |
765 HashMap::Entry* cache_entry = | 757 base::HashMap::Entry* cache_entry = |
766 entries_.LookupOrInsert(object, HeapEntriesMap::Hash(object)); | 758 entries_.LookupOrInsert(object, HeapEntriesMap::Hash(object)); |
767 cache_entry->value = const_cast<char*>(tag); | 759 cache_entry->value = const_cast<char*>(tag); |
768 } | 760 } |
769 | 761 |
770 | 762 |
771 V8HeapExplorer::V8HeapExplorer( | 763 V8HeapExplorer::V8HeapExplorer( |
772 HeapSnapshot* snapshot, | 764 HeapSnapshot* snapshot, |
773 SnapshottingProgressReportingInterface* progress, | 765 SnapshottingProgressReportingInterface* progress, |
774 v8::HeapProfiler::ObjectNameResolver* resolver) | 766 v8::HeapProfiler::ObjectNameResolver* resolver) |
775 : heap_(snapshot->profiler()->heap_object_map()->heap()), | 767 : heap_(snapshot->profiler()->heap_object_map()->heap()), |
(...skipping 1471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2247 native_groups_(StringsMatch), | 2239 native_groups_(StringsMatch), |
2248 filler_(NULL) { | 2240 filler_(NULL) { |
2249 synthetic_entries_allocator_ = | 2241 synthetic_entries_allocator_ = |
2250 new BasicHeapEntriesAllocator(snapshot, HeapEntry::kSynthetic); | 2242 new BasicHeapEntriesAllocator(snapshot, HeapEntry::kSynthetic); |
2251 native_entries_allocator_ = | 2243 native_entries_allocator_ = |
2252 new BasicHeapEntriesAllocator(snapshot, HeapEntry::kNative); | 2244 new BasicHeapEntriesAllocator(snapshot, HeapEntry::kNative); |
2253 } | 2245 } |
2254 | 2246 |
2255 | 2247 |
2256 NativeObjectsExplorer::~NativeObjectsExplorer() { | 2248 NativeObjectsExplorer::~NativeObjectsExplorer() { |
2257 for (HashMap::Entry* p = objects_by_info_.Start(); | 2249 for (base::HashMap::Entry* p = objects_by_info_.Start(); p != NULL; |
2258 p != NULL; | |
2259 p = objects_by_info_.Next(p)) { | 2250 p = objects_by_info_.Next(p)) { |
2260 v8::RetainedObjectInfo* info = | 2251 v8::RetainedObjectInfo* info = |
2261 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); | 2252 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); |
2262 info->Dispose(); | 2253 info->Dispose(); |
2263 List<HeapObject*>* objects = | 2254 List<HeapObject*>* objects = |
2264 reinterpret_cast<List<HeapObject*>* >(p->value); | 2255 reinterpret_cast<List<HeapObject*>* >(p->value); |
2265 delete objects; | 2256 delete objects; |
2266 } | 2257 } |
2267 for (HashMap::Entry* p = native_groups_.Start(); | 2258 for (base::HashMap::Entry* p = native_groups_.Start(); p != NULL; |
2268 p != NULL; | |
2269 p = native_groups_.Next(p)) { | 2259 p = native_groups_.Next(p)) { |
2270 v8::RetainedObjectInfo* info = | 2260 v8::RetainedObjectInfo* info = |
2271 reinterpret_cast<v8::RetainedObjectInfo*>(p->value); | 2261 reinterpret_cast<v8::RetainedObjectInfo*>(p->value); |
2272 info->Dispose(); | 2262 info->Dispose(); |
2273 } | 2263 } |
2274 delete synthetic_entries_allocator_; | 2264 delete synthetic_entries_allocator_; |
2275 delete native_entries_allocator_; | 2265 delete native_entries_allocator_; |
2276 } | 2266 } |
2277 | 2267 |
2278 | 2268 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2330 parent_entry, | 2320 parent_entry, |
2331 "native", | 2321 "native", |
2332 child_entry); | 2322 child_entry); |
2333 } | 2323 } |
2334 } | 2324 } |
2335 isolate->global_handles()->RemoveImplicitRefGroups(); | 2325 isolate->global_handles()->RemoveImplicitRefGroups(); |
2336 } | 2326 } |
2337 | 2327 |
2338 List<HeapObject*>* NativeObjectsExplorer::GetListMaybeDisposeInfo( | 2328 List<HeapObject*>* NativeObjectsExplorer::GetListMaybeDisposeInfo( |
2339 v8::RetainedObjectInfo* info) { | 2329 v8::RetainedObjectInfo* info) { |
2340 HashMap::Entry* entry = objects_by_info_.LookupOrInsert(info, InfoHash(info)); | 2330 base::HashMap::Entry* entry = |
| 2331 objects_by_info_.LookupOrInsert(info, InfoHash(info)); |
2341 if (entry->value != NULL) { | 2332 if (entry->value != NULL) { |
2342 info->Dispose(); | 2333 info->Dispose(); |
2343 } else { | 2334 } else { |
2344 entry->value = new List<HeapObject*>(4); | 2335 entry->value = new List<HeapObject*>(4); |
2345 } | 2336 } |
2346 return reinterpret_cast<List<HeapObject*>* >(entry->value); | 2337 return reinterpret_cast<List<HeapObject*>* >(entry->value); |
2347 } | 2338 } |
2348 | 2339 |
2349 | 2340 |
2350 bool NativeObjectsExplorer::IterateAndExtractReferences( | 2341 bool NativeObjectsExplorer::IterateAndExtractReferences( |
2351 SnapshotFiller* filler) { | 2342 SnapshotFiller* filler) { |
2352 filler_ = filler; | 2343 filler_ = filler; |
2353 FillRetainedObjects(); | 2344 FillRetainedObjects(); |
2354 FillImplicitReferences(); | 2345 FillImplicitReferences(); |
2355 if (EstimateObjectsCount() > 0) { | 2346 if (EstimateObjectsCount() > 0) { |
2356 for (HashMap::Entry* p = objects_by_info_.Start(); | 2347 for (base::HashMap::Entry* p = objects_by_info_.Start(); p != NULL; |
2357 p != NULL; | |
2358 p = objects_by_info_.Next(p)) { | 2348 p = objects_by_info_.Next(p)) { |
2359 v8::RetainedObjectInfo* info = | 2349 v8::RetainedObjectInfo* info = |
2360 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); | 2350 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); |
2361 SetNativeRootReference(info); | 2351 SetNativeRootReference(info); |
2362 List<HeapObject*>* objects = | 2352 List<HeapObject*>* objects = |
2363 reinterpret_cast<List<HeapObject*>* >(p->value); | 2353 reinterpret_cast<List<HeapObject*>* >(p->value); |
2364 for (int i = 0; i < objects->length(); ++i) { | 2354 for (int i = 0; i < objects->length(); ++i) { |
2365 SetWrapperNativeReferences(objects->at(i), info); | 2355 SetWrapperNativeReferences(objects->at(i), info); |
2366 } | 2356 } |
2367 } | 2357 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2399 }; | 2389 }; |
2400 | 2390 |
2401 | 2391 |
2402 NativeGroupRetainedObjectInfo* NativeObjectsExplorer::FindOrAddGroupInfo( | 2392 NativeGroupRetainedObjectInfo* NativeObjectsExplorer::FindOrAddGroupInfo( |
2403 const char* label) { | 2393 const char* label) { |
2404 const char* label_copy = names_->GetCopy(label); | 2394 const char* label_copy = names_->GetCopy(label); |
2405 uint32_t hash = StringHasher::HashSequentialString( | 2395 uint32_t hash = StringHasher::HashSequentialString( |
2406 label_copy, | 2396 label_copy, |
2407 static_cast<int>(strlen(label_copy)), | 2397 static_cast<int>(strlen(label_copy)), |
2408 isolate_->heap()->HashSeed()); | 2398 isolate_->heap()->HashSeed()); |
2409 HashMap::Entry* entry = | 2399 base::HashMap::Entry* entry = |
2410 native_groups_.LookupOrInsert(const_cast<char*>(label_copy), hash); | 2400 native_groups_.LookupOrInsert(const_cast<char*>(label_copy), hash); |
2411 if (entry->value == NULL) { | 2401 if (entry->value == NULL) { |
2412 entry->value = new NativeGroupRetainedObjectInfo(label); | 2402 entry->value = new NativeGroupRetainedObjectInfo(label); |
2413 } | 2403 } |
2414 return static_cast<NativeGroupRetainedObjectInfo*>(entry->value); | 2404 return static_cast<NativeGroupRetainedObjectInfo*>(entry->value); |
2415 } | 2405 } |
2416 | 2406 |
2417 | 2407 |
2418 void NativeObjectsExplorer::SetNativeRootReference( | 2408 void NativeObjectsExplorer::SetNativeRootReference( |
2419 v8::RetainedObjectInfo* info) { | 2409 v8::RetainedObjectInfo* info) { |
(...skipping 25 matching lines...) Expand all Loading... |
2445 wrapper_entry->index(), | 2435 wrapper_entry->index(), |
2446 "native", | 2436 "native", |
2447 info_entry); | 2437 info_entry); |
2448 filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, | 2438 filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, |
2449 info_entry->index(), | 2439 info_entry->index(), |
2450 wrapper_entry); | 2440 wrapper_entry); |
2451 } | 2441 } |
2452 | 2442 |
2453 | 2443 |
2454 void NativeObjectsExplorer::SetRootNativeRootsReference() { | 2444 void NativeObjectsExplorer::SetRootNativeRootsReference() { |
2455 for (HashMap::Entry* entry = native_groups_.Start(); | 2445 for (base::HashMap::Entry* entry = native_groups_.Start(); entry; |
2456 entry; | |
2457 entry = native_groups_.Next(entry)) { | 2446 entry = native_groups_.Next(entry)) { |
2458 NativeGroupRetainedObjectInfo* group_info = | 2447 NativeGroupRetainedObjectInfo* group_info = |
2459 static_cast<NativeGroupRetainedObjectInfo*>(entry->value); | 2448 static_cast<NativeGroupRetainedObjectInfo*>(entry->value); |
2460 HeapEntry* group_entry = | 2449 HeapEntry* group_entry = |
2461 filler_->FindOrAddEntry(group_info, native_entries_allocator_); | 2450 filler_->FindOrAddEntry(group_info, native_entries_allocator_); |
2462 DCHECK(group_entry != NULL); | 2451 DCHECK(group_entry != NULL); |
2463 filler_->SetIndexedAutoIndexReference( | 2452 filler_->SetIndexedAutoIndexReference( |
2464 HeapGraphEdge::kElement, | 2453 HeapGraphEdge::kElement, |
2465 snapshot_->root()->index(), | 2454 snapshot_->root()->index(), |
2466 group_entry); | 2455 group_entry); |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2714 writer_->AddString("\"strings\":["); | 2703 writer_->AddString("\"strings\":["); |
2715 SerializeStrings(); | 2704 SerializeStrings(); |
2716 if (writer_->aborted()) return; | 2705 if (writer_->aborted()) return; |
2717 writer_->AddCharacter(']'); | 2706 writer_->AddCharacter(']'); |
2718 writer_->AddCharacter('}'); | 2707 writer_->AddCharacter('}'); |
2719 writer_->Finalize(); | 2708 writer_->Finalize(); |
2720 } | 2709 } |
2721 | 2710 |
2722 | 2711 |
2723 int HeapSnapshotJSONSerializer::GetStringId(const char* s) { | 2712 int HeapSnapshotJSONSerializer::GetStringId(const char* s) { |
2724 HashMap::Entry* cache_entry = | 2713 base::HashMap::Entry* cache_entry = |
2725 strings_.LookupOrInsert(const_cast<char*>(s), StringHash(s)); | 2714 strings_.LookupOrInsert(const_cast<char*>(s), StringHash(s)); |
2726 if (cache_entry->value == NULL) { | 2715 if (cache_entry->value == NULL) { |
2727 cache_entry->value = reinterpret_cast<void*>(next_string_id_++); | 2716 cache_entry->value = reinterpret_cast<void*>(next_string_id_++); |
2728 } | 2717 } |
2729 return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value)); | 2718 return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value)); |
2730 } | 2719 } |
2731 | 2720 |
2732 | 2721 |
2733 namespace { | 2722 namespace { |
2734 | 2723 |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3099 } | 3088 } |
3100 } | 3089 } |
3101 } | 3090 } |
3102 writer_->AddCharacter('\"'); | 3091 writer_->AddCharacter('\"'); |
3103 } | 3092 } |
3104 | 3093 |
3105 | 3094 |
3106 void HeapSnapshotJSONSerializer::SerializeStrings() { | 3095 void HeapSnapshotJSONSerializer::SerializeStrings() { |
3107 ScopedVector<const unsigned char*> sorted_strings( | 3096 ScopedVector<const unsigned char*> sorted_strings( |
3108 strings_.occupancy() + 1); | 3097 strings_.occupancy() + 1); |
3109 for (HashMap::Entry* entry = strings_.Start(); | 3098 for (base::HashMap::Entry* entry = strings_.Start(); entry != NULL; |
3110 entry != NULL; | |
3111 entry = strings_.Next(entry)) { | 3099 entry = strings_.Next(entry)) { |
3112 int index = static_cast<int>(reinterpret_cast<uintptr_t>(entry->value)); | 3100 int index = static_cast<int>(reinterpret_cast<uintptr_t>(entry->value)); |
3113 sorted_strings[index] = reinterpret_cast<const unsigned char*>(entry->key); | 3101 sorted_strings[index] = reinterpret_cast<const unsigned char*>(entry->key); |
3114 } | 3102 } |
3115 writer_->AddString("\"<dummy>\""); | 3103 writer_->AddString("\"<dummy>\""); |
3116 for (int i = 1; i < sorted_strings.length(); ++i) { | 3104 for (int i = 1; i < sorted_strings.length(); ++i) { |
3117 writer_->AddCharacter(','); | 3105 writer_->AddCharacter(','); |
3118 SerializeString(sorted_strings[i]); | 3106 SerializeString(sorted_strings[i]); |
3119 if (writer_->aborted()) return; | 3107 if (writer_->aborted()) return; |
3120 } | 3108 } |
3121 } | 3109 } |
3122 | 3110 |
3123 | 3111 |
3124 } // namespace internal | 3112 } // namespace internal |
3125 } // namespace v8 | 3113 } // namespace v8 |
OLD | NEW |