Backed out 2 changesets (bug 1908320) for causing wr failures on align-items-baseline...
[gecko.git] / js / src / jit / CacheIRSpewer.h
blob6ceb1bb1066580ca704dff853abcea44948a5753
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 jstypeProperty(const char* name, const JSType type);
57 void cacheIRSequence(CacheIRReader& reader);
58 void attached(const char* name);
59 void endCache();
61 public:
62 static CacheIRSpewer& singleton() { return cacheIRspewer; }
63 bool init(const char* name);
65 class MOZ_RAII Guard {
66 CacheIRSpewer& sp_;
67 const IRGenerator& gen_;
68 const char* name_;
70 public:
71 Guard(const IRGenerator& gen, const char* name)
72 : sp_(CacheIRSpewer::singleton()), gen_(gen), name_(name) {
73 if (sp_.enabled()) {
74 sp_.lock().lock();
75 sp_.beginCache(gen_);
79 ~Guard() {
80 if (sp_.enabled()) {
81 const CacheIRWriter& writer = gen_.writerRef();
82 if (!writer.failed() && writer.codeLength() > 0) {
83 CacheIRReader reader(writer);
84 sp_.cacheIRSequence(reader);
86 if (name_ != nullptr) {
87 sp_.attached(name_);
89 sp_.endCache();
90 if (sp_.guardCount_++ % sp_.spewInterval_ == 0) {
91 sp_.output_.flush();
93 sp_.lock().unlock();
97 void valueProperty(const char* name, const Value& v) const {
98 sp_.valueProperty(name, v);
101 void opcodeProperty(const char* name, const JSOp op) const {
102 sp_.opcodeProperty(name, op);
105 void jstypeProperty(const char* name, const JSType type) const {
106 sp_.jstypeProperty(name, type);
109 explicit operator bool() const { return sp_.enabled(); }
113 extern void SpewCacheIROps(GenericPrinter& out, const char* prefix,
114 const CacheIRStubInfo* info);
116 } // namespace jit
117 } // namespace js
119 #endif /* JS_CACHEIR_SPEW */
121 #endif /* jit_CacheIRSpewer_h */