Revision: 3124 Author: [email protected] Date: Mon Oct 26 03:51:30 2009 Log: Heap profiler improvements.
- account code objects in retainers profile; - differentiate between function boilerplates and closures; - simplify code; Review URL: http://codereview.chromium.org/335016 http://code.google.com/p/v8/source/detail?r=3124 Modified: /branches/bleeding_edge/src/heap-profiler.cc /branches/bleeding_edge/src/heap-profiler.h /branches/bleeding_edge/src/heap.h /branches/bleeding_edge/src/objects.cc ======================================= --- /branches/bleeding_edge/src/heap-profiler.cc Wed Oct 21 05:39:45 2009 +++ /branches/bleeding_edge/src/heap-profiler.cc Mon Oct 26 03:51:30 2009 @@ -78,6 +78,10 @@ } } else if (obj->IsString()) { return JSObjectsCluster(Heap::String_symbol()); + } else if (obj->IsJSGlobalPropertyCell()) { + return JSObjectsCluster(JSObjectsCluster::GLOBAL_PROPERTY); + } else if (obj->IsCode() || obj->IsSharedFunctionInfo() || obj->IsScript()) { + return JSObjectsCluster(JSObjectsCluster::CODE); } return JSObjectsCluster(); } @@ -112,6 +116,16 @@ if (FixedArray::cast(obj->elements())->length() != 0) { size += obj->elements()->Size(); } + // For functions, also account non-empty context and literals sizes. + if (obj->IsJSFunction()) { + JSFunction* f = JSFunction::cast(obj); + if (f->unchecked_context()->IsContext()) { + size += f->context()->Size(); + } + if (f->literals()->length() != 0) { + size += f->literals()->Size(); + } + } return size; } @@ -127,15 +141,15 @@ } void VisitPointer(Object** o) { - if ((*o)->IsJSObject() || (*o)->IsString()) { - profile_->StoreReference(cluster_, HeapObject::cast(*o)); - } else if ((*o)->IsFixedArray() && !inside_array_) { + if ((*o)->IsFixedArray() && !inside_array_) { // Traverse one level deep for data members that are fixed arrays. // This covers the case of 'elements' and 'properties' of JSObject, // and function contexts. inside_array_ = true; FixedArray::cast(*o)->Iterate(this); inside_array_ = false; + } else { + profile_->StoreReference(cluster_, HeapObject::cast(*o)); } } @@ -340,6 +354,8 @@ accumulator->Add("(roots)"); } else if (constructor_ == FromSpecialCase(GLOBAL_PROPERTY)) { accumulator->Add("(global property)"); + } else if (constructor_ == FromSpecialCase(CODE)) { + accumulator->Add("(code)"); } else if (constructor_ == FromSpecialCase(SELF)) { accumulator->Add("(self)"); } else { @@ -527,6 +543,7 @@ void RetainerHeapProfile::StoreReference(const JSObjectsCluster& cluster, HeapObject* ref) { JSObjectsCluster ref_cluster = Clusterizer::Clusterize(ref); + if (ref_cluster.is_null()) return; JSObjectsRetainerTree::Locator ref_loc; if (retainers_tree_.Insert(ref_cluster, &ref_loc)) { ref_loc.set_value(new JSObjectsClusterTree()); @@ -537,15 +554,10 @@ void RetainerHeapProfile::CollectStats(HeapObject* obj) { - if (obj->IsJSObject()) { - const JSObjectsCluster cluster = Clusterizer::Clusterize(obj); - ReferencesExtractor extractor(cluster, this); - obj->Iterate(&extractor); - } else if (obj->IsJSGlobalPropertyCell()) { - JSObjectsCluster global_prop(JSObjectsCluster::GLOBAL_PROPERTY); - ReferencesExtractor extractor(global_prop, this); - obj->Iterate(&extractor); - } + const JSObjectsCluster cluster = Clusterizer::Clusterize(obj); + if (cluster.is_null()) return; + ReferencesExtractor extractor(cluster, this); + obj->Iterate(&extractor); } ======================================= --- /branches/bleeding_edge/src/heap-profiler.h Thu Oct 15 00:50:23 2009 +++ /branches/bleeding_edge/src/heap-profiler.h Mon Oct 26 03:51:30 2009 @@ -54,7 +54,8 @@ enum SpecialCase { ROOTS = 1, GLOBAL_PROPERTY = 2, - SELF = 3 // This case is used in ClustersCoarser only. + CODE = 3, + SELF = 100 // This case is used in ClustersCoarser only. }; JSObjectsCluster() : constructor_(NULL), instance_(NULL) {} @@ -97,6 +98,7 @@ switch (special) { case ROOTS: return Heap::result_symbol(); case GLOBAL_PROPERTY: return Heap::code_symbol(); + case CODE: return Heap::arguments_shadow_symbol(); case SELF: return Heap::catch_var_symbol(); default: UNREACHABLE(); ======================================= --- /branches/bleeding_edge/src/heap.h Wed Oct 21 08:03:34 2009 +++ /branches/bleeding_edge/src/heap.h Mon Oct 26 03:51:30 2009 @@ -221,7 +221,8 @@ V(exec_symbol, "exec") \ V(zero_symbol, "0") \ V(global_eval_symbol, "GlobalEval") \ - V(identity_hash_symbol, "v8::IdentityHash") + V(identity_hash_symbol, "v8::IdentityHash") \ + V(closure_symbol, "(closure)") // Forward declaration of the GCTracer class. ======================================= --- /branches/bleeding_edge/src/objects.cc Fri Oct 23 02:19:17 2009 +++ /branches/bleeding_edge/src/objects.cc Mon Oct 26 03:51:30 2009 @@ -1251,7 +1251,8 @@ String* JSObject::constructor_name() { if (IsJSFunction()) { - return Heap::function_class_symbol(); + return JSFunction::cast(this)->IsBoilerplate() ? + Heap::function_class_symbol() : Heap::closure_symbol(); } if (map()->constructor()->IsJSFunction()) { JSFunction* constructor = JSFunction::cast(map()->constructor()); --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---
