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 <utility> |
| 8 |
7 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
8 #include "src/conversions.h" | 10 #include "src/conversions.h" |
9 #include "src/debug/debug.h" | 11 #include "src/debug/debug.h" |
10 #include "src/objects-body-descriptors.h" | 12 #include "src/objects-body-descriptors.h" |
11 #include "src/profiler/allocation-tracker.h" | 13 #include "src/profiler/allocation-tracker.h" |
12 #include "src/profiler/heap-profiler.h" | 14 #include "src/profiler/heap-profiler.h" |
13 #include "src/profiler/heap-snapshot-generator-inl.h" | 15 #include "src/profiler/heap-snapshot-generator-inl.h" |
14 | 16 |
15 namespace v8 { | 17 namespace v8 { |
16 namespace internal { | 18 namespace internal { |
(...skipping 2263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2280 | 2282 |
2281 | 2283 |
2282 int NativeObjectsExplorer::EstimateObjectsCount() { | 2284 int NativeObjectsExplorer::EstimateObjectsCount() { |
2283 FillRetainedObjects(); | 2285 FillRetainedObjects(); |
2284 return objects_by_info_.occupancy(); | 2286 return objects_by_info_.occupancy(); |
2285 } | 2287 } |
2286 | 2288 |
2287 | 2289 |
2288 void NativeObjectsExplorer::FillRetainedObjects() { | 2290 void NativeObjectsExplorer::FillRetainedObjects() { |
2289 if (embedder_queried_) return; | 2291 if (embedder_queried_) return; |
2290 Isolate* isolate = isolate_; | 2292 v8::HandleScope scope(reinterpret_cast<v8::Isolate*>(isolate_)); |
2291 const GCType major_gc_type = kGCTypeMarkSweepCompact; | 2293 v8::HeapProfiler::RetainerInfos infos = |
2292 // Record objects that are joined into ObjectGroups. | 2294 snapshot_->profiler()->GetRetainerInfos(isolate_); |
2293 isolate->heap()->CallGCPrologueCallbacks( | 2295 for (auto& pair : infos.groups) { |
2294 major_gc_type, kGCCallbackFlagConstructRetainedObjectInfos); | 2296 List<HeapObject*>* list = GetListMaybeDisposeInfo(pair.first); |
2295 List<ObjectGroup*>* groups = isolate->global_handles()->object_groups(); | 2297 for (auto& persistent : pair.second) { |
2296 for (int i = 0; i < groups->length(); ++i) { | 2298 if (persistent->IsEmpty()) continue; |
2297 ObjectGroup* group = groups->at(i); | 2299 |
2298 if (group->info == NULL) continue; | 2300 Handle<Object> object = v8::Utils::OpenHandle( |
2299 List<HeapObject*>* list = GetListMaybeDisposeInfo(group->info); | 2301 *persistent->Get(reinterpret_cast<v8::Isolate*>(isolate_))); |
2300 for (size_t j = 0; j < group->length; ++j) { | 2302 DCHECK(!object.is_null()); |
2301 HeapObject* obj = HeapObject::cast(*group->objects[j]); | 2303 HeapObject* heap_object = HeapObject::cast(*object); |
2302 list->Add(obj); | 2304 list->Add(heap_object); |
2303 in_groups_.Insert(obj); | 2305 in_groups_.Insert(heap_object); |
2304 } | 2306 } |
2305 group->info = NULL; // Acquire info object ownership. | |
2306 } | 2307 } |
2307 isolate->global_handles()->RemoveObjectGroups(); | 2308 |
2308 isolate->heap()->CallGCEpilogueCallbacks(major_gc_type, kNoGCCallbackFlags); | |
2309 // Record objects that are not in ObjectGroups, but have class ID. | 2309 // Record objects that are not in ObjectGroups, but have class ID. |
2310 GlobalHandlesExtractor extractor(this); | 2310 GlobalHandlesExtractor extractor(this); |
2311 isolate->global_handles()->IterateAllRootsWithClassIds(&extractor); | 2311 isolate_->global_handles()->IterateAllRootsWithClassIds(&extractor); |
| 2312 |
| 2313 edges_ = std::move(infos.edges); |
2312 embedder_queried_ = true; | 2314 embedder_queried_ = true; |
2313 } | 2315 } |
2314 | 2316 |
| 2317 void NativeObjectsExplorer::FillEdges() { |
| 2318 v8::HandleScope scope(reinterpret_cast<v8::Isolate*>(isolate_)); |
| 2319 // Fill in actual edges found. |
| 2320 for (auto& pair : edges_) { |
| 2321 if (pair.first->IsEmpty() || pair.second->IsEmpty()) continue; |
2315 | 2322 |
2316 void NativeObjectsExplorer::FillImplicitReferences() { | 2323 Handle<Object> parent_object = v8::Utils::OpenHandle( |
2317 Isolate* isolate = isolate_; | 2324 *pair.first->Get(reinterpret_cast<v8::Isolate*>(isolate_))); |
2318 List<ImplicitRefGroup*>* groups = | 2325 HeapObject* parent = HeapObject::cast(*parent_object); |
2319 isolate->global_handles()->implicit_ref_groups(); | |
2320 for (int i = 0; i < groups->length(); ++i) { | |
2321 ImplicitRefGroup* group = groups->at(i); | |
2322 HeapObject* parent = *group->parent; | |
2323 int parent_entry = | 2326 int parent_entry = |
2324 filler_->FindOrAddEntry(parent, native_entries_allocator_)->index(); | 2327 filler_->FindOrAddEntry(parent, native_entries_allocator_)->index(); |
2325 DCHECK(parent_entry != HeapEntry::kNoEntry); | 2328 DCHECK(parent_entry != HeapEntry::kNoEntry); |
2326 Object*** children = group->children; | 2329 Handle<Object> child_object = v8::Utils::OpenHandle( |
2327 for (size_t j = 0; j < group->length; ++j) { | 2330 *pair.second->Get(reinterpret_cast<v8::Isolate*>(isolate_))); |
2328 Object* child = *children[j]; | 2331 HeapObject* child = HeapObject::cast(*child_object); |
2329 HeapEntry* child_entry = | 2332 HeapEntry* child_entry = |
2330 filler_->FindOrAddEntry(child, native_entries_allocator_); | 2333 filler_->FindOrAddEntry(child, native_entries_allocator_); |
2331 filler_->SetNamedReference( | 2334 filler_->SetNamedReference(HeapGraphEdge::kInternal, parent_entry, "native", |
2332 HeapGraphEdge::kInternal, | 2335 child_entry); |
2333 parent_entry, | |
2334 "native", | |
2335 child_entry); | |
2336 } | |
2337 } | 2336 } |
2338 isolate->global_handles()->RemoveImplicitRefGroups(); | 2337 edges_.clear(); |
2339 } | 2338 } |
2340 | 2339 |
2341 List<HeapObject*>* NativeObjectsExplorer::GetListMaybeDisposeInfo( | 2340 List<HeapObject*>* NativeObjectsExplorer::GetListMaybeDisposeInfo( |
2342 v8::RetainedObjectInfo* info) { | 2341 v8::RetainedObjectInfo* info) { |
2343 base::HashMap::Entry* entry = | 2342 base::HashMap::Entry* entry = |
2344 objects_by_info_.LookupOrInsert(info, InfoHash(info)); | 2343 objects_by_info_.LookupOrInsert(info, InfoHash(info)); |
2345 if (entry->value != NULL) { | 2344 if (entry->value != NULL) { |
2346 info->Dispose(); | 2345 info->Dispose(); |
2347 } else { | 2346 } else { |
2348 entry->value = new List<HeapObject*>(4); | 2347 entry->value = new List<HeapObject*>(4); |
2349 } | 2348 } |
2350 return reinterpret_cast<List<HeapObject*>* >(entry->value); | 2349 return reinterpret_cast<List<HeapObject*>* >(entry->value); |
2351 } | 2350 } |
2352 | 2351 |
2353 | 2352 |
2354 bool NativeObjectsExplorer::IterateAndExtractReferences( | 2353 bool NativeObjectsExplorer::IterateAndExtractReferences( |
2355 SnapshotFiller* filler) { | 2354 SnapshotFiller* filler) { |
2356 filler_ = filler; | 2355 filler_ = filler; |
2357 FillRetainedObjects(); | 2356 FillRetainedObjects(); |
2358 FillImplicitReferences(); | 2357 FillEdges(); |
2359 if (EstimateObjectsCount() > 0) { | 2358 if (EstimateObjectsCount() > 0) { |
2360 for (base::HashMap::Entry* p = objects_by_info_.Start(); p != NULL; | 2359 for (base::HashMap::Entry* p = objects_by_info_.Start(); p != NULL; |
2361 p = objects_by_info_.Next(p)) { | 2360 p = objects_by_info_.Next(p)) { |
2362 v8::RetainedObjectInfo* info = | 2361 v8::RetainedObjectInfo* info = |
2363 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); | 2362 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); |
2364 SetNativeRootReference(info); | 2363 SetNativeRootReference(info); |
2365 List<HeapObject*>* objects = | 2364 List<HeapObject*>* objects = |
2366 reinterpret_cast<List<HeapObject*>* >(p->value); | 2365 reinterpret_cast<List<HeapObject*>* >(p->value); |
2367 for (int i = 0; i < objects->length(); ++i) { | 2366 for (int i = 0; i < objects->length(); ++i) { |
2368 SetWrapperNativeReferences(objects->at(i), info); | 2367 SetWrapperNativeReferences(objects->at(i), info); |
(...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3115 for (int i = 1; i < sorted_strings.length(); ++i) { | 3114 for (int i = 1; i < sorted_strings.length(); ++i) { |
3116 writer_->AddCharacter(','); | 3115 writer_->AddCharacter(','); |
3117 SerializeString(sorted_strings[i]); | 3116 SerializeString(sorted_strings[i]); |
3118 if (writer_->aborted()) return; | 3117 if (writer_->aborted()) return; |
3119 } | 3118 } |
3120 } | 3119 } |
3121 | 3120 |
3122 | 3121 |
3123 } // namespace internal | 3122 } // namespace internal |
3124 } // namespace v8 | 3123 } // namespace v8 |
OLD | NEW |