js/src/jit/JSONSpewer.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

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.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 * vim: set ts=8 sts=4 et sw=4 tw=99:
michael@0 3 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include "jit/JSONSpewer.h"
michael@0 8
michael@0 9 #include <stdarg.h>
michael@0 10
michael@0 11 #include "jit/LinearScan.h"
michael@0 12 #include "jit/LIR.h"
michael@0 13 #include "jit/MIR.h"
michael@0 14 #include "jit/MIRGraph.h"
michael@0 15 #include "jit/RangeAnalysis.h"
michael@0 16
michael@0 17 using namespace js;
michael@0 18 using namespace js::jit;
michael@0 19
michael@0 20 JSONSpewer::~JSONSpewer()
michael@0 21 {
michael@0 22 if (fp_)
michael@0 23 fclose(fp_);
michael@0 24 }
michael@0 25
michael@0 26 void
michael@0 27 JSONSpewer::indent()
michael@0 28 {
michael@0 29 if (!fp_)
michael@0 30 return;
michael@0 31 JS_ASSERT(indentLevel_ >= 0);
michael@0 32 fprintf(fp_, "\n");
michael@0 33 for (int i = 0; i < indentLevel_; i++)
michael@0 34 fprintf(fp_, " ");
michael@0 35 }
michael@0 36
michael@0 37 void
michael@0 38 JSONSpewer::property(const char *name)
michael@0 39 {
michael@0 40 if (!fp_)
michael@0 41 return;
michael@0 42
michael@0 43 if (!first_)
michael@0 44 fprintf(fp_, ",");
michael@0 45 indent();
michael@0 46 fprintf(fp_, "\"%s\":", name);
michael@0 47 first_ = false;
michael@0 48 }
michael@0 49
michael@0 50 void
michael@0 51 JSONSpewer::beginObject()
michael@0 52 {
michael@0 53 if (!fp_)
michael@0 54 return;
michael@0 55
michael@0 56 if (!first_) {
michael@0 57 fprintf(fp_, ",");
michael@0 58 indent();
michael@0 59 }
michael@0 60 fprintf(fp_, "{");
michael@0 61 indentLevel_++;
michael@0 62 first_ = true;
michael@0 63 }
michael@0 64
michael@0 65 void
michael@0 66 JSONSpewer::beginObjectProperty(const char *name)
michael@0 67 {
michael@0 68 if (!fp_)
michael@0 69 return;
michael@0 70
michael@0 71 property(name);
michael@0 72 fprintf(fp_, "{");
michael@0 73 indentLevel_++;
michael@0 74 first_ = true;
michael@0 75 }
michael@0 76
michael@0 77 void
michael@0 78 JSONSpewer::beginListProperty(const char *name)
michael@0 79 {
michael@0 80 if (!fp_)
michael@0 81 return;
michael@0 82
michael@0 83 property(name);
michael@0 84 fprintf(fp_, "[");
michael@0 85 first_ = true;
michael@0 86 }
michael@0 87
michael@0 88 void
michael@0 89 JSONSpewer::stringProperty(const char *name, const char *format, ...)
michael@0 90 {
michael@0 91 if (!fp_)
michael@0 92 return;
michael@0 93
michael@0 94 va_list ap;
michael@0 95 va_start(ap, format);
michael@0 96
michael@0 97 property(name);
michael@0 98 fprintf(fp_, "\"");
michael@0 99 vfprintf(fp_, format, ap);
michael@0 100 fprintf(fp_, "\"");
michael@0 101
michael@0 102 va_end(ap);
michael@0 103 }
michael@0 104
michael@0 105 void
michael@0 106 JSONSpewer::stringValue(const char *format, ...)
michael@0 107 {
michael@0 108 if (!fp_)
michael@0 109 return;
michael@0 110
michael@0 111 va_list ap;
michael@0 112 va_start(ap, format);
michael@0 113
michael@0 114 if (!first_)
michael@0 115 fprintf(fp_, ",");
michael@0 116 fprintf(fp_, "\"");
michael@0 117 vfprintf(fp_, format, ap);
michael@0 118 fprintf(fp_, "\"");
michael@0 119
michael@0 120 va_end(ap);
michael@0 121 first_ = false;
michael@0 122 }
michael@0 123
michael@0 124 void
michael@0 125 JSONSpewer::integerProperty(const char *name, int value)
michael@0 126 {
michael@0 127 if (!fp_)
michael@0 128 return;
michael@0 129
michael@0 130 property(name);
michael@0 131 fprintf(fp_, "%d", value);
michael@0 132 }
michael@0 133
michael@0 134 void
michael@0 135 JSONSpewer::integerValue(int value)
michael@0 136 {
michael@0 137 if (!fp_)
michael@0 138 return;
michael@0 139
michael@0 140 if (!first_)
michael@0 141 fprintf(fp_, ",");
michael@0 142 fprintf(fp_, "%d", value);
michael@0 143 first_ = false;
michael@0 144 }
michael@0 145
michael@0 146 void
michael@0 147 JSONSpewer::endObject()
michael@0 148 {
michael@0 149 if (!fp_)
michael@0 150 return;
michael@0 151
michael@0 152 indentLevel_--;
michael@0 153 indent();
michael@0 154 fprintf(fp_, "}");
michael@0 155 first_ = false;
michael@0 156 }
michael@0 157
michael@0 158 void
michael@0 159 JSONSpewer::endList()
michael@0 160 {
michael@0 161 if (!fp_)
michael@0 162 return;
michael@0 163
michael@0 164 fprintf(fp_, "]");
michael@0 165 first_ = false;
michael@0 166 }
michael@0 167
michael@0 168 bool
michael@0 169 JSONSpewer::init(const char *path)
michael@0 170 {
michael@0 171 fp_ = fopen(path, "w");
michael@0 172 if (!fp_)
michael@0 173 return false;
michael@0 174
michael@0 175 beginObject();
michael@0 176 beginListProperty("functions");
michael@0 177 return true;
michael@0 178 }
michael@0 179
michael@0 180 void
michael@0 181 JSONSpewer::beginFunction(JSScript *script)
michael@0 182 {
michael@0 183 if (inFunction_)
michael@0 184 endFunction();
michael@0 185
michael@0 186 beginObject();
michael@0 187 if (script)
michael@0 188 stringProperty("name", "%s:%d", script->filename(), script->lineno());
michael@0 189 else
michael@0 190 stringProperty("name", "asm.js compilation");
michael@0 191 beginListProperty("passes");
michael@0 192
michael@0 193 inFunction_ = true;
michael@0 194 }
michael@0 195
michael@0 196 void
michael@0 197 JSONSpewer::beginPass(const char *pass)
michael@0 198 {
michael@0 199 beginObject();
michael@0 200 stringProperty("name", pass);
michael@0 201 }
michael@0 202
michael@0 203 void
michael@0 204 JSONSpewer::spewMResumePoint(MResumePoint *rp)
michael@0 205 {
michael@0 206 if (!rp)
michael@0 207 return;
michael@0 208
michael@0 209 beginObjectProperty("resumePoint");
michael@0 210
michael@0 211 if (rp->caller())
michael@0 212 integerProperty("caller", rp->caller()->block()->id());
michael@0 213
michael@0 214 property("mode");
michael@0 215 switch (rp->mode()) {
michael@0 216 case MResumePoint::ResumeAt:
michael@0 217 fprintf(fp_, "\"At\"");
michael@0 218 break;
michael@0 219 case MResumePoint::ResumeAfter:
michael@0 220 fprintf(fp_, "\"After\"");
michael@0 221 break;
michael@0 222 case MResumePoint::Outer:
michael@0 223 fprintf(fp_, "\"Outer\"");
michael@0 224 break;
michael@0 225 }
michael@0 226
michael@0 227 beginListProperty("operands");
michael@0 228 for (MResumePoint *iter = rp; iter; iter = iter->caller()) {
michael@0 229 for (int i = iter->numOperands() - 1; i >= 0; i--)
michael@0 230 integerValue(iter->getOperand(i)->id());
michael@0 231 }
michael@0 232 endList();
michael@0 233
michael@0 234 endObject();
michael@0 235 }
michael@0 236
michael@0 237 void
michael@0 238 JSONSpewer::spewMDef(MDefinition *def)
michael@0 239 {
michael@0 240 beginObject();
michael@0 241
michael@0 242 integerProperty("id", def->id());
michael@0 243
michael@0 244 property("opcode");
michael@0 245 fprintf(fp_, "\"");
michael@0 246 def->printOpcode(fp_);
michael@0 247 fprintf(fp_, "\"");
michael@0 248
michael@0 249 beginListProperty("attributes");
michael@0 250 #define OUTPUT_ATTRIBUTE(X) do{ if(def->is##X()) stringValue(#X); } while(0);
michael@0 251 MIR_FLAG_LIST(OUTPUT_ATTRIBUTE);
michael@0 252 #undef OUTPUT_ATTRIBUTE
michael@0 253 endList();
michael@0 254
michael@0 255 beginListProperty("inputs");
michael@0 256 for (size_t i = 0, e = def->numOperands(); i < e; i++)
michael@0 257 integerValue(def->getOperand(i)->id());
michael@0 258 endList();
michael@0 259
michael@0 260 beginListProperty("uses");
michael@0 261 for (MUseDefIterator use(def); use; use++)
michael@0 262 integerValue(use.def()->id());
michael@0 263 endList();
michael@0 264
michael@0 265 bool isTruncated = false;
michael@0 266 if (def->isAdd() || def->isSub() || def->isMod() || def->isMul() || def->isDiv())
michael@0 267 isTruncated = static_cast<MBinaryArithInstruction*>(def)->isTruncated();
michael@0 268
michael@0 269 if (def->type() != MIRType_None && def->range()) {
michael@0 270 Sprinter sp(GetIonContext()->cx);
michael@0 271 sp.init();
michael@0 272 def->range()->print(sp);
michael@0 273 stringProperty("type", "%s : %s%s", sp.string(), StringFromMIRType(def->type()), (isTruncated ? " (t)" : ""));
michael@0 274 } else {
michael@0 275 stringProperty("type", "%s%s", StringFromMIRType(def->type()), (isTruncated ? " (t)" : ""));
michael@0 276 }
michael@0 277
michael@0 278 if (def->isInstruction()) {
michael@0 279 if (MResumePoint *rp = def->toInstruction()->resumePoint())
michael@0 280 spewMResumePoint(rp);
michael@0 281 }
michael@0 282
michael@0 283 endObject();
michael@0 284 }
michael@0 285
michael@0 286 void
michael@0 287 JSONSpewer::spewMIR(MIRGraph *mir)
michael@0 288 {
michael@0 289 if (!fp_)
michael@0 290 return;
michael@0 291
michael@0 292 beginObjectProperty("mir");
michael@0 293 beginListProperty("blocks");
michael@0 294
michael@0 295 for (MBasicBlockIterator block(mir->begin()); block != mir->end(); block++) {
michael@0 296 beginObject();
michael@0 297
michael@0 298 integerProperty("number", block->id());
michael@0 299
michael@0 300 beginListProperty("attributes");
michael@0 301 if (block->isLoopBackedge())
michael@0 302 stringValue("backedge");
michael@0 303 if (block->isLoopHeader())
michael@0 304 stringValue("loopheader");
michael@0 305 if (block->isSplitEdge())
michael@0 306 stringValue("splitedge");
michael@0 307 endList();
michael@0 308
michael@0 309 beginListProperty("predecessors");
michael@0 310 for (size_t i = 0; i < block->numPredecessors(); i++)
michael@0 311 integerValue(block->getPredecessor(i)->id());
michael@0 312 endList();
michael@0 313
michael@0 314 beginListProperty("successors");
michael@0 315 for (size_t i = 0; i < block->numSuccessors(); i++)
michael@0 316 integerValue(block->getSuccessor(i)->id());
michael@0 317 endList();
michael@0 318
michael@0 319 beginListProperty("instructions");
michael@0 320 for (MPhiIterator phi(block->phisBegin()); phi != block->phisEnd(); phi++)
michael@0 321 spewMDef(*phi);
michael@0 322 for (MInstructionIterator i(block->begin()); i != block->end(); i++)
michael@0 323 spewMDef(*i);
michael@0 324 endList();
michael@0 325
michael@0 326 spewMResumePoint(block->entryResumePoint());
michael@0 327
michael@0 328 endObject();
michael@0 329 }
michael@0 330
michael@0 331 endList();
michael@0 332 endObject();
michael@0 333 }
michael@0 334
michael@0 335 void
michael@0 336 JSONSpewer::spewLIns(LInstruction *ins)
michael@0 337 {
michael@0 338 if (!fp_)
michael@0 339 return;
michael@0 340
michael@0 341 beginObject();
michael@0 342
michael@0 343 integerProperty("id", ins->id());
michael@0 344
michael@0 345 property("opcode");
michael@0 346 fprintf(fp_, "\"");
michael@0 347 ins->dump(fp_);
michael@0 348 fprintf(fp_, "\"");
michael@0 349
michael@0 350 beginListProperty("defs");
michael@0 351 for (size_t i = 0; i < ins->numDefs(); i++)
michael@0 352 integerValue(ins->getDef(i)->virtualRegister());
michael@0 353 endList();
michael@0 354
michael@0 355 endObject();
michael@0 356 }
michael@0 357
michael@0 358 void
michael@0 359 JSONSpewer::spewLIR(MIRGraph *mir)
michael@0 360 {
michael@0 361 if (!fp_)
michael@0 362 return;
michael@0 363
michael@0 364 beginObjectProperty("lir");
michael@0 365 beginListProperty("blocks");
michael@0 366
michael@0 367 for (MBasicBlockIterator i(mir->begin()); i != mir->end(); i++) {
michael@0 368 LBlock *block = i->lir();
michael@0 369 if (!block)
michael@0 370 continue;
michael@0 371
michael@0 372 beginObject();
michael@0 373 integerProperty("number", i->id());
michael@0 374
michael@0 375 beginListProperty("instructions");
michael@0 376 for (size_t p = 0; p < block->numPhis(); p++)
michael@0 377 spewLIns(block->getPhi(p));
michael@0 378 for (LInstructionIterator ins(block->begin()); ins != block->end(); ins++)
michael@0 379 spewLIns(*ins);
michael@0 380 endList();
michael@0 381
michael@0 382 endObject();
michael@0 383 }
michael@0 384
michael@0 385 endList();
michael@0 386 endObject();
michael@0 387 }
michael@0 388
michael@0 389 void
michael@0 390 JSONSpewer::spewIntervals(LinearScanAllocator *regalloc)
michael@0 391 {
michael@0 392 if (!fp_)
michael@0 393 return;
michael@0 394
michael@0 395 beginObjectProperty("intervals");
michael@0 396 beginListProperty("blocks");
michael@0 397
michael@0 398 for (size_t bno = 0; bno < regalloc->graph.numBlocks(); bno++) {
michael@0 399 beginObject();
michael@0 400 integerProperty("number", bno);
michael@0 401 beginListProperty("vregs");
michael@0 402
michael@0 403 LBlock *lir = regalloc->graph.getBlock(bno);
michael@0 404 for (LInstructionIterator ins = lir->begin(); ins != lir->end(); ins++) {
michael@0 405 for (size_t k = 0; k < ins->numDefs(); k++) {
michael@0 406 uint32_t id = ins->getDef(k)->virtualRegister();
michael@0 407 VirtualRegister *vreg = &regalloc->vregs[id];
michael@0 408
michael@0 409 beginObject();
michael@0 410 integerProperty("vreg", id);
michael@0 411 beginListProperty("intervals");
michael@0 412
michael@0 413 for (size_t i = 0; i < vreg->numIntervals(); i++) {
michael@0 414 LiveInterval *live = vreg->getInterval(i);
michael@0 415
michael@0 416 if (live->numRanges()) {
michael@0 417 beginObject();
michael@0 418 property("allocation");
michael@0 419 fprintf(fp_, "\"%s\"", live->getAllocation()->toString());
michael@0 420 beginListProperty("ranges");
michael@0 421
michael@0 422 for (size_t j = 0; j < live->numRanges(); j++) {
michael@0 423 beginObject();
michael@0 424 integerProperty("start", live->getRange(j)->from.pos());
michael@0 425 integerProperty("end", live->getRange(j)->to.pos());
michael@0 426 endObject();
michael@0 427 }
michael@0 428
michael@0 429 endList();
michael@0 430 endObject();
michael@0 431 }
michael@0 432 }
michael@0 433
michael@0 434 endList();
michael@0 435 endObject();
michael@0 436 }
michael@0 437 }
michael@0 438
michael@0 439 endList();
michael@0 440 endObject();
michael@0 441 }
michael@0 442
michael@0 443 endList();
michael@0 444 endObject();
michael@0 445 }
michael@0 446
michael@0 447 void
michael@0 448 JSONSpewer::endPass()
michael@0 449 {
michael@0 450 endObject();
michael@0 451 fflush(fp_);
michael@0 452 }
michael@0 453
michael@0 454 void
michael@0 455 JSONSpewer::endFunction()
michael@0 456 {
michael@0 457 JS_ASSERT(inFunction_);
michael@0 458 endList();
michael@0 459 endObject();
michael@0 460 fflush(fp_);
michael@0 461 inFunction_ = false;
michael@0 462 }
michael@0 463
michael@0 464 void
michael@0 465 JSONSpewer::finish()
michael@0 466 {
michael@0 467 if (!fp_)
michael@0 468 return;
michael@0 469
michael@0 470 if (inFunction_)
michael@0 471 endFunction();
michael@0 472
michael@0 473 endList();
michael@0 474 endObject();
michael@0 475 fprintf(fp_, "\n");
michael@0 476
michael@0 477 fclose(fp_);
michael@0 478 fp_ = nullptr;
michael@0 479 }
michael@0 480

mercurial