1// Copyright 2016 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_PROFILER_LISTENER_H_
6#define V8_PROFILER_PROFILER_LISTENER_H_
7
8#include <vector>
9
10#include "src/code-events.h"
11#include "src/profiler/profile-generator.h"
12
13namespace v8 {
14namespace internal {
15
16class CodeEventsContainer;
17
18class CodeEventObserver {
19 public:
20  virtual void CodeEventHandler(const CodeEventsContainer& evt_rec) = 0;
21  virtual ~CodeEventObserver() {}
22};
23
24class ProfilerListener : public CodeEventListener {
25 public:
26  explicit ProfilerListener(Isolate* isolate);
27  ~ProfilerListener() override;
28
29  void CallbackEvent(Name* name, Address entry_point) override;
30  void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
31                       AbstractCode* code, const char* comment) override;
32  void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
33                       AbstractCode* code, Name* name) override;
34  void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
35                       AbstractCode* code, SharedFunctionInfo* shared,
36                       Name* script_name) override;
37  void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
38                       AbstractCode* code, SharedFunctionInfo* shared,
39                       Name* script_name, int line, int column) override;
40  void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
41                       AbstractCode* code, int args_count) override;
42  void CodeMovingGCEvent() override {}
43  void CodeMoveEvent(AbstractCode* from, Address to) override;
44  void CodeDisableOptEvent(AbstractCode* code,
45                           SharedFunctionInfo* shared) override;
46  void CodeDeoptEvent(Code* code, Address pc, int fp_to_sp_delta) override;
47  void GetterCallbackEvent(Name* name, Address entry_point) override;
48  void RegExpCodeCreateEvent(AbstractCode* code, String* source) override;
49  void SetterCallbackEvent(Name* name, Address entry_point) override;
50  void SharedFunctionInfoMoveEvent(Address from, Address to) override {}
51
52  CodeEntry* NewCodeEntry(
53      CodeEventListener::LogEventsAndTags tag, const char* name,
54      const char* name_prefix = CodeEntry::kEmptyNamePrefix,
55      const char* resource_name = CodeEntry::kEmptyResourceName,
56      int line_number = v8::CpuProfileNode::kNoLineNumberInfo,
57      int column_number = v8::CpuProfileNode::kNoColumnNumberInfo,
58      JITLineInfoTable* line_info = NULL, Address instruction_start = NULL);
59
60  void AddObserver(CodeEventObserver* observer);
61  void RemoveObserver(CodeEventObserver* observer);
62  V8_INLINE bool HasObservers() { return !observers_.empty(); }
63
64  const char* GetName(Name* name) {
65    return function_and_resource_names_.GetName(name);
66  }
67  const char* GetName(int args_count) {
68    return function_and_resource_names_.GetName(args_count);
69  }
70  const char* GetFunctionName(Name* name) {
71    return function_and_resource_names_.GetFunctionName(name);
72  }
73  const char* GetFunctionName(const char* name) {
74    return function_and_resource_names_.GetFunctionName(name);
75  }
76
77 private:
78  void RecordInliningInfo(CodeEntry* entry, AbstractCode* abstract_code);
79  void RecordDeoptInlinedFrames(CodeEntry* entry, AbstractCode* abstract_code);
80  Name* InferScriptName(Name* name, SharedFunctionInfo* info);
81  V8_INLINE void DispatchCodeEvent(const CodeEventsContainer& evt_rec) {
82    base::LockGuard<base::Mutex> guard(&mutex_);
83    for (auto observer : observers_) {
84      observer->CodeEventHandler(evt_rec);
85    }
86  }
87
88  StringsStorage function_and_resource_names_;
89  std::vector<CodeEntry*> code_entries_;
90  std::vector<CodeEventObserver*> observers_;
91  base::Mutex mutex_;
92
93  DISALLOW_COPY_AND_ASSIGN(ProfilerListener);
94};
95
96}  // namespace internal
97}  // namespace v8
98
99#endif  // V8_PROFILER_PROFILER_LISTENER_H_
100