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 1469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2245 native_groups_(StringsMatch), | 2237 native_groups_(StringsMatch), |
2246 filler_(NULL) { | 2238 filler_(NULL) { |
2247 synthetic_entries_allocator_ = | 2239 synthetic_entries_allocator_ = |
2248 new BasicHeapEntriesAllocator(snapshot, HeapEntry::kSynthetic); | 2240 new BasicHeapEntriesAllocator(snapshot, HeapEntry::kSynthetic); |
2249 native_entries_allocator_ = | 2241 native_entries_allocator_ = |
2250 new BasicHeapEntriesAllocator(snapshot, HeapEntry::kNative); | 2242 new BasicHeapEntriesAllocator(snapshot, HeapEntry::kNative); |
2251 } | 2243 } |
2252 | 2244 |
2253 | 2245 |
2254 NativeObjectsExplorer::~NativeObjectsExplorer() { | 2246 NativeObjectsExplorer::~NativeObjectsExplorer() { |
2255 for (HashMap::Entry* p = objects_by_info_.Start(); | 2247 for (base::HashMap::Entry* p = objects_by_info_.Start(); p != NULL; |
2256 p != NULL; | |
2257 p = objects_by_info_.Next(p)) { | 2248 p = objects_by_info_.Next(p)) { |
2258 v8::RetainedObjectInfo* info = | 2249 v8::RetainedObjectInfo* info = |
2259 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); | 2250 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); |
2260 info->Dispose(); | 2251 info->Dispose(); |
2261 List<HeapObject*>* objects = | 2252 List<HeapObject*>* objects = |
2262 reinterpret_cast<List<HeapObject*>* >(p->value); | 2253 reinterpret_cast<List<HeapObject*>* >(p->value); |
2263 delete objects; | 2254 delete objects; |
2264 } | 2255 } |
2265 for (HashMap::Entry* p = native_groups_.Start(); | 2256 for (base::HashMap::Entry* p = native_groups_.Start(); p != NULL; |
2266 p != NULL; | |
2267 p = native_groups_.Next(p)) { | 2257 p = native_groups_.Next(p)) { |
2268 v8::RetainedObjectInfo* info = | 2258 v8::RetainedObjectInfo* info = |
2269 reinterpret_cast<v8::RetainedObjectInfo*>(p->value); | 2259 reinterpret_cast<v8::RetainedObjectInfo*>(p->value); |
2270 info->Dispose(); | 2260 info->Dispose(); |
2271 } | 2261 } |
2272 delete synthetic_entries_allocator_; | 2262 delete synthetic_entries_allocator_; |
2273 delete native_entries_allocator_; | 2263 delete native_entries_allocator_; |
2274 } | 2264 } |
2275 | 2265 |
2276 | 2266 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2328 parent_entry, | 2318 parent_entry, |
2329 "native", | 2319 "native", |
2330 child_entry); | 2320 child_entry); |
2331 } | 2321 } |
2332 } | 2322 } |
2333 isolate->global_handles()->RemoveImplicitRefGroups(); | 2323 isolate->global_handles()->RemoveImplicitRefGroups(); |
2334 } | 2324 } |
2335 | 2325 |
2336 List<HeapObject*>* NativeObjectsExplorer::GetListMaybeDisposeInfo( | 2326 List<HeapObject*>* NativeObjectsExplorer::GetListMaybeDisposeInfo( |
2337 v8::RetainedObjectInfo* info) { | 2327 v8::RetainedObjectInfo* info) { |
2338 HashMap::Entry* entry = objects_by_info_.LookupOrInsert(info, InfoHash(info)); | 2328 base::HashMap::Entry* entry = |
| 2329 objects_by_info_.LookupOrInsert(info, InfoHash(info)); |
2339 if (entry->value != NULL) { | 2330 if (entry->value != NULL) { |
2340 info->Dispose(); | 2331 info->Dispose(); |
2341 } else { | 2332 } else { |
2342 entry->value = new List<HeapObject*>(4); | 2333 entry->value = new List<HeapObject*>(4); |
2343 } | 2334 } |
2344 return reinterpret_cast<List<HeapObject*>* >(entry->value); | 2335 return reinterpret_cast<List<HeapObject*>* >(entry->value); |
2345 } | 2336 } |
2346 | 2337 |
2347 | 2338 |
2348 bool NativeObjectsExplorer::IterateAndExtractReferences( | 2339 bool NativeObjectsExplorer::IterateAndExtractReferences( |
2349 SnapshotFiller* filler) { | 2340 SnapshotFiller* filler) { |
2350 filler_ = filler; | 2341 filler_ = filler; |
2351 FillRetainedObjects(); | 2342 FillRetainedObjects(); |
2352 FillImplicitReferences(); | 2343 FillImplicitReferences(); |
2353 if (EstimateObjectsCount() > 0) { | 2344 if (EstimateObjectsCount() > 0) { |
2354 for (HashMap::Entry* p = objects_by_info_.Start(); | 2345 for (base::HashMap::Entry* p = objects_by_info_.Start(); p != NULL; |
2355 p != NULL; | |
2356 p = objects_by_info_.Next(p)) { | 2346 p = objects_by_info_.Next(p)) { |
2357 v8::RetainedObjectInfo* info = | 2347 v8::RetainedObjectInfo* info = |
2358 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); | 2348 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); |
2359 SetNativeRootReference(info); | 2349 SetNativeRootReference(info); |
2360 List<HeapObject*>* objects = | 2350 List<HeapObject*>* objects = |
2361 reinterpret_cast<List<HeapObject*>* >(p->value); | 2351 reinterpret_cast<List<HeapObject*>* >(p->value); |
2362 for (int i = 0; i < objects->length(); ++i) { | 2352 for (int i = 0; i < objects->length(); ++i) { |
2363 SetWrapperNativeReferences(objects->at(i), info); | 2353 SetWrapperNativeReferences(objects->at(i), info); |
2364 } | 2354 } |
2365 } | 2355 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2397 }; | 2387 }; |
2398 | 2388 |
2399 | 2389 |
2400 NativeGroupRetainedObjectInfo* NativeObjectsExplorer::FindOrAddGroupInfo( | 2390 NativeGroupRetainedObjectInfo* NativeObjectsExplorer::FindOrAddGroupInfo( |
2401 const char* label) { | 2391 const char* label) { |
2402 const char* label_copy = names_->GetCopy(label); | 2392 const char* label_copy = names_->GetCopy(label); |
2403 uint32_t hash = StringHasher::HashSequentialString( | 2393 uint32_t hash = StringHasher::HashSequentialString( |
2404 label_copy, | 2394 label_copy, |
2405 static_cast<int>(strlen(label_copy)), | 2395 static_cast<int>(strlen(label_copy)), |
2406 isolate_->heap()->HashSeed()); | 2396 isolate_->heap()->HashSeed()); |
2407 HashMap::Entry* entry = | 2397 base::HashMap::Entry* entry = |
2408 native_groups_.LookupOrInsert(const_cast<char*>(label_copy), hash); | 2398 native_groups_.LookupOrInsert(const_cast<char*>(label_copy), hash); |
2409 if (entry->value == NULL) { | 2399 if (entry->value == NULL) { |
2410 entry->value = new NativeGroupRetainedObjectInfo(label); | 2400 entry->value = new NativeGroupRetainedObjectInfo(label); |
2411 } | 2401 } |
2412 return static_cast<NativeGroupRetainedObjectInfo*>(entry->value); | 2402 return static_cast<NativeGroupRetainedObjectInfo*>(entry->value); |
2413 } | 2403 } |
2414 | 2404 |
2415 | 2405 |
2416 void NativeObjectsExplorer::SetNativeRootReference( | 2406 void NativeObjectsExplorer::SetNativeRootReference( |
2417 v8::RetainedObjectInfo* info) { | 2407 v8::RetainedObjectInfo* info) { |
(...skipping 25 matching lines...) Expand all Loading... |
2443 wrapper_entry->index(), | 2433 wrapper_entry->index(), |
2444 "native", | 2434 "native", |
2445 info_entry); | 2435 info_entry); |
2446 filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, | 2436 filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, |
2447 info_entry->index(), | 2437 info_entry->index(), |
2448 wrapper_entry); | 2438 wrapper_entry); |
2449 } | 2439 } |
2450 | 2440 |
2451 | 2441 |
2452 void NativeObjectsExplorer::SetRootNativeRootsReference() { | 2442 void NativeObjectsExplorer::SetRootNativeRootsReference() { |
2453 for (HashMap::Entry* entry = native_groups_.Start(); | 2443 for (base::HashMap::Entry* entry = native_groups_.Start(); entry; |
2454 entry; | |
2455 entry = native_groups_.Next(entry)) { | 2444 entry = native_groups_.Next(entry)) { |
2456 NativeGroupRetainedObjectInfo* group_info = | 2445 NativeGroupRetainedObjectInfo* group_info = |
2457 static_cast<NativeGroupRetainedObjectInfo*>(entry->value); | 2446 static_cast<NativeGroupRetainedObjectInfo*>(entry->value); |
2458 HeapEntry* group_entry = | 2447 HeapEntry* group_entry = |
2459 filler_->FindOrAddEntry(group_info, native_entries_allocator_); | 2448 filler_->FindOrAddEntry(group_info, native_entries_allocator_); |
2460 DCHECK(group_entry != NULL); | 2449 DCHECK(group_entry != NULL); |
2461 filler_->SetIndexedAutoIndexReference( | 2450 filler_->SetIndexedAutoIndexReference( |
2462 HeapGraphEdge::kElement, | 2451 HeapGraphEdge::kElement, |
2463 snapshot_->root()->index(), | 2452 snapshot_->root()->index(), |
2464 group_entry); | 2453 group_entry); |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2712 writer_->AddString("\"strings\":["); | 2701 writer_->AddString("\"strings\":["); |
2713 SerializeStrings(); | 2702 SerializeStrings(); |
2714 if (writer_->aborted()) return; | 2703 if (writer_->aborted()) return; |
2715 writer_->AddCharacter(']'); | 2704 writer_->AddCharacter(']'); |
2716 writer_->AddCharacter('}'); | 2705 writer_->AddCharacter('}'); |
2717 writer_->Finalize(); | 2706 writer_->Finalize(); |
2718 } | 2707 } |
2719 | 2708 |
2720 | 2709 |
2721 int HeapSnapshotJSONSerializer::GetStringId(const char* s) { | 2710 int HeapSnapshotJSONSerializer::GetStringId(const char* s) { |
2722 HashMap::Entry* cache_entry = | 2711 base::HashMap::Entry* cache_entry = |
2723 strings_.LookupOrInsert(const_cast<char*>(s), StringHash(s)); | 2712 strings_.LookupOrInsert(const_cast<char*>(s), StringHash(s)); |
2724 if (cache_entry->value == NULL) { | 2713 if (cache_entry->value == NULL) { |
2725 cache_entry->value = reinterpret_cast<void*>(next_string_id_++); | 2714 cache_entry->value = reinterpret_cast<void*>(next_string_id_++); |
2726 } | 2715 } |
2727 return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value)); | 2716 return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value)); |
2728 } | 2717 } |
2729 | 2718 |
2730 | 2719 |
2731 namespace { | 2720 namespace { |
2732 | 2721 |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3097 } | 3086 } |
3098 } | 3087 } |
3099 } | 3088 } |
3100 writer_->AddCharacter('\"'); | 3089 writer_->AddCharacter('\"'); |
3101 } | 3090 } |
3102 | 3091 |
3103 | 3092 |
3104 void HeapSnapshotJSONSerializer::SerializeStrings() { | 3093 void HeapSnapshotJSONSerializer::SerializeStrings() { |
3105 ScopedVector<const unsigned char*> sorted_strings( | 3094 ScopedVector<const unsigned char*> sorted_strings( |
3106 strings_.occupancy() + 1); | 3095 strings_.occupancy() + 1); |
3107 for (HashMap::Entry* entry = strings_.Start(); | 3096 for (base::HashMap::Entry* entry = strings_.Start(); entry != NULL; |
3108 entry != NULL; | |
3109 entry = strings_.Next(entry)) { | 3097 entry = strings_.Next(entry)) { |
3110 int index = static_cast<int>(reinterpret_cast<uintptr_t>(entry->value)); | 3098 int index = static_cast<int>(reinterpret_cast<uintptr_t>(entry->value)); |
3111 sorted_strings[index] = reinterpret_cast<const unsigned char*>(entry->key); | 3099 sorted_strings[index] = reinterpret_cast<const unsigned char*>(entry->key); |
3112 } | 3100 } |
3113 writer_->AddString("\"<dummy>\""); | 3101 writer_->AddString("\"<dummy>\""); |
3114 for (int i = 1; i < sorted_strings.length(); ++i) { | 3102 for (int i = 1; i < sorted_strings.length(); ++i) { |
3115 writer_->AddCharacter(','); | 3103 writer_->AddCharacter(','); |
3116 SerializeString(sorted_strings[i]); | 3104 SerializeString(sorted_strings[i]); |
3117 if (writer_->aborted()) return; | 3105 if (writer_->aborted()) return; |
3118 } | 3106 } |
3119 } | 3107 } |
3120 | 3108 |
3121 | 3109 |
3122 } // namespace internal | 3110 } // namespace internal |
3123 } // namespace v8 | 3111 } // namespace v8 |
OLD | NEW |