Upstream version 11.39.244.0
[platform/framework/web/crosswalk.git] / src / v8 / src / xdk-utils.h
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
4 \r
5 #ifndef __xdk_utils_h__\r
6 #define __xdk_utils_h__\r
7 \r
8 #include <map>\r
9 #include <set>\r
10 #include <sstream>\r
11 #include <string>\r
12 #include "src/hashmap.h"\r
13 \r
14 namespace v8 {\r
15 namespace internal {\r
16 \r
17 class AggregatedChunks;\r
18 class StringsStorage;\r
19 class JavaScriptFrame;\r
20 \r
21 // --- ClassNames\r
22 class ClassNames {\r
23  public:\r
24   explicit ClassNames(StringsStorage* names);\r
25 \r
26   unsigned registerName(const char* className);\r
27   std::string SerializeChunk();\r
28   String* GetConstructorName(Address address);\r
29 \r
30  private:\r
31   unsigned counter_;\r
32   HashMap char_to_idx_;\r
33   StringsStorage* names_;\r
34 };\r
35 \r
36 \r
37 // --- ShadowStack\r
38 class CallTree {\r
39  public:\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
45 \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
48   // callsite\r
49   unsigned index_;\r
50   CallTree* parent_;\r
51   // the only one field which characterize the call point\r
52   unsigned callsite_;\r
53 };\r
54 \r
55 \r
56 class ShadowStack {\r
57   CallTree root_;\r
58 \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
62 \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
67  public:\r
68   ShadowStack();\r
69   ~ShadowStack();\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
72   // unroll.\r
73   unsigned registerStack(const List<unsigned>& shadow_stack_);\r
74   std::string SerializeChunk();\r
75 };\r
76 \r
77 \r
78 // --- SymbolsStorage\r
79 struct SymInfoKey {\r
80   size_t function_id_;\r
81   unsigned line_;\r
82   unsigned column_;\r
83 };\r
84 \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
89 }\r
90 \r
91 \r
92 struct SymInfoValue {\r
93   unsigned symId_;\r
94   std::string funcName_;\r
95   std::string sourceFile_;\r
96 };\r
97 \r
98 \r
99 class SymbolsStorage {\r
100  public:\r
101   unsigned registerSymInfo(size_t functionId,\r
102                                std::string functionName,\r
103                                std::string sourceName, unsigned line,\r
104                                unsigned column);\r
105   unsigned FindOrRegisterFrame(JavaScriptFrame* frame);\r
106   SymbolsStorage(Heap* heap, StringsStorage* names);\r
107   ~SymbolsStorage();\r
108   std::string SerializeChunk();\r
109 \r
110  private:\r
111   HashMap symbols_;\r
112   unsigned curSym_;\r
113   // fast living storage which duplicate info but is cleaned regularly\r
114   SymInfoKey* reserved_key_;\r
115   HashMap sym_info_hash_;\r
116   Heap* heap_;\r
117   StringsStorage* names_;\r
118 };\r
119 \r
120 \r
121 struct PostCollectedInfo {\r
122   int size_;\r
123   int timeStamp_;\r
124   int stackId_;\r
125   unsigned className_;\r
126   bool dirty_;\r
127 };\r
128 \r
129 \r
130 class RuntimeInfo {\r
131  public:\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
141 \r
142  private:\r
143   HashMap working_set_hash_;\r
144   AggregatedChunks* aggregated_chunks_;\r
145   unsigned AllocatedBeforeCollectionFrame_;\r
146 };\r
147 \r
148 \r
149 struct AggregatedKey {\r
150   int stackId_;\r
151   // do we need class here? is not it defined by the stack id?\r
152   unsigned classId_;\r
153   unsigned tsBegin_;\r
154   unsigned tsEnd_;\r
155 };\r
156 \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
162 }\r
163 \r
164 \r
165 struct AggregatedValue {\r
166   unsigned size_;\r
167   unsigned objects_;\r
168 };\r
169 \r
170 \r
171 class AggregatedChunks {\r
172  public:\r
173   AggregatedChunks();\r
174   ~AggregatedChunks();\r
175   void addObjectToAggregated(PostCollectedInfo* info, unsigned td);\r
176   std::string SerializeChunk();\r
177 \r
178  private:\r
179   HashMap aggregated_map_;\r
180   int bucketSize_;\r
181   AggregatedKey* reserved_key_;\r
182 };\r
183 \r
184 \r
185 struct RefId {\r
186   int stackId_;\r
187   int classId_;\r
188   std::string field_;\r
189 };\r
190 \r
191 inline bool operator < (const RefId& first, const RefId& second ) {\r
192   if (first.stackId_ < second.stackId_ )\r
193     return true;\r
194   else if (first.stackId_ > second.stackId_ )\r
195     return false;\r
196   if (first.classId_ < second.classId_ )\r
197     return true;\r
198   if (first.classId_ > second.classId_ )\r
199     return false;\r
200   if (first.field_.compare(second.field_) < 0 )\r
201     return true;\r
202 \r
203   return false;\r
204 }\r
205 \r
206 typedef std::set<RefId> REFERENCESET;\r
207 \r
208 \r
209 struct RefSet {\r
210   REFERENCESET references_;\r
211 };\r
212 \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
222       return true;\r
223     if (*cit2 < *cit1 )\r
224       return false;\r
225     cit1++;\r
226     cit2++;\r
227   }\r
228   return false;\r
229 }\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
233 \r
234 \r
235 class References {\r
236  public:\r
237   void addReference(const RefId& parent,\r
238                     const RefSet& refSet,\r
239                     int parentTime);\r
240   void clear();\r
241   std::string serialize() const;\r
242 \r
243  private:\r
244   PARENTREFMAP refMap_;\r
245 };\r
246 \r
247 \r
248 } }  // namespace v8::internal\r
249 #endif  // __xdk_utils_h__\r