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/. */
6 
7 #ifndef jit_PerfSpewer_h
8 #define jit_PerfSpewer_h
9 
10 #ifdef JS_ION_PERF
11 #  include <stdio.h>
12 #endif
13 
14 #include "jit/Label.h"
15 
16 namespace {
17 struct AutoLockPerfMap;
18 }
19 
20 namespace js {
21 namespace jit {
22 
23 class MBasicBlock;
24 class MacroAssembler;
25 
26 #ifdef JS_ION_PERF
27 void CheckPerf();
28 bool PerfBlockEnabled();
29 bool PerfFuncEnabled();
PerfEnabled()30 static inline bool PerfEnabled() {
31   return PerfBlockEnabled() || PerfFuncEnabled();
32 }
33 #else
CheckPerf()34 static inline void CheckPerf() {}
PerfBlockEnabled()35 static inline bool PerfBlockEnabled() { return false; }
PerfFuncEnabled()36 static inline bool PerfFuncEnabled() { return false; }
PerfEnabled()37 static inline bool PerfEnabled() { return false; }
38 #endif
39 
40 #ifdef JS_ION_PERF
41 
42 struct Record {
43   const char* filename;
44   unsigned lineNumber;
45   unsigned columnNumber;
46   uint32_t id;
47   Label start, end;
48   size_t startOffset, endOffset;
49 
RecordRecord50   Record(const char* filename, unsigned lineNumber, unsigned columnNumber,
51          uint32_t id)
52       : filename(filename),
53         lineNumber(lineNumber),
54         columnNumber(columnNumber),
55         id(id),
56         startOffset(0u),
57         endOffset(0u) {}
58 };
59 
60 typedef Vector<Record, 1, SystemAllocPolicy> BasicBlocksVector;
61 
62 class PerfSpewer {
63  protected:
64   static uint32_t nextFunctionIndex;
65 
66  public:
67   Label endInlineCode;
68 
69  protected:
70   BasicBlocksVector basicBlocks_;
71 
72  public:
73   [[nodiscard]] virtual bool startBasicBlock(MBasicBlock* blk,
74                                              MacroAssembler& masm);
75   virtual void endBasicBlock(MacroAssembler& masm);
76   void noteEndInlineCode(MacroAssembler& masm);
77 
78   void writeProfile(JSScript* script, JitCode* code, MacroAssembler& masm);
79 
80   static void WriteEntry(const AutoLockPerfMap&, uintptr_t address, size_t size,
81                          const char* fmt, ...) MOZ_FORMAT_PRINTF(4, 5);
82 };
83 
84 void writePerfSpewerBaselineProfile(JSScript* script, JitCode* code);
85 void writePerfSpewerJitCodeProfile(JitCode* code, const char* msg);
86 
87 // wasm doesn't support block annotations.
88 class WasmPerfSpewer : public PerfSpewer {
89  public:
startBasicBlock(MBasicBlock * blk,MacroAssembler & masm)90   [[nodiscard]] bool startBasicBlock(MBasicBlock* blk, MacroAssembler& masm) {
91     return true;
92   }
endBasicBlock(MacroAssembler & masm)93   void endBasicBlock(MacroAssembler& masm) {}
94 };
95 
96 void writePerfSpewerWasmMap(uintptr_t base, uintptr_t size,
97                             const char* filename, const char* annotation);
98 void writePerfSpewerWasmFunctionMap(uintptr_t base, uintptr_t size,
99                                     const char* filename, unsigned lineno,
100                                     const char* funcName);
101 
102 #endif  // JS_ION_PERF
103 
104 }  // namespace jit
105 }  // namespace js
106 
107 #endif /* jit_PerfSpewer_h */
108