Line data Source code
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/. */
6 :
7 : #ifndef TraceLogging_h
8 : #define TraceLogging_h
9 :
10 : #include "mozilla/GuardObjects.h"
11 : #include "mozilla/LinkedList.h"
12 : #include "mozilla/MemoryReporting.h"
13 :
14 : #include "jsalloc.h"
15 :
16 : #include "js/HashTable.h"
17 : #include "js/TypeDecls.h"
18 : #include "js/Vector.h"
19 : #include "vm/MutexIDs.h"
20 : #include "vm/TraceLoggingGraph.h"
21 : #include "vm/TraceLoggingTypes.h"
22 :
23 : struct JSRuntime;
24 :
25 : namespace JS {
26 : class ReadOnlyCompileOptions;
27 : } // namespace JS
28 :
29 : namespace js {
30 :
31 : namespace jit {
32 : class CompileRuntime;
33 : } // namespace jit
34 :
35 : /*
36 : * Tracelogging overview.
37 : *
38 : * Tracelogging makes it possible to trace the occurrence of a single event
39 : * and/or the start and stop of an event. This is implemented with as low
40 : * overhead as possible to not interfere with running.
41 : *
42 : * Logging something is done in 3 stages.
43 : * 1) Get the tracelogger of the current thread. cx may be omitted, in which
44 : * case it will be fetched from TLS.
45 : * - TraceLoggerForCurrentThread(cx);
46 : *
47 : * 2) Optionally create a TraceLoggerEvent for the text that needs to get logged. This
48 : * step takes some time, so try to do this beforehand, outside the hot
49 : * path and don't do unnecessary repetitions, since it will cripple
50 : * performance.
51 : * - TraceLoggerEvent event(logger, "foo");
52 : *
53 : * There are also some predefined events. They are located in
54 : * TraceLoggerTextId. They don't require to create an TraceLoggerEvent and
55 : * can also be used as an argument to these functions.
56 : *
57 : * 3) Log the occurrence of a single event:
58 : * - TraceLogTimestamp(logger, TraceLoggerTextId);
59 : * Note: it is temporarily not supported to provide an TraceLoggerEvent as
60 : * argument to log the occurrence of a single event.
61 : *
62 : * or log the start and stop of an event:
63 : * - TraceLogStartEvent(logger, TraceLoggerTextId);
64 : * - TraceLogStartEvent(logger, TraceLoggerEvent);
65 : * - TraceLogStopEvent(logger, TraceLoggerTextId);
66 : * - TraceLogStopEvent(logger, TraceLoggerEvent);
67 : *
68 : * or the start/stop of an event with a RAII class:
69 : * - AutoTraceLog atl(logger, TraceLoggerTextId);
70 : * - AutoTraceLog atl(logger, TraceLoggerEvent);
71 : */
72 :
73 : class AutoTraceLog;
74 : class TraceLoggerEventPayload;
75 : class TraceLoggerThread;
76 :
77 : /**
78 : * An event that can be used to report start/stop events to TraceLogger. It
79 : * prepares the given info by requesting a TraceLoggerEventPayload containing
80 : * the string to report and an unique id. It also increases the useCount of
81 : * this payload, so it cannot get removed.
82 : */
83 : class TraceLoggerEvent {
84 : #ifdef JS_TRACE_LOGGING
85 : private:
86 : class EventPayloadOrTextId {
87 :
88 : /**
89 : * Payload can be a pointer to a TraceLoggerEventPayload* or a
90 : * TraceLoggerTextId. The last bit decides how to read the payload.
91 : *
92 : * payload_ = [ | 0 ]
93 : * ------------------------ = TraceLoggerEventPayload* (incl. last bit)
94 : * payload_ = [ | 1 ]
95 : * ------------------- = TraceLoggerTextId (excl. last bit)
96 : */
97 : uintptr_t payload_;
98 :
99 : public:
100 27044 : EventPayloadOrTextId()
101 27044 : : payload_(0)
102 27044 : { }
103 :
104 180089 : bool isEventPayload() const {
105 180089 : return (payload_ & 1) == 0;
106 : }
107 546 : TraceLoggerEventPayload* eventPayload() const {
108 546 : MOZ_ASSERT(isEventPayload());
109 546 : return (TraceLoggerEventPayload*) payload_;
110 : }
111 0 : void setEventPayload(TraceLoggerEventPayload* payload) {
112 0 : payload_ = (uintptr_t)payload;
113 0 : MOZ_ASSERT((payload_ & 1) == 0);
114 0 : }
115 152586 : bool isTextId() const {
116 152586 : return (payload_ & 1) == 1;
117 : }
118 50862 : uint32_t textId() const {
119 50862 : MOZ_ASSERT(isTextId());
120 50862 : return payload_ >> 1;
121 : }
122 26417 : void setTextId(TraceLoggerTextId textId) {
123 : static_assert(TraceLogger_Last < (UINT32_MAX >> 1), "Too many predefined text ids.");
124 26417 : payload_ = (((uint32_t)textId) << 1) | 1;
125 26417 : }
126 : };
127 :
128 : EventPayloadOrTextId payload_;
129 :
130 : public:
131 627 : TraceLoggerEvent()
132 627 : : payload_()
133 627 : {}
134 : explicit TraceLoggerEvent(TraceLoggerTextId textId);
135 : TraceLoggerEvent(TraceLoggerTextId type, JSScript* script);
136 : TraceLoggerEvent(TraceLoggerTextId type, const char* filename, size_t line, size_t column);
137 : explicit TraceLoggerEvent(const char* text);
138 : TraceLoggerEvent(const TraceLoggerEvent& event);
139 : TraceLoggerEvent& operator=(const TraceLoggerEvent& other);
140 : ~TraceLoggerEvent();
141 : uint32_t textId() const;
142 101724 : bool hasTextId() const {
143 101724 : return hasExtPayload() || payload_.isTextId();
144 : }
145 :
146 : private:
147 0 : TraceLoggerEventPayload* extPayload() const {
148 0 : MOZ_ASSERT(hasExtPayload());
149 0 : return payload_.eventPayload();
150 : }
151 179543 : bool hasExtPayload() const {
152 179543 : return payload_.isEventPayload() && !!payload_.eventPayload();
153 : }
154 : #else
155 : public:
156 : TraceLoggerEvent() {}
157 : explicit TraceLoggerEvent(TraceLoggerTextId textId) {}
158 : TraceLoggerEvent(TraceLoggerTextId type, JSScript* script) {}
159 : TraceLoggerEvent(TraceLoggerTextId type, const char* filename, size_t line, size_t column) {}
160 : explicit TraceLoggerEvent(const char* text) {}
161 : TraceLoggerEvent(const TraceLoggerEvent& event) {}
162 : TraceLoggerEvent& operator=(const TraceLoggerEvent& other) { return *this; };
163 : ~TraceLoggerEvent() {}
164 : uint32_t textId() const { return 0; }
165 : bool hasTextId() const { return false; }
166 : #endif
167 :
168 : };
169 :
170 : #ifdef DEBUG
171 : bool CurrentThreadOwnsTraceLoggerThreadStateLock();
172 : #endif
173 :
174 : /**
175 : * An internal class holding the string information to report, together with an
176 : * unique id, a useCount and a pointerCount. Whenever this useCount reaches 0, this event
177 : * cannot get started/stopped anymore. Consumers may still request the
178 : * string information through maybeEventText below, but this may not succeed:
179 : * when the use count becomes zero, a payload may be deleted by any thread
180 : * holding the TraceLoggerThreadState lock, after that the pointers have been
181 : * cleared out of the pointerMap. That means pointerCount needs to be zero.
182 : */
183 : class TraceLoggerEventPayload {
184 : uint32_t textId_;
185 : UniqueChars string_;
186 : mozilla::Atomic<uint32_t> uses_;
187 : mozilla::Atomic<uint32_t> pointerCount_;
188 :
189 : public:
190 0 : TraceLoggerEventPayload(uint32_t textId, char* string)
191 0 : : textId_(textId),
192 : string_(string),
193 0 : uses_(0)
194 0 : { }
195 :
196 0 : ~TraceLoggerEventPayload() {
197 0 : MOZ_ASSERT(uses_ == 0);
198 0 : }
199 :
200 0 : uint32_t textId() {
201 0 : return textId_;
202 : }
203 0 : const char* string() {
204 0 : return string_.get();
205 : }
206 0 : uint32_t uses() {
207 0 : return uses_;
208 : }
209 0 : uint32_t pointerCount() {
210 0 : return pointerCount_;
211 : }
212 :
213 : // Payloads may have their use count change at any time, *except* the count
214 : // can only go from zero to non-zero while the thread state lock is held.
215 : // This should only happen under getOrCreateEventPayload below, and avoids
216 : // races with purgeUnusedPayloads.
217 0 : void use() {
218 0 : MOZ_ASSERT_IF(!uses_, CurrentThreadOwnsTraceLoggerThreadStateLock());
219 0 : uses_++;
220 0 : }
221 0 : void release() {
222 0 : uses_--;
223 0 : }
224 0 : void incPointerCount() {
225 0 : MOZ_ASSERT(CurrentThreadOwnsTraceLoggerThreadStateLock());
226 0 : pointerCount_++;
227 0 : }
228 0 : void decPointerCount() {
229 0 : MOZ_ASSERT(CurrentThreadOwnsTraceLoggerThreadStateLock());
230 0 : pointerCount_--;
231 0 : }
232 0 : size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
233 0 : return mallocSizeOf(string_.get());
234 : }
235 0 : size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
236 0 : return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf);
237 : }
238 : };
239 :
240 : // Per thread trace logger state.
241 : class TraceLoggerThread : public mozilla::LinkedListElement<TraceLoggerThread>
242 : {
243 : #ifdef JS_TRACE_LOGGING
244 : private:
245 : uint32_t enabled_;
246 : bool failed;
247 :
248 : UniquePtr<TraceLoggerGraph> graph;
249 :
250 : ContinuousSpace<EventEntry> events;
251 :
252 : // Every time the events get flushed, this count is increased by one.
253 : // Together with events.lastEntryId(), this gives an unique id for every
254 : // event.
255 : uint32_t iteration_;
256 :
257 : #ifdef DEBUG
258 : typedef Vector<uint32_t, 1, js::SystemAllocPolicy > GraphStack;
259 : GraphStack graphStack;
260 : #endif
261 :
262 : public:
263 : AutoTraceLog* top;
264 :
265 22 : TraceLoggerThread()
266 22 : : enabled_(0),
267 : failed(false),
268 : graph(),
269 : iteration_(0),
270 22 : top(nullptr)
271 22 : { }
272 :
273 : bool init();
274 : ~TraceLoggerThread();
275 :
276 : bool init(uint32_t loggerId);
277 : void initGraph();
278 :
279 : bool enable();
280 : bool enable(JSContext* cx);
281 : bool disable(bool force = false, const char* = "");
282 0 : bool enabled() { return enabled_ > 0; }
283 :
284 : void silentFail(const char* error);
285 :
286 : size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
287 : size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
288 :
289 : private:
290 : bool fail(JSContext* cx, const char* error);
291 :
292 : public:
293 : // Given the previous iteration and size, return an array of events
294 : // (there could be lost events). At the same time update the iteration and
295 : // size and gives back how many events there are.
296 0 : EventEntry* getEventsStartingAt(uint32_t* lastIteration, uint32_t* lastSize, size_t* num) {
297 : EventEntry* start;
298 0 : if (iteration_ == *lastIteration) {
299 0 : MOZ_ASSERT(*lastSize <= events.size());
300 0 : *num = events.size() - *lastSize;
301 0 : start = events.data() + *lastSize;
302 : } else {
303 0 : *num = events.size();
304 0 : start = events.data();
305 : }
306 :
307 0 : getIterationAndSize(lastIteration, lastSize);
308 0 : return start;
309 : }
310 :
311 0 : void getIterationAndSize(uint32_t* iteration, uint32_t* size) const {
312 0 : *iteration = iteration_;
313 0 : *size = events.size();
314 0 : }
315 :
316 : // Extract the details filename, lineNumber and columnNumber out of a event
317 : // containing script information.
318 : void extractScriptDetails(uint32_t textId, const char** filename, size_t* filename_len,
319 : const char** lineno, size_t* lineno_len, const char** colno,
320 : size_t* colno_len);
321 :
322 0 : bool lostEvents(uint32_t lastIteration, uint32_t lastSize) {
323 : // If still logging in the same iteration, there are no lost events.
324 0 : if (lastIteration == iteration_) {
325 0 : MOZ_ASSERT(lastSize <= events.size());
326 0 : return false;
327 : }
328 :
329 : // If we are in the next consecutive iteration we are only sure we
330 : // didn't lose any events when the lastSize equals the maximum size
331 : // 'events' can get.
332 0 : if (lastIteration == iteration_ - 1 && lastSize == events.maxSize())
333 0 : return false;
334 :
335 0 : return true;
336 : }
337 :
338 : private:
339 : const char* maybeEventText(uint32_t id);
340 : public:
341 0 : const char* eventText(uint32_t id) {
342 0 : const char* text = maybeEventText(id);
343 0 : MOZ_ASSERT(text);
344 0 : return text;
345 : };
346 : bool textIdIsScriptEvent(uint32_t id);
347 :
348 : public:
349 : // Log an event (no start/stop, only the timestamp is recorded).
350 : void logTimestamp(TraceLoggerTextId id);
351 :
352 : // Record timestamps for start and stop of an event.
353 : void startEvent(TraceLoggerTextId id);
354 : void startEvent(const TraceLoggerEvent& event);
355 : void stopEvent(TraceLoggerTextId id);
356 : void stopEvent(const TraceLoggerEvent& event);
357 :
358 : // These functions are actually private and shouldn't be used in normal
359 : // code. They are made public so they can be used in assembly.
360 : void logTimestamp(uint32_t id);
361 : void startEvent(uint32_t id);
362 : void stopEvent(uint32_t id);
363 : private:
364 : void stopEvent();
365 : void log(uint32_t id);
366 :
367 : public:
368 0 : static unsigned offsetOfEnabled() {
369 0 : return offsetof(TraceLoggerThread, enabled_);
370 : }
371 : #endif
372 : };
373 :
374 : // Process wide trace logger state.
375 : class TraceLoggerThreadState
376 : {
377 : #ifdef JS_TRACE_LOGGING
378 : #ifdef DEBUG
379 : bool initialized;
380 : #endif
381 :
382 : bool enabledTextIds[TraceLogger_Last];
383 : bool cooperatingThreadEnabled;
384 : bool helperThreadEnabled;
385 : bool graphSpewingEnabled;
386 : bool spewErrors;
387 : mozilla::LinkedList<TraceLoggerThread> threadLoggers;
388 :
389 : typedef HashMap<const void*,
390 : TraceLoggerEventPayload*,
391 : PointerHasher<const void*, 3>,
392 : SystemAllocPolicy> PointerHashMap;
393 : typedef HashMap<uint32_t,
394 : TraceLoggerEventPayload*,
395 : DefaultHasher<uint32_t>,
396 : SystemAllocPolicy> TextIdHashMap;
397 : PointerHashMap pointerMap;
398 : TextIdHashMap textIdPayloads;
399 : uint32_t nextTextId;
400 :
401 : public:
402 : uint64_t startupTime;
403 : Mutex lock;
404 :
405 3 : TraceLoggerThreadState()
406 3 : :
407 : #ifdef DEBUG
408 : initialized(false),
409 : #endif
410 : cooperatingThreadEnabled(false),
411 : helperThreadEnabled(false),
412 : graphSpewingEnabled(false),
413 : spewErrors(false),
414 : nextTextId(TraceLogger_Last),
415 : startupTime(0),
416 3 : lock(js::mutexid::TraceLoggerThreadState)
417 3 : { }
418 :
419 : bool init();
420 : ~TraceLoggerThreadState();
421 :
422 : TraceLoggerThread* forCurrentThread(JSContext* cx);
423 : void destroyLogger(TraceLoggerThread* logger);
424 :
425 168139 : bool isTextIdEnabled(uint32_t textId) {
426 168139 : if (textId < TraceLogger_Last)
427 168139 : return enabledTextIds[textId];
428 0 : return true;
429 : }
430 : void enableTextId(JSContext* cx, uint32_t textId);
431 : void disableTextId(JSContext* cx, uint32_t textId);
432 0 : void maybeSpewError(const char* text) {
433 0 : if (spewErrors)
434 0 : fprintf(stderr, "%s\n", text);
435 0 : }
436 :
437 : const char* maybeEventText(uint32_t id);
438 :
439 : void purgeUnusedPayloads();
440 :
441 : // These functions map a unique input to a logger ID.
442 : // This can be used to give start and stop events. Calls to these functions should be
443 : // limited if possible, because of the overhead.
444 : // Note: it is not allowed to use them in logTimestamp.
445 : TraceLoggerEventPayload* getOrCreateEventPayload(const char* text);
446 : TraceLoggerEventPayload* getOrCreateEventPayload(JSScript* script);
447 : TraceLoggerEventPayload* getOrCreateEventPayload(const char* filename, size_t lineno,
448 : size_t colno, const void* p);
449 :
450 : size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf);
451 0 : size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) {
452 0 : return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf);
453 : }
454 : #endif
455 : };
456 :
457 : #ifdef JS_TRACE_LOGGING
458 : void DestroyTraceLoggerThreadState();
459 : void DestroyTraceLogger(TraceLoggerThread* logger);
460 :
461 : TraceLoggerThread* TraceLoggerForCurrentThread(JSContext* cx = nullptr);
462 : #else
463 : inline TraceLoggerThread* TraceLoggerForCurrentThread(JSContext* cx = nullptr) {
464 : return nullptr;
465 : };
466 : #endif
467 :
468 : inline bool TraceLoggerEnable(TraceLoggerThread* logger) {
469 : #ifdef JS_TRACE_LOGGING
470 : if (logger)
471 : return logger->enable();
472 : #endif
473 : return false;
474 : }
475 0 : inline bool TraceLoggerEnable(TraceLoggerThread* logger, JSContext* cx) {
476 : #ifdef JS_TRACE_LOGGING
477 0 : if (logger)
478 0 : return logger->enable(cx);
479 : #endif
480 0 : return false;
481 : }
482 0 : inline bool TraceLoggerDisable(TraceLoggerThread* logger) {
483 : #ifdef JS_TRACE_LOGGING
484 0 : if (logger)
485 0 : return logger->disable();
486 : #endif
487 0 : return false;
488 : }
489 : inline void TraceLoggerSilentFail(TraceLoggerThread* logger, const char* error) {
490 : #ifdef JS_TRACE_LOGGING
491 : if (logger)
492 : logger->silentFail(error);
493 : #endif
494 : }
495 :
496 : #ifdef JS_TRACE_LOGGING
497 : bool TraceLogTextIdEnabled(uint32_t textId);
498 : void TraceLogEnableTextId(JSContext* cx, uint32_t textId);
499 : void TraceLogDisableTextId(JSContext* cx, uint32_t textId);
500 : #else
501 : inline bool TraceLogTextIdEnabled(uint32_t textId) {
502 : return false;
503 : }
504 : inline void TraceLogEnableTextId(JSContext* cx, uint32_t textId) {}
505 : inline void TraceLogDisableTextId(JSContext* cx, uint32_t textId) {}
506 : #endif
507 0 : inline void TraceLogTimestamp(TraceLoggerThread* logger, TraceLoggerTextId textId) {
508 : #ifdef JS_TRACE_LOGGING
509 0 : if (logger)
510 0 : logger->logTimestamp(textId);
511 : #endif
512 0 : }
513 12442 : inline void TraceLogStartEvent(TraceLoggerThread* logger, TraceLoggerTextId textId) {
514 : #ifdef JS_TRACE_LOGGING
515 12442 : if (logger)
516 12442 : logger->startEvent(textId);
517 : #endif
518 12442 : }
519 12299 : inline void TraceLogStartEvent(TraceLoggerThread* logger, const TraceLoggerEvent& event) {
520 : #ifdef JS_TRACE_LOGGING
521 12299 : if (logger)
522 12299 : logger->startEvent(event);
523 : #endif
524 12299 : }
525 14266 : inline void TraceLogStopEvent(TraceLoggerThread* logger, TraceLoggerTextId textId) {
526 : #ifdef JS_TRACE_LOGGING
527 14266 : if (logger)
528 14266 : logger->stopEvent(textId);
529 : #endif
530 14266 : }
531 10325 : inline void TraceLogStopEvent(TraceLoggerThread* logger, const TraceLoggerEvent& event) {
532 : #ifdef JS_TRACE_LOGGING
533 10325 : if (logger)
534 10325 : logger->stopEvent(event);
535 : #endif
536 10325 : }
537 :
538 : // Helper functions for assembly. May not be used otherwise.
539 : inline void TraceLogTimestampPrivate(TraceLoggerThread* logger, uint32_t id) {
540 : #ifdef JS_TRACE_LOGGING
541 : if (logger)
542 : logger->logTimestamp(id);
543 : #endif
544 : }
545 0 : inline void TraceLogStartEventPrivate(TraceLoggerThread* logger, uint32_t id) {
546 : #ifdef JS_TRACE_LOGGING
547 0 : if (logger)
548 0 : logger->startEvent(id);
549 : #endif
550 0 : }
551 0 : inline void TraceLogStopEventPrivate(TraceLoggerThread* logger, uint32_t id) {
552 : #ifdef JS_TRACE_LOGGING
553 0 : if (logger)
554 0 : logger->stopEvent(id);
555 : #endif
556 0 : }
557 :
558 : size_t SizeOfTraceLogState(mozilla::MallocSizeOf mallocSizeOf);
559 :
560 : // Automatic logging at the start and end of function call.
561 : class MOZ_RAII AutoTraceLog
562 : {
563 : #ifdef JS_TRACE_LOGGING
564 : TraceLoggerThread* logger;
565 : union {
566 : const TraceLoggerEvent* event;
567 : TraceLoggerTextId id;
568 : } payload;
569 : bool isEvent;
570 : bool executed;
571 : AutoTraceLog* prev;
572 :
573 : public:
574 14119 : AutoTraceLog(TraceLoggerThread* logger,
575 : const TraceLoggerEvent& event MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
576 14119 : : logger(logger),
577 : isEvent(true),
578 14119 : executed(false)
579 : {
580 14119 : MOZ_GUARD_OBJECT_NOTIFIER_INIT;
581 14119 : payload.event = &event;
582 14119 : if (logger) {
583 14119 : logger->startEvent(event);
584 :
585 14119 : prev = logger->top;
586 14119 : logger->top = this;
587 : }
588 14119 : }
589 :
590 28684 : AutoTraceLog(TraceLoggerThread* logger, TraceLoggerTextId id MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
591 28684 : : logger(logger),
592 : isEvent(false),
593 28684 : executed(false)
594 : {
595 28684 : MOZ_GUARD_OBJECT_NOTIFIER_INIT;
596 28684 : payload.id = id;
597 28684 : if (logger) {
598 28684 : logger->startEvent(id);
599 :
600 28684 : prev = logger->top;
601 28684 : logger->top = this;
602 : }
603 28684 : }
604 :
605 42806 : ~AutoTraceLog()
606 42806 : {
607 42806 : if (logger) {
608 42806 : while (this != logger->top)
609 0 : logger->top->stop();
610 42806 : stop();
611 : }
612 42806 : }
613 : private:
614 42806 : void stop() {
615 42806 : if (!executed) {
616 42806 : executed = true;
617 42806 : if (isEvent)
618 14121 : logger->stopEvent(*payload.event);
619 : else
620 28685 : logger->stopEvent(payload.id);
621 : }
622 :
623 42806 : if (logger->top == this)
624 42806 : logger->top = prev;
625 42806 : }
626 : #else
627 : public:
628 : AutoTraceLog(TraceLoggerThread* logger, uint32_t textId MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
629 : {
630 : MOZ_GUARD_OBJECT_NOTIFIER_INIT;
631 : }
632 : AutoTraceLog(TraceLoggerThread* logger,
633 : const TraceLoggerEvent& event MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
634 : {
635 : MOZ_GUARD_OBJECT_NOTIFIER_INIT;
636 : }
637 : #endif
638 :
639 : private:
640 : MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
641 : };
642 :
643 : } // namespace js
644 :
645 : #endif /* TraceLogging_h */
|