| Index: src/heap-profiler.h
|
| diff --git a/src/heap-profiler.h b/src/heap-profiler.h
|
| index 858c5f2f6733d6bf5365176d5241f60f67f0bb58..c32f4c425ff6ae8b0364c839ea9aa948fb1e8f58 100644
|
| --- a/src/heap-profiler.h
|
| +++ b/src/heap-profiler.h
|
| @@ -28,9 +28,7 @@
|
| #ifndef V8_HEAP_PROFILER_H_
|
| #define V8_HEAP_PROFILER_H_
|
|
|
| -#include "allocation.h"
|
| #include "isolate.h"
|
| -#include "zone-inl.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
| @@ -81,10 +79,6 @@ class HeapProfiler {
|
| return snapshots_->is_tracking_objects();
|
| }
|
|
|
| - // Obsolete interface.
|
| - // Write a single heap sample to the log file.
|
| - static void WriteSample();
|
| -
|
| private:
|
| HeapProfiler();
|
| ~HeapProfiler();
|
| @@ -103,295 +97,6 @@ class HeapProfiler {
|
| #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->catch_var_symbol();
|
| - case CODE: return HEAP->code_symbol();
|
| - case SELF: return HEAP->this_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 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:
|
| - void Setup();
|
| - void RecordJSObjectAllocation(Object* obj) {
|
| - if (FLAG_log_producers) DoRecordJSObjectAllocation(obj);
|
| - }
|
| -
|
| - private:
|
| - ProducerHeapProfile() : can_log_(false) { }
|
| -
|
| - void DoRecordJSObjectAllocation(Object* obj);
|
| - Isolate* isolate_;
|
| - bool can_log_;
|
| -
|
| - friend class Isolate;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(ProducerHeapProfile);
|
| -};
|
| -
|
| -#endif // ENABLE_LOGGING_AND_PROFILING
|
| -
|
| } } // namespace v8::internal
|
|
|
| #endif // V8_HEAP_PROFILER_H_
|
|
|