Index: src/heap.cc |
diff --git a/src/heap.cc b/src/heap.cc |
index 949dd80c3b9a28e1eed25ca1db1a95ae657ddf91..01dc1e78982963025b6c826c5aff03b319e335d5 100644 |
--- a/src/heap.cc |
+++ b/src/heap.cc |
@@ -33,6 +33,7 @@ |
#include "codegen-inl.h" |
#include "compilation-cache.h" |
#include "debug.h" |
+#include "heap-profiler.h" |
#include "global-handles.h" |
#include "mark-compact.h" |
#include "natives.h" |
@@ -3544,164 +3545,6 @@ 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(HeapObject* 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) { |
- ASSERT(name != NULL); |
- SmartPointer<char> s_name( |
- name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)); |
- LOG(HeapSampleJSConstructorEvent(*s_name, |
- number_and_size.number(), |
- number_and_size.bytes())); |
-} |
- |
- |
-void JSConstructorProfile::CollectStats(HeapObject* obj) { |
- String* constructor = NULL; |
- int size; |
- if (obj->IsString()) { |
- constructor = Heap::String_symbol(); |
- size = obj->Size(); |
- } else if (obj->IsJSObject()) { |
- JSObject* js_obj = JSObject::cast(obj); |
- constructor = js_obj->constructor_name(); |
- size = CalculateJSObjectNetworkSize(js_obj); |
- } else { |
- return; |
- } |
- |
- JSObjectsInfoTree::Locator loc; |
- if (!js_objects_info_tree_.Find(constructor, &loc)) { |
- js_objects_info_tree_.Insert(constructor, &loc); |
- } |
- NumberAndSizeInfo number_and_size = loc.value(); |
- number_and_size.increment_number(1); |
- number_and_size.increment_bytes(size); |
- loc.set_value(number_and_size); |
-} |
- |
- |
-void JSConstructorProfile::PrintStats() { |
- js_objects_info_tree_.ForEach(this); |
-} |
- |
-} // namespace |
-#endif |
- |
- |
-// |
-// HeapProfiler class implementation. |
-// |
-#ifdef ENABLE_LOGGING_AND_PROFILING |
-void HeapProfiler::CollectStats(HeapObject* obj, HistogramInfo* info) { |
- InstanceType type = obj->map()->instance_type(); |
- ASSERT(0 <= type && type <= LAST_TYPE); |
- info[type].increment_number(1); |
- info[type].increment_bytes(obj->Size()); |
-} |
-#endif |
- |
- |
-#ifdef ENABLE_LOGGING_AND_PROFILING |
-void HeapProfiler::WriteSample() { |
- LOG(HeapSampleBeginEvent("Heap", "allocated")); |
- LOG(HeapSampleStats( |
- "Heap", "allocated", Heap::Capacity(), Heap::SizeOfObjects())); |
- |
- HistogramInfo info[LAST_TYPE+1]; |
-#define DEF_TYPE_NAME(name) info[name].set_name(#name); |
- INSTANCE_TYPE_LIST(DEF_TYPE_NAME) |
-#undef DEF_TYPE_NAME |
- |
- JSConstructorProfile js_cons_profile; |
- HeapIterator iterator; |
- while (iterator.has_next()) { |
- HeapObject* obj = iterator.next(); |
- CollectStats(obj, info); |
- js_cons_profile.CollectStats(obj); |
- } |
- |
- // Lump all the string types together. |
- int string_number = 0; |
- int string_bytes = 0; |
-#define INCREMENT_SIZE(type, size, name, camel_name) \ |
- string_number += info[type].number(); \ |
- string_bytes += info[type].bytes(); |
- STRING_TYPE_LIST(INCREMENT_SIZE) |
-#undef INCREMENT_SIZE |
- if (string_bytes > 0) { |
- LOG(HeapSampleItemEvent("STRING_TYPE", string_number, string_bytes)); |
- } |
- |
- for (int i = FIRST_NONSTRING_TYPE; i <= LAST_TYPE; ++i) { |
- if (info[i].bytes() > 0) { |
- LOG(HeapSampleItemEvent(info[i].name(), info[i].number(), |
- info[i].bytes())); |
- } |
- } |
- |
- js_cons_profile.PrintStats(); |
- |
- LOG(HeapSampleEndEvent("Heap", "allocated")); |
-} |
- |
- |
-#endif |
- |
- |
- |
#ifdef DEBUG |
static bool search_for_any_global; |