Skip to content

Commit 8840421

Browse files
committed
Bug 1632067 part 4 - Generate spewer code and use it for text and JSON spewers. r=iain
This changes the JSON spewer to include a bit more information. I'm not sure if this breaks anything that's actively being used, but it should be easy to fix. Most of the enums are just converted to an integer, but we could now easily dump a string representation for them like what we do for JSOp. Hopefully this won't affect code size too much. JS_CACHEIR_SPEW is only defined in debug and Nightly builds so there should be no effect on beta/release builds. Differential Revision: https://phabricator.services.mozilla.com/D71902 UltraBlame original commit: 04b3647283a27b4da8d34ec0a19bb6afefe5f7fa
1 parent ad05691 commit 8840421

File tree

5 files changed

+362
-79
lines changed

5 files changed

+362
-79
lines changed

js/src/jit/CacheIR.h

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,18 @@ class CallFlags {
304304
}
305305
bool isSameRealm() const { return isSameRealm_; }
306306

307+
uint8_t toByte() const {
308+
309+
uint8_t value = getArgFormat();
310+
if (isConstructing()) {
311+
value |= CallFlags::IsConstructing;
312+
}
313+
if (isSameRealm()) {
314+
value |= CallFlags::IsSameRealm;
315+
}
316+
return value;
317+
}
318+
307319
private:
308320
ArgFormat argFormat_;
309321
bool isConstructing_;
@@ -500,22 +512,7 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter {
500512
operandLastUsed_[opId.id()] = nextInstructionId_ - 1;
501513
}
502514

503-
void writeCallFlagsImm(CallFlags flags) {
504-
505-
uint8_t value = flags.getArgFormat();
506-
if (flags.isConstructing()) {
507-
value |= CallFlags::IsConstructing;
508-
}
509-
if (flags.isSameRealm()) {
510-
value |= CallFlags::IsSameRealm;
511-
}
512-
buffer_.writeByte(uint32_t(value));
513-
}
514-
515-
void writeOpWithOperandId(CacheOp op, OperandId opId) {
516-
writeOp(op);
517-
writeOperandId(opId);
518-
}
515+
void writeCallFlagsImm(CallFlags flags) { buffer_.writeByte(flags.toByte()); }
519516

520517
uint8_t addStubField(uint64_t value, StubField::Type fieldType) {
521518
uint8_t offset = 0;

js/src/jit/CacheIRSpewer.cpp

Lines changed: 251 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,254 @@
2929
using namespace js;
3030
using namespace js::jit;
3131

32+
33+
34+
35+
36+
37+
38+
39+
class MOZ_RAII CacheIROpsJitSpewer {
40+
GenericPrinter& out_;
41+
42+
43+
const char* prefix_;
44+
45+
CACHE_IR_SPEWER_GENERATED
46+
47+
void spewOp(CacheOp op) {
48+
const char* opName = CacheIrOpNames[size_t(op)];
49+
out_.printf("%s%-30s", prefix_, opName);
50+
}
51+
void spewOpEnd() { out_.printf("\n"); }
52+
53+
void spewArgSeparator() { out_.printf(", "); }
54+
55+
void spewOperandId(const char* name, OperandId id) {
56+
spewRawOperandId(name, id.id());
57+
}
58+
void spewRawOperandId(const char* name, uint32_t id) {
59+
out_.printf("%s %u", name, id);
60+
}
61+
void spewField(const char* name, uint32_t offset) {
62+
out_.printf("%s %u", name, offset);
63+
}
64+
void spewTypedThingLayoutImm(const char* name, TypedThingLayout layout) {
65+
switch (layout) {
66+
case Layout_TypedArray:
67+
out_.printf("%s TypedArray", name);
68+
return;
69+
case Layout_OutlineTypedObject:
70+
out_.printf("%s OutlineTypedObject", name);
71+
return;
72+
case Layout_InlineTypedObject:
73+
out_.printf("%s InlineTypedObject", name);
74+
return;
75+
}
76+
MOZ_CRASH("Unknown layout");
77+
}
78+
void spewBoolImm(const char* name, bool b) {
79+
out_.printf("%s %s", name, b ? "true" : "false");
80+
}
81+
void spewByteImm(const char* name, uint8_t val) {
82+
out_.printf("%s %u", name, val);
83+
}
84+
void spewJSOpImm(const char* name, JSOp op) {
85+
out_.printf("%s JSOp::%s", name, CodeName(op));
86+
}
87+
void spewStaticStringImm(const char* name, const char* str) {
88+
out_.printf("%s \"%s\"", name, str);
89+
}
90+
void spewInt32Imm(const char* name, int32_t val) {
91+
out_.printf("%s %d", name, val);
92+
}
93+
void spewUInt32Imm(const char* name, uint32_t val) {
94+
out_.printf("%s %u", name, val);
95+
}
96+
void spewCallFlagsImm(const char* name, CallFlags flags) {
97+
out_.printf("%s (format %u, isConstructing %u, isSameRealm %u)", name,
98+
flags.getArgFormat(), flags.isConstructing(),
99+
flags.isSameRealm());
100+
}
101+
void spewJSWhyMagicImm(const char* name, JSWhyMagic magic) {
102+
out_.printf("%s JSWhyMagic(%u)", name, unsigned(magic));
103+
}
104+
void spewScalarTypeImm(const char* name, Scalar::Type type) {
105+
out_.printf("%s Scalar::Type(%u)", name, unsigned(type));
106+
}
107+
void spewReferenceTypeImm(const char* name, ReferenceType type) {
108+
out_.printf("%s ReferenceType(%u)", name, unsigned(type));
109+
}
110+
void spewMetaTwoByteKindImm(const char* name, MetaTwoByteKind kind) {
111+
out_.printf("%s MetaTwoByteKind(%u)", name, unsigned(kind));
112+
}
113+
void spewValueTypeImm(const char* name, ValueType type) {
114+
out_.printf("%s ValueType(%u)", name, unsigned(type));
115+
}
116+
void spewJSNativeImm(const char* name, JSNative native) {
117+
out_.printf("%s %p", name, native);
118+
}
119+
void spewGuardClassKindImm(const char* name, GuardClassKind kind) {
120+
out_.printf("%s GuardClassKind(%u)", name, unsigned(kind));
121+
}
122+
123+
public:
124+
CacheIROpsJitSpewer(GenericPrinter& out, const char* prefix)
125+
: out_(out), prefix_(prefix) {}
126+
127+
void spew(CacheIRReader& reader) {
128+
do {
129+
switch (reader.readOp()) {
130+
# define SPEW_OP(op, ...) \
131+
case CacheOp::op: \
132+
spew##op(reader); \
133+
break;
134+
CACHE_IR_OPS(SPEW_OP)
135+
# undef SPEW_OP
136+
137+
default:
138+
MOZ_CRASH("Invalid op");
139+
}
140+
} while (reader.more());
141+
}
142+
};
143+
144+
void js::jit::SpewCacheIROps(GenericPrinter& out, const char* prefix,
145+
const CacheIRStubInfo* info) {
146+
CacheIRReader reader(info);
147+
CacheIROpsJitSpewer spewer(out, prefix);
148+
spewer.spew(reader);
149+
}
150+
151+
152+
153+
154+
155+
156+
157+
158+
159+
160+
161+
162+
163+
164+
165+
166+
167+
168+
169+
170+
171+
172+
173+
174+
175+
176+
177+
178+
179+
180+
class MOZ_RAII CacheIROpsJSONSpewer {
181+
JSONPrinter& j_;
182+
183+
CACHE_IR_SPEWER_GENERATED
184+
185+
void spewOp(CacheOp op) {
186+
const char* opName = CacheIrOpNames[size_t(op)];
187+
j_.beginObject();
188+
j_.property("op", opName);
189+
j_.beginListProperty("args");
190+
}
191+
void spewOpEnd() {
192+
j_.endList();
193+
j_.endObject();
194+
}
195+
196+
void spewArgSeparator() {}
197+
198+
template <typename T>
199+
void spewArgImpl(const char* name, const char* type, T value) {
200+
j_.beginObject();
201+
j_.property("name", name);
202+
j_.property("type", type);
203+
j_.property("value", value);
204+
j_.endObject();
205+
}
206+
207+
void spewOperandId(const char* name, OperandId id) {
208+
spewRawOperandId(name, id.id());
209+
}
210+
void spewRawOperandId(const char* name, uint32_t id) {
211+
spewArgImpl(name, "Id", id);
212+
}
213+
void spewField(const char* name, uint32_t offset) {
214+
spewArgImpl(name, "Field", offset);
215+
}
216+
void spewTypedThingLayoutImm(const char* name, TypedThingLayout layout) {
217+
spewArgImpl(name, "Imm", unsigned(layout));
218+
}
219+
void spewBoolImm(const char* name, bool b) { spewArgImpl(name, "Imm", b); }
220+
void spewByteImm(const char* name, uint8_t val) {
221+
spewArgImpl(name, "Imm", val);
222+
}
223+
void spewJSOpImm(const char* name, JSOp op) {
224+
spewArgImpl(name, "JSOp", CodeName(op));
225+
}
226+
void spewStaticStringImm(const char* name, const char* str) {
227+
spewArgImpl(name, "String", str);
228+
}
229+
void spewInt32Imm(const char* name, int32_t val) {
230+
spewArgImpl(name, "Imm", val);
231+
}
232+
void spewUInt32Imm(const char* name, uint32_t val) {
233+
spewArgImpl(name, "Imm", val);
234+
}
235+
void spewCallFlagsImm(const char* name, CallFlags flags) {
236+
spewArgImpl(name, "Imm", flags.toByte());
237+
}
238+
void spewJSWhyMagicImm(const char* name, JSWhyMagic magic) {
239+
spewArgImpl(name, "Imm", unsigned(magic));
240+
}
241+
void spewScalarTypeImm(const char* name, Scalar::Type type) {
242+
spewArgImpl(name, "Imm", unsigned(type));
243+
}
244+
void spewReferenceTypeImm(const char* name, ReferenceType type) {
245+
spewArgImpl(name, "Imm", unsigned(type));
246+
}
247+
void spewMetaTwoByteKindImm(const char* name, MetaTwoByteKind kind) {
248+
spewArgImpl(name, "Imm", unsigned(kind));
249+
}
250+
void spewValueTypeImm(const char* name, ValueType type) {
251+
spewArgImpl(name, "Imm", unsigned(type));
252+
}
253+
void spewJSNativeImm(const char* name, JSNative native) {
254+
spewArgImpl(name, "Word", uintptr_t(native));
255+
}
256+
void spewGuardClassKindImm(const char* name, GuardClassKind kind) {
257+
spewArgImpl(name, "Imm", unsigned(kind));
258+
}
259+
260+
public:
261+
explicit CacheIROpsJSONSpewer(JSONPrinter& j) : j_(j) {}
262+
263+
void spew(CacheIRReader& reader) {
264+
do {
265+
switch (reader.readOp()) {
266+
# define SPEW_OP(op, ...) \
267+
case CacheOp::op: \
268+
spew##op(reader); \
269+
break;
270+
CACHE_IR_OPS(SPEW_OP)
271+
# undef SPEW_OP
272+
273+
default:
274+
MOZ_CRASH("Invalid op");
275+
}
276+
} while (reader.more());
277+
}
278+
};
279+
32280
CacheIRSpewer CacheIRSpewer::cacheIRspewer;
33281

34282
CacheIRSpewer::CacheIRSpewer()
@@ -193,68 +441,15 @@ void CacheIRSpewer::opcodeProperty(const char* name, const JSOp op) {
193441
j.endStringProperty();
194442
}
195443

196-
void CacheIRSpewer::CacheIRArg(JSONPrinter& j, CacheIRReader& r,
197-
CacheIROpFormat::ArgType arg) {
198-
j.beginObject();
199-
switch (arg) {
200-
case CacheIROpFormat::None:
201-
break;
202-
case CacheIROpFormat::Id:
203-
j.property("Id", r.readByte());
204-
break;
205-
case CacheIROpFormat::Field:
206-
j.property("Field", r.readByte());
207-
break;
208-
case CacheIROpFormat::Byte:
209-
j.property("Byte", r.readByte());
210-
break;
211-
case CacheIROpFormat::Int32:
212-
j.property("Int32", r.int32Immediate());
213-
break;
214-
case CacheIROpFormat::UInt32:
215-
j.property("Uint32", r.uint32Immediate());
216-
break;
217-
case CacheIROpFormat::Word:
218-
j.property("Word", uintptr_t(r.pointer()));
219-
break;
220-
}
221-
j.endObject();
222-
}
223-
template <typename... Args>
224-
void CacheIRSpewer::CacheIRArgs(JSONPrinter& j, CacheIRReader& r,
225-
Args... args) {
226-
using namespace js::jit::CacheIROpFormat;
227-
228-
(CacheIRArg(j, r, args), ...);
229-
}
230-
231444
void CacheIRSpewer::cacheIRSequence(CacheIRReader& reader) {
232-
using namespace js::jit::CacheIROpFormat;
233-
234445
MOZ_ASSERT(enabled());
235446
JSONPrinter& j = json_.ref();
236447

237448
j.beginListProperty("cacheIR");
238-
while (reader.more()) {
239-
j.beginObject();
240-
CacheOp op = reader.readOp();
241-
j.property("op", CacheIrOpNames[uint32_t(op)]);
242-
j.beginListProperty("args");
243-
244-
switch (op) {
245-
# define DEFINE_OP(op, ...) \
246-
case CacheOp::op: \
247-
CacheIRArgs(j, reader, __VA_ARGS__); \
248-
break;
249-
CACHE_IR_OPS(DEFINE_OP)
250-
# undef DEFINE_OP
251-
default:
252-
MOZ_CRASH("unreachable");
253-
}
254449

255-
j.endList();
256-
j.endObject();
257-
}
450+
CacheIROpsJSONSpewer spewer(j);
451+
spewer.spew(reader);
452+
258453
j.endList();
259454
}
260455

js/src/jit/CacheIRSpewer.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,6 @@ class CacheIRSpewer {
5151
void valueProperty(const char* name, const Value& v);
5252
void opcodeProperty(const char* name, const JSOp op);
5353
void cacheIRSequence(CacheIRReader& reader);
54-
void CacheIRArg(JSONPrinter& j, CacheIRReader& r,
55-
CacheIROpFormat::ArgType arg);
56-
template <typename... Args>
57-
void CacheIRArgs(JSONPrinter& j, CacheIRReader& r, Args... args);
5854
void attached(const char* name);
5955
void endCache();
6056

@@ -105,6 +101,9 @@ class CacheIRSpewer {
105101
};
106102
};
107103

104+
extern void SpewCacheIROps(GenericPrinter& out, const char* prefix,
105+
const CacheIRStubInfo* info);
106+
108107
}
109108
}
110109

0 commit comments

Comments
 (0)