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