| 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
|
|
|