| 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 |