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

Unified Diff: src/profile-generator.h

Issue 2722005: The new JS Heap Profiler: the main part. (Closed)
Patch Set: Comments addressed Created 10 years, 6 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/profile-generator.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/profile-generator.h
diff --git a/src/profile-generator.h b/src/profile-generator.h
index be0e94ea1983fa0f13344a67efc76e498a634891..3f90702bc4e2a2d29741fa58a2d85fe17cd0dcd7 100644
--- a/src/profile-generator.h
+++ b/src/profile-generator.h
@@ -31,6 +31,7 @@
#ifdef ENABLE_LOGGING_AND_PROFILING
#include "hashmap.h"
+#include "../include/v8-profiler.h"
namespace v8 {
namespace internal {
@@ -53,6 +54,8 @@ class TokenEnumerator {
List<bool> token_removed_;
friend class TokenEnumeratorTester;
+
+ DISALLOW_COPY_AND_ASSIGN(TokenEnumerator);
};
@@ -357,6 +360,8 @@ class SampleRateCalculator {
unsigned measurements_count_;
unsigned wall_time_query_countdown_;
double last_wall_time_;
+
+ DISALLOW_COPY_AND_ASSIGN(SampleRateCalculator);
};
@@ -416,6 +421,310 @@ class ProfileGenerator {
DISALLOW_COPY_AND_ASSIGN(ProfileGenerator);
};
+
+class HeapSnapshot;
+class HeapEntry;
+
+
+class HeapGraphEdge {
+ public:
+ enum Type {
+ CONTEXT_VARIABLE,
+ ELEMENT,
+ PROPERTY
+ };
+
+ HeapGraphEdge(Type type, const char* name, HeapEntry* from, HeapEntry* to);
+ HeapGraphEdge(int index, HeapEntry* from, HeapEntry* to);
+
+ Type type() const { return type_; }
+ int index() const {
+ ASSERT(type_ == ELEMENT);
+ return index_;
+ }
+ const char* name() const {
+ ASSERT(type_ == CONTEXT_VARIABLE || type_ == PROPERTY);
+ return name_;
+ }
+ HeapEntry* from() const { return from_; }
+ HeapEntry* to() const { return to_; }
+
+ private:
+ Type type_;
+ union {
+ int index_;
+ const char* name_;
+ };
+ HeapEntry* from_;
+ HeapEntry* to_;
+
+ DISALLOW_COPY_AND_ASSIGN(HeapGraphEdge);
+};
+
+
+class HeapGraphPath;
+class CachedHeapGraphPath;
+
+class HeapEntry {
+ public:
+ enum Type {
+ INTERNAL,
+ ARRAY,
+ STRING,
+ JS_OBJECT,
+ CODE,
+ CLOSURE
+ };
+
+ explicit HeapEntry(HeapSnapshot* snapshot)
+ : snapshot_(snapshot),
+ visited_(false),
+ type_(INTERNAL),
+ name_(""),
+ next_auto_index_(0),
+ self_size_(0),
+ security_token_id_(TokenEnumerator::kNoSecurityToken),
+ children_(1),
+ retainers_(0),
+ retaining_paths_(0),
+ total_size_(kUnknownSize),
+ non_shared_total_size_(kUnknownSize),
+ painted_(kUnpainted) { }
+ HeapEntry(HeapSnapshot* snapshot,
+ Type type,
+ const char* name,
+ int self_size,
+ int security_token_id)
+ : snapshot_(snapshot),
+ visited_(false),
+ type_(type),
+ name_(name),
+ next_auto_index_(1),
+ self_size_(self_size),
+ security_token_id_(security_token_id),
+ children_(4),
+ retainers_(4),
+ retaining_paths_(4),
+ total_size_(kUnknownSize),
+ non_shared_total_size_(kUnknownSize),
+ painted_(kUnpainted) { }
+ ~HeapEntry();
+
+ bool visited() const { return visited_; }
+ Type type() const { return type_; }
+ const char* name() const { return name_; }
+ int self_size() const { return self_size_; }
+ int security_token_id() const { return security_token_id_; }
+ bool painted_reachable() { return painted_ == kPaintReachable; }
+ bool not_painted_reachable_from_others() {
+ return painted_ != kPaintReachableFromOthers;
+ }
+ const List<HeapGraphEdge*>* children() const { return &children_; }
+ const List<HeapGraphEdge*>* retainers() const { return &retainers_; }
+ const List<HeapGraphPath*>* GetRetainingPaths();
+
+ void ClearPaint() { painted_ = kUnpainted; }
+ void CutEdges();
+ void MarkAsVisited() { visited_ = true; }
+ void PaintReachable() {
+ ASSERT(painted_ == kUnpainted);
+ painted_ = kPaintReachable;
+ }
+ void PaintReachableFromOthers() { painted_ = kPaintReachableFromOthers; }
+ void SetClosureReference(const char* name, HeapEntry* entry);
+ void SetElementReference(int index, HeapEntry* entry);
+ void SetPropertyReference(const char* name, HeapEntry* entry);
+ void SetAutoIndexReference(HeapEntry* entry);
+
+ int TotalSize();
+ int NonSharedTotalSize();
+
+ void Print(int max_depth, int indent);
+
+ private:
+ int CalculateTotalSize();
+ int CalculateNonSharedTotalSize();
+ void FindRetainingPaths(HeapEntry* node, CachedHeapGraphPath* prev_path);
+ void RemoveChild(HeapGraphEdge* edge);
+ void RemoveRetainer(HeapGraphEdge* edge);
+
+ const char* TypeAsString();
+
+ HeapSnapshot* snapshot_;
+ bool visited_;
+ Type type_;
+ const char* name_;
+ int next_auto_index_;
+ int self_size_;
+ int security_token_id_;
+ List<HeapGraphEdge*> children_;
+ List<HeapGraphEdge*> retainers_;
+ List<HeapGraphPath*> retaining_paths_;
+ int total_size_;
+ int non_shared_total_size_;
+ int painted_;
+
+ static const int kUnknownSize = -1;
+ static const int kUnpainted = 0;
+ static const int kPaintReachable = 1;
+ static const int kPaintReachableFromOthers = 2;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(HeapEntry);
+};
+
+
+class HeapGraphPath {
+ public:
+ HeapGraphPath()
+ : path_(8) { }
+ explicit HeapGraphPath(const List<HeapGraphEdge*>& path);
+
+ void Add(HeapGraphEdge* edge) { path_.Add(edge); }
+ void Set(int index, HeapGraphEdge* edge) { path_[index] = edge; }
+ const List<HeapGraphEdge*>* path() const { return &path_; }
+
+ void Print();
+
+ private:
+ List<HeapGraphEdge*> path_;
+
+ DISALLOW_COPY_AND_ASSIGN(HeapGraphPath);
+};
+
+
+class HeapEntriesMap {
+ public:
+ HeapEntriesMap();
+ ~HeapEntriesMap();
+
+ void Alias(HeapObject* object, HeapEntry* entry);
+ void Apply(void (HeapEntry::*Func)(void));
+ template<class Visitor>
+ void Apply(Visitor* visitor);
+ HeapEntry* Map(HeapObject* object);
+ void Pair(HeapObject* object, HeapEntry* entry);
+
+ private:
+ INLINE(uint32_t Hash(HeapObject* object)) {
+ return static_cast<uint32_t>(reinterpret_cast<intptr_t>(object));
+ }
+ INLINE(static bool HeapObjectsMatch(void* key1, void* key2)) {
+ return key1 == key2;
+ }
+ INLINE(bool IsAlias(void* ptr)) {
+ return reinterpret_cast<intptr_t>(ptr) & kAliasTag;
+ }
+
+ static const intptr_t kAliasTag = 1;
+
+ HashMap entries_;
+
+ DISALLOW_COPY_AND_ASSIGN(HeapEntriesMap);
+};
+
+
+class HeapSnapshotsCollection;
+
+// HeapSnapshot represents a single heap snapshot. It is stored in
+// HeapSnapshotsCollection, which is also a factory for
+// HeapSnapshots. All HeapSnapshots share strings copied from JS heap
+// to be able to return them even if they were collected.
+// HeapSnapshotGenerator fills in a HeapSnapshot.
+class HeapSnapshot {
+ public:
+ HeapSnapshot(HeapSnapshotsCollection* collection,
+ const char* title,
+ unsigned uid);
+ void ClearPaint();
+ void CutObjectsFromForeignSecurityContexts();
+ HeapEntry* GetEntry(Object* object);
+ void SetClosureReference(
+ HeapEntry* parent, String* reference_name, Object* child);
+ void SetElementReference(HeapEntry* parent, int index, Object* child);
+ void SetPropertyReference(
+ HeapEntry* parent, String* reference_name, Object* child);
+
+ INLINE(const char* title() const) { return title_; }
+ INLINE(unsigned uid() const) { return uid_; }
+ const HeapEntry* const_root() const { return &root_; }
+ HeapEntry* root() { return &root_; }
+ template<class Visitor>
+ void IterateEntries(Visitor* visitor) { entries_.Apply(visitor); }
+
+ void Print(int max_depth);
+
+ private:
+ HeapEntry* AddEntry(HeapObject* object, HeapEntry::Type type) {
+ return AddEntry(object, type, "");
+ }
+ HeapEntry* AddEntry(
+ HeapObject* object, HeapEntry::Type type, const char* name);
+ void AddEntryAlias(HeapObject* object, HeapEntry* entry) {
+ entries_.Alias(object, entry);
+ }
+ HeapEntry* FindEntry(HeapObject* object) {
+ return entries_.Map(object);
+ }
+ int GetGlobalSecurityToken();
+ int GetObjectSecurityToken(HeapObject* obj);
+ static int GetObjectSize(HeapObject* obj);
+ static int CalculateNetworkSize(JSObject* obj);
+
+ HeapSnapshotsCollection* collection_;
+ const char* title_;
+ unsigned uid_;
+ HeapEntry root_;
+ // HeapObject* -> HeapEntry*
+ HeapEntriesMap entries_;
+
+ DISALLOW_COPY_AND_ASSIGN(HeapSnapshot);
+};
+
+
+class HeapSnapshotsCollection {
+ public:
+ HeapSnapshotsCollection();
+ ~HeapSnapshotsCollection();
+
+ HeapSnapshot* NewSnapshot(const char* name, unsigned uid);
+ List<HeapSnapshot*>* snapshots() { return &snapshots_; }
+ HeapSnapshot* GetSnapshot(unsigned uid);
+
+ const char* GetName(String* name) { return names_.GetName(name); }
+
+ TokenEnumerator* token_enumerator() { return token_enumerator_; }
+
+ private:
+ INLINE(static bool HeapSnapshotsMatch(void* key1, void* key2)) {
+ return key1 == key2;
+ }
+
+ List<HeapSnapshot*> snapshots_;
+ // uid -> HeapSnapshot*
+ HashMap snapshots_uids_;
+ StringsStorage names_;
+ TokenEnumerator* token_enumerator_;
+
+ DISALLOW_COPY_AND_ASSIGN(HeapSnapshotsCollection);
+};
+
+
+class HeapSnapshotGenerator {
+ public:
+ explicit HeapSnapshotGenerator(HeapSnapshot* snapshot);
+ void GenerateSnapshot();
+
+ private:
+ void ExtractReferences(HeapObject* obj);
+ void ExtractClosureReferences(JSObject* js_obj, HeapEntry* entry);
+ void ExtractPropertyReferences(JSObject* js_obj, HeapEntry* entry);
+ void ExtractElementReferences(JSObject* js_obj, HeapEntry* entry);
+
+ HeapSnapshot* snapshot_;
+
+ DISALLOW_COPY_AND_ASSIGN(HeapSnapshotGenerator);
+};
+
} } // namespace v8::internal
#endif // ENABLE_LOGGING_AND_PROFILING
« no previous file with comments | « no previous file | src/profile-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698