diff options
Diffstat (limited to 'deps/v8/src/heap-profiler.h')
-rw-r--r-- | deps/v8/src/heap-profiler.h | 317 |
1 files changed, 19 insertions, 298 deletions
diff --git a/deps/v8/src/heap-profiler.h b/deps/v8/src/heap-profiler.h index 20ba457c5b..c32f4c425f 100644 --- a/deps/v8/src/heap-profiler.h +++ b/deps/v8/src/heap-profiler.h @@ -28,7 +28,7 @@ #ifndef V8_HEAP_PROFILER_H_ #define V8_HEAP_PROFILER_H_ -#include "zone-inl.h" +#include "isolate.h" namespace v8 { namespace internal { @@ -38,14 +38,15 @@ namespace internal { class HeapSnapshot; class HeapSnapshotsCollection; -#define HEAP_PROFILE(Call) \ - do { \ - if (v8::internal::HeapProfiler::is_profiling()) { \ - v8::internal::HeapProfiler::Call; \ - } \ +#define HEAP_PROFILE(heap, call) \ + do { \ + v8::internal::HeapProfiler* profiler = heap->isolate()->heap_profiler(); \ + if (profiler != NULL && profiler->is_profiling()) { \ + profiler->call; \ + } \ } while (false) #else -#define HEAP_PROFILE(Call) ((void) 0) +#define HEAP_PROFILE(heap, call) ((void) 0) #endif // ENABLE_LOGGING_AND_PROFILING // The HeapProfiler writes data to the log files, which can be postprocessed @@ -65,16 +66,18 @@ class HeapProfiler { static int GetSnapshotsCount(); static HeapSnapshot* GetSnapshot(int index); static HeapSnapshot* FindSnapshot(unsigned uid); + static void DeleteAllSnapshots(); - static void ObjectMoveEvent(Address from, Address to); + void ObjectMoveEvent(Address from, Address to); - static INLINE(bool is_profiling()) { - return singleton_ != NULL && singleton_->snapshots_->is_tracking_objects(); - } + void DefineWrapperClass( + uint16_t class_id, v8::HeapProfiler::WrapperInfoCallback callback); - // Obsolete interface. - // Write a single heap sample to the log file. - static void WriteSample(); + v8::RetainedObjectInfo* ExecuteWrapperClassCallback(uint16_t class_id, + Object** wrapper); + INLINE(bool is_profiling()) { + return snapshots_->is_tracking_objects(); + } private: HeapProfiler(); @@ -85,297 +88,15 @@ class HeapProfiler { HeapSnapshot* TakeSnapshotImpl(String* name, int type, v8::ActivityControl* control); + void ResetSnapshots(); HeapSnapshotsCollection* snapshots_; unsigned next_snapshot_uid_; + List<v8::HeapProfiler::WrapperInfoCallback> wrapper_callbacks_; - static HeapProfiler* singleton_; #endif // ENABLE_LOGGING_AND_PROFILING }; - -#ifdef ENABLE_LOGGING_AND_PROFILING - -// JSObjectsCluster describes a group of JS objects that are -// considered equivalent in terms of a particular profile. -class JSObjectsCluster BASE_EMBEDDED { - public: - // These special cases are used in retainer profile. - enum SpecialCase { - ROOTS = 1, - GLOBAL_PROPERTY = 2, - CODE = 3, - SELF = 100 // This case is used in ClustersCoarser only. - }; - - JSObjectsCluster() : constructor_(NULL), instance_(NULL) {} - explicit JSObjectsCluster(String* constructor) - : constructor_(constructor), instance_(NULL) {} - explicit JSObjectsCluster(SpecialCase special) - : constructor_(FromSpecialCase(special)), instance_(NULL) {} - JSObjectsCluster(String* constructor, Object* instance) - : constructor_(constructor), instance_(instance) {} - - static int CompareConstructors(const JSObjectsCluster& a, - const JSObjectsCluster& b) { - // Strings are unique, so it is sufficient to compare their pointers. - return a.constructor_ == b.constructor_ ? 0 - : (a.constructor_ < b.constructor_ ? -1 : 1); - } - static int Compare(const JSObjectsCluster& a, const JSObjectsCluster& b) { - // Strings are unique, so it is sufficient to compare their pointers. - const int cons_cmp = CompareConstructors(a, b); - return cons_cmp == 0 ? - (a.instance_ == b.instance_ ? 0 : (a.instance_ < b.instance_ ? -1 : 1)) - : cons_cmp; - } - static int Compare(const JSObjectsCluster* a, const JSObjectsCluster* b) { - return Compare(*a, *b); - } - - bool is_null() const { return constructor_ == NULL; } - bool can_be_coarsed() const { return instance_ != NULL; } - String* constructor() const { return constructor_; } - Object* instance() const { return instance_; } - - const char* GetSpecialCaseName() const; - void Print(StringStream* accumulator) const; - // Allows null clusters to be printed. - void DebugPrint(StringStream* accumulator) const; - - private: - static String* FromSpecialCase(SpecialCase special) { - // We use symbols that are illegal JS identifiers to identify special cases. - // Their actual value is irrelevant for us. - 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(); - return NULL; - } - } - - String* constructor_; - Object* instance_; -}; - - -struct JSObjectsClusterTreeConfig { - typedef JSObjectsCluster Key; - typedef NumberAndSizeInfo Value; - static const Key kNoKey; - static const Value kNoValue; - static int Compare(const Key& a, const Key& b) { - return Key::Compare(a, b); - } -}; -typedef ZoneSplayTree<JSObjectsClusterTreeConfig> JSObjectsClusterTree; - - -// ConstructorHeapProfile is responsible for gathering and logging -// "constructor profile" of JS objects allocated on heap. -// It is run during garbage collection cycle, thus it doesn't need -// to use handles. -class ConstructorHeapProfile BASE_EMBEDDED { - public: - ConstructorHeapProfile(); - virtual ~ConstructorHeapProfile() {} - void CollectStats(HeapObject* obj); - void PrintStats(); - - template<class Callback> - void ForEach(Callback* callback) { js_objects_info_tree_.ForEach(callback); } - // Used by ZoneSplayTree::ForEach. Made virtual to allow overriding in tests. - virtual void Call(const JSObjectsCluster& cluster, - const NumberAndSizeInfo& number_and_size); - - private: - ZoneScope zscope_; - JSObjectsClusterTree js_objects_info_tree_; -}; - - -// JSObjectsRetainerTree is used to represent retainer graphs using -// adjacency list form: -// -// Cluster -> (Cluster -> NumberAndSizeInfo) -// -// Subordinate splay trees are stored by pointer. They are zone-allocated, -// so it isn't needed to manage their lifetime. -// -struct JSObjectsRetainerTreeConfig { - typedef JSObjectsCluster Key; - typedef JSObjectsClusterTree* Value; - static const Key kNoKey; - static const Value kNoValue; - static int Compare(const Key& a, const Key& b) { - return Key::Compare(a, b); - } -}; -typedef ZoneSplayTree<JSObjectsRetainerTreeConfig> JSObjectsRetainerTree; - - -class ClustersCoarser BASE_EMBEDDED { - public: - ClustersCoarser(); - - // Processes a given retainer graph. - void Process(JSObjectsRetainerTree* tree); - - // Returns an equivalent cluster (can be the cluster itself). - // If the given cluster doesn't have an equivalent, returns null cluster. - JSObjectsCluster GetCoarseEquivalent(const JSObjectsCluster& cluster); - // Returns whether a cluster can be substitued with an equivalent and thus, - // skipped in some cases. - bool HasAnEquivalent(const JSObjectsCluster& cluster); - - // Used by JSObjectsRetainerTree::ForEach. - void Call(const JSObjectsCluster& cluster, JSObjectsClusterTree* tree); - void Call(const JSObjectsCluster& cluster, - const NumberAndSizeInfo& number_and_size); - - private: - // Stores a list of back references for a cluster. - struct ClusterBackRefs { - explicit ClusterBackRefs(const JSObjectsCluster& cluster_); - ClusterBackRefs(const ClusterBackRefs& src); - ClusterBackRefs& operator=(const ClusterBackRefs& src); - - static int Compare(const ClusterBackRefs& a, const ClusterBackRefs& b); - void SortRefs() { refs.Sort(JSObjectsCluster::Compare); } - static void SortRefsIterator(ClusterBackRefs* ref) { ref->SortRefs(); } - - JSObjectsCluster cluster; - ZoneList<JSObjectsCluster> refs; - }; - typedef ZoneList<ClusterBackRefs> SimilarityList; - - // A tree for storing a list of equivalents for a cluster. - struct ClusterEqualityConfig { - typedef JSObjectsCluster Key; - typedef JSObjectsCluster Value; - static const Key kNoKey; - static const Value kNoValue; - static int Compare(const Key& a, const Key& b) { - return Key::Compare(a, b); - } - }; - typedef ZoneSplayTree<ClusterEqualityConfig> EqualityTree; - - static int ClusterBackRefsCmp(const ClusterBackRefs* a, - const ClusterBackRefs* b) { - return ClusterBackRefs::Compare(*a, *b); - } - int DoProcess(JSObjectsRetainerTree* tree); - int FillEqualityTree(); - - static const int kInitialBackrefsListCapacity = 2; - static const int kInitialSimilarityListCapacity = 2000; - // Number of passes for finding equivalents. Limits the length of paths - // that can be considered equivalent. - static const int kMaxPassesCount = 10; - - ZoneScope zscope_; - SimilarityList sim_list_; - EqualityTree eq_tree_; - ClusterBackRefs* current_pair_; - JSObjectsRetainerTree* current_set_; - const JSObjectsCluster* self_; -}; - - -// RetainerHeapProfile is responsible for gathering and logging -// "retainer profile" of JS objects allocated on heap. -// It is run during garbage collection cycle, thus it doesn't need -// to use handles. -class RetainerTreeAggregator; - -class RetainerHeapProfile BASE_EMBEDDED { - public: - class Printer { - public: - virtual ~Printer() {} - virtual void PrintRetainers(const JSObjectsCluster& cluster, - const StringStream& retainers) = 0; - }; - - RetainerHeapProfile(); - ~RetainerHeapProfile(); - - RetainerTreeAggregator* aggregator() { return aggregator_; } - ClustersCoarser* coarser() { return &coarser_; } - JSObjectsRetainerTree* retainers_tree() { return &retainers_tree_; } - - void CollectStats(HeapObject* obj); - void CoarseAndAggregate(); - void PrintStats(); - void DebugPrintStats(Printer* printer); - void StoreReference(const JSObjectsCluster& cluster, HeapObject* ref); - - private: - ZoneScope zscope_; - JSObjectsRetainerTree retainers_tree_; - ClustersCoarser coarser_; - RetainerTreeAggregator* aggregator_; -}; - - -class AggregatedHeapSnapshot { - public: - AggregatedHeapSnapshot(); - ~AggregatedHeapSnapshot(); - - HistogramInfo* info() { return info_; } - ConstructorHeapProfile* js_cons_profile() { return &js_cons_profile_; } - RetainerHeapProfile* js_retainer_profile() { return &js_retainer_profile_; } - - private: - HistogramInfo* info_; - ConstructorHeapProfile js_cons_profile_; - RetainerHeapProfile js_retainer_profile_; -}; - - -class HeapEntriesMap; -class HeapEntriesAllocator; -class HeapSnapshot; - -class AggregatedHeapSnapshotGenerator { - public: - explicit AggregatedHeapSnapshotGenerator(AggregatedHeapSnapshot* snapshot); - void GenerateSnapshot(); - void FillHeapSnapshot(HeapSnapshot* snapshot); - - static const int kAllStringsType = LAST_TYPE + 1; - - private: - void CalculateStringsStats(); - void CollectStats(HeapObject* obj); - template<class Iterator> - void IterateRetainers( - HeapEntriesAllocator* allocator, HeapEntriesMap* entries_map); - - AggregatedHeapSnapshot* agg_snapshot_; -}; - - -class ProducerHeapProfile : public AllStatic { - public: - static void Setup(); - static void RecordJSObjectAllocation(Object* obj) { - if (FLAG_log_producers) DoRecordJSObjectAllocation(obj); - } - - private: - static void DoRecordJSObjectAllocation(Object* obj); - static bool can_log_; -}; - -#endif // ENABLE_LOGGING_AND_PROFILING - } } // namespace v8::internal #endif // V8_HEAP_PROFILER_H_ |