# HG changeset patch
# User Hannes Verschore <hv1989@gmail.com>
# Date 1450481544 18000
# Node ID 6bc6cbcf117e2e230ab189c5d3f244f30a294232
# Parent e33b2a6d17d48e38f0a6f67ce1e4e65d73ed797e
Bug 1231170: TraceLogger - Use size in debugger instead of the current id to track last logged item, r=bbouvier
diff --git a/js/src/jit-test/tests/tracelogger/bug1231170.js b/js/src/jit-test/tests/tracelogger/bug1231170.js
new file mode 100644
-
|
+
|
|
| 1 | var du = new Debugger(); |
| 2 | if (typeof du.drainTraceLogger === "function") |
| 3 | du.drainTraceLogger(); |
diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp
a
|
b
|
Debugger::Debugger(JSContext* cx, Native
|
372 | 372 | maxAllocationsLogLength(DEFAULT_MAX_LOG_LENGTH), |
373 | 373 | allocationsLogOverflowed(false), |
374 | 374 | frames(cx->runtime()), |
375 | 375 | scripts(cx), |
376 | 376 | sources(cx), |
377 | 377 | objects(cx), |
378 | 378 | environments(cx), |
379 | 379 | #ifdef NIGHTLY_BUILD |
380 | | traceLoggerLastDrainedId(0), |
| 380 | traceLoggerLastDrainedSize(0), |
381 | 381 | traceLoggerLastDrainedIteration(0), |
382 | 382 | #endif |
383 | | traceLoggerScriptedCallsLastDrainedId(0), |
| 383 | traceLoggerScriptedCallsLastDrainedSize(0), |
384 | 384 | traceLoggerScriptedCallsLastDrainedIteration(0) |
385 | 385 | { |
386 | 386 | assertSameCompartment(cx, dbg); |
387 | 387 | |
388 | 388 | cx->runtime()->debuggerList.insertBack(this); |
389 | 389 | JS_INIT_CLIST(&breakpoints); |
390 | 390 | JS_INIT_CLIST(&onNewGlobalObjectWatchersLink); |
391 | 391 | } |
… |
… |
Debugger::drainTraceLogger(JSContext* cx
|
4397 | 4397 | { |
4398 | 4398 | THIS_DEBUGGER(cx, argc, vp, "drainTraceLogger", args, dbg); |
4399 | 4399 | if (!args.requireAtLeast(cx, "Debugger.drainTraceLogger", 0)) |
4400 | 4400 | return false; |
4401 | 4401 | |
4402 | 4402 | size_t num; |
4403 | 4403 | TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime()); |
4404 | 4404 | bool lostEvents = logger->lostEvents(dbg->traceLoggerLastDrainedIteration, |
4405 | | dbg->traceLoggerLastDrainedId); |
| 4405 | dbg->traceLoggerLastDrainedSize); |
4406 | 4406 | EventEntry* events = logger->getEventsStartingAt(&dbg->traceLoggerLastDrainedIteration, |
4407 | | &dbg->traceLoggerLastDrainedId, |
| 4407 | &dbg->traceLoggerLastDrainedSize, |
4408 | 4408 | &num); |
4409 | 4409 | |
4410 | 4410 | RootedObject array(cx, NewDenseEmptyArray(cx)); |
4411 | 4411 | JSAtom* dataAtom = Atomize(cx, "data", strlen("data")); |
4412 | 4412 | if (!dataAtom) |
4413 | 4413 | return false; |
4414 | 4414 | RootedId dataId(cx, AtomToId(dataAtom)); |
4415 | 4415 | |
… |
… |
Debugger::drainTraceLoggerScriptCalls(JS
|
4492 | 4492 | { |
4493 | 4493 | THIS_DEBUGGER(cx, argc, vp, "drainTraceLoggerScriptCalls", args, dbg); |
4494 | 4494 | if (!args.requireAtLeast(cx, "Debugger.drainTraceLoggerScriptCalls", 0)) |
4495 | 4495 | return false; |
4496 | 4496 | |
4497 | 4497 | size_t num; |
4498 | 4498 | TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime()); |
4499 | 4499 | bool lostEvents = logger->lostEvents(dbg->traceLoggerScriptedCallsLastDrainedIteration, |
4500 | | dbg->traceLoggerScriptedCallsLastDrainedId); |
| 4500 | dbg->traceLoggerScriptedCallsLastDrainedSize); |
4501 | 4501 | EventEntry* events = logger->getEventsStartingAt( |
4502 | 4502 | &dbg->traceLoggerScriptedCallsLastDrainedIteration, |
4503 | | &dbg->traceLoggerScriptedCallsLastDrainedId, |
| 4503 | &dbg->traceLoggerScriptedCallsLastDrainedSize, |
4504 | 4504 | &num); |
4505 | 4505 | |
4506 | 4506 | RootedObject array(cx, NewDenseEmptyArray(cx)); |
4507 | 4507 | RootedId fileNameId(cx, AtomToId(cx->names().fileName)); |
4508 | 4508 | RootedId lineNumberId(cx, AtomToId(cx->names().lineNumber)); |
4509 | 4509 | RootedId columnNumberId(cx, AtomToId(cx->names().columnNumber)); |
4510 | 4510 | JSAtom* logTypeAtom = Atomize(cx, "logType", strlen("logType")); |
4511 | 4511 | if (!logTypeAtom) |
diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h
a
|
b
|
class Debugger : private mozilla::Linked
|
443 | 443 | /* The map from debuggee Envs to Debugger.Environment instances. */ |
444 | 444 | ObjectWeakMap environments; |
445 | 445 | |
446 | 446 | /* |
447 | 447 | * Keep track of tracelogger last drained identifiers to know if there are |
448 | 448 | * lost events. |
449 | 449 | */ |
450 | 450 | #ifdef NIGHTLY_BUILD |
451 | | uint32_t traceLoggerLastDrainedId; |
| 451 | uint32_t traceLoggerLastDrainedSize; |
452 | 452 | uint32_t traceLoggerLastDrainedIteration; |
453 | 453 | #endif |
454 | | uint32_t traceLoggerScriptedCallsLastDrainedId; |
| 454 | uint32_t traceLoggerScriptedCallsLastDrainedSize; |
455 | 455 | uint32_t traceLoggerScriptedCallsLastDrainedIteration; |
456 | 456 | |
457 | 457 | class FrameRange; |
458 | 458 | class ScriptQuery; |
459 | 459 | class ObjectQuery; |
460 | 460 | |
461 | 461 | bool addDebuggeeGlobal(JSContext* cx, Handle<GlobalObject*> obj); |
462 | 462 | void removeDebuggeeGlobal(FreeOp* fop, GlobalObject* global, |
diff --git a/js/src/vm/TraceLogging.h b/js/src/vm/TraceLogging.h
a
|
b
|
class TraceLoggerThread
|
203 | 203 | bool enable(); |
204 | 204 | bool enable(JSContext* cx); |
205 | 205 | bool disable(); |
206 | 206 | |
207 | | // Given the previous iteration and lastEntryId, return an array of events |
| 207 | // Given the previous iteration and size, return an array of events |
208 | 208 | // (there could be lost events). At the same time update the iteration and |
209 | | // lastEntry and gives back how many events there are. |
210 | | EventEntry* getEventsStartingAt(uint32_t* lastIteration, uint32_t* lastEntryId, size_t* num) { |
| 209 | // size and gives back how many events there are. |
| 210 | EventEntry* getEventsStartingAt(uint32_t* lastIteration, uint32_t* lastSize, size_t* num) { |
211 | 211 | EventEntry* start; |
212 | 212 | if (iteration_ == *lastIteration) { |
213 | | MOZ_ASSERT(*lastEntryId < events.size()); |
214 | | *num = events.lastEntryId() - *lastEntryId; |
215 | | start = events.data() + *lastEntryId + 1; |
| 213 | MOZ_ASSERT(*lastSize <= events.size()); |
| 214 | *num = events.size() - *lastSize; |
| 215 | start = events.data() + *lastSize; |
216 | 216 | } else { |
217 | 217 | *num = events.size(); |
218 | 218 | start = events.data(); |
219 | 219 | } |
220 | 220 | |
221 | 221 | *lastIteration = iteration_; |
222 | | *lastEntryId = events.lastEntryId(); |
| 222 | *lastSize = events.size(); |
223 | 223 | return start; |
224 | 224 | } |
225 | 225 | |
226 | 226 | // Extract the details filename, lineNumber and columnNumber out of a event |
227 | 227 | // containing script information. |
228 | 228 | void extractScriptDetails(uint32_t textId, const char** filename, size_t* filename_len, |
229 | 229 | const char** lineno, size_t* lineno_len, const char** colno, |
230 | 230 | size_t* colno_len); |
231 | 231 | |
232 | | bool lostEvents(uint32_t lastIteration, uint32_t lastEntryId) { |
| 232 | bool lostEvents(uint32_t lastIteration, uint32_t lastSize) { |
233 | 233 | // If still logging in the same iteration, there are no lost events. |
234 | 234 | if (lastIteration == iteration_) { |
235 | | MOZ_ASSERT(lastEntryId < events.size()); |
| 235 | MOZ_ASSERT(lastSize <= events.size()); |
236 | 236 | return false; |
237 | 237 | } |
238 | 238 | |
239 | | // When proceeded to the next iteration and lastEntryId points to |
240 | | // the maximum capacity there are no logs that are lost. |
241 | | if (lastIteration + 1 == iteration_ && lastEntryId == events.capacity()) |
| 239 | // If we are in a consecutive iteration we are only sure we didn't lose any events, |
| 240 | // when the lastSize equals the maximum size 'events' can get. |
| 241 | if (lastIteration == iteration_ - 1 && lastSize == CONTINUOUSSPACE_LIMIT) |
242 | 242 | return false; |
243 | 243 | |
244 | 244 | return true; |
245 | 245 | } |
246 | 246 | |
247 | 247 | const char* eventText(uint32_t id); |
248 | 248 | bool textIdIsScriptEvent(uint32_t id); |
249 | 249 | |