1 : /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sw=4 et tw=80:
3 : *
4 : * ***** BEGIN LICENSE BLOCK *****
5 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 : *
7 : * The contents of this file are subject to the Mozilla Public License Version
8 : * 1.1 (the "License"); you may not use this file except in compliance with
9 : * the License. You may obtain a copy of the License at
10 : * http://www.mozilla.org/MPL/
11 : *
12 : * Software distributed under the License is distributed on an "AS IS" basis,
13 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 : * for the specific language governing rights and limitations under the
15 : * License.
16 : *
17 : * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
18 : * June 12, 2009.
19 : *
20 : * The Initial Developer of the Original Code is
21 : * the Mozilla Corporation.
22 : *
23 : * Contributor(s):
24 : * Steve Fink <sfink@mozilla.org>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either of the GNU General Public License Version 2 or later (the "GPL"),
28 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #ifndef _JSPROBES_H
41 : #define _JSPROBES_H
42 :
43 : #ifdef INCLUDE_MOZILLA_DTRACE
44 : #include "javascript-trace.h"
45 : #endif
46 : #include "jspubtd.h"
47 : #include "jsprvtd.h"
48 : #include "jsscript.h"
49 : #include "jsobj.h"
50 :
51 : #ifdef JS_METHODJIT
52 : #include "methodjit/MethodJIT.h"
53 : #endif
54 :
55 : namespace js {
56 :
57 : namespace mjit {
58 : struct NativeAddressInfo;
59 : struct JSActiveFrame;
60 : }
61 :
62 : namespace Probes {
63 :
64 : /*
65 : * Static probes
66 : *
67 : * The probe points defined in this file are scattered around the SpiderMonkey
68 : * source tree. The presence of Probes::someEvent() means that someEvent is
69 : * about to happen or has happened. To the extent possible, probes should be
70 : * inserted in all paths associated with a given event, regardless of the
71 : * active runmode (interpreter/traceJIT/methodJIT/ionJIT).
72 : *
73 : * When a probe fires, it is handled by any probe handling backends that have
74 : * been compiled in. By default, most probes do nothing or at least do nothing
75 : * expensive, so the presence of the probe should have negligible effect on
76 : * running time. (Probes in slow paths may do something by default, as long as
77 : * there is no noticeable slowdown.)
78 : *
79 : * For some probes, the mere existence of the probe is too expensive even if it
80 : * does nothing when called. For example, just having consistent information
81 : * available for a function call entry/exit probe causes the JITs to
82 : * de-optimize function calls. In those cases, the JITs may query at compile
83 : * time whether a probe is desired, and omit the probe invocation if not. If a
84 : * probe is runtime-disabled at compilation time, it is not guaranteed to fire
85 : * within a compiled function if it is later enabled.
86 : *
87 : * Not all backends handle all of the probes listed here.
88 : */
89 :
90 : /*
91 : * Internal use only: remember whether "profiling", whatever that means, is
92 : * currently active. Used for state management.
93 : */
94 : extern bool ProfilingActive;
95 :
96 : extern const char nullName[];
97 : extern const char anonymousName[];
98 :
99 : /* Called when first runtime is created for this process */
100 : JSBool startEngine();
101 :
102 : /* JSRuntime created, with currently valid fields */
103 : bool createRuntime(JSRuntime *rt);
104 :
105 : /* JSRuntime about to be destroyed */
106 : bool destroyRuntime(JSRuntime *rt);
107 :
108 : /* Total JS engine shutdown */
109 : bool shutdown();
110 :
111 : /*
112 : * Test whether we are tracking JS function call enter/exit. The JITs use this
113 : * to decide whether they can optimize in a way that would prevent probes from
114 : * firing.
115 : */
116 : bool callTrackingActive(JSContext *);
117 :
118 : /*
119 : * Test whether anything is looking for JIT native code registration events.
120 : * This information will not be collected otherwise.
121 : */
122 : bool wantNativeAddressInfo(JSContext *);
123 :
124 : /* Entering a JS function */
125 : bool enterJSFun(JSContext *, JSFunction *, JSScript *, int counter = 1);
126 :
127 : /* About to leave a JS function */
128 : bool exitJSFun(JSContext *, JSFunction *, JSScript *, int counter = 0);
129 :
130 : /* Executing a script */
131 : bool startExecution(JSContext *cx, JSScript *script);
132 :
133 : /* Script has completed execution */
134 : bool stopExecution(JSContext *cx, JSScript *script);
135 :
136 : /* Heap has been resized */
137 : bool resizeHeap(JSCompartment *compartment, size_t oldSize, size_t newSize);
138 :
139 : /*
140 : * Object has been created. |obj| must exist (its class and size are read)
141 : */
142 : bool createObject(JSContext *cx, JSObject *obj);
143 :
144 : /* Resize events are being tracked. */
145 : bool objectResizeActive();
146 :
147 : /* Object has been resized */
148 : bool resizeObject(JSContext *cx, JSObject *obj, size_t oldSize, size_t newSize);
149 :
150 : /*
151 : * Object is about to be finalized. |obj| must still exist (its class is
152 : * read)
153 : */
154 : bool finalizeObject(JSObject *obj);
155 :
156 : /*
157 : * String has been created.
158 : *
159 : * |string|'s content is not (yet) valid. |length| is the length of the string
160 : * and does not imply anything about the amount of storage consumed to store
161 : * the string. (It may be a short string, an external string, or a rope, and
162 : * the encoding is not taken into consideration.)
163 : */
164 : bool createString(JSContext *cx, JSString *string, size_t length);
165 :
166 : /*
167 : * String is about to be finalized
168 : *
169 : * |string| must still have a valid length.
170 : */
171 : bool finalizeString(JSString *string);
172 :
173 : /* Script is about to be compiled */
174 : bool compileScriptBegin(JSContext *cx, const char *filename, int lineno);
175 :
176 : /* Script has just finished compilation */
177 : bool compileScriptEnd(JSContext *cx, JSScript *script, const char *filename, int lineno);
178 :
179 : /* About to make a call from JS into native code */
180 : bool calloutBegin(JSContext *cx, JSFunction *fun);
181 :
182 : /* Native code called by JS has terminated */
183 : bool calloutEnd(JSContext *cx, JSFunction *fun);
184 :
185 : /* Unimplemented */
186 : bool acquireMemory(JSContext *cx, void *address, size_t nbytes);
187 : bool releaseMemory(JSContext *cx, void *address, size_t nbytes);
188 :
189 : /*
190 : * Garbage collection probes
191 : *
192 : * GC timing is tricky and at the time of this writing is changing frequently.
193 : * GCStart/GCEnd are intended to bracket the entire garbage collection (either
194 : * global or single-compartment), but a separate thread may continue doing work
195 : * after GCEnd.
196 : *
197 : * Multiple compartments' GC will be interleaved during a global collection
198 : * (eg, compartment 1 starts, compartment 2 starts, compartment 1 ends, ...)
199 : */
200 : bool GCStart();
201 : bool GCEnd();
202 :
203 : bool GCStartMarkPhase();
204 : bool GCEndMarkPhase();
205 :
206 : bool GCStartSweepPhase();
207 : bool GCEndSweepPhase();
208 :
209 : /*
210 : * Various APIs for inserting custom probe points. These might be used to mark
211 : * when something starts and stops, or for various other purposes the user has
212 : * in mind. These are useful to export to JS so that JS code can mark
213 : * application-meaningful events and phases of execution.
214 : *
215 : * Not all backends support these.
216 : */
217 : bool CustomMark(JSString *string);
218 : bool CustomMark(const char *string);
219 : bool CustomMark(int marker);
220 :
221 : /* JIT code observation */
222 :
223 : enum JITReportGranularity {
224 : JITREPORT_GRANULARITY_NONE = 0,
225 : JITREPORT_GRANULARITY_FUNCTION = 1,
226 : JITREPORT_GRANULARITY_LINE = 2,
227 : JITREPORT_GRANULARITY_OP = 3
228 : };
229 :
230 : /*
231 : * Observer class for JIT code allocation/deallocation. Currently, this only
232 : * handles the method JIT, and does not get notifications when JIT code is
233 : * changed (patched) with no new allocation.
234 : */
235 0 : class JITWatcher {
236 : public:
237 0 : struct NativeRegion {
238 : mjit::JSActiveFrame *frame;
239 : JSScript *script;
240 : size_t inlinedOffset;
241 : jsbytecode *pc;
242 : jsbytecode *endpc;
243 : uintptr_t mainOffset;
244 : uintptr_t stubOffset;
245 : bool enter;
246 : };
247 :
248 : typedef Vector<NativeRegion, 0, RuntimeAllocPolicy> RegionVector;
249 :
250 : virtual JITReportGranularity granularityRequested() = 0;
251 :
252 : #ifdef JS_METHODJIT
253 : static bool CollectNativeRegions(RegionVector ®ions,
254 : JSRuntime *rt,
255 : mjit::JITChunk *jit,
256 : mjit::JSActiveFrame *outerFrame,
257 : mjit::JSActiveFrame **inlineFrames);
258 :
259 : virtual void registerMJITCode(JSContext *cx, js::mjit::JITScript *jscr,
260 : mjit::JSActiveFrame *outerFrame,
261 : mjit::JSActiveFrame **inlineFrames,
262 : void *mainCodeAddress, size_t mainCodeSize,
263 : void *stubCodeAddress, size_t stubCodeSize) = 0;
264 :
265 : virtual void discardMJITCode(JSContext *cx, mjit::JITScript *jscr, JSScript *script,
266 : void* address) = 0;
267 :
268 : virtual void registerICCode(JSContext *cx,
269 : js::mjit::JITScript *jscr, JSScript *script, jsbytecode* pc,
270 : void *start, size_t size) = 0;
271 : #endif
272 :
273 : virtual void discardExecutableRegion(void *start, size_t size) = 0;
274 : };
275 :
276 : /*
277 : * Register a JITWatcher subclass to be informed of JIT code
278 : * allocation/deallocation.
279 : */
280 : bool
281 : addJITWatcher(JITWatcher *watcher);
282 :
283 : /*
284 : * Remove (and destroy) a registered JITWatcher. rt may be NULL. Returns false
285 : * if the watcher is not found.
286 : */
287 : bool
288 : removeJITWatcher(JSRuntime *rt, JITWatcher *watcher);
289 :
290 : /*
291 : * Remove (and destroy) all registered JITWatchers. rt may be NULL.
292 : */
293 : void
294 : removeAllJITWatchers(JSRuntime *rt);
295 :
296 : /*
297 : * Finest granularity of JIT information desired by all watchers.
298 : */
299 : JITReportGranularity
300 : JITGranularityRequested();
301 :
302 : #ifdef JS_METHODJIT
303 : /*
304 : * New method JIT code has been created
305 : */
306 : void
307 : registerMJITCode(JSContext *cx, js::mjit::JITScript *jscr,
308 : mjit::JSActiveFrame *outerFrame,
309 : mjit::JSActiveFrame **inlineFrames,
310 : void *mainCodeAddress, size_t mainCodeSize,
311 : void *stubCodeAddress, size_t stubCodeSize);
312 :
313 : /*
314 : * Method JIT code is about to be discarded
315 : */
316 : void
317 : discardMJITCode(JSContext *cx, mjit::JITScript *jscr, JSScript *script, void* address);
318 :
319 : /*
320 : * IC code has been allocated within the given JITScript
321 : */
322 : void
323 : registerICCode(JSContext *cx,
324 : mjit::JITScript *jscr, JSScript *script, jsbytecode* pc,
325 : void *start, size_t size);
326 : #endif /* JS_METHODJIT */
327 :
328 : /*
329 : * A whole region of code has been deallocated, containing any number of ICs.
330 : * (ICs are unregistered in a batch, so individual ICs are not registered.)
331 : */
332 : void
333 : discardExecutableRegion(void *start, size_t size);
334 :
335 : /*
336 : * Internal: DTrace-specific functions to be called during Probes::enterJSFun
337 : * and Probes::exitJSFun. These will not be inlined, but the argument
338 : * marshalling required for these probe points is expensive enough that it
339 : * shouldn't really matter.
340 : */
341 : void DTraceEnterJSFun(JSContext *cx, JSFunction *fun, JSScript *script);
342 : void DTraceExitJSFun(JSContext *cx, JSFunction *fun, JSScript *script);
343 :
344 : /*
345 : * Internal: ETW-specific probe functions
346 : */
347 : #ifdef MOZ_ETW
348 : // ETW Handlers
349 : bool ETWCreateRuntime(JSRuntime *rt);
350 : bool ETWDestroyRuntime(JSRuntime *rt);
351 : bool ETWShutdown();
352 : bool ETWCallTrackingActive(JSContext *cx);
353 : bool ETWEnterJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int counter);
354 : bool ETWExitJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int counter);
355 : bool ETWCreateObject(JSContext *cx, JSObject *obj);
356 : bool ETWFinalizeObject(JSObject *obj);
357 : bool ETWResizeObject(JSContext *cx, JSObject *obj, size_t oldSize, size_t newSize);
358 : bool ETWCreateString(JSContext *cx, JSString *string, size_t length);
359 : bool ETWFinalizeString(JSString *string);
360 : bool ETWCompileScriptBegin(const char *filename, int lineno);
361 : bool ETWCompileScriptEnd(const char *filename, int lineno);
362 : bool ETWCalloutBegin(JSContext *cx, JSFunction *fun);
363 : bool ETWCalloutEnd(JSContext *cx, JSFunction *fun);
364 : bool ETWAcquireMemory(JSContext *cx, void *address, size_t nbytes);
365 : bool ETWReleaseMemory(JSContext *cx, void *address, size_t nbytes);
366 : bool ETWGCStart();
367 : bool ETWGCEnd();
368 : bool ETWGCStartMarkPhase();
369 : bool ETWGCEndMarkPhase();
370 : bool ETWGCStartSweepPhase();
371 : bool ETWGCEndSweepPhase();
372 : bool ETWCustomMark(JSString *string);
373 : bool ETWCustomMark(const char *string);
374 : bool ETWCustomMark(int marker);
375 : bool ETWStartExecution(JSContext *cx, JSScript *script);
376 : bool ETWStopExecution(JSContext *cx, JSScript *script);
377 : bool ETWResizeHeap(JSCompartment *compartment, size_t oldSize, size_t newSize);
378 : #endif
379 :
380 : } /* namespace Probes */
381 :
382 : /*
383 : * Many probe handlers are implemented inline for minimal performance impact,
384 : * especially important when no backends are enabled.
385 : */
386 :
387 : inline bool
388 126308 : Probes::callTrackingActive(JSContext *cx)
389 : {
390 : #ifdef INCLUDE_MOZILLA_DTRACE
391 : if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED() || JAVASCRIPT_FUNCTION_RETURN_ENABLED())
392 : return true;
393 : #endif
394 : #ifdef MOZ_TRACE_JSCALLS
395 : if (cx->functionCallback)
396 : return true;
397 : #endif
398 : #ifdef MOZ_ETW
399 : if (ProfilingActive && ETWCallTrackingActive(cx))
400 : return true;
401 : #endif
402 126308 : return false;
403 : }
404 :
405 : inline bool
406 128881 : Probes::wantNativeAddressInfo(JSContext *cx)
407 : {
408 : return (cx->reportGranularity >= JITREPORT_GRANULARITY_FUNCTION &&
409 128881 : JITGranularityRequested() >= JITREPORT_GRANULARITY_FUNCTION);
410 : }
411 :
412 : inline bool
413 26591268 : Probes::enterJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int counter)
414 : {
415 26591268 : bool ok = true;
416 : #ifdef INCLUDE_MOZILLA_DTRACE
417 : if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED())
418 : DTraceEnterJSFun(cx, fun, script);
419 : #endif
420 : #ifdef MOZ_TRACE_JSCALLS
421 : cx->doFunctionCallback(fun, script, counter);
422 : #endif
423 : #ifdef MOZ_ETW
424 : if (ProfilingActive && !ETWEnterJSFun(cx, fun, script, counter))
425 : ok = false;
426 : #endif
427 :
428 26591268 : return ok;
429 : }
430 :
431 : inline bool
432 27781688 : Probes::exitJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int counter)
433 : {
434 27781688 : bool ok = true;
435 :
436 : #ifdef INCLUDE_MOZILLA_DTRACE
437 : if (JAVASCRIPT_FUNCTION_RETURN_ENABLED())
438 : DTraceExitJSFun(cx, fun, script);
439 : #endif
440 : #ifdef MOZ_TRACE_JSCALLS
441 : if (counter > 0)
442 : counter = -counter;
443 : cx->doFunctionCallback(fun, script, counter);
444 : #endif
445 : #ifdef MOZ_ETW
446 : if (ProfilingActive && !ETWExitJSFun(cx, fun, script, counter))
447 : ok = false;
448 : #endif
449 :
450 27781688 : return ok;
451 : }
452 :
453 : inline bool
454 4134747 : Probes::resizeHeap(JSCompartment *compartment, size_t oldSize, size_t newSize)
455 : {
456 4134747 : bool ok = true;
457 :
458 : #ifdef MOZ_ETW
459 : if (ProfilingActive && !ETWResizeHeap(compartment, oldSize, newSize))
460 : ok = false;
461 : #endif
462 :
463 4134747 : return ok;
464 : }
465 :
466 : #ifdef INCLUDE_MOZILLA_DTRACE
467 : static const char *ObjectClassname(JSObject *obj) {
468 : if (!obj)
469 : return "(null object)";
470 : Class *clasp = obj->getClass();
471 : if (!clasp)
472 : return "(null)";
473 : const char *class_name = clasp->name;
474 : if (!class_name)
475 : return "(null class name)";
476 : return class_name;
477 : }
478 : #endif
479 :
480 : inline bool
481 37721845 : Probes::createObject(JSContext *cx, JSObject *obj)
482 : {
483 37721845 : bool ok = true;
484 :
485 : #ifdef INCLUDE_MOZILLA_DTRACE
486 : if (JAVASCRIPT_OBJECT_CREATE_ENABLED())
487 : JAVASCRIPT_OBJECT_CREATE(ObjectClassname(obj), (uintptr_t)obj);
488 : #endif
489 : #ifdef MOZ_ETW
490 : if (ProfilingActive && !ETWCreateObject(cx, obj))
491 : ok = false;
492 : #endif
493 :
494 37721845 : return ok;
495 : }
496 :
497 : inline bool
498 45369271 : Probes::finalizeObject(JSObject *obj)
499 : {
500 45369271 : bool ok = true;
501 :
502 : #ifdef INCLUDE_MOZILLA_DTRACE
503 : if (JAVASCRIPT_OBJECT_FINALIZE_ENABLED()) {
504 : Class *clasp = obj->getClass();
505 :
506 : /* the first arg is NULL - reserved for future use (filename?) */
507 : JAVASCRIPT_OBJECT_FINALIZE(NULL, (char *)clasp->name, (uintptr_t)obj);
508 : }
509 : #endif
510 : #ifdef MOZ_ETW
511 : if (ProfilingActive && !ETWFinalizeObject(obj))
512 : ok = false;
513 : #endif
514 :
515 45369271 : return ok;
516 : }
517 :
518 : inline bool
519 12709725 : Probes::objectResizeActive()
520 : {
521 : #ifdef MOZ_ETW
522 : if (ProfilingActive)
523 : return true;
524 : #endif
525 :
526 12709725 : return false;
527 : }
528 :
529 : inline bool
530 0 : Probes::resizeObject(JSContext *cx, JSObject *obj, size_t oldSize, size_t newSize)
531 : {
532 0 : bool ok = true;
533 :
534 : #ifdef MOZ_ETW
535 : if (ProfilingActive && !ETWResizeObject(cx, obj, oldSize, newSize))
536 : ok = false;
537 : #endif
538 :
539 0 : return ok;
540 : }
541 :
542 : inline bool
543 116375005 : Probes::createString(JSContext *cx, JSString *string, size_t length)
544 : {
545 116375005 : bool ok = true;
546 :
547 : #ifdef MOZ_ETW
548 : if (ProfilingActive && !ETWCreateString(cx, string, length))
549 : ok = false;
550 : #endif
551 :
552 116375005 : return ok;
553 : }
554 :
555 : inline bool
556 : Probes::finalizeString(JSString *string)
557 : {
558 : bool ok = true;
559 :
560 : #ifdef MOZ_ETW
561 : if (ProfilingActive && !ETWFinalizeString(string))
562 : ok = false;
563 : #endif
564 :
565 : return ok;
566 : }
567 :
568 : inline bool
569 120957 : Probes::compileScriptBegin(JSContext *cx, const char *filename, int lineno)
570 : {
571 120957 : bool ok = true;
572 :
573 : #ifdef MOZ_ETW
574 : if (ProfilingActive && !ETWCompileScriptBegin(filename, lineno))
575 : ok = false;
576 : #endif
577 :
578 120957 : return ok;
579 : }
580 :
581 : inline bool
582 120957 : Probes::compileScriptEnd(JSContext *cx, JSScript *script, const char *filename, int lineno)
583 : {
584 120957 : bool ok = true;
585 :
586 : #ifdef MOZ_ETW
587 : if (ProfilingActive && !ETWCompileScriptEnd(filename, lineno))
588 : ok = false;
589 : #endif
590 :
591 120957 : return ok;
592 : }
593 :
594 : inline bool
595 218004 : Probes::calloutBegin(JSContext *cx, JSFunction *fun)
596 : {
597 218004 : bool ok = true;
598 :
599 : #ifdef MOZ_ETW
600 : if (ProfilingActive && !ETWCalloutBegin(cx, fun))
601 : ok = false;
602 : #endif
603 :
604 218004 : return ok;
605 : }
606 :
607 : inline bool
608 218004 : Probes::calloutEnd(JSContext *cx, JSFunction *fun)
609 : {
610 218004 : bool ok = true;
611 :
612 : #ifdef MOZ_ETW
613 : if (ProfilingActive && !ETWCalloutEnd(cx, fun))
614 : ok = false;
615 : #endif
616 :
617 218004 : return ok;
618 : }
619 :
620 : inline bool
621 : Probes::acquireMemory(JSContext *cx, void *address, size_t nbytes)
622 : {
623 : bool ok = true;
624 :
625 : #ifdef MOZ_ETW
626 : if (ProfilingActive && !ETWAcquireMemory(cx, address, nbytes))
627 : ok = false;
628 : #endif
629 :
630 : return ok;
631 : }
632 :
633 : inline bool
634 : Probes::releaseMemory(JSContext *cx, void *address, size_t nbytes)
635 : {
636 : bool ok = true;
637 :
638 : #ifdef MOZ_ETW
639 : if (ProfilingActive && !ETWReleaseMemory(cx, address, nbytes))
640 : ok = false;
641 : #endif
642 :
643 : return ok;
644 : }
645 :
646 : inline bool
647 51092 : Probes::GCStart()
648 : {
649 51092 : bool ok = true;
650 :
651 : #ifdef MOZ_ETW
652 : if (ProfilingActive && !ETWGCStart())
653 : ok = false;
654 : #endif
655 :
656 51092 : return ok;
657 : }
658 :
659 : inline bool
660 51092 : Probes::GCEnd()
661 : {
662 51092 : bool ok = true;
663 :
664 : #ifdef MOZ_ETW
665 : if (ProfilingActive && !ETWGCEnd())
666 : ok = false;
667 : #endif
668 :
669 51092 : return ok;
670 : }
671 :
672 : inline bool
673 153276 : Probes::GCStartMarkPhase()
674 : {
675 153276 : bool ok = true;
676 :
677 : #ifdef MOZ_ETW
678 : if (ProfilingActive && !ETWGCStartMarkPhase())
679 : ok = false;
680 : #endif
681 :
682 153276 : return ok;
683 : }
684 :
685 : inline bool
686 153276 : Probes::GCEndMarkPhase()
687 : {
688 153276 : bool ok = true;
689 :
690 : #ifdef MOZ_ETW
691 : if (ProfilingActive && !ETWGCEndMarkPhase())
692 : ok = false;
693 : #endif
694 :
695 153276 : return ok;
696 : }
697 :
698 : inline bool
699 51092 : Probes::GCStartSweepPhase()
700 : {
701 51092 : bool ok = true;
702 :
703 : #ifdef MOZ_ETW
704 : if (ProfilingActive && !ETWGCStartSweepPhase())
705 : ok = false;
706 : #endif
707 :
708 51092 : return ok;
709 : }
710 :
711 : inline bool
712 51092 : Probes::GCEndSweepPhase()
713 : {
714 51092 : bool ok = true;
715 :
716 : #ifdef MOZ_ETW
717 : if (ProfilingActive && !ETWGCEndSweepPhase())
718 : ok = false;
719 : #endif
720 :
721 51092 : return ok;
722 : }
723 :
724 : inline bool
725 : Probes::CustomMark(JSString *string)
726 : {
727 : bool ok = true;
728 :
729 : #ifdef MOZ_ETW
730 : if (ProfilingActive && !ETWCustomMark(string))
731 : ok = false;
732 : #endif
733 :
734 : return ok;
735 : }
736 :
737 : inline bool
738 : Probes::CustomMark(const char *string)
739 : {
740 : bool ok = true;
741 :
742 : #ifdef MOZ_ETW
743 : if (ProfilingActive && !ETWCustomMark(string))
744 : ok = false;
745 : #endif
746 :
747 : return ok;
748 : }
749 :
750 : inline bool
751 : Probes::CustomMark(int marker)
752 : {
753 : bool ok = true;
754 :
755 : #ifdef MOZ_ETW
756 : if (ProfilingActive && !ETWCustomMark(marker))
757 : ok = false;
758 : #endif
759 :
760 : return ok;
761 : }
762 :
763 : inline bool
764 179593 : Probes::startExecution(JSContext *cx, JSScript *script)
765 : {
766 179593 : bool ok = true;
767 :
768 : #ifdef INCLUDE_MOZILLA_DTRACE
769 : if (JAVASCRIPT_EXECUTE_START_ENABLED())
770 : JAVASCRIPT_EXECUTE_START((script->filename ? (char *)script->filename : nullName),
771 : script->lineno);
772 : #endif
773 : #ifdef MOZ_ETW
774 : if (ProfilingActive && !ETWStartExecution(cx, script))
775 : ok = false;
776 : #endif
777 :
778 179593 : return ok;
779 : }
780 :
781 : inline bool
782 179593 : Probes::stopExecution(JSContext *cx, JSScript *script)
783 : {
784 179593 : bool ok = true;
785 :
786 : #ifdef INCLUDE_MOZILLA_DTRACE
787 : if (JAVASCRIPT_EXECUTE_DONE_ENABLED())
788 : JAVASCRIPT_EXECUTE_DONE((script->filename ? (char *)script->filename : nullName),
789 : script->lineno);
790 : #endif
791 : #ifdef MOZ_ETW
792 : if (ProfilingActive && !ETWStopExecution(cx, script))
793 : ok = false;
794 : #endif
795 :
796 179593 : return ok;
797 : }
798 :
799 : struct AutoFunctionCallProbe {
800 : JSContext * const cx;
801 : JSFunction *fun;
802 : JSScript *script;
803 : JS_DECL_USE_GUARD_OBJECT_NOTIFIER
804 :
805 84066 : AutoFunctionCallProbe(JSContext *cx, JSFunction *fun, JSScript *script
806 : JS_GUARD_OBJECT_NOTIFIER_PARAM)
807 84066 : : cx(cx), fun(fun), script(script)
808 : {
809 84066 : JS_GUARD_OBJECT_NOTIFIER_INIT;
810 84066 : Probes::enterJSFun(cx, fun, script);
811 84066 : }
812 :
813 168132 : ~AutoFunctionCallProbe() {
814 84066 : Probes::exitJSFun(cx, fun, script);
815 84066 : }
816 : };
817 :
818 : } /* namespace js */
819 :
820 : /*
821 : * Internal functions for controlling various profilers. The profiler-specific
822 : * implementations of these are mostly in jsdbgapi.cpp.
823 : */
824 :
825 : #endif /* _JSPROBES_H */
|