1 // Copyright 2014 the V8 project authors. All rights reserved.
\r
2 // Use of this source code is governed by a BSD-style license that can be
\r
3 // found in the LICENSE file.
\r
5 #ifndef __xdk_utils_h__
\r
6 #define __xdk_utils_h__
\r
12 #include "src/hashmap.h"
\r
15 namespace internal {
\r
17 class AggregatedChunks;
\r
18 class StringsStorage;
\r
19 class JavaScriptFrame;
\r
24 explicit ClassNames(StringsStorage* names);
\r
26 unsigned registerName(const char* className);
\r
27 std::string SerializeChunk();
\r
28 String* GetConstructorName(Address address);
\r
32 HashMap char_to_idx_;
\r
33 StringsStorage* names_;
\r
40 // For quick search we use below member. it is not reasnable to use here
\r
41 // map because it occupies a lot of space even in empty state and such nodes
\r
42 // will be many. In opposite to map, std::map uses binary tree search and
\r
43 // don't store buffer, but allocates it dinamically
\r
44 std::map<unsigned, CallTree*> children_;
\r
46 // This is _not_ the same as index in the children_. This index is
\r
47 // incremental value from list of all nodes, but the key in the children_ is
\r
51 // the only one field which characterize the call point
\r
59 // unsigned here is ok, size_t is not required because even 10 millions
\r
60 // objects in this class will lead to the significant memory consumption
\r
61 unsigned last_index_;
\r
63 // TODO(amalyshe): rewrite using List, storing nodes and use index in the list
\r
64 // instead pointer to CallTree in the children_
\r
65 std::map<unsigned, CallTree*> allNodes_;
\r
66 unsigned serializedCounter_;
\r
70 // Returns unique stack id. This method can work with incremental stacks when
\r
71 // we have old stack id, new tail and number of functions that we need to
\r
73 unsigned registerStack(const List<unsigned>& shadow_stack_);
\r
74 std::string SerializeChunk();
\r
78 // --- SymbolsStorage
\r
80 size_t function_id_;
\r
85 bool inline operator == (const SymInfoKey& key1, const SymInfoKey& key2) {
\r
86 return key1.function_id_ == key2.function_id_ &&
\r
87 key1.line_ == key2.line_ &&
\r
88 key1.column_ == key2.column_;
\r
92 struct SymInfoValue {
\r
94 std::string funcName_;
\r
95 std::string sourceFile_;
\r
99 class SymbolsStorage {
\r
101 unsigned registerSymInfo(size_t functionId,
\r
102 std::string functionName,
\r
103 std::string sourceName, unsigned line,
\r
105 unsigned FindOrRegisterFrame(JavaScriptFrame* frame);
\r
106 SymbolsStorage(Heap* heap, StringsStorage* names);
\r
108 std::string SerializeChunk();
\r
113 // fast living storage which duplicate info but is cleaned regularly
\r
114 SymInfoKey* reserved_key_;
\r
115 HashMap sym_info_hash_;
\r
117 StringsStorage* names_;
\r
121 struct PostCollectedInfo {
\r
125 unsigned className_;
\r
130 class RuntimeInfo {
\r
132 explicit RuntimeInfo(AggregatedChunks* aggregated_chunks);
\r
133 PostCollectedInfo* FindPostCollectedInfo(Address addr);
\r
134 PostCollectedInfo* AddPostCollectedInfo(Address addr,
\r
135 unsigned time_delta = 0,
\r
136 PostCollectedInfo* info = NULL);
\r
137 PostCollectedInfo* AddPreCollectionInfo(Address addr, unsigned size);
\r
138 void RemoveInfo(Address addr);
\r
139 void InitABCFrame(unsigned abc_frame);
\r
140 void CollectGarbaged(unsigned ts);
\r
143 HashMap working_set_hash_;
\r
144 AggregatedChunks* aggregated_chunks_;
\r
145 unsigned AllocatedBeforeCollectionFrame_;
\r
149 struct AggregatedKey {
\r
151 // do we need class here? is not it defined by the stack id?
\r
157 bool inline operator == (const AggregatedKey& key1, const AggregatedKey& key2) {
\r
158 return key1.stackId_ == key2.stackId_ &&
\r
159 key1.classId_ == key2.classId_ &&
\r
160 key1.tsBegin_ == key2.tsBegin_ &&
\r
161 key1.tsEnd_ == key2.tsEnd_;
\r
165 struct AggregatedValue {
\r
171 class AggregatedChunks {
\r
173 AggregatedChunks();
\r
174 ~AggregatedChunks();
\r
175 void addObjectToAggregated(PostCollectedInfo* info, unsigned td);
\r
176 std::string SerializeChunk();
\r
179 HashMap aggregated_map_;
\r
181 AggregatedKey* reserved_key_;
\r
188 std::string field_;
\r
191 inline bool operator < (const RefId& first, const RefId& second ) {
\r
192 if (first.stackId_ < second.stackId_ )
\r
194 else if (first.stackId_ > second.stackId_ )
\r
196 if (first.classId_ < second.classId_ )
\r
198 if (first.classId_ > second.classId_ )
\r
200 if (first.field_.compare(second.field_) < 0 )
\r
206 typedef std::set<RefId> REFERENCESET;
\r
210 REFERENCESET references_;
\r
213 inline bool operator < (const RefSet& first, const RefSet& second) {
\r
214 // compare the sizes first of all
\r
215 if (first.references_.size() != second.references_.size() )
\r
216 return first.references_.size() < second.references_.size();
\r
217 // iterating by the first
\r
218 REFERENCESET::const_iterator cit1 = first.references_.begin();
\r
219 REFERENCESET::const_iterator cit2 = second.references_.begin();
\r
220 while (cit1 != first.references_.end()) {
\r
221 if (*cit1 < *cit2 )
\r
223 if (*cit2 < *cit1 )
\r
230 typedef std::map<unsigned int, int> TIMETOCOUNT;
\r
231 typedef std::map<RefSet, TIMETOCOUNT> REFERENCESETS;
\r
232 typedef std::map<RefId, REFERENCESETS> PARENTREFMAP;
\r
237 void addReference(const RefId& parent,
\r
238 const RefSet& refSet,
\r
241 std::string serialize() const;
\r
244 PARENTREFMAP refMap_;
\r
248 } } // namespace v8::internal
\r
249 #endif // __xdk_utils_h__
\r