|
29 | 29 | using namespace js;
|
30 | 30 | using namespace js::jit;
|
31 | 31 |
|
| 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 | + |
32 | 280 | CacheIRSpewer CacheIRSpewer::cacheIRspewer;
|
33 | 281 |
|
34 | 282 | CacheIRSpewer::CacheIRSpewer()
|
@@ -193,68 +441,15 @@ void CacheIRSpewer::opcodeProperty(const char* name, const JSOp op) {
|
193 | 441 | j.endStringProperty();
|
194 | 442 | }
|
195 | 443 |
|
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 |
| - |
231 | 444 | void CacheIRSpewer::cacheIRSequence(CacheIRReader& reader) {
|
232 |
| - using namespace js::jit::CacheIROpFormat; |
233 |
| - |
234 | 445 | MOZ_ASSERT(enabled());
|
235 | 446 | JSONPrinter& j = json_.ref();
|
236 | 447 |
|
237 | 448 | 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 |
| - } |
254 | 449 |
|
255 |
| - j.endList(); |
256 |
| - j.endObject(); |
257 |
| - } |
| 450 | + CacheIROpsJSONSpewer spewer(j); |
| 451 | + spewer.spew(reader); |
| 452 | + |
258 | 453 | j.endList();
|
259 | 454 | }
|
260 | 455 |
|
|
0 commit comments