v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
profile-generator.h
Go to the documentation of this file.
1// Copyright 2011 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_PROFILER_PROFILE_GENERATOR_H_
6#define V8_PROFILER_PROFILE_GENERATOR_H_
7
8#include <atomic>
9#include <deque>
10#include <limits>
11#include <map>
12#include <memory>
13#include <unordered_map>
14#include <utility>
15#include <vector>
16
17#include "include/v8-profiler.h"
25
26namespace v8 {
27namespace internal {
28
29struct TickSample;
30
31// Provides a mapping from the offsets within generated code or a bytecode array
32// to the source line and inlining id.
34 public:
38
39 void SetPosition(int pc_offset, int line, int inlining_id);
40 int GetSourceLineNumber(int pc_offset) const;
41 int GetInliningId(int pc_offset) const;
42
43 size_t Size() const;
44 void print() const;
45
46 private:
48 bool operator<(const SourcePositionTuple& other) const {
49 return pc_offset < other.pc_offset;
50 }
54 };
55 // This is logically a map, but we store it as a vector of tuples, sorted by
56 // the pc offset, so that we can save space and look up items using binary
57 // search.
58 std::vector<SourcePositionTuple> pc_offsets_to_lines_;
59};
60
62
63class CodeEntry {
64 public:
65 enum class CodeType { JS, WASM, OTHER };
66
67 // CodeEntry may reference strings (|name|, |resource_name|) managed by a
68 // StringsStorage instance. These must be freed via ReleaseStrings.
69 inline CodeEntry(LogEventListener::CodeTag tag, const char* name,
73 std::unique_ptr<SourcePositionTable> line_info = nullptr,
74 bool is_shared_cross_origin = false,
75 CodeType code_type = CodeType::JS);
76 CodeEntry(const CodeEntry&) = delete;
77 CodeEntry& operator=(const CodeEntry&) = delete;
79 // No alive handles should be associated with the CodeEntry at time of
80 // destruction.
83 }
84
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 const SourcePositionTable* line_info() const { return line_info_.get(); }
90 int script_id() const { return script_id_; }
92 int position() const { return position_; }
97 const char* bailout_reason() const {
98 return rare_data_ ? rare_data_->bailout_reason_ : kEmptyBailoutReason;
99 }
100
101 void set_deopt_info(const char* deopt_reason, int deopt_id,
102 std::vector<CpuProfileDeoptFrame> inlined_frames);
103
104 size_t EstimatedSize() const;
106 bool has_deopt_info() const {
107 return rare_data_ && rare_data_->deopt_id_ != kNoDeoptimizationId;
108 }
110 if (!rare_data_) return;
111 // TODO(alph): Clear rare_data_ if that was the only field in use.
112 rare_data_->deopt_reason_ = kNoDeoptReason;
113 rare_data_->deopt_id_ = kNoDeoptimizationId;
114 }
115
116 const char* code_type_string() const {
118 case CodeType::JS:
119 return "JS";
120 case CodeType::WASM:
121 return "wasm";
122 case CodeType::OTHER:
123 return "other";
124 }
125 }
126
127 // Returns the start address of the instruction segment represented by this
128 // CodeEntry. Used as a key in the containing InstructionStreamMap.
131
133
135
136 void SetBuiltinId(Builtin id);
138
142
143 // Returns whether or not the lifetime of this CodeEntry is reference
144 // counted, and managed by an InstructionStreamMap.
146
147 uint32_t GetHash() const;
148 bool IsSameFunctionAs(const CodeEntry* entry) const;
149
150 int GetSourceLine(int pc_offset) const;
151
152 struct Equals {
153 bool operator()(const CodeEntry* lhs, const CodeEntry* rhs) const {
154 return lhs->IsSameFunctionAs(rhs);
155 }
156 };
157 struct Hasher {
158 std::size_t operator()(CodeEntry* e) const { return e->GetHash(); }
159 };
160
161 void SetInlineStacks(
162 std::unordered_set<CodeEntry*, Hasher, Equals> inline_entries,
163 std::unordered_map<int, std::vector<CodeEntryAndLineNumber>>
164 inline_stacks);
165 const std::vector<CodeEntryAndLineNumber>* GetInlineStack(
166 int pc_offset) const;
167
171
175
176 V8_EXPORT_PRIVATE static const char* const kEmptyResourceName;
177 static const char* const kEmptyBailoutReason;
178 static const char* const kNoDeoptReason;
179
180 V8_EXPORT_PRIVATE static const char* const kProgramEntryName;
181 V8_EXPORT_PRIVATE static const char* const kIdleEntryName;
183 // Used to represent frames for which we have no reliable way to
184 // detect function.
186 V8_EXPORT_PRIVATE static const char* const kRootEntryName;
187
193
194 // Releases strings owned by this CodeEntry, which may be allocated in the
195 // provided StringsStorage instance. This instance is not stored directly
196 // with the CodeEntry in order to reduce memory footprint.
197 // Called before every destruction.
198 void ReleaseStrings(StringsStorage& strings);
199
200 void print() const;
201
202 private:
203 friend class CodeEntryStorage;
204
205 struct RareData {
209 std::unordered_map<int, std::vector<CodeEntryAndLineNumber>> inline_stacks_;
210 std::unordered_set<CodeEntry*, Hasher, Equals> inline_entries_;
211 std::vector<CpuProfileDeoptFrame> deopt_inlined_frames_;
212 };
213
215
220
221 size_t AddRef() {
223 DCHECK_LT(ref_count_, std::numeric_limits<size_t>::max());
224 ref_count_++;
225 return ref_count_;
226 }
227
228 size_t DecRef() {
230 DCHECK_GT(ref_count_, 0UL);
231 ref_count_--;
232 return ref_count_;
233 }
234
239 "builtin_count exceeds size of bitfield");
243
244 std::uint32_t bit_field_;
245 std::atomic<std::size_t> ref_count_ = {0};
246 const char* name_;
247 const char* resource_name_;
252 std::unique_ptr<SourcePositionTable> line_info_;
253 std::unique_ptr<RareData> rare_data_;
256};
257
262
263using ProfileStackTrace = std::vector<CodeEntryAndLineNumber>;
264
265// Filters stack frames from sources other than a target native context.
267 public:
270
271 // Invoked when a native context has changed address.
272 void OnMoveEvent(Address from_address, Address to_address);
273
279
280 // Update the context's tracked address based on VM-thread events.
282 native_context_address_ = address;
283 }
285
286 private:
288};
289
290class ProfileTree;
291
293 public:
294 inline ProfileNode(ProfileTree* tree, CodeEntry* entry, ProfileNode* parent,
295 int line_number = 0);
296 ~ProfileNode();
297 ProfileNode(const ProfileNode&) = delete;
299
300 ProfileNode* FindChild(
301 CodeEntry* entry,
302 int line_number = v8::CpuProfileNode::kNoLineNumberInfo);
303 ProfileNode* FindOrAddChild(CodeEntry* entry, int line_number = 0);
304 void IncrementSelfTicks() { ++self_ticks_; }
305 void IncreaseSelfTicks(unsigned amount) { self_ticks_ += amount; }
306 void IncrementLineTicks(int src_line);
307
308 CodeEntry* entry() const { return entry_; }
309 unsigned self_ticks() const { return self_ticks_; }
310 const std::vector<ProfileNode*>* children() const { return &children_list_; }
311 unsigned id() const { return id_; }
312 ProfileNode* parent() const { return parent_; }
313 int line_number() const {
314 return line_number_ != 0 ? line_number_ : entry_->line_number();
315 }
316 CpuProfileNode::SourceType source_type() const;
317
318 unsigned int GetHitLineCount() const {
319 return static_cast<unsigned int>(line_ticks_.size());
320 }
321 bool GetLineTicks(v8::CpuProfileNode::LineTick* entries,
322 unsigned int length) const;
323 void CollectDeoptInfo(CodeEntry* entry);
324 const std::vector<CpuProfileDeoptInfo>& deopt_infos() const {
325 return deopt_infos_;
326 }
327 Isolate* isolate() const;
328
329 void Print(int indent) const;
330
331 private:
332 struct Equals {
334 CodeEntryAndLineNumber rhs) const {
335 return lhs.code_entry->IsSameFunctionAs(rhs.code_entry) &&
336 lhs.line_number == rhs.line_number;
337 }
338 };
339 struct Hasher {
340 std::size_t operator()(CodeEntryAndLineNumber pair) const {
341 return pair.code_entry->GetHash() ^ ComputeUnseededHash(pair.line_number);
342 }
343 };
344
347 unsigned self_ticks_;
348 std::unordered_map<CodeEntryAndLineNumber, ProfileNode*, Hasher, Equals>
351 std::vector<ProfileNode*> children_list_;
353 unsigned id_;
354 // maps line number --> number of ticks
355 std::unordered_map<int, int> line_ticks_;
356
357 std::vector<CpuProfileDeoptInfo> deopt_infos_;
358};
359
360class CodeEntryStorage;
361
363 public:
364 explicit ProfileTree(Isolate* isolate, CodeEntryStorage* storage = nullptr);
365 ~ProfileTree();
366 ProfileTree(const ProfileTree&) = delete;
368
370
371 ProfileNode* AddPathFromEnd(
372 const std::vector<CodeEntry*>& path,
374 bool update_stats = true);
375 ProfileNode* AddPathFromEnd(
376 const ProfileStackTrace& path,
378 bool update_stats = true,
379 ProfilingMode mode = ProfilingMode::kLeafNodeLineNumbers);
380 ProfileNode* root() const { return root_; }
381 unsigned next_node_id() { return next_node_id_++; }
382
383 void Print() const { root_->Print(0); }
384
385 Isolate* isolate() const { return isolate_; }
386
387 void EnqueueNode(const ProfileNode* node) { pending_nodes_.push_back(node); }
388 size_t pending_nodes_count() const { return pending_nodes_.size(); }
389 std::vector<const ProfileNode*> TakePendingNodes() {
390 return std::move(pending_nodes_);
391 }
392
393 CodeEntryStorage* code_entries() { return code_entries_; }
394
395 private:
396 template <typename Callback>
397 void TraverseDepthFirst(Callback* callback);
398
399 std::vector<const ProfileNode*> pending_nodes_;
400
405};
406
407class CpuProfiler;
408
410 public:
419
421 CpuProfiler* profiler, ProfilerId id, const char* title,
422 CpuProfilingOptions options,
423 std::unique_ptr<DiscardedSamplesDelegate> delegate = nullptr);
424 CpuProfile(const CpuProfile&) = delete;
425 CpuProfile& operator=(const CpuProfile&) = delete;
426
427 // Checks whether or not the given TickSample should be (sub)sampled, given
428 // the sampling interval of the profiler that recorded it (in microseconds).
429 V8_EXPORT_PRIVATE bool CheckSubsample(base::TimeDelta sampling_interval);
430 // Add pc -> ... -> main() call path to the profile.
431 void AddPath(base::TimeTicks timestamp, const ProfileStackTrace& path,
432 int src_line, bool update_stats,
433 base::TimeDelta sampling_interval, StateTag state,
434 EmbedderStateTag embedder_state,
435 const std::optional<uint64_t> trace_id = std::nullopt);
436 void FinishProfile();
437
438 const char* title() const { return title_; }
439 const ProfileTree* top_down() const { return &top_down_; }
440
441 int samples_count() const { return static_cast<int>(samples_.size()); }
442 const SampleInfo& sample(int index) const { return samples_[index]; }
443
444 int64_t sampling_interval_us() const {
445 return options_.sampling_interval_us();
446 }
447
450 CpuProfiler* cpu_profiler() const { return profiler_; }
452 ProfilerId id() const { return id_; }
453
455
456 V8_EXPORT_PRIVATE void Print() const;
457
458 private:
460
461 const char* title_;
463 std::unique_ptr<DiscardedSamplesDelegate> delegate_;
467 std::deque<SampleInfo> samples_;
472 // Number of microseconds worth of profiler ticks that should elapse before
473 // the next sample is recorded.
475};
476
478 public:
480 std::unique_ptr<DiscardedSamplesDelegate> delegate)
481 : delegate_(std::move(delegate)) {}
482
483 void Run() override { delegate_->Notify(); }
484
485 private:
486 std::unique_ptr<DiscardedSamplesDelegate> delegate_;
487};
488
490 public:
491 explicit InstructionStreamMap(CodeEntryStorage& storage);
495
496 // Adds the given CodeEntry to the InstructionStreamMap. The
497 // InstructionStreamMap takes ownership of the CodeEntry.
498 void AddCode(Address addr, CodeEntry* entry, unsigned size);
499 void MoveCode(Address from, Address to);
500 // Attempts to remove the given CodeEntry from the InstructionStreamMap.
501 // Returns true iff the entry was found and removed.
502 bool RemoveCode(CodeEntry*);
503 void ClearCodesInRange(Address start, Address end);
504 CodeEntry* FindEntry(Address addr, Address* out_instruction_start = nullptr);
505 void Print();
506 size_t size() const { return code_map_.size(); }
507
508 size_t GetEstimatedMemoryUsage() const;
509
510 CodeEntryStorage& code_entries() { return code_entries_; }
511
512 void Clear();
513
514 private:
517 unsigned size;
518 };
519
520 std::multimap<Address, CodeEntryMapInfo> code_map_;
522};
523
524// Manages the lifetime of CodeEntry objects, and stores shared resources
525// between them.
527 public:
528 template <typename... Args>
529 static CodeEntry* Create(Args&&... args) {
530 CodeEntry* const entry = new CodeEntry(std::forward<Args>(args)...);
531 entry->mark_ref_counted();
532 return entry;
533 }
534
535 void AddRef(CodeEntry*);
536 void DecRef(CodeEntry*);
537
538 StringsStorage& strings() { return function_and_resource_names_; }
539
540 private:
542};
543
545 public:
546 explicit CpuProfilesCollection(Isolate* isolate);
549
550 void set_cpu_profiler(CpuProfiler* profiler) { profiler_ = profiler; }
551 CpuProfilingResult StartProfiling(
552 const char* title = nullptr, CpuProfilingOptions options = {},
553 std::unique_ptr<DiscardedSamplesDelegate> delegate = nullptr);
554
555 // This Method is only visible for testing
556 CpuProfilingResult StartProfilingForTesting(ProfilerId id);
557 CpuProfile* StopProfiling(ProfilerId id);
558 bool IsLastProfileLeft(ProfilerId id);
559 CpuProfile* Lookup(const char* title);
560
561 std::vector<std::unique_ptr<CpuProfile>>* profiles() {
562 return &finished_profiles_;
563 }
564 const char* GetName(Tagged<Name> name) {
565 return resource_names_.GetName(name);
566 }
567 void RemoveProfile(CpuProfile* profile);
568
569 // Finds a common sampling interval dividing each CpuProfile's interval,
570 // rounded up to the nearest multiple of the CpuProfiler's sampling interval.
571 // Returns 0 if no profiles are attached.
572 base::TimeDelta GetCommonSamplingInterval();
573
574 // Called from profile generator thread.
575 void AddPathToCurrentProfiles(
576 base::TimeTicks timestamp, const ProfileStackTrace& path, int src_line,
577 bool update_stats, base::TimeDelta sampling_interval, StateTag state,
578 EmbedderStateTag embedder_state_tag,
579 Address native_context_address = kNullAddress,
580 Address native_embedder_context_address = kNullAddress,
581 const std::optional<uint64_t> trace_id = std::nullopt);
582
583 // Called from profile generator thread.
584 void UpdateNativeContextAddressForCurrentProfiles(Address from, Address to);
585
586 // Limits the number of profiles that can be simultaneously collected.
587 static const int kMaxSimultaneousProfiles = 100;
588
589 private:
590 CpuProfilingResult StartProfiling(
591 ProfilerId id, const char* title = nullptr,
592 CpuProfilingOptions options = {},
593 std::unique_ptr<DiscardedSamplesDelegate> delegate = nullptr);
595 std::vector<std::unique_ptr<CpuProfile>> finished_profiles_;
597
598 // Accessed by VM thread and profile generator thread.
599 std::vector<std::unique_ptr<CpuProfile>> current_profiles_;
601 static std::atomic<ProfilerId> last_id_;
603};
604
606 public:
608 : profile_(profile), writer_(nullptr) {}
611 void Serialize(v8::OutputStream* stream);
612
613 private:
614 void SerializePositionTicks(const v8::CpuProfileNode* node, int lineCount);
615 void SerializeCallFrame(const v8::CpuProfileNode* node);
616 void SerializeChildren(const v8::CpuProfileNode* node, int childrenCount);
617 void SerializeNode(const v8::CpuProfileNode* node);
618 void SerializeNodes();
619 void SerializeSamples();
620 void SerializeTimeDeltas();
621 void SerializeImpl();
622
623 static const int kEdgeFieldsCount;
624 static const int kNodeFieldsCount;
625
628};
629
630} // namespace internal
631} // namespace v8
632
633#endif // V8_PROFILER_PROFILE_GENERATOR_H_
Isolate * isolate_
static const int kNoColumnNumberInfo
static const int kNoLineNumberInfo
static constexpr U kNumValues
Definition bit-field.h:43
static constexpr T decode(U value)
Definition bit-field.h:66
static V8_NODISCARD constexpr U update(U previous, T value)
Definition bit-field.h:61
static constexpr int kBuiltinCount
Definition builtins.h:105
static CodeEntry * Create(Args &&... args)
static const char *const kNoDeoptReason
LogEventListener::CodeTag code_tag() const
static V8_EXPORT_PRIVATE const char *const kUnresolvedFunctionName
bool IsSameFunctionAs(const CodeEntry *entry) const
std::atomic< std::size_t > ref_count_
void FillFunctionInfo(Tagged< SharedFunctionInfo > shared)
Address ** heap_object_location_address()
const SourcePositionTable * line_info() const
const char * bailout_reason() const
void set_script_id(int script_id)
std::unique_ptr< RareData > rare_data_
CodeEntry & operator=(const CodeEntry &)=delete
CodeEntry(const CodeEntry &)=delete
static V8_EXPORT_PRIVATE const char *const kIdleEntryName
CodeEntry(LogEventListener::CodeTag tag, const char *name, const char *resource_name=CodeEntry::kEmptyResourceName, int line_number=v8::CpuProfileNode::kNoLineNumberInfo, int column_number=v8::CpuProfileNode::kNoColumnNumberInfo, std::unique_ptr< SourcePositionTable > line_info=nullptr, bool is_shared_cross_origin=false, CodeType code_type=CodeType::JS)
void SetInlineStacks(std::unordered_set< CodeEntry *, Hasher, Equals > inline_entries, std::unordered_map< int, std::vector< CodeEntryAndLineNumber > > inline_stacks)
static V8_EXPORT_PRIVATE CodeEntry * gc_entry()
LogEventListener::Event event() const
static V8_EXPORT_PRIVATE const char *const kGarbageCollectorEntryName
void set_bailout_reason(const char *bailout_reason)
CpuProfileDeoptInfo GetDeoptInfo()
const char * name() const
static V8_EXPORT_PRIVATE CodeEntry * root_entry()
const std::vector< CodeEntryAndLineNumber > * GetInlineStack(int pc_offset) const
std::unique_ptr< SourcePositionTable > line_info_
void set_position(int position)
void ReleaseStrings(StringsStorage &strings)
static V8_EXPORT_PRIVATE const char *const kEmptyResourceName
static V8_EXPORT_PRIVATE CodeEntry * program_entry()
const char * code_type_string() const
static const char *const kEmptyBailoutReason
void set_instruction_start(Address address)
static V8_EXPORT_PRIVATE CodeEntry * idle_entry()
int GetSourceLine(int pc_offset) const
static V8_EXPORT_PRIVATE const char *const kRootEntryName
void set_deopt_info(const char *deopt_reason, int deopt_id, std::vector< CpuProfileDeoptFrame > inlined_frames)
static V8_EXPORT_PRIVATE CodeEntry * unresolved_entry()
const char * resource_name() const
static V8_EXPORT_PRIVATE const char *const kProgramEntryName
Address instruction_start() const
void set_native_context_address(Address address)
ContextFilter(Address native_context_address=kNullAddress)
bool Accept(Address native_context_address) const
void OnMoveEvent(Address from_address, Address to_address)
CpuProfileJSONSerializer & operator=(const CpuProfileJSONSerializer &)=delete
CpuProfileJSONSerializer(const CpuProfileJSONSerializer &)=delete
void SerializeNode(const v8::CpuProfileNode *node)
void SerializeChildren(const v8::CpuProfileNode *node, int childrenCount)
void Serialize(v8::OutputStream *stream)
void SerializeCallFrame(const v8::CpuProfileNode *node)
void SerializePositionTicks(const v8::CpuProfileNode *node, int lineCount)
std::unique_ptr< DiscardedSamplesDelegate > delegate_
CpuProfileMaxSamplesCallbackTask(std::unique_ptr< DiscardedSamplesDelegate > delegate)
const ProfileTree * top_down() const
std::unique_ptr< DiscardedSamplesDelegate > delegate_
int64_t sampling_interval_us() const
const CpuProfilingOptions options_
base::TimeTicks start_time() const
void AddPath(base::TimeTicks timestamp, const ProfileStackTrace &path, int src_line, bool update_stats, base::TimeDelta sampling_interval, StateTag state, EmbedderStateTag embedder_state, const std::optional< uint64_t > trace_id=std::nullopt)
ContextFilter & context_filter()
std::deque< SampleInfo > samples_
CpuProfile(const CpuProfile &)=delete
const char * title() const
CpuProfile & operator=(const CpuProfile &)=delete
V8_EXPORT_PRIVATE bool CheckSubsample(base::TimeDelta sampling_interval)
CpuProfiler * cpu_profiler() const
base::TimeTicks end_time() const
const SampleInfo & sample(int index) const
V8_EXPORT_PRIVATE CpuProfile(CpuProfiler *profiler, ProfilerId id, const char *title, CpuProfilingOptions options, std::unique_ptr< DiscardedSamplesDelegate > delegate=nullptr)
V8_EXPORT_PRIVATE void Print() const
base::TimeDelta next_sample_delta_
CpuProfiler *const profiler_
const char * GetName(Tagged< Name > name)
std::vector< std::unique_ptr< CpuProfile > > finished_profiles_
CpuProfilesCollection & operator=(const CpuProfilesCollection &)=delete
std::vector< std::unique_ptr< CpuProfile > > * profiles()
CpuProfilesCollection(const CpuProfilesCollection &)=delete
static std::atomic< ProfilerId > last_id_
void set_cpu_profiler(CpuProfiler *profiler)
std::vector< std::unique_ptr< CpuProfile > > current_profiles_
std::multimap< Address, CodeEntryMapInfo > code_map_
InstructionStreamMap(const InstructionStreamMap &)=delete
InstructionStreamMap & operator=(const InstructionStreamMap &)=delete
std::vector< CpuProfileDeoptInfo > deopt_infos_
ProfileNode(const ProfileNode &)=delete
ProfileNode * parent() const
std::unordered_map< int, int > line_ticks_
unsigned int GetHitLineCount() const
const std::vector< ProfileNode * > * children() const
const std::vector< CpuProfileDeoptInfo > & deopt_infos() const
std::unordered_map< CodeEntryAndLineNumber, ProfileNode *, Hasher, Equals > children_
std::vector< ProfileNode * > children_list_
ProfileNode & operator=(const ProfileNode &)=delete
void IncreaseSelfTicks(unsigned amount)
CodeEntryStorage * code_entries()
std::vector< const ProfileNode * > pending_nodes_
CodeEntryStorage *const code_entries_
ProfileNode * root() const
ProfileTree & operator=(const ProfileTree &)=delete
void EnqueueNode(const ProfileNode *node)
ProfileTree(const ProfileTree &)=delete
std::vector< const ProfileNode * > TakePendingNodes()
SourcePositionTable(const SourcePositionTable &)=delete
SourcePositionTable & operator=(const SourcePositionTable &)=delete
std::vector< SourcePositionTuple > pc_offsets_to_lines_
int start
int end
base::Vector< const DirectHandle< Object > > args
Definition execution.cc:74
Isolate * isolate
HeapEntry * entry_
TNode< Object > callback
ZoneVector< Entry > entries
int pc_offset
STL namespace.
uint32_t ComputeUnseededHash(uint32_t key)
Definition utils.h:271
const int kHeapObjectTag
Definition v8-internal.h:72
static constexpr Address kNullAddress
Definition v8-internal.h:53
std::vector< CodeEntryAndLineNumber > ProfileStackTrace
constexpr int kNoDeoptimizationId
Definition globals.h:861
CpuProfilingMode
uint32_t ProfilerId
Definition v8-profiler.h:32
StateTag
Definition v8-unwinder.h:36
BytecodeSequenceNode * parent_
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define DCHECK_GT(v1, v2)
Definition logging.h:487
#define V8_EXPORT_PRIVATE
Definition macros.h:460
bool operator()(const CodeEntry *lhs, const CodeEntry *rhs) const
std::size_t operator()(CodeEntry *e) const
std::vector< CpuProfileDeoptFrame > deopt_inlined_frames_
std::unordered_map< int, std::vector< CodeEntryAndLineNumber > > inline_stacks_
std::unordered_set< CodeEntry *, Hasher, Equals > inline_entries_
const std::optional< uint64_t > trace_id
bool operator()(CodeEntryAndLineNumber lhs, CodeEntryAndLineNumber rhs) const
std::size_t operator()(CodeEntryAndLineNumber pair) const
bool operator<(const SourcePositionTuple &other) const