PageRenderTime 68ms CodeModel.GetById 22ms app.highlight 41ms RepoModel.GetById 1ms app.codeStats 0ms

/js/src/jsprobes.h

http://github.com/zpao/v8monkey
C Header | 825 lines | 499 code | 143 blank | 183 comment | 66 complexity | 03d69f7e2ec48b9b2ce5193899ccd0f8 MD5 | raw file
  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
 55namespace js {
 56
 57namespace mjit {
 58struct NativeAddressInfo;
 59struct JSActiveFrame;
 60}
 61
 62namespace 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 */
 94extern bool ProfilingActive;
 95
 96extern const char nullName[];
 97extern const char anonymousName[];
 98
 99/* Called when first runtime is created for this process */
100JSBool startEngine();
101
102/* JSRuntime created, with currently valid fields */
103bool createRuntime(JSRuntime *rt);
104
105/* JSRuntime about to be destroyed */
106bool destroyRuntime(JSRuntime *rt);
107
108/* Total JS engine shutdown */
109bool 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 */
116bool 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 */
122bool wantNativeAddressInfo(JSContext *);
123
124/* Entering a JS function */
125bool enterJSFun(JSContext *, JSFunction *, JSScript *, int counter = 1);
126
127/* About to leave a JS function */
128bool exitJSFun(JSContext *, JSFunction *, JSScript *, int counter = 0);
129
130/* Executing a script */
131bool startExecution(JSContext *cx, JSScript *script);
132
133/* Script has completed execution */
134bool stopExecution(JSContext *cx, JSScript *script);
135
136/* Heap has been resized */
137bool 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 */
142bool createObject(JSContext *cx, JSObject *obj);
143
144/* Resize events are being tracked. */
145bool objectResizeActive();
146
147/* Object has been resized */
148bool 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 */
154bool 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 */
164bool 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 */
171bool finalizeString(JSString *string);
172
173/* Script is about to be compiled */
174bool compileScriptBegin(JSContext *cx, const char *filename, int lineno);
175
176/* Script has just finished compilation */
177bool compileScriptEnd(JSContext *cx, JSScript *script, const char *filename, int lineno);
178
179/* About to make a call from JS into native code */
180bool calloutBegin(JSContext *cx, JSFunction *fun);
181
182/* Native code called by JS has terminated */
183bool calloutEnd(JSContext *cx, JSFunction *fun);
184
185/* Unimplemented */
186bool acquireMemory(JSContext *cx, void *address, size_t nbytes);
187bool 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 */
200bool GCStart();
201bool GCEnd();
202
203bool GCStartMarkPhase();
204bool GCEndMarkPhase();
205
206bool GCStartSweepPhase();
207bool 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 */
217bool CustomMark(JSString *string);
218bool CustomMark(const char *string);
219bool CustomMark(int marker);
220
221/* JIT code observation */
222
223enum 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 */
235class JITWatcher {
236public:
237    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 &regions,
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 */
280bool
281addJITWatcher(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 */
287bool
288removeJITWatcher(JSRuntime *rt, JITWatcher *watcher);
289
290/*
291 * Remove (and destroy) all registered JITWatchers. rt may be NULL.
292 */
293void
294removeAllJITWatchers(JSRuntime *rt);
295
296/*
297 * Finest granularity of JIT information desired by all watchers.
298 */
299JITReportGranularity
300JITGranularityRequested();
301
302#ifdef JS_METHODJIT
303/*
304 * New method JIT code has been created
305 */
306void
307registerMJITCode(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 */
316void
317discardMJITCode(JSContext *cx, mjit::JITScript *jscr, JSScript *script, void* address);
318
319/*
320 * IC code has been allocated within the given JITScript
321 */
322void
323registerICCode(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 */
332void
333discardExecutableRegion(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 */
341void DTraceEnterJSFun(JSContext *cx, JSFunction *fun, JSScript *script);
342void DTraceExitJSFun(JSContext *cx, JSFunction *fun, JSScript *script);
343
344/*
345 * Internal: ETW-specific probe functions
346 */
347#ifdef MOZ_ETW
348// ETW Handlers
349bool ETWCreateRuntime(JSRuntime *rt);
350bool ETWDestroyRuntime(JSRuntime *rt);
351bool ETWShutdown();
352bool ETWCallTrackingActive(JSContext *cx);
353bool ETWEnterJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int counter);
354bool ETWExitJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int counter);
355bool ETWCreateObject(JSContext *cx, JSObject *obj);
356bool ETWFinalizeObject(JSObject *obj);
357bool ETWResizeObject(JSContext *cx, JSObject *obj, size_t oldSize, size_t newSize);
358bool ETWCreateString(JSContext *cx, JSString *string, size_t length);
359bool ETWFinalizeString(JSString *string);
360bool ETWCompileScriptBegin(const char *filename, int lineno);
361bool ETWCompileScriptEnd(const char *filename, int lineno);
362bool ETWCalloutBegin(JSContext *cx, JSFunction *fun);
363bool ETWCalloutEnd(JSContext *cx, JSFunction *fun);
364bool ETWAcquireMemory(JSContext *cx, void *address, size_t nbytes);
365bool ETWReleaseMemory(JSContext *cx, void *address, size_t nbytes);
366bool ETWGCStart();
367bool ETWGCEnd();
368bool ETWGCStartMarkPhase();
369bool ETWGCEndMarkPhase();
370bool ETWGCStartSweepPhase();
371bool ETWGCEndSweepPhase();
372bool ETWCustomMark(JSString *string);
373bool ETWCustomMark(const char *string);
374bool ETWCustomMark(int marker);
375bool ETWStartExecution(JSContext *cx, JSScript *script);
376bool ETWStopExecution(JSContext *cx, JSScript *script);
377bool 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
387inline bool
388Probes::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    return false;
403}
404
405inline bool
406Probes::wantNativeAddressInfo(JSContext *cx)
407{
408    return (cx->reportGranularity >= JITREPORT_GRANULARITY_FUNCTION &&
409            JITGranularityRequested() >= JITREPORT_GRANULARITY_FUNCTION);
410}
411
412inline bool
413Probes::enterJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int counter)
414{
415    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    return ok;
429}
430
431inline bool
432Probes::exitJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int counter)
433{
434    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    return ok;
451}
452
453inline bool
454Probes::resizeHeap(JSCompartment *compartment, size_t oldSize, size_t newSize)
455{
456    bool ok = true;
457
458#ifdef MOZ_ETW
459    if (ProfilingActive && !ETWResizeHeap(compartment, oldSize, newSize))
460        ok = false;
461#endif
462
463    return ok;
464}
465
466#ifdef INCLUDE_MOZILLA_DTRACE
467static 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
480inline bool
481Probes::createObject(JSContext *cx, JSObject *obj)
482{
483    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    return ok;
495}
496
497inline bool
498Probes::finalizeObject(JSObject *obj)
499{
500    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    return ok;
516}
517
518inline bool
519Probes::objectResizeActive()
520{
521#ifdef MOZ_ETW
522    if (ProfilingActive)
523        return true;
524#endif
525
526    return false;
527}
528
529inline bool
530Probes::resizeObject(JSContext *cx, JSObject *obj, size_t oldSize, size_t newSize)
531{
532    bool ok = true;
533
534#ifdef MOZ_ETW
535    if (ProfilingActive && !ETWResizeObject(cx, obj, oldSize, newSize))
536        ok = false;
537#endif
538
539    return ok;
540}
541
542inline bool
543Probes::createString(JSContext *cx, JSString *string, size_t length)
544{
545    bool ok = true;
546
547#ifdef MOZ_ETW
548    if (ProfilingActive && !ETWCreateString(cx, string, length))
549        ok = false;
550#endif
551
552    return ok;
553}
554
555inline bool
556Probes::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
568inline bool
569Probes::compileScriptBegin(JSContext *cx, const char *filename, int lineno)
570{
571    bool ok = true;
572
573#ifdef MOZ_ETW
574    if (ProfilingActive && !ETWCompileScriptBegin(filename, lineno))
575        ok = false;
576#endif
577
578    return ok;
579}
580
581inline bool
582Probes::compileScriptEnd(JSContext *cx, JSScript *script, const char *filename, int lineno)
583{
584    bool ok = true;
585
586#ifdef MOZ_ETW
587    if (ProfilingActive && !ETWCompileScriptEnd(filename, lineno))
588        ok = false;
589#endif
590
591    return ok;
592}
593
594inline bool
595Probes::calloutBegin(JSContext *cx, JSFunction *fun)
596{
597    bool ok = true;
598
599#ifdef MOZ_ETW
600    if (ProfilingActive && !ETWCalloutBegin(cx, fun))
601        ok = false;
602#endif
603
604    return ok;
605}
606
607inline bool
608Probes::calloutEnd(JSContext *cx, JSFunction *fun)
609{
610    bool ok = true;
611
612#ifdef MOZ_ETW
613    if (ProfilingActive && !ETWCalloutEnd(cx, fun))
614        ok = false;
615#endif
616
617    return ok;
618}
619
620inline bool
621Probes::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
633inline bool
634Probes::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
646inline bool
647Probes::GCStart()
648{
649    bool ok = true;
650
651#ifdef MOZ_ETW
652    if (ProfilingActive && !ETWGCStart())
653        ok = false;
654#endif
655
656    return ok;
657}
658
659inline bool
660Probes::GCEnd()
661{
662    bool ok = true;
663
664#ifdef MOZ_ETW
665    if (ProfilingActive && !ETWGCEnd())
666        ok = false;
667#endif
668
669    return ok;
670}
671
672inline bool
673Probes::GCStartMarkPhase()
674{
675    bool ok = true;
676
677#ifdef MOZ_ETW
678    if (ProfilingActive && !ETWGCStartMarkPhase())
679        ok = false;
680#endif
681
682    return ok;
683}
684
685inline bool
686Probes::GCEndMarkPhase()
687{
688    bool ok = true;
689
690#ifdef MOZ_ETW
691    if (ProfilingActive && !ETWGCEndMarkPhase())
692        ok = false;
693#endif
694
695    return ok;
696}
697
698inline bool
699Probes::GCStartSweepPhase()
700{
701    bool ok = true;
702
703#ifdef MOZ_ETW
704    if (ProfilingActive && !ETWGCStartSweepPhase())
705        ok = false;
706#endif
707
708    return ok;
709}
710
711inline bool
712Probes::GCEndSweepPhase()
713{
714    bool ok = true;
715
716#ifdef MOZ_ETW
717    if (ProfilingActive && !ETWGCEndSweepPhase())
718        ok = false;
719#endif
720
721    return ok;
722}
723
724inline bool
725Probes::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
737inline bool
738Probes::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
750inline bool
751Probes::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
763inline bool
764Probes::startExecution(JSContext *cx, JSScript *script)
765{
766    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    return ok;
779}
780
781inline bool
782Probes::stopExecution(JSContext *cx, JSScript *script)
783{
784    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    return ok;
797}
798
799struct AutoFunctionCallProbe {
800    JSContext * const cx;
801    JSFunction *fun;
802    JSScript *script;
803    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
804
805    AutoFunctionCallProbe(JSContext *cx, JSFunction *fun, JSScript *script
806                          JS_GUARD_OBJECT_NOTIFIER_PARAM)
807      : cx(cx), fun(fun), script(script)
808    {
809        JS_GUARD_OBJECT_NOTIFIER_INIT;
810        Probes::enterJSFun(cx, fun, script);
811    }
812
813    ~AutoFunctionCallProbe() {
814        Probes::exitJSFun(cx, fun, script);
815    }
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 */