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

Unified Diff: src/heap.cc

Issue 159504: Introduce first approximation of constructor heap profile for JS objects. (Closed)
Patch Set: Soeren's comments applied Created 11 years, 5 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/jsregexp.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap.cc
diff --git a/src/heap.cc b/src/heap.cc
index 233f02f8a3daebb51467811fa4eb1823f4bc56a1..feb01202b64b4886d163d344bf38e175b1243198 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -3411,6 +3411,100 @@ void HeapIterator::reset() {
}
+#ifdef ENABLE_LOGGING_AND_PROFILING
+namespace {
+
+// JSConstructorProfile is responsible for gathering and logging
+// "constructor profile" of JS object allocated on heap.
+// It is run during garbage collection cycle, thus it doesn't need
+// to use handles.
+class JSConstructorProfile BASE_EMBEDDED {
+ public:
+ JSConstructorProfile() : zscope_(DELETE_ON_EXIT) {}
+ void CollectStats(JSObject* obj);
+ void PrintStats();
+ // Used by ZoneSplayTree::ForEach.
+ void Call(String* name, const NumberAndSizeInfo& number_and_size);
+ private:
+ struct TreeConfig {
+ typedef String* Key;
+ typedef NumberAndSizeInfo Value;
+ static const Key kNoKey;
+ static const Value kNoValue;
+ // Strings are unique, so it is sufficient to compare their pointers.
+ static int Compare(const Key& a, const Key& b) {
+ return a == b ? 0 : (a < b ? -1 : 1);
+ }
+ };
+
+ typedef ZoneSplayTree<TreeConfig> JSObjectsInfoTree;
+ static int CalculateJSObjectNetworkSize(JSObject* obj);
+
+ ZoneScope zscope_;
+ JSObjectsInfoTree js_objects_info_tree_;
+};
+
+const JSConstructorProfile::TreeConfig::Key
+ JSConstructorProfile::TreeConfig::kNoKey = NULL;
+const JSConstructorProfile::TreeConfig::Value
+ JSConstructorProfile::TreeConfig::kNoValue;
+
+
+int JSConstructorProfile::CalculateJSObjectNetworkSize(JSObject* obj) {
+ int size = obj->Size();
+ // If 'properties' and 'elements' are non-empty (thus, non-shared),
+ // take their size into account.
+ if (FixedArray::cast(obj->properties())->length() != 0) {
+ size += obj->properties()->Size();
+ }
+ if (FixedArray::cast(obj->elements())->length() != 0) {
+ size += obj->elements()->Size();
+ }
+ return size;
+}
+
+
+void JSConstructorProfile::Call(String* name,
+ const NumberAndSizeInfo& number_and_size) {
+ SmartPointer<char> s_name;
+ if (name != NULL) {
+ s_name = name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
+ }
+ LOG(HeapSampleJSConstructorEvent(*s_name,
+ number_and_size.number(),
+ number_and_size.bytes()));
+}
+
+
+void JSConstructorProfile::CollectStats(JSObject* obj) {
+ String* constructor_func = NULL;
+ if (obj->map()->constructor()->IsJSFunction()) {
+ JSFunction* constructor = JSFunction::cast(obj->map()->constructor());
+ SharedFunctionInfo* sfi = constructor->shared();
+ String* name = String::cast(sfi->name());
+ constructor_func = name->length() > 0 ? name : sfi->inferred_name();
+ } else if (obj->IsJSFunction()) {
+ constructor_func = Heap::function_class_symbol();
+ }
+ JSObjectsInfoTree::Locator loc;
+ if (!js_objects_info_tree_.Find(constructor_func, &loc)) {
+ js_objects_info_tree_.Insert(constructor_func, &loc);
+ }
+ NumberAndSizeInfo number_and_size = loc.value();
+ number_and_size.increment_number(1);
+ number_and_size.increment_bytes(CalculateJSObjectNetworkSize(obj));
+ loc.set_value(number_and_size);
+}
+
+
+void JSConstructorProfile::PrintStats() {
+ js_objects_info_tree_.ForEach(this);
+}
+
+} // namespace
+#endif
+
+
//
// HeapProfiler class implementation.
//
@@ -3435,9 +3529,14 @@ void HeapProfiler::WriteSample() {
INSTANCE_TYPE_LIST(DEF_TYPE_NAME)
#undef DEF_TYPE_NAME
+ JSConstructorProfile js_cons_profile;
HeapIterator iterator;
while (iterator.has_next()) {
- CollectStats(iterator.next(), info);
+ HeapObject* obj = iterator.next();
+ CollectStats(obj, info);
+ if (obj->IsJSObject()) {
+ js_cons_profile.CollectStats(JSObject::cast(obj));
+ }
}
// Lump all the string types together.
@@ -3459,6 +3558,8 @@ void HeapProfiler::WriteSample() {
}
}
+ js_cons_profile.PrintStats();
+
LOG(HeapSampleEndEvent("Heap", "allocated"));
}
« no previous file with comments | « no previous file | src/jsregexp.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698