Bug 1834537 - Part 1: Simplify JIT nursery allocation r=jandem
[gecko.git] / js / src / jit / CacheIRSpewer.h
blobfba33ba990e3bd71fcd8ac606f6163a4e1b65010
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_CacheIRSpewer_h
8 #define jit_CacheIRSpewer_h
10 #ifdef JS_CACHEIR_SPEW
12 # include "mozilla/Maybe.h"
14 # include "jit/CacheIR.h"
15 # include "jit/CacheIRGenerator.h"
16 # include "jit/CacheIRReader.h"
17 # include "jit/CacheIRWriter.h"
18 # include "js/TypeDecls.h"
19 # include "threading/LockGuard.h"
20 # include "vm/JSONPrinter.h"
21 # include "vm/MutexIDs.h"
23 namespace js {
24 namespace jit {
26 class CacheIRSpewer {
27 Mutex outputLock_ MOZ_UNANNOTATED;
28 Fprinter output_;
29 mozilla::Maybe<JSONPrinter> json_;
30 static CacheIRSpewer cacheIRspewer;
32 // Counter to record how many times Guard class is called. This is used to
33 // determine when to flush outputs based on the given interval value.
34 // For example, if |spewInterval_ = 2|, outputs will be flushed on
35 // guardCount_ values 0,2,4,6,...
36 uint32_t guardCount_;
38 // Interval at which to flush output files. This value can be set with the
39 // environment variable |CACHEIR_LOG_FLUSH|.
40 uint32_t spewInterval_;
42 CacheIRSpewer();
43 ~CacheIRSpewer();
45 bool enabled() { return json_.isSome(); }
47 // These methods can only be called when enabled() is true.
48 Mutex& lock() {
49 MOZ_ASSERT(enabled());
50 return outputLock_;
53 void beginCache(const IRGenerator& generator);
54 void valueProperty(const char* name, const Value& v);
55 void opcodeProperty(const char* name, const JSOp op);
56 void cacheIRSequence(CacheIRReader& reader);
57 void attached(const char* name);
58 void endCache();
60 public:
61 static CacheIRSpewer& singleton() { return cacheIRspewer; }
62 bool init(const char* name);
64 class MOZ_RAII Guard {
65 CacheIRSpewer& sp_;
66 const IRGenerator& gen_;
67 const char* name_;
69 public:
70 Guard(const IRGenerator& gen, const char* name)
71 : sp_(CacheIRSpewer::singleton()), gen_(gen), name_(name) {
72 if (sp_.enabled()) {
73 sp_.lock().lock();
74 sp_.beginCache(gen_);
78 ~Guard() {
79 if (sp_.enabled()) {
80 const CacheIRWriter& writer = gen_.writerRef();
81 if (!writer.failed() && writer.codeLength() > 0) {
82 CacheIRReader reader(writer);
83 sp_.cacheIRSequence(reader);
85 if (name_ != nullptr) {
86 sp_.attached(name_);
88 sp_.endCache();
89 if (sp_.guardCount_++ % sp_.spewInterval_ == 0) {
90 sp_.output_.flush();
92 sp_.lock().unlock();
96 void valueProperty(const char* name, const Value& v) const {
97 sp_.valueProperty(name, v);
100 void opcodeProperty(const char* name, const JSOp op) const {
101 sp_.opcodeProperty(name, op);
104 explicit operator bool() const { return sp_.enabled(); }
108 extern void SpewCacheIROps(GenericPrinter& out, const char* prefix,
109 const CacheIRStubInfo* info);
111 } // namespace jit
112 } // namespace js
114 #endif /* JS_CACHEIR_SPEW */
116 #endif /* jit_CacheIRSpewer_h */