mozjs38-fix-tracelogger.patch 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. # === Fix the SM38 tracelogger ===
  2. # This patch is a squashed version of several patches that were adapted
  3. # to fix failing hunks.
  4. #
  5. # Applied in the following order, they are:
  6. # * https://bugzilla.mozilla.org/show_bug.cgi?id=1223767
  7. # Assertion failure: i < size_, at js/src/vm/TraceLoggingTypes.h:210
  8. # Also fix stop-information to make reduce.py work correctly.
  9. # * https://bugzilla.mozilla.org/show_bug.cgi?id=1227914
  10. # Limit the memory tracelogger can take.
  11. # This causes tracelogger to flush data to the disk regularly and prevents out of
  12. # memory issues if a lot of data gets logged.
  13. # * https://bugzilla.mozilla.org/show_bug.cgi?id=1155618
  14. # Fix tracelogger destructor that touches possibly uninitialised hash table.
  15. # * https://bugzilla.mozilla.org/show_bug.cgi?id=1223636
  16. # Don't treat extraTextId as containing only extra ids.
  17. # This fixes an assertion failure: id == nextTextId at js/src/vm/TraceLoggingGraph.cpp
  18. # * https://bugzilla.mozilla.org/show_bug.cgi?id=1227028
  19. # Fix when to keep the payload of a TraceLogger event.
  20. # This fixes an assertion failure: textId < uint32_t(1 << 31) at js/src/vm/TraceLoggingGraph.h
  21. # * https://bugzilla.mozilla.org/show_bug.cgi?id=1266649
  22. # Handle failing to add to pointermap gracefully.
  23. # * https://bugzilla.mozilla.org/show_bug.cgi?id=1280648
  24. # Don't cache based on pointers to movable GC things.
  25. # * https://bugzilla.mozilla.org/show_bug.cgi?id=1224123
  26. # Fix the use of LastEntryId in tracelogger.h.
  27. # * https://bugzilla.mozilla.org/show_bug.cgi?id=1231170
  28. # Use size in debugger instead of the current id to track last logged item.
  29. # * https://bugzilla.mozilla.org/show_bug.cgi?id=1221844
  30. # Move TraceLogger_Invalidation to LOG_ITEM.
  31. # Add some debug checks to logTimestamp.
  32. # * https://bugzilla.mozilla.org/show_bug.cgi?id=1255766
  33. # Also mark resizing of memory.
  34. # * https://bugzilla.mozilla.org/show_bug.cgi?id=1259403
  35. # Only increase capacity by multiples of 2.
  36. # Always make sure there are 3 free slots for events.
  37. # ===
  38. diff --git a/js/src/jit-test/tests/tracelogger/bug1231170.js b/js/src/jit-test/tests/tracelogger/bug1231170.js
  39. new file mode 100644
  40. index 0000000..023e93e
  41. --- /dev/null
  42. +++ b/js/src/jit-test/tests/tracelogger/bug1231170.js
  43. @@ -0,0 +1,3 @@
  44. +var du = new Debugger();
  45. +if (typeof du.drainTraceLogger === "function")
  46. + du.drainTraceLogger();
  47. diff --git a/js/src/jit-test/tests/tracelogger/bug1266649.js b/js/src/jit-test/tests/tracelogger/bug1266649.js
  48. new file mode 100644
  49. index 0000000..81ae7ad
  50. --- /dev/null
  51. +++ b/js/src/jit-test/tests/tracelogger/bug1266649.js
  52. @@ -0,0 +1,10 @@
  53. +
  54. +var du = new Debugger();
  55. +if (typeof du.setupTraceLogger === "function" &&
  56. + typeof oomTest === 'function')
  57. +{
  58. + du.setupTraceLogger({
  59. + Scripts: true
  60. + })
  61. + oomTest(() => function(){});
  62. +}
  63. diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp
  64. index 93e2fda..09049d6 100644
  65. --- a/js/src/jit/Ion.cpp
  66. +++ b/js/src/jit/Ion.cpp
  67. @@ -1055,6 +1055,8 @@ IonScript::Destroy(FreeOp* fop, IonScript* script)
  68. script->destroyCaches();
  69. script->unlinkFromRuntime(fop);
  70. + // Frees the potential event we have set.
  71. + script->traceLoggerScriptEvent_ = TraceLoggerEvent();
  72. fop->free_(script);
  73. }
  74. diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp
  75. index 26262fd..af7f313 100644
  76. --- a/js/src/vm/Debugger.cpp
  77. +++ b/js/src/vm/Debugger.cpp
  78. @@ -369,10 +369,10 @@ Debugger::Debugger(JSContext* cx, NativeObject* dbg)
  79. objects(cx),
  80. environments(cx),
  81. #ifdef NIGHTLY_BUILD
  82. - traceLoggerLastDrainedId(0),
  83. + traceLoggerLastDrainedSize(0),
  84. traceLoggerLastDrainedIteration(0),
  85. #endif
  86. - traceLoggerScriptedCallsLastDrainedId(0),
  87. + traceLoggerScriptedCallsLastDrainedSize(0),
  88. traceLoggerScriptedCallsLastDrainedIteration(0)
  89. {
  90. assertSameCompartment(cx, dbg);
  91. @@ -3907,9 +3907,9 @@ Debugger::drainTraceLogger(JSContext* cx, unsigned argc, Value* vp)
  92. size_t num;
  93. TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
  94. bool lostEvents = logger->lostEvents(dbg->traceLoggerLastDrainedIteration,
  95. - dbg->traceLoggerLastDrainedId);
  96. + dbg->traceLoggerLastDrainedSize);
  97. EventEntry* events = logger->getEventsStartingAt(&dbg->traceLoggerLastDrainedIteration,
  98. - &dbg->traceLoggerLastDrainedId,
  99. + &dbg->traceLoggerLastDrainedSize,
  100. &num);
  101. RootedObject array(cx, NewDenseEmptyArray(cx));
  102. @@ -4002,10 +4002,10 @@ Debugger::drainTraceLoggerScriptCalls(JSContext* cx, unsigned argc, Value* vp)
  103. size_t num;
  104. TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
  105. bool lostEvents = logger->lostEvents(dbg->traceLoggerScriptedCallsLastDrainedIteration,
  106. - dbg->traceLoggerScriptedCallsLastDrainedId);
  107. + dbg->traceLoggerScriptedCallsLastDrainedSize);
  108. EventEntry* events = logger->getEventsStartingAt(
  109. &dbg->traceLoggerScriptedCallsLastDrainedIteration,
  110. - &dbg->traceLoggerScriptedCallsLastDrainedId,
  111. + &dbg->traceLoggerScriptedCallsLastDrainedSize,
  112. &num);
  113. RootedObject array(cx, NewDenseEmptyArray(cx));
  114. diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h
  115. index 8cac36a..c92d685 100644
  116. --- a/js/src/vm/Debugger.h
  117. +++ b/js/src/vm/Debugger.h
  118. @@ -314,10 +314,10 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
  119. * lost events.
  120. */
  121. #ifdef NIGHTLY_BUILD
  122. - uint32_t traceLoggerLastDrainedId;
  123. + uint32_t traceLoggerLastDrainedSize;
  124. uint32_t traceLoggerLastDrainedIteration;
  125. #endif
  126. - uint32_t traceLoggerScriptedCallsLastDrainedId;
  127. + uint32_t traceLoggerScriptedCallsLastDrainedSize;
  128. uint32_t traceLoggerScriptedCallsLastDrainedIteration;
  129. class FrameRange;
  130. diff --git a/js/src/vm/TraceLogging.cpp b/js/src/vm/TraceLogging.cpp
  131. index 6715b36..9766a6f 100644
  132. --- a/js/src/vm/TraceLogging.cpp
  133. +++ b/js/src/vm/TraceLogging.cpp
  134. @@ -131,7 +131,7 @@ TraceLoggerThread::init()
  135. {
  136. if (!pointerMap.init())
  137. return false;
  138. - if (!extraTextId.init())
  139. + if (!textIdPayloads.init())
  140. return false;
  141. if (!events.init())
  142. return false;
  143. @@ -185,10 +185,10 @@ TraceLoggerThread::~TraceLoggerThread()
  144. graph = nullptr;
  145. }
  146. - for (TextIdHashMap::Range r = extraTextId.all(); !r.empty(); r.popFront())
  147. - js_delete(r.front().value());
  148. - extraTextId.finish();
  149. - pointerMap.finish();
  150. + if (textIdPayloads.initialized()) {
  151. + for (TextIdHashMap::Range r = textIdPayloads.all(); !r.empty(); r.popFront())
  152. + js_delete(r.front().value());
  153. + }
  154. }
  155. bool
  156. @@ -287,7 +287,7 @@ TraceLoggerThread::eventText(uint32_t id)
  157. if (id < TraceLogger_Last)
  158. return TLTextIdString(static_cast<TraceLoggerTextId>(id));
  159. - TextIdHashMap::Ptr p = extraTextId.lookup(id);
  160. + TextIdHashMap::Ptr p = textIdPayloads.lookup(id);
  161. MOZ_ASSERT(p);
  162. return p->value()->string();
  163. @@ -341,13 +341,15 @@ TraceLoggerThread::extractScriptDetails(uint32_t textId, const char** filename,
  164. TraceLoggerEventPayload*
  165. TraceLoggerThread::getOrCreateEventPayload(TraceLoggerTextId textId)
  166. {
  167. - TextIdHashMap::AddPtr p = extraTextId.lookupForAdd(textId);
  168. - if (p)
  169. + TextIdHashMap::AddPtr p = textIdPayloads.lookupForAdd(textId);
  170. + if (p) {
  171. + MOZ_ASSERT(p->value()->textId() == textId); // Sanity check.
  172. return p->value();
  173. + }
  174. TraceLoggerEventPayload* payload = js_new<TraceLoggerEventPayload>(textId, (char*)nullptr);
  175. - if (!extraTextId.add(p, textId, payload))
  176. + if (!textIdPayloads.add(p, textId, payload))
  177. return nullptr;
  178. return payload;
  179. @@ -357,8 +359,10 @@ TraceLoggerEventPayload*
  180. TraceLoggerThread::getOrCreateEventPayload(const char* text)
  181. {
  182. PointerHashMap::AddPtr p = pointerMap.lookupForAdd((const void*)text);
  183. - if (p)
  184. + if (p) {
  185. + MOZ_ASSERT(p->value()->textId() < nextTextId); // Sanity check.
  186. return p->value();
  187. + }
  188. size_t len = strlen(text);
  189. char* str = js_pod_malloc<char>(len + 1);
  190. @@ -369,7 +373,7 @@ TraceLoggerThread::getOrCreateEventPayload(const char* text)
  191. MOZ_ASSERT(ret == len);
  192. MOZ_ASSERT(strlen(str) == len);
  193. - uint32_t textId = extraTextId.count() + TraceLogger_Last;
  194. + uint32_t textId = nextTextId;
  195. TraceLoggerEventPayload* payload = js_new<TraceLoggerEventPayload>(textId, str);
  196. if (!payload) {
  197. @@ -377,17 +381,19 @@ TraceLoggerThread::getOrCreateEventPayload(const char* text)
  198. return nullptr;
  199. }
  200. - if (!extraTextId.putNew(textId, payload)) {
  201. + if (!textIdPayloads.putNew(textId, payload)) {
  202. js_delete(payload);
  203. return nullptr;
  204. }
  205. - if (!pointerMap.add(p, text, payload))
  206. - return nullptr;
  207. -
  208. if (graph.get())
  209. graph->addTextId(textId, str);
  210. + nextTextId++;
  211. +
  212. + if (!pointerMap.add(p, text, payload))
  213. + return nullptr;
  214. +
  215. return payload;
  216. }
  217. @@ -407,9 +413,14 @@ TraceLoggerThread::getOrCreateEventPayload(TraceLoggerTextId type, const char* f
  218. if (!traceLoggerState->isTextIdEnabled(type))
  219. return getOrCreateEventPayload(type);
  220. - PointerHashMap::AddPtr p = pointerMap.lookupForAdd(ptr);
  221. - if (p)
  222. - return p->value();
  223. + PointerHashMap::AddPtr p;
  224. + if (ptr) {
  225. + p = pointerMap.lookupForAdd(ptr);
  226. + if (p) {
  227. + MOZ_ASSERT(p->value()->textId() < nextTextId); // Sanity check.
  228. + return p->value();
  229. + }
  230. + }
  231. // Compute the length of the string to create.
  232. size_t lenFilename = strlen(filename);
  233. @@ -428,24 +439,28 @@ TraceLoggerThread::getOrCreateEventPayload(TraceLoggerTextId type, const char* f
  234. MOZ_ASSERT(ret == len);
  235. MOZ_ASSERT(strlen(str) == len);
  236. - uint32_t textId = extraTextId.count() + TraceLogger_Last;
  237. + uint32_t textId = nextTextId;
  238. TraceLoggerEventPayload* payload = js_new<TraceLoggerEventPayload>(textId, str);
  239. if (!payload) {
  240. js_free(str);
  241. return nullptr;
  242. }
  243. - if (!extraTextId.putNew(textId, payload)) {
  244. + if (!textIdPayloads.putNew(textId, payload)) {
  245. js_delete(payload);
  246. return nullptr;
  247. }
  248. - if (!pointerMap.add(p, ptr, payload))
  249. - return nullptr;
  250. -
  251. if (graph.get())
  252. graph->addTextId(textId, str);
  253. + nextTextId++;
  254. +
  255. + if (ptr) {
  256. + if (!pointerMap.add(p, ptr, payload))
  257. + return nullptr;
  258. + }
  259. +
  260. return payload;
  261. }
  262. @@ -453,14 +468,14 @@ TraceLoggerEventPayload*
  263. TraceLoggerThread::getOrCreateEventPayload(TraceLoggerTextId type, JSScript* script)
  264. {
  265. return getOrCreateEventPayload(type, script->filename(), script->lineno(), script->column(),
  266. - script);
  267. + nullptr);
  268. }
  269. TraceLoggerEventPayload*
  270. TraceLoggerThread::getOrCreateEventPayload(TraceLoggerTextId type,
  271. const JS::ReadOnlyCompileOptions& script)
  272. {
  273. - return getOrCreateEventPayload(type, script.filename(), script.lineno, script.column, &script);
  274. + return getOrCreateEventPayload(type, script.filename(), script.lineno, script.column, nullptr);
  275. }
  276. void
  277. @@ -485,7 +500,7 @@ TraceLoggerThread::startEvent(uint32_t id)
  278. if (!traceLoggerState->isTextIdEnabled(id))
  279. return;
  280. - logTimestamp(id);
  281. + log(id);
  282. }
  283. void
  284. @@ -510,7 +525,7 @@ TraceLoggerThread::stopEvent(uint32_t id)
  285. if (!traceLoggerState->isTextIdEnabled(id))
  286. return;
  287. - logTimestamp(TraceLogger_Stop);
  288. + log(TraceLogger_Stop);
  289. }
  290. void
  291. @@ -522,23 +537,57 @@ TraceLoggerThread::logTimestamp(TraceLoggerTextId id)
  292. void
  293. TraceLoggerThread::logTimestamp(uint32_t id)
  294. {
  295. + MOZ_ASSERT(id > TraceLogger_LastTreeItem && id < TraceLogger_Last);
  296. + log(id);
  297. +}
  298. +
  299. +void
  300. +TraceLoggerThread::log(uint32_t id)
  301. +{
  302. if (enabled == 0)
  303. return;
  304. MOZ_ASSERT(traceLoggerState);
  305. - if (!events.ensureSpaceBeforeAdd()) {
  306. +
  307. + // We request for 3 items to add, since if we don't have enough room
  308. + // we record the time it took to make more place. To log this information
  309. + // we need 2 extra free entries.
  310. + if (!events.hasSpaceForAdd(3)) {
  311. uint64_t start = rdtsc() - traceLoggerState->startupTime;
  312. - if (graph.get())
  313. - graph->log(events);
  314. + if (!events.ensureSpaceBeforeAdd(3)) {
  315. + if (graph.get())
  316. + graph->log(events);
  317. +
  318. + iteration_++;
  319. + events.clear();
  320. +
  321. + // Remove the item in the pointerMap for which the payloads
  322. + // have no uses anymore
  323. + for (PointerHashMap::Enum e(pointerMap); !e.empty(); e.popFront()) {
  324. + if (e.front().value()->uses() != 0)
  325. + continue;
  326. +
  327. + TextIdHashMap::Ptr p = textIdPayloads.lookup(e.front().value()->textId());
  328. + MOZ_ASSERT(p);
  329. + textIdPayloads.remove(p);
  330. +
  331. + e.removeFront();
  332. + }
  333. - iteration_++;
  334. - events.clear();
  335. + // Free all payloads that have no uses anymore.
  336. + for (TextIdHashMap::Enum e(textIdPayloads); !e.empty(); e.popFront()) {
  337. + if (e.front().value()->uses() == 0) {
  338. + js_delete(e.front().value());
  339. + e.removeFront();
  340. + }
  341. + }
  342. + }
  343. // Log the time it took to flush the events as being from the
  344. // Tracelogger.
  345. if (graph.get()) {
  346. - MOZ_ASSERT(events.capacity() > 2);
  347. + MOZ_ASSERT(events.hasSpaceForAdd(2));
  348. EventEntry& entryStart = events.pushUninitialized();
  349. entryStart.time = start;
  350. entryStart.textId = TraceLogger_Internal;
  351. @@ -548,13 +597,6 @@ TraceLoggerThread::logTimestamp(uint32_t id)
  352. entryStop.textId = TraceLogger_Stop;
  353. }
  354. - // Free all TextEvents that have no uses anymore.
  355. - for (TextIdHashMap::Enum e(extraTextId); !e.empty(); e.popFront()) {
  356. - if (e.front().value()->uses() == 0) {
  357. - js_delete(e.front().value());
  358. - e.removeFront();
  359. - }
  360. - }
  361. }
  362. uint64_t time = rdtsc() - traceLoggerState->startupTime;
  363. @@ -956,3 +998,16 @@ TraceLoggerEvent::~TraceLoggerEvent()
  364. if (payload_)
  365. payload_->release();
  366. }
  367. +
  368. +TraceLoggerEvent&
  369. +TraceLoggerEvent::operator=(const TraceLoggerEvent& other)
  370. +{
  371. + if (hasPayload())
  372. + payload()->release();
  373. + if (other.hasPayload())
  374. + other.payload()->use();
  375. +
  376. + payload_ = other.payload_;
  377. +
  378. + return *this;
  379. +}
  380. diff --git a/js/src/vm/TraceLogging.h b/js/src/vm/TraceLogging.h
  381. index a124dcb..91a1eb0 100644
  382. --- a/js/src/vm/TraceLogging.h
  383. +++ b/js/src/vm/TraceLogging.h
  384. @@ -110,6 +110,9 @@ class TraceLoggerEvent {
  385. bool hasPayload() const {
  386. return !!payload_;
  387. }
  388. +
  389. + TraceLoggerEvent& operator=(const TraceLoggerEvent& other);
  390. + TraceLoggerEvent(const TraceLoggerEvent& event) = delete;
  391. };
  392. /**
  393. @@ -130,6 +133,10 @@ class TraceLoggerEventPayload {
  394. uses_(0)
  395. { }
  396. + ~TraceLoggerEventPayload() {
  397. + MOZ_ASSERT(uses_ == 0);
  398. + }
  399. +
  400. uint32_t textId() {
  401. return textId_;
  402. }
  403. @@ -166,7 +173,8 @@ class TraceLoggerThread
  404. mozilla::UniquePtr<TraceLoggerGraph> graph;
  405. PointerHashMap pointerMap;
  406. - TextIdHashMap extraTextId;
  407. + TextIdHashMap textIdPayloads;
  408. + uint32_t nextTextId;
  409. ContinuousSpace<EventEntry> events;
  410. @@ -181,6 +189,7 @@ class TraceLoggerThread
  411. : enabled(0),
  412. failed(false),
  413. graph(),
  414. + nextTextId(TraceLogger_Last),
  415. iteration_(0),
  416. top(nullptr)
  417. { }
  418. @@ -195,22 +204,22 @@ class TraceLoggerThread
  419. bool enable(JSContext* cx);
  420. bool disable();
  421. - // Given the previous iteration and lastEntryId, return an array of events
  422. + // Given the previous iteration and size, return an array of events
  423. // (there could be lost events). At the same time update the iteration and
  424. - // lastEntry and gives back how many events there are.
  425. - EventEntry* getEventsStartingAt(uint32_t* lastIteration, uint32_t* lastEntryId, size_t* num) {
  426. + // size and gives back how many events there are.
  427. + EventEntry* getEventsStartingAt(uint32_t* lastIteration, uint32_t* lastSize, size_t* num) {
  428. EventEntry* start;
  429. if (iteration_ == *lastIteration) {
  430. - MOZ_ASSERT(events.lastEntryId() >= *lastEntryId);
  431. - *num = events.lastEntryId() - *lastEntryId;
  432. - start = events.data() + *lastEntryId + 1;
  433. + MOZ_ASSERT(*lastSize <= events.size());
  434. + *num = events.size() - *lastSize;
  435. + start = events.data() + *lastSize;
  436. } else {
  437. - *num = events.lastEntryId() + 1;
  438. + *num = events.size();
  439. start = events.data();
  440. }
  441. *lastIteration = iteration_;
  442. - *lastEntryId = events.lastEntryId();
  443. + *lastSize = events.size();
  444. return start;
  445. }
  446. @@ -220,16 +229,16 @@ class TraceLoggerThread
  447. const char** lineno, size_t* lineno_len, const char** colno,
  448. size_t* colno_len);
  449. - bool lostEvents(uint32_t lastIteration, uint32_t lastEntryId) {
  450. + bool lostEvents(uint32_t lastIteration, uint32_t lastSize) {
  451. // If still logging in the same iteration, there are no lost events.
  452. if (lastIteration == iteration_) {
  453. - MOZ_ASSERT(lastEntryId <= events.lastEntryId());
  454. + MOZ_ASSERT(lastSize <= events.size());
  455. return false;
  456. }
  457. - // When proceeded to the next iteration and lastEntryId points to
  458. - // the maximum capacity there are no logs that are lost.
  459. - if (lastIteration + 1 == iteration_ && lastEntryId == events.capacity())
  460. + // If we are in a consecutive iteration we are only sure we didn't lose any events,
  461. + // when the lastSize equals the maximum size 'events' can get.
  462. + if (lastIteration == iteration_ - 1 && lastSize == events.maxSize())
  463. return false;
  464. return true;
  465. @@ -268,6 +277,7 @@ class TraceLoggerThread
  466. void stopEvent(uint32_t id);
  467. private:
  468. void stopEvent();
  469. + void log(uint32_t id);
  470. public:
  471. static unsigned offsetOfEnabled() {
  472. diff --git a/js/src/vm/TraceLoggingGraph.cpp b/js/src/vm/TraceLoggingGraph.cpp
  473. index d1b7f2e..a4eb273 100644
  474. --- a/js/src/vm/TraceLoggingGraph.cpp
  475. +++ b/js/src/vm/TraceLoggingGraph.cpp
  476. @@ -276,7 +276,7 @@ TraceLoggerGraph::flush()
  477. if (bytesWritten < tree.size())
  478. return false;
  479. - treeOffset += tree.lastEntryId();
  480. + treeOffset += tree.size();
  481. tree.clear();
  482. }
  483. @@ -359,7 +359,7 @@ TraceLoggerGraph::startEventInternal(uint32_t id, uint64_t timestamp)
  484. if (parent.lastChildId() == 0) {
  485. MOZ_ASSERT(!entry.hasChildren());
  486. - MOZ_ASSERT(parent.treeId() == tree.lastEntryId() + treeOffset);
  487. + MOZ_ASSERT(parent.treeId() == treeOffset + tree.size() - 1);
  488. if (!updateHasChildren(parent.treeId()))
  489. return false;
  490. diff --git a/js/src/vm/TraceLoggingTypes.h b/js/src/vm/TraceLoggingTypes.h
  491. index f1c9d0c..10b76d6 100644
  492. --- a/js/src/vm/TraceLoggingTypes.h
  493. +++ b/js/src/vm/TraceLoggingTypes.h
  494. @@ -21,7 +21,6 @@
  495. _(Internal) \
  496. _(Interpreter) \
  497. _(InlinedScripts) \
  498. - _(Invalidation) \
  499. _(IonCompilation) \
  500. _(IonCompilationPaused) \
  501. _(IonLinking) \
  502. @@ -60,6 +59,7 @@
  503. #define TRACELOGGER_LOG_ITEMS(_) \
  504. _(Bailout) \
  505. + _(Invalidation) \
  506. _(Disable) \
  507. _(Enable) \
  508. _(Stop)
  509. @@ -130,6 +130,9 @@ class ContinuousSpace {
  510. uint32_t size_;
  511. uint32_t capacity_;
  512. + // The maximum amount of ram memory a continuous space structure can take (in bytes).
  513. + static const uint32_t LIMIT = 200 * 1024 * 1024;
  514. +
  515. public:
  516. ContinuousSpace ()
  517. : data_(nullptr)
  518. @@ -151,6 +154,10 @@ class ContinuousSpace {
  519. data_ = nullptr;
  520. }
  521. + static uint32_t maxSize() {
  522. + return LIMIT / sizeof(T);
  523. + }
  524. +
  525. T* data() {
  526. return data_;
  527. }
  528. @@ -187,11 +194,14 @@ class ContinuousSpace {
  529. if (hasSpaceForAdd(count))
  530. return true;
  531. + // Limit the size of a continuous buffer.
  532. + if (size_ + count > maxSize())
  533. + return false;
  534. +
  535. uint32_t nCapacity = capacity_ * 2;
  536. - if (size_ + count > nCapacity)
  537. - nCapacity = size_ + count;
  538. - T* entries = (T*) js_realloc(data_, nCapacity * sizeof(T));
  539. + nCapacity = (nCapacity < maxSize()) ? nCapacity : maxSize();
  540. + T* entries = (T*) js_realloc(data_, nCapacity * sizeof(T));
  541. if (!entries)
  542. return false;