v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
profile-generator.h
Go to the documentation of this file.
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_PROFILE_GENERATOR_H_
29 #define V8_PROFILE_GENERATOR_H_
30 
31 #include "allocation.h"
32 #include "hashmap.h"
33 #include "../include/v8-profiler.h"
34 
35 namespace v8 {
36 namespace internal {
37 
38 struct OffsetRange;
39 
40 // Provides a storage of strings allocated in C++ heap, to hold them
41 // forever, even if they disappear from JS heap or external storage.
43  public:
44  explicit StringsStorage(Heap* heap);
46 
47  const char* GetCopy(const char* src);
48  const char* GetFormatted(const char* format, ...);
49  const char* GetVFormatted(const char* format, va_list args);
50  const char* GetName(Name* name);
51  const char* GetName(int index);
52  const char* GetFunctionName(Name* name);
53  const char* GetFunctionName(const char* name);
54  size_t GetUsedMemorySize() const;
55 
56  private:
57  static const int kMaxNameSize = 1024;
58 
59  static bool StringsMatch(void* key1, void* key2);
60  const char* BeautifyFunctionName(const char* name);
61  const char* AddOrDisposeString(char* str, int len);
62  HashMap::Entry* GetEntry(const char* str, int len);
63 
64  uint32_t hash_seed_;
65  HashMap names_;
66 
67  DISALLOW_COPY_AND_ASSIGN(StringsStorage);
68 };
69 
70 
71 class CodeEntry {
72  public:
73  // CodeEntry doesn't own name strings, just references them.
75  const char* name,
80  ~CodeEntry();
81 
82  bool is_js_function() const { return is_js_function_tag(tag_); }
83  const char* name_prefix() const { return name_prefix_; }
84  bool has_name_prefix() const { return name_prefix_[0] != '\0'; }
85  const char* name() const { return name_; }
86  const char* resource_name() const { return resource_name_; }
87  int line_number() const { return line_number_; }
88  int column_number() const { return column_number_; }
89  void set_shared_id(int shared_id) { shared_id_ = shared_id; }
90  int script_id() const { return script_id_; }
91  void set_script_id(int script_id) { script_id_ = script_id; }
92  void set_bailout_reason(const char* bailout_reason) {
93  bailout_reason_ = bailout_reason;
94  }
95  const char* bailout_reason() const { return bailout_reason_; }
96 
97  static inline bool is_js_function_tag(Logger::LogEventsAndTags tag);
98 
99  List<OffsetRange>* no_frame_ranges() const { return no_frame_ranges_; }
101  no_frame_ranges_ = ranges;
102  }
103 
104  void SetBuiltinId(Builtins::Name id);
105  Builtins::Name builtin_id() const { return builtin_id_; }
106 
107  uint32_t GetCallUid() const;
108  bool IsSameAs(CodeEntry* entry) const;
109 
110  static const char* const kEmptyNamePrefix;
111  static const char* const kEmptyResourceName;
112  static const char* const kEmptyBailoutReason;
113 
114  private:
115  Logger::LogEventsAndTags tag_ : 8;
116  Builtins::Name builtin_id_ : 8;
117  const char* name_prefix_;
118  const char* name_;
119  const char* resource_name_;
120  int line_number_;
121  int column_number_;
122  int shared_id_;
123  int script_id_;
124  List<OffsetRange>* no_frame_ranges_;
125  const char* bailout_reason_;
126 
127  DISALLOW_COPY_AND_ASSIGN(CodeEntry);
128 };
129 
130 
131 class ProfileTree;
132 
133 class ProfileNode {
134  public:
135  inline ProfileNode(ProfileTree* tree, CodeEntry* entry);
136 
139  void IncrementSelfTicks() { ++self_ticks_; }
140  void IncreaseSelfTicks(unsigned amount) { self_ticks_ += amount; }
141 
142  CodeEntry* entry() const { return entry_; }
143  unsigned self_ticks() const { return self_ticks_; }
144  const List<ProfileNode*>* children() const { return &children_list_; }
145  unsigned id() const { return id_; }
146 
147  void Print(int indent);
148 
149  private:
150  static bool CodeEntriesMatch(void* entry1, void* entry2) {
151  return reinterpret_cast<CodeEntry*>(entry1)->IsSameAs(
152  reinterpret_cast<CodeEntry*>(entry2));
153  }
154 
155  static uint32_t CodeEntryHash(CodeEntry* entry) {
156  return entry->GetCallUid();
157  }
158 
159  ProfileTree* tree_;
160  CodeEntry* entry_;
161  unsigned self_ticks_;
162  // Mapping from CodeEntry* to ProfileNode*
163  HashMap children_;
164  List<ProfileNode*> children_list_;
165  unsigned id_;
166 
167  DISALLOW_COPY_AND_ASSIGN(ProfileNode);
168 };
169 
170 
171 class ProfileTree {
172  public:
173  ProfileTree();
174  ~ProfileTree();
175 
177  void AddPathFromStart(const Vector<CodeEntry*>& path);
178  ProfileNode* root() const { return root_; }
179  unsigned next_node_id() { return next_node_id_++; }
180 
181  void Print() {
182  root_->Print(0);
183  }
184 
185  private:
186  template <typename Callback>
187  void TraverseDepthFirst(Callback* callback);
188 
189  CodeEntry root_entry_;
190  unsigned next_node_id_;
191  ProfileNode* root_;
192 
193  DISALLOW_COPY_AND_ASSIGN(ProfileTree);
194 };
195 
196 
197 class CpuProfile {
198  public:
199  CpuProfile(const char* title, bool record_samples);
200 
201  // Add pc -> ... -> main() call path to the profile.
202  void AddPath(const Vector<CodeEntry*>& path);
204 
205  const char* title() const { return title_; }
206  const ProfileTree* top_down() const { return &top_down_; }
207 
208  int samples_count() const { return samples_.length(); }
209  ProfileNode* sample(int index) const { return samples_.at(index); }
210 
211  Time start_time() const { return start_time_; }
212  Time end_time() const { return end_time_; }
213 
214  void UpdateTicksScale();
215 
216  void Print();
217 
218  private:
219  const char* title_;
220  bool record_samples_;
221  Time start_time_;
222  Time end_time_;
223  ElapsedTimer timer_;
224  List<ProfileNode*> samples_;
225  ProfileTree top_down_;
226 
227  DISALLOW_COPY_AND_ASSIGN(CpuProfile);
228 };
229 
230 
231 class CodeMap {
232  public:
233  CodeMap() : next_shared_id_(1) { }
234  void AddCode(Address addr, CodeEntry* entry, unsigned size);
235  void MoveCode(Address from, Address to);
236  CodeEntry* FindEntry(Address addr, Address* start = NULL);
237  int GetSharedId(Address addr);
238 
239  void Print();
240 
241  private:
242  struct CodeEntryInfo {
243  CodeEntryInfo(CodeEntry* an_entry, unsigned a_size)
244  : entry(an_entry), size(a_size) { }
245  CodeEntry* entry;
246  unsigned size;
247  };
248 
249  struct CodeTreeConfig {
250  typedef Address Key;
251  typedef CodeEntryInfo Value;
252  static const Key kNoKey;
253  static const Value NoValue() { return CodeEntryInfo(NULL, 0); }
254  static int Compare(const Key& a, const Key& b) {
255  return a < b ? -1 : (a > b ? 1 : 0);
256  }
257  };
258  typedef SplayTree<CodeTreeConfig> CodeTree;
259 
260  class CodeTreePrinter {
261  public:
262  void Call(const Address& key, const CodeEntryInfo& value);
263  };
264 
265  void DeleteAllCoveredCode(Address start, Address end);
266 
267  // Fake CodeEntry pointer to distinguish shared function entries.
268  static CodeEntry* const kSharedFunctionCodeEntry;
269 
270  CodeTree tree_;
271  int next_shared_id_;
272 
273  DISALLOW_COPY_AND_ASSIGN(CodeMap);
274 };
275 
276 
278  public:
279  explicit CpuProfilesCollection(Heap* heap);
281 
282  bool StartProfiling(const char* title, bool record_samples);
283  CpuProfile* StopProfiling(const char* title);
284  List<CpuProfile*>* profiles() { return &finished_profiles_; }
285  const char* GetName(Name* name) {
286  return function_and_resource_names_.GetName(name);
287  }
288  const char* GetName(int args_count) {
289  return function_and_resource_names_.GetName(args_count);
290  }
291  const char* GetFunctionName(Name* name) {
292  return function_and_resource_names_.GetFunctionName(name);
293  }
294  const char* GetFunctionName(const char* name) {
295  return function_and_resource_names_.GetFunctionName(name);
296  }
297  bool IsLastProfile(const char* title);
298  void RemoveProfile(CpuProfile* profile);
299 
302  const char* name,
303  const char* name_prefix = CodeEntry::kEmptyNamePrefix,
304  const char* resource_name = CodeEntry::kEmptyResourceName,
305  int line_number = v8::CpuProfileNode::kNoLineNumberInfo,
306  int column_number = v8::CpuProfileNode::kNoColumnNumberInfo);
307 
308  // Called from profile generator thread.
310 
311  // Limits the number of profiles that can be simultaneously collected.
312  static const int kMaxSimultaneousProfiles = 100;
313 
314  private:
315  StringsStorage function_and_resource_names_;
316  List<CodeEntry*> code_entries_;
317  List<CpuProfile*> finished_profiles_;
318 
319  // Accessed by VM thread and profile generator thread.
320  List<CpuProfile*> current_profiles_;
321  Semaphore current_profiles_semaphore_;
322 
323  DISALLOW_COPY_AND_ASSIGN(CpuProfilesCollection);
324 };
325 
326 
328  public:
329  explicit ProfileGenerator(CpuProfilesCollection* profiles);
330 
331  void RecordTickSample(const TickSample& sample);
332 
333  CodeMap* code_map() { return &code_map_; }
334 
335  static const char* const kAnonymousFunctionName;
336  static const char* const kProgramEntryName;
337  static const char* const kIdleEntryName;
338  static const char* const kGarbageCollectorEntryName;
339  // Used to represent frames for which we have no reliable way to
340  // detect function.
341  static const char* const kUnresolvedFunctionName;
342 
343  private:
344  CodeEntry* EntryForVMState(StateTag tag);
345 
346  CpuProfilesCollection* profiles_;
347  CodeMap code_map_;
348  CodeEntry* program_entry_;
349  CodeEntry* idle_entry_;
350  CodeEntry* gc_entry_;
351  CodeEntry* unresolved_entry_;
352 
353  DISALLOW_COPY_AND_ASSIGN(ProfileGenerator);
354 };
355 
356 
357 } } // namespace v8::internal
358 
359 #endif // V8_PROFILE_GENERATOR_H_
byte * Address
Definition: globals.h:186
CodeEntry(Logger::LogEventsAndTags tag, const char *name, const char *name_prefix=CodeEntry::kEmptyNamePrefix, const char *resource_name=CodeEntry::kEmptyResourceName, int line_number=v8::CpuProfileNode::kNoLineNumberInfo, int column_number=v8::CpuProfileNode::kNoColumnNumberInfo)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
Definition: flags.cc:269
static const char *const kEmptyBailoutReason
const char * title() const
const char * bailout_reason() const
uint32_t GetCallUid() const
ProfileNode * root() const
int line_number() const
void set_shared_id(int shared_id)
ProfileGenerator(CpuProfilesCollection *profiles)
static const char *const kUnresolvedFunctionName
TickSample * sample
void IncreaseSelfTicks(unsigned amount)
void set_bailout_reason(const char *bailout_reason)
const char * GetName(Name *name)
CodeEntry * entry() const
ProfileNode * sample(int index) const
const char * GetFormatted(const char *format,...)
int script_id() const
~CodeEntry()
List< OffsetRange > * no_frame_ranges() const
void SetBuiltinId(Builtins::Name id)
const char * GetName(int args_count)
const List< ProfileNode * > * children() const
void set_no_frame_ranges(List< OffsetRange > *ranges)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object size
Definition: flags.cc:211
const ProfileTree * top_down() const
static const int kNoColumnNumberInfo
Definition: v8-profiler.h:92
void RecordTickSample(const TickSample &sample)
const char * GetFunctionName(Name *name)
int GetSharedId(Address addr)
ProfileNode * FindChild(CodeEntry *entry)
int Compare(const T &a, const T &b)
Definition: utils.h:161
void MoveCode(Address from, Address to)
static const char *const kProgramEntryName
bool is_js_function() const
CpuProfile(const char *title, bool record_samples)
const char * resource_name() const
bool StartProfiling(const char *title, bool record_samples)
bool IsSameAs(CodeEntry *entry) const
void RemoveProfile(CpuProfile *profile)
const char * name() const
static const char *const kGarbageCollectorEntryName
void AddPathToCurrentProfiles(const Vector< CodeEntry * > &path)
static const char *const kIdleEntryName
Builtins::Name builtin_id() const
ProfileNode(ProfileTree *tree, CodeEntry *entry)
void AddPath(const Vector< CodeEntry * > &path)
void AddCode(Address addr, CodeEntry *entry, unsigned size)
void AddPathFromStart(const Vector< CodeEntry * > &path)
static const char *const kAnonymousFunctionName
static const char *const kEmptyResourceName
int column_number() const
const char * GetCopy(const char *src)
TemplateHashMapImpl< FreeStoreAllocationPolicy > HashMap
Definition: hashmap.h:113
static const char *const kEmptyNamePrefix
const char * GetFunctionName(const char *name)
const char * GetFunctionName(Name *name)
CodeEntry * NewCodeEntry(Logger::LogEventsAndTags tag, const char *name, const char *name_prefix=CodeEntry::kEmptyNamePrefix, const char *resource_name=CodeEntry::kEmptyResourceName, int line_number=v8::CpuProfileNode::kNoLineNumberInfo, int column_number=v8::CpuProfileNode::kNoColumnNumberInfo)
ProfileNode * AddPathFromEnd(const Vector< CodeEntry * > &path)
CpuProfile * StopProfiling(const char *title)
unsigned self_ticks() const
const char * GetVFormatted(const char *format, va_list args)
CodeEntry * FindEntry(Address addr, Address *start=NULL)
static const int kNoLineNumberInfo
Definition: v8-profiler.h:91
bool has_name_prefix() const
ProfileNode * FindOrAddChild(CodeEntry *entry)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long expose natives in global object expose freeBuffer extension expose gc extension under the specified name expose externalize string extension number of stack frames to capture disable builtin natives files print name of functions for which code is generated use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations always try to OSR functions trace optimize function deoptimization minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions trace debugging JSON request response trace out of bounds accesses to external arrays trace_js_array_abuse automatically set the debug break flag when debugger commands are in the queue abort by crashing maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print statistics of the maximum memory committed for the heap in name
Definition: flags.cc:505
static bool is_js_function_tag(Logger::LogEventsAndTags tag)
const char * name_prefix() const
void set_script_id(int script_id)