Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(310)

Side by Side Diff: src/heap-profiler.cc

Issue 335016: Heap profiler improvements. (Closed)
Patch Set: Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 String* constructor = JSObject::cast(js_obj)->constructor_name(); 71 String* constructor = JSObject::cast(js_obj)->constructor_name();
72 // Differentiate Object and Array instances. 72 // Differentiate Object and Array instances.
73 if (fine_grain && (constructor == Heap::Object_symbol() || 73 if (fine_grain && (constructor == Heap::Object_symbol() ||
74 constructor == Heap::Array_symbol())) { 74 constructor == Heap::Array_symbol())) {
75 return JSObjectsCluster(constructor, obj); 75 return JSObjectsCluster(constructor, obj);
76 } else { 76 } else {
77 return JSObjectsCluster(constructor); 77 return JSObjectsCluster(constructor);
78 } 78 }
79 } else if (obj->IsString()) { 79 } else if (obj->IsString()) {
80 return JSObjectsCluster(Heap::String_symbol()); 80 return JSObjectsCluster(Heap::String_symbol());
81 } else if (obj->IsJSGlobalPropertyCell()) {
82 return JSObjectsCluster(JSObjectsCluster::GLOBAL_PROPERTY);
83 } else if (obj->IsCode() || obj->IsSharedFunctionInfo() || obj->IsScript()) {
84 return JSObjectsCluster(JSObjectsCluster::CODE);
81 } 85 }
82 return JSObjectsCluster(); 86 return JSObjectsCluster();
83 } 87 }
84 88
85 89
86 void Clusterizer::InsertIntoTree(JSObjectsClusterTree* tree, 90 void Clusterizer::InsertIntoTree(JSObjectsClusterTree* tree,
87 HeapObject* obj, bool fine_grain) { 91 HeapObject* obj, bool fine_grain) {
88 JSObjectsCluster cluster = Clusterize(obj, fine_grain); 92 JSObjectsCluster cluster = Clusterize(obj, fine_grain);
89 if (cluster.is_null()) return; 93 if (cluster.is_null()) return;
90 InsertIntoTree(tree, cluster, GetObjectSize(obj)); 94 InsertIntoTree(tree, cluster, GetObjectSize(obj));
(...skipping 14 matching lines...) Expand all
105 int Clusterizer::CalculateNetworkSize(JSObject* obj) { 109 int Clusterizer::CalculateNetworkSize(JSObject* obj) {
106 int size = obj->Size(); 110 int size = obj->Size();
107 // If 'properties' and 'elements' are non-empty (thus, non-shared), 111 // If 'properties' and 'elements' are non-empty (thus, non-shared),
108 // take their size into account. 112 // take their size into account.
109 if (FixedArray::cast(obj->properties())->length() != 0) { 113 if (FixedArray::cast(obj->properties())->length() != 0) {
110 size += obj->properties()->Size(); 114 size += obj->properties()->Size();
111 } 115 }
112 if (FixedArray::cast(obj->elements())->length() != 0) { 116 if (FixedArray::cast(obj->elements())->length() != 0) {
113 size += obj->elements()->Size(); 117 size += obj->elements()->Size();
114 } 118 }
119 // For functions, also account non-empty context and literals sizes.
120 if (obj->IsJSFunction()) {
121 JSFunction* f = JSFunction::cast(obj);
122 if (f->unchecked_context()->IsContext()) {
123 size += f->context()->Size();
124 }
125 if (f->literals()->length() != 0) {
126 size += f->literals()->Size();
127 }
128 }
115 return size; 129 return size;
116 } 130 }
117 131
118 132
119 // A helper class for recording back references. 133 // A helper class for recording back references.
120 class ReferencesExtractor : public ObjectVisitor { 134 class ReferencesExtractor : public ObjectVisitor {
121 public: 135 public:
122 ReferencesExtractor(const JSObjectsCluster& cluster, 136 ReferencesExtractor(const JSObjectsCluster& cluster,
123 RetainerHeapProfile* profile) 137 RetainerHeapProfile* profile)
124 : cluster_(cluster), 138 : cluster_(cluster),
125 profile_(profile), 139 profile_(profile),
126 inside_array_(false) { 140 inside_array_(false) {
127 } 141 }
128 142
129 void VisitPointer(Object** o) { 143 void VisitPointer(Object** o) {
130 if ((*o)->IsJSObject() || (*o)->IsString()) { 144 if ((*o)->IsFixedArray() && !inside_array_) {
131 profile_->StoreReference(cluster_, HeapObject::cast(*o));
132 } else if ((*o)->IsFixedArray() && !inside_array_) {
133 // Traverse one level deep for data members that are fixed arrays. 145 // Traverse one level deep for data members that are fixed arrays.
134 // This covers the case of 'elements' and 'properties' of JSObject, 146 // This covers the case of 'elements' and 'properties' of JSObject,
135 // and function contexts. 147 // and function contexts.
136 inside_array_ = true; 148 inside_array_ = true;
137 FixedArray::cast(*o)->Iterate(this); 149 FixedArray::cast(*o)->Iterate(this);
138 inside_array_ = false; 150 inside_array_ = false;
151 } else {
152 profile_->StoreReference(cluster_, HeapObject::cast(*o));
139 } 153 }
140 } 154 }
141 155
142 void VisitPointers(Object** start, Object** end) { 156 void VisitPointers(Object** start, Object** end) {
143 for (Object** p = start; p < end; p++) VisitPointer(p); 157 for (Object** p = start; p < end; p++) VisitPointer(p);
144 } 158 }
145 159
146 private: 160 private:
147 const JSObjectsCluster& cluster_; 161 const JSObjectsCluster& cluster_;
148 RetainerHeapProfile* profile_; 162 RetainerHeapProfile* profile_;
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 return name[0] != '\0' ? name : "(anonymous)"; 347 return name[0] != '\0' ? name : "(anonymous)";
334 } 348 }
335 349
336 350
337 void JSObjectsCluster::Print(StringStream* accumulator) const { 351 void JSObjectsCluster::Print(StringStream* accumulator) const {
338 ASSERT(!is_null()); 352 ASSERT(!is_null());
339 if (constructor_ == FromSpecialCase(ROOTS)) { 353 if (constructor_ == FromSpecialCase(ROOTS)) {
340 accumulator->Add("(roots)"); 354 accumulator->Add("(roots)");
341 } else if (constructor_ == FromSpecialCase(GLOBAL_PROPERTY)) { 355 } else if (constructor_ == FromSpecialCase(GLOBAL_PROPERTY)) {
342 accumulator->Add("(global property)"); 356 accumulator->Add("(global property)");
357 } else if (constructor_ == FromSpecialCase(CODE)) {
358 accumulator->Add("(code)");
343 } else if (constructor_ == FromSpecialCase(SELF)) { 359 } else if (constructor_ == FromSpecialCase(SELF)) {
344 accumulator->Add("(self)"); 360 accumulator->Add("(self)");
345 } else { 361 } else {
346 SmartPointer<char> s_name( 362 SmartPointer<char> s_name(
347 constructor_->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)); 363 constructor_->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL));
348 accumulator->Add("%s", GetConstructorName(*s_name)); 364 accumulator->Add("%s", GetConstructorName(*s_name));
349 if (instance_ != NULL) { 365 if (instance_ != NULL) {
350 accumulator->Add(":%p", static_cast<void*>(instance_)); 366 accumulator->Add(":%p", static_cast<void*>(instance_));
351 } 367 }
352 } 368 }
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 : zscope_(DELETE_ON_EXIT) { 536 : zscope_(DELETE_ON_EXIT) {
521 JSObjectsCluster roots(JSObjectsCluster::ROOTS); 537 JSObjectsCluster roots(JSObjectsCluster::ROOTS);
522 ReferencesExtractor extractor(roots, this); 538 ReferencesExtractor extractor(roots, this);
523 Heap::IterateRoots(&extractor); 539 Heap::IterateRoots(&extractor);
524 } 540 }
525 541
526 542
527 void RetainerHeapProfile::StoreReference(const JSObjectsCluster& cluster, 543 void RetainerHeapProfile::StoreReference(const JSObjectsCluster& cluster,
528 HeapObject* ref) { 544 HeapObject* ref) {
529 JSObjectsCluster ref_cluster = Clusterizer::Clusterize(ref); 545 JSObjectsCluster ref_cluster = Clusterizer::Clusterize(ref);
546 if (ref_cluster.is_null()) return;
530 JSObjectsRetainerTree::Locator ref_loc; 547 JSObjectsRetainerTree::Locator ref_loc;
531 if (retainers_tree_.Insert(ref_cluster, &ref_loc)) { 548 if (retainers_tree_.Insert(ref_cluster, &ref_loc)) {
532 ref_loc.set_value(new JSObjectsClusterTree()); 549 ref_loc.set_value(new JSObjectsClusterTree());
533 } 550 }
534 JSObjectsClusterTree* referenced_by = ref_loc.value(); 551 JSObjectsClusterTree* referenced_by = ref_loc.value();
535 Clusterizer::InsertReferenceIntoTree(referenced_by, cluster); 552 Clusterizer::InsertReferenceIntoTree(referenced_by, cluster);
536 } 553 }
537 554
538 555
539 void RetainerHeapProfile::CollectStats(HeapObject* obj) { 556 void RetainerHeapProfile::CollectStats(HeapObject* obj) {
540 if (obj->IsJSObject()) { 557 const JSObjectsCluster cluster = Clusterizer::Clusterize(obj);
541 const JSObjectsCluster cluster = Clusterizer::Clusterize(obj); 558 if (cluster.is_null()) return;
542 ReferencesExtractor extractor(cluster, this); 559 ReferencesExtractor extractor(cluster, this);
543 obj->Iterate(&extractor); 560 obj->Iterate(&extractor);
544 } else if (obj->IsJSGlobalPropertyCell()) {
545 JSObjectsCluster global_prop(JSObjectsCluster::GLOBAL_PROPERTY);
546 ReferencesExtractor extractor(global_prop, this);
547 obj->Iterate(&extractor);
548 }
549 } 561 }
550 562
551 563
552 void RetainerHeapProfile::DebugPrintStats( 564 void RetainerHeapProfile::DebugPrintStats(
553 RetainerHeapProfile::Printer* printer) { 565 RetainerHeapProfile::Printer* printer) {
554 coarser_.Process(&retainers_tree_); 566 coarser_.Process(&retainers_tree_);
555 // Print clusters that have no equivalents, aggregating their retainers. 567 // Print clusters that have no equivalents, aggregating their retainers.
556 AggregatingRetainerTreePrinter agg_printer(&coarser_, printer); 568 AggregatingRetainerTreePrinter agg_printer(&coarser_, printer);
557 retainers_tree_.ForEach(&agg_printer); 569 retainers_tree_.ForEach(&agg_printer);
558 // Now aggregate clusters that have equivalents... 570 // Now aggregate clusters that have equivalents...
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 GlobalHandles::MakeWeak(handle.location(), 685 GlobalHandles::MakeWeak(handle.location(),
674 static_cast<void*>(stack.start()), 686 static_cast<void*>(stack.start()),
675 StackWeakReferenceCallback); 687 StackWeakReferenceCallback);
676 } 688 }
677 689
678 690
679 #endif // ENABLE_LOGGING_AND_PROFILING 691 #endif // ENABLE_LOGGING_AND_PROFILING
680 692
681 693
682 } } // namespace v8::internal 694 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap-profiler.h ('k') | src/objects.cc » ('j') | src/objects.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698