Bug 1885489 - Part 5: Add SnapshotIterator::readInt32(). r=iain
[gecko.git] / js / src / jit / JSONSpewer.cpp
blob81ce1a2859ea63cba51e35aa1ed1fa4f33ec9d31
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 #ifdef JS_JITSPEW
9 # include "jit/JSONSpewer.h"
11 # include "jit/BacktrackingAllocator.h"
12 # include "jit/LIR.h"
13 # include "jit/MIR.h"
14 # include "jit/MIRGraph.h"
15 # include "jit/RangeAnalysis.h"
17 using namespace js;
18 using namespace js::jit;
20 void JSONSpewer::beginFunction(JSScript* script) {
21 beginObject();
22 formatProperty("name", "%s:%u", script->filename(), script->lineno());
23 beginListProperty("passes");
26 void JSONSpewer::beginWasmFunction(unsigned funcIndex) {
27 beginObject();
28 formatProperty("name", "wasm-func%u", funcIndex);
29 beginListProperty("passes");
32 void JSONSpewer::beginPass(const char* pass) {
33 beginObject();
34 property("name", pass);
37 void JSONSpewer::spewMResumePoint(MResumePoint* rp) {
38 if (!rp) {
39 return;
42 beginObjectProperty("resumePoint");
44 if (rp->caller()) {
45 property("caller", rp->caller()->block()->id());
48 property("mode", ResumeModeToString(rp->mode()));
50 beginListProperty("operands");
51 for (MResumePoint* iter = rp; iter; iter = iter->caller()) {
52 for (int i = iter->numOperands() - 1; i >= 0; i--) {
53 value(iter->getOperand(i)->id());
55 if (iter->caller()) {
56 value("|");
59 endList();
61 endObject();
64 void JSONSpewer::spewMDef(MDefinition* def) {
65 beginObject();
67 property("id", def->id());
69 propertyName("opcode");
70 out_.printf("\"");
71 def->printOpcode(out_);
72 out_.printf("\"");
74 beginListProperty("attributes");
75 # define OUTPUT_ATTRIBUTE(X) \
76 do { \
77 if (def->is##X()) value(#X); \
78 } while (0);
79 MIR_FLAG_LIST(OUTPUT_ATTRIBUTE);
80 # undef OUTPUT_ATTRIBUTE
81 endList();
83 beginListProperty("inputs");
84 for (size_t i = 0, e = def->numOperands(); i < e; i++) {
85 value(def->getOperand(i)->id());
87 endList();
89 beginListProperty("uses");
90 for (MUseDefIterator use(def); use; use++) {
91 value(use.def()->id());
93 endList();
95 if (!def->isLowered()) {
96 beginListProperty("memInputs");
97 if (def->dependency()) {
98 value(def->dependency()->id());
100 endList();
103 bool isTruncated = false;
104 if (def->isAdd() || def->isSub() || def->isMod() || def->isMul() ||
105 def->isDiv()) {
106 isTruncated = static_cast<MBinaryArithInstruction*>(def)->isTruncated();
109 if (def->type() != MIRType::None && def->range()) {
110 beginStringProperty("type");
111 def->range()->dump(out_);
112 out_.printf(" : %s%s", StringFromMIRType(def->type()),
113 (isTruncated ? " (t)" : ""));
114 endStringProperty();
115 } else {
116 formatProperty("type", "%s%s", StringFromMIRType(def->type()),
117 (isTruncated ? " (t)" : ""));
120 if (def->isInstruction()) {
121 if (MResumePoint* rp = def->toInstruction()->resumePoint()) {
122 spewMResumePoint(rp);
126 endObject();
129 void JSONSpewer::spewMIR(MIRGraph* mir) {
130 beginObjectProperty("mir");
131 beginListProperty("blocks");
133 for (MBasicBlockIterator block(mir->begin()); block != mir->end(); block++) {
134 beginObject();
136 property("number", block->id());
138 beginListProperty("attributes");
139 if (block->hasLastIns()) {
140 if (block->isLoopBackedge()) {
141 value("backedge");
143 if (block->isLoopHeader()) {
144 value("loopheader");
146 if (block->isSplitEdge()) {
147 value("splitedge");
150 endList();
152 beginListProperty("predecessors");
153 for (size_t i = 0; i < block->numPredecessors(); i++) {
154 value(block->getPredecessor(i)->id());
156 endList();
158 beginListProperty("successors");
159 if (block->hasLastIns()) {
160 for (size_t i = 0; i < block->numSuccessors(); i++) {
161 value(block->getSuccessor(i)->id());
164 endList();
166 beginListProperty("instructions");
167 for (MPhiIterator phi(block->phisBegin()); phi != block->phisEnd(); phi++) {
168 spewMDef(*phi);
170 for (MInstructionIterator i(block->begin()); i != block->end(); i++) {
171 spewMDef(*i);
173 endList();
175 spewMResumePoint(block->entryResumePoint());
177 endObject();
180 endList();
181 endObject();
184 void JSONSpewer::spewLIns(LNode* ins) {
185 beginObject();
187 property("id", ins->id());
189 propertyName("opcode");
190 out_.printf("\"");
191 ins->dump(out_);
192 out_.printf("\"");
194 beginListProperty("defs");
195 for (size_t i = 0; i < ins->numDefs(); i++) {
196 if (ins->isPhi()) {
197 value(ins->toPhi()->getDef(i)->virtualRegister());
198 } else {
199 value(ins->toInstruction()->getDef(i)->virtualRegister());
202 endList();
204 endObject();
207 void JSONSpewer::spewLIR(MIRGraph* mir) {
208 beginObjectProperty("lir");
209 beginListProperty("blocks");
211 for (MBasicBlockIterator i(mir->begin()); i != mir->end(); i++) {
212 LBlock* block = i->lir();
213 if (!block) {
214 continue;
217 beginObject();
218 property("number", i->id());
220 beginListProperty("instructions");
221 for (size_t p = 0; p < block->numPhis(); p++) {
222 spewLIns(block->getPhi(p));
224 for (LInstructionIterator ins(block->begin()); ins != block->end(); ins++) {
225 spewLIns(*ins);
227 endList();
229 endObject();
232 endList();
233 endObject();
236 void JSONSpewer::spewRanges(BacktrackingAllocator* regalloc) {
237 beginObjectProperty("ranges");
238 beginListProperty("blocks");
240 for (size_t bno = 0; bno < regalloc->graph.numBlocks(); bno++) {
241 beginObject();
242 property("number", bno);
243 beginListProperty("vregs");
245 LBlock* lir = regalloc->graph.getBlock(bno);
246 for (LInstructionIterator ins = lir->begin(); ins != lir->end(); ins++) {
247 for (size_t k = 0; k < ins->numDefs(); k++) {
248 uint32_t id = ins->getDef(k)->virtualRegister();
249 VirtualRegister* vreg = &regalloc->vregs[id];
251 beginObject();
252 property("vreg", id);
253 beginListProperty("ranges");
255 for (LiveRange::RegisterLinkIterator iter = vreg->rangesBegin(); iter;
256 iter++) {
257 LiveRange* range = LiveRange::get(*iter);
259 beginObject();
260 property("allocation",
261 range->bundle()->allocation().toString().get());
262 property("start", range->from().bits());
263 property("end", range->to().bits());
264 endObject();
267 endList();
268 endObject();
272 endList();
273 endObject();
276 endList();
277 endObject();
280 void JSONSpewer::endPass() { endObject(); }
282 void JSONSpewer::endFunction() {
283 endList();
284 endObject();
287 #endif /* JS_JITSPEW */