Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
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 #include "jit/JSONSpewer.h"
9 #include <stdarg.h>
11 #include "jit/LinearScan.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 JSONSpewer::~JSONSpewer()
21 {
22 if (fp_)
23 fclose(fp_);
24 }
26 void
27 JSONSpewer::indent()
28 {
29 if (!fp_)
30 return;
31 JS_ASSERT(indentLevel_ >= 0);
32 fprintf(fp_, "\n");
33 for (int i = 0; i < indentLevel_; i++)
34 fprintf(fp_, " ");
35 }
37 void
38 JSONSpewer::property(const char *name)
39 {
40 if (!fp_)
41 return;
43 if (!first_)
44 fprintf(fp_, ",");
45 indent();
46 fprintf(fp_, "\"%s\":", name);
47 first_ = false;
48 }
50 void
51 JSONSpewer::beginObject()
52 {
53 if (!fp_)
54 return;
56 if (!first_) {
57 fprintf(fp_, ",");
58 indent();
59 }
60 fprintf(fp_, "{");
61 indentLevel_++;
62 first_ = true;
63 }
65 void
66 JSONSpewer::beginObjectProperty(const char *name)
67 {
68 if (!fp_)
69 return;
71 property(name);
72 fprintf(fp_, "{");
73 indentLevel_++;
74 first_ = true;
75 }
77 void
78 JSONSpewer::beginListProperty(const char *name)
79 {
80 if (!fp_)
81 return;
83 property(name);
84 fprintf(fp_, "[");
85 first_ = true;
86 }
88 void
89 JSONSpewer::stringProperty(const char *name, const char *format, ...)
90 {
91 if (!fp_)
92 return;
94 va_list ap;
95 va_start(ap, format);
97 property(name);
98 fprintf(fp_, "\"");
99 vfprintf(fp_, format, ap);
100 fprintf(fp_, "\"");
102 va_end(ap);
103 }
105 void
106 JSONSpewer::stringValue(const char *format, ...)
107 {
108 if (!fp_)
109 return;
111 va_list ap;
112 va_start(ap, format);
114 if (!first_)
115 fprintf(fp_, ",");
116 fprintf(fp_, "\"");
117 vfprintf(fp_, format, ap);
118 fprintf(fp_, "\"");
120 va_end(ap);
121 first_ = false;
122 }
124 void
125 JSONSpewer::integerProperty(const char *name, int value)
126 {
127 if (!fp_)
128 return;
130 property(name);
131 fprintf(fp_, "%d", value);
132 }
134 void
135 JSONSpewer::integerValue(int value)
136 {
137 if (!fp_)
138 return;
140 if (!first_)
141 fprintf(fp_, ",");
142 fprintf(fp_, "%d", value);
143 first_ = false;
144 }
146 void
147 JSONSpewer::endObject()
148 {
149 if (!fp_)
150 return;
152 indentLevel_--;
153 indent();
154 fprintf(fp_, "}");
155 first_ = false;
156 }
158 void
159 JSONSpewer::endList()
160 {
161 if (!fp_)
162 return;
164 fprintf(fp_, "]");
165 first_ = false;
166 }
168 bool
169 JSONSpewer::init(const char *path)
170 {
171 fp_ = fopen(path, "w");
172 if (!fp_)
173 return false;
175 beginObject();
176 beginListProperty("functions");
177 return true;
178 }
180 void
181 JSONSpewer::beginFunction(JSScript *script)
182 {
183 if (inFunction_)
184 endFunction();
186 beginObject();
187 if (script)
188 stringProperty("name", "%s:%d", script->filename(), script->lineno());
189 else
190 stringProperty("name", "asm.js compilation");
191 beginListProperty("passes");
193 inFunction_ = true;
194 }
196 void
197 JSONSpewer::beginPass(const char *pass)
198 {
199 beginObject();
200 stringProperty("name", pass);
201 }
203 void
204 JSONSpewer::spewMResumePoint(MResumePoint *rp)
205 {
206 if (!rp)
207 return;
209 beginObjectProperty("resumePoint");
211 if (rp->caller())
212 integerProperty("caller", rp->caller()->block()->id());
214 property("mode");
215 switch (rp->mode()) {
216 case MResumePoint::ResumeAt:
217 fprintf(fp_, "\"At\"");
218 break;
219 case MResumePoint::ResumeAfter:
220 fprintf(fp_, "\"After\"");
221 break;
222 case MResumePoint::Outer:
223 fprintf(fp_, "\"Outer\"");
224 break;
225 }
227 beginListProperty("operands");
228 for (MResumePoint *iter = rp; iter; iter = iter->caller()) {
229 for (int i = iter->numOperands() - 1; i >= 0; i--)
230 integerValue(iter->getOperand(i)->id());
231 }
232 endList();
234 endObject();
235 }
237 void
238 JSONSpewer::spewMDef(MDefinition *def)
239 {
240 beginObject();
242 integerProperty("id", def->id());
244 property("opcode");
245 fprintf(fp_, "\"");
246 def->printOpcode(fp_);
247 fprintf(fp_, "\"");
249 beginListProperty("attributes");
250 #define OUTPUT_ATTRIBUTE(X) do{ if(def->is##X()) stringValue(#X); } while(0);
251 MIR_FLAG_LIST(OUTPUT_ATTRIBUTE);
252 #undef OUTPUT_ATTRIBUTE
253 endList();
255 beginListProperty("inputs");
256 for (size_t i = 0, e = def->numOperands(); i < e; i++)
257 integerValue(def->getOperand(i)->id());
258 endList();
260 beginListProperty("uses");
261 for (MUseDefIterator use(def); use; use++)
262 integerValue(use.def()->id());
263 endList();
265 bool isTruncated = false;
266 if (def->isAdd() || def->isSub() || def->isMod() || def->isMul() || def->isDiv())
267 isTruncated = static_cast<MBinaryArithInstruction*>(def)->isTruncated();
269 if (def->type() != MIRType_None && def->range()) {
270 Sprinter sp(GetIonContext()->cx);
271 sp.init();
272 def->range()->print(sp);
273 stringProperty("type", "%s : %s%s", sp.string(), StringFromMIRType(def->type()), (isTruncated ? " (t)" : ""));
274 } else {
275 stringProperty("type", "%s%s", StringFromMIRType(def->type()), (isTruncated ? " (t)" : ""));
276 }
278 if (def->isInstruction()) {
279 if (MResumePoint *rp = def->toInstruction()->resumePoint())
280 spewMResumePoint(rp);
281 }
283 endObject();
284 }
286 void
287 JSONSpewer::spewMIR(MIRGraph *mir)
288 {
289 if (!fp_)
290 return;
292 beginObjectProperty("mir");
293 beginListProperty("blocks");
295 for (MBasicBlockIterator block(mir->begin()); block != mir->end(); block++) {
296 beginObject();
298 integerProperty("number", block->id());
300 beginListProperty("attributes");
301 if (block->isLoopBackedge())
302 stringValue("backedge");
303 if (block->isLoopHeader())
304 stringValue("loopheader");
305 if (block->isSplitEdge())
306 stringValue("splitedge");
307 endList();
309 beginListProperty("predecessors");
310 for (size_t i = 0; i < block->numPredecessors(); i++)
311 integerValue(block->getPredecessor(i)->id());
312 endList();
314 beginListProperty("successors");
315 for (size_t i = 0; i < block->numSuccessors(); i++)
316 integerValue(block->getSuccessor(i)->id());
317 endList();
319 beginListProperty("instructions");
320 for (MPhiIterator phi(block->phisBegin()); phi != block->phisEnd(); phi++)
321 spewMDef(*phi);
322 for (MInstructionIterator i(block->begin()); i != block->end(); i++)
323 spewMDef(*i);
324 endList();
326 spewMResumePoint(block->entryResumePoint());
328 endObject();
329 }
331 endList();
332 endObject();
333 }
335 void
336 JSONSpewer::spewLIns(LInstruction *ins)
337 {
338 if (!fp_)
339 return;
341 beginObject();
343 integerProperty("id", ins->id());
345 property("opcode");
346 fprintf(fp_, "\"");
347 ins->dump(fp_);
348 fprintf(fp_, "\"");
350 beginListProperty("defs");
351 for (size_t i = 0; i < ins->numDefs(); i++)
352 integerValue(ins->getDef(i)->virtualRegister());
353 endList();
355 endObject();
356 }
358 void
359 JSONSpewer::spewLIR(MIRGraph *mir)
360 {
361 if (!fp_)
362 return;
364 beginObjectProperty("lir");
365 beginListProperty("blocks");
367 for (MBasicBlockIterator i(mir->begin()); i != mir->end(); i++) {
368 LBlock *block = i->lir();
369 if (!block)
370 continue;
372 beginObject();
373 integerProperty("number", i->id());
375 beginListProperty("instructions");
376 for (size_t p = 0; p < block->numPhis(); p++)
377 spewLIns(block->getPhi(p));
378 for (LInstructionIterator ins(block->begin()); ins != block->end(); ins++)
379 spewLIns(*ins);
380 endList();
382 endObject();
383 }
385 endList();
386 endObject();
387 }
389 void
390 JSONSpewer::spewIntervals(LinearScanAllocator *regalloc)
391 {
392 if (!fp_)
393 return;
395 beginObjectProperty("intervals");
396 beginListProperty("blocks");
398 for (size_t bno = 0; bno < regalloc->graph.numBlocks(); bno++) {
399 beginObject();
400 integerProperty("number", bno);
401 beginListProperty("vregs");
403 LBlock *lir = regalloc->graph.getBlock(bno);
404 for (LInstructionIterator ins = lir->begin(); ins != lir->end(); ins++) {
405 for (size_t k = 0; k < ins->numDefs(); k++) {
406 uint32_t id = ins->getDef(k)->virtualRegister();
407 VirtualRegister *vreg = ®alloc->vregs[id];
409 beginObject();
410 integerProperty("vreg", id);
411 beginListProperty("intervals");
413 for (size_t i = 0; i < vreg->numIntervals(); i++) {
414 LiveInterval *live = vreg->getInterval(i);
416 if (live->numRanges()) {
417 beginObject();
418 property("allocation");
419 fprintf(fp_, "\"%s\"", live->getAllocation()->toString());
420 beginListProperty("ranges");
422 for (size_t j = 0; j < live->numRanges(); j++) {
423 beginObject();
424 integerProperty("start", live->getRange(j)->from.pos());
425 integerProperty("end", live->getRange(j)->to.pos());
426 endObject();
427 }
429 endList();
430 endObject();
431 }
432 }
434 endList();
435 endObject();
436 }
437 }
439 endList();
440 endObject();
441 }
443 endList();
444 endObject();
445 }
447 void
448 JSONSpewer::endPass()
449 {
450 endObject();
451 fflush(fp_);
452 }
454 void
455 JSONSpewer::endFunction()
456 {
457 JS_ASSERT(inFunction_);
458 endList();
459 endObject();
460 fflush(fp_);
461 inFunction_ = false;
462 }
464 void
465 JSONSpewer::finish()
466 {
467 if (!fp_)
468 return;
470 if (inFunction_)
471 endFunction();
473 endList();
474 endObject();
475 fprintf(fp_, "\n");
477 fclose(fp_);
478 fp_ = nullptr;
479 }