Bug 1890750 - Part 1: Include NATIVE_JIT_ENTRY in FunctionFlags::HasJitEntryFlags...
[gecko.git] / js / src / jit / PerfSpewer.h
blob8b04dc4419f7d32acd25ba4a50805c9128f28740
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef jit_PerfSpewer_h
8 #define jit_PerfSpewer_h
10 #ifdef JS_ION_PERF
11 # include <stdio.h>
12 #endif
13 #include "jit/BaselineFrameInfo.h"
14 #include "jit/CacheIR.h"
15 #include "jit/JitCode.h"
16 #include "jit/LIR.h"
17 #include "js/AllocPolicy.h"
18 #include "js/JitCodeAPI.h"
19 #include "js/Vector.h"
20 #include "vm/JSScript.h"
22 namespace js::jit {
24 using ProfilerJitCodeVector = Vector<JS::JitCodeRecord, 0, SystemAllocPolicy>;
26 void ResetPerfSpewer(bool enabled);
28 struct AutoLockPerfSpewer {
29 AutoLockPerfSpewer();
30 ~AutoLockPerfSpewer();
33 class MBasicBlock;
34 class MacroAssembler;
36 bool PerfEnabled();
38 class PerfSpewer {
39 protected:
40 struct OpcodeEntry {
41 uint32_t offset = 0;
42 unsigned opcode = 0;
43 jsbytecode* bytecodepc = nullptr;
45 // This string is used to replace the opcode, to define things like
46 // Prologue/Epilogue, or to add operand info.
47 UniqueChars str;
49 explicit OpcodeEntry(uint32_t offset_, unsigned opcode_, UniqueChars& str_,
50 jsbytecode* pc)
51 : offset(offset_), opcode(opcode_), bytecodepc(pc) {
52 str = std::move(str_);
55 explicit OpcodeEntry(uint32_t offset_, unsigned opcode_, UniqueChars& str_)
56 : offset(offset_), opcode(opcode_) {
57 str = std::move(str_);
59 explicit OpcodeEntry(uint32_t offset_, UniqueChars& str_)
60 : offset(offset_) {
61 str = std::move(str_);
63 explicit OpcodeEntry(uint32_t offset_, unsigned opcode_)
64 : offset(offset_), opcode(opcode_) {}
66 explicit OpcodeEntry(jsbytecode* pc) : bytecodepc(pc) {}
68 OpcodeEntry(OpcodeEntry&& copy) {
69 offset = copy.offset;
70 opcode = copy.opcode;
71 bytecodepc = copy.bytecodepc;
72 str = std::move(copy.str);
75 // Do not copy the UniqueChars member.
76 OpcodeEntry(OpcodeEntry& copy) = delete;
78 Vector<OpcodeEntry, 0, SystemAllocPolicy> opcodes_;
80 uint32_t lir_opcode_length = 0;
81 uint32_t js_opcode_length = 0;
83 virtual JS::JitTier GetTier() { return JS::JitTier::Other; }
85 virtual const char* CodeName(unsigned op) = 0;
87 virtual void saveJitCodeSourceInfo(JSScript* script, JitCode* code,
88 JS::JitCodeRecord* record,
89 AutoLockPerfSpewer& lock);
91 void saveDebugInfo(JSScript* script, JitCode* code,
92 JS::JitCodeRecord* profilerRecord,
93 AutoLockPerfSpewer& lock);
95 void saveProfile(JitCode* code, UniqueChars& desc, JSScript* script);
97 void saveJitCodeIRInfo(JitCode* code, JS::JitCodeRecord* profilerRecord,
98 AutoLockPerfSpewer& lock);
100 public:
101 PerfSpewer() = default;
103 void recordOffset(MacroAssembler& masm, const char*);
105 static void Init();
107 static void CollectJitCodeInfo(UniqueChars& function_name, JitCode* code,
108 JS::JitCodeRecord*, AutoLockPerfSpewer& lock);
109 static void CollectJitCodeInfo(UniqueChars& function_name, void* code_addr,
110 uint64_t code_size,
111 JS::JitCodeRecord* profilerRecord,
112 AutoLockPerfSpewer& lock);
115 void CollectPerfSpewerJitCodeProfile(JitCode* code, const char* msg);
116 void CollectPerfSpewerJitCodeProfile(uintptr_t base, uint64_t size,
117 const char* msg);
119 void CollectPerfSpewerWasmMap(uintptr_t base, uintptr_t size,
120 const char* filename, const char* annotation);
121 void CollectPerfSpewerWasmFunctionMap(uintptr_t base, uintptr_t size,
122 const char* filename, unsigned lineno,
123 const char* funcName);
125 class IonPerfSpewer : public PerfSpewer {
126 JS::JitTier GetTier() override { return JS::JitTier::Ion; }
127 const char* CodeName(unsigned op) override;
129 public:
130 void recordInstruction(MacroAssembler& masm, LInstruction* ins);
131 void saveProfile(JSContext* cx, JSScript* script, JitCode* code);
134 class BaselineInterpreterPerfSpewer : public PerfSpewer {
135 JS::JitTier GetTier() override { return JS::JitTier::Baseline; }
136 const char* CodeName(unsigned op) override;
138 // Do nothing, BaselineInterpreter has no source to reference.
139 void saveJitCodeSourceInfo(JSScript* script, JitCode* code,
140 JS::JitCodeRecord* record,
141 AutoLockPerfSpewer& lock) override {}
143 public:
144 void recordOffset(MacroAssembler& masm, JSOp op);
145 void recordOffset(MacroAssembler& masm, const char* name);
146 void saveProfile(JitCode* code);
149 class BaselinePerfSpewer : public PerfSpewer {
150 JS::JitTier GetTier() override { return JS::JitTier::Baseline; }
151 const char* CodeName(unsigned op) override;
153 public:
154 void recordInstruction(JSContext* cx, MacroAssembler& masm, jsbytecode* pc,
155 CompilerFrameInfo& frame);
156 void saveProfile(JSContext* cx, JSScript* script, JitCode* code);
159 class InlineCachePerfSpewer : public PerfSpewer {
160 JS::JitTier GetTier() override { return JS::JitTier::IC; }
161 const char* CodeName(unsigned op) override;
163 public:
164 void recordInstruction(MacroAssembler& masm, CacheOp op);
167 class BaselineICPerfSpewer : public InlineCachePerfSpewer {
168 void saveJitCodeSourceInfo(JSScript* script, JitCode* code,
169 JS::JitCodeRecord* record,
170 AutoLockPerfSpewer& lock) override {
171 // Baseline IC stubs are shared and have no source code to reference.
172 return;
175 public:
176 void saveProfile(JitCode* code, const char* stubName);
179 class IonICPerfSpewer : public InlineCachePerfSpewer {
180 public:
181 explicit IonICPerfSpewer(jsbytecode* pc);
183 void saveJitCodeSourceInfo(JSScript* script, JitCode* code,
184 JS::JitCodeRecord* record,
185 AutoLockPerfSpewer& lock) override;
187 void saveProfile(JSContext* cx, JSScript* script, JitCode* code,
188 const char* stubName);
191 class PerfSpewerRangeRecorder {
192 using OffsetPair = std::tuple<uint32_t, UniqueChars>;
193 Vector<OffsetPair, 0, js::SystemAllocPolicy> ranges;
195 MacroAssembler& masm;
197 void appendEntry(UniqueChars& desc);
199 public:
200 explicit PerfSpewerRangeRecorder(MacroAssembler& masm_) : masm(masm_){};
201 void recordOffset(const char* name);
202 void recordOffset(const char* name, JSContext* cx, JSScript* script);
203 void recordVMWrapperOffset(const char* name);
204 void collectRangesForJitCode(JitCode* code);
207 } // namespace js::jit
209 #endif /* jit_PerfSpewer_h */