summaryrefslogtreecommitdiffstats
path: root/js/src/vm/Probes.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/vm/Probes.h')
-rw-r--r--js/src/vm/Probes.h144
1 files changed, 144 insertions, 0 deletions
diff --git a/js/src/vm/Probes.h b/js/src/vm/Probes.h
new file mode 100644
index 0000000000..83c984e55c
--- /dev/null
+++ b/js/src/vm/Probes.h
@@ -0,0 +1,144 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef vm_Probes_h
+#define vm_Probes_h
+
+#ifdef INCLUDE_MOZILLA_DTRACE
+# include "javascript-trace.h"
+#endif
+
+#include "vm/JSObject.h"
+
+namespace js {
+
+class InterpreterFrame;
+
+namespace probes {
+
+/*
+ * Static probes
+ *
+ * The probe points defined in this file are scattered around the SpiderMonkey
+ * source tree. The presence of probes::SomeEvent() means that someEvent is
+ * about to happen or has happened. To the extent possible, probes should be
+ * inserted in all paths associated with a given event, regardless of the
+ * active runmode (interpreter/traceJIT/methodJIT/ionJIT).
+ *
+ * When a probe fires, it is handled by any probe handling backends that have
+ * been compiled in. By default, most probes do nothing or at least do nothing
+ * expensive, so the presence of the probe should have negligible effect on
+ * running time. (Probes in slow paths may do something by default, as long as
+ * there is no noticeable slowdown.)
+ *
+ * For some probes, the mere existence of the probe is too expensive even if it
+ * does nothing when called. For example, just having consistent information
+ * available for a function call entry/exit probe causes the JITs to
+ * de-optimize function calls. In those cases, the JITs may query at compile
+ * time whether a probe is desired, and omit the probe invocation if not. If a
+ * probe is runtime-disabled at compilation time, it is not guaranteed to fire
+ * within a compiled function if it is later enabled.
+ *
+ * Not all backends handle all of the probes listed here.
+ */
+
+/*
+ * Internal use only: remember whether "profiling", whatever that means, is
+ * currently active. Used for state management.
+ */
+extern bool ProfilingActive;
+
+extern const char nullName[];
+extern const char anonymousName[];
+
+/*
+ * Test whether we are tracking JS function call enter/exit. The JITs use this
+ * to decide whether they can optimize in a way that would prevent probes from
+ * firing.
+ */
+bool CallTrackingActive(JSContext*);
+
+/* Entering a JS function */
+bool EnterScript(JSContext*, JSScript*, JSFunction*, InterpreterFrame*);
+
+/* About to leave a JS function */
+void ExitScript(JSContext*, JSScript*, JSFunction*, bool popProfilerFrame);
+
+/* Executing a script */
+bool StartExecution(JSScript* script);
+
+/* Script has completed execution */
+bool StopExecution(JSScript* script);
+
+/*
+ * Object has been created. |obj| must exist (its class and size are read)
+ */
+bool CreateObject(JSContext* cx, JSObject* obj);
+
+/*
+ * Object is about to be finalized. |obj| must still exist (its class is
+ * read)
+ */
+bool FinalizeObject(JSObject* obj);
+
+/*
+ * Internal: DTrace-specific functions to be called during probes::EnterScript
+ * and probes::ExitScript. These will not be inlined, but the argument
+ * marshalling required for these probe points is expensive enough that it
+ * shouldn't really matter.
+ */
+void DTraceEnterJSFun(JSContext* cx, JSFunction* fun, JSScript* script);
+void DTraceExitJSFun(JSContext* cx, JSFunction* fun, JSScript* script);
+
+} // namespace probes
+
+#ifdef INCLUDE_MOZILLA_DTRACE
+static const char* ObjectClassname(JSObject* obj) {
+ if (!obj) {
+ return "(null object)";
+ }
+ const JSClass* clasp = obj->getClass();
+ if (!clasp) {
+ return "(null)";
+ }
+ const char* class_name = clasp->name;
+ if (!class_name) {
+ return "(null class name)";
+ }
+ return class_name;
+}
+#endif
+
+inline bool probes::CreateObject(JSContext* cx, JSObject* obj) {
+ bool ok = true;
+
+#ifdef INCLUDE_MOZILLA_DTRACE
+ if (JAVASCRIPT_OBJECT_CREATE_ENABLED()) {
+ JAVASCRIPT_OBJECT_CREATE(ObjectClassname(obj), (uintptr_t)obj);
+ }
+#endif
+
+ return ok;
+}
+
+inline bool probes::FinalizeObject(JSObject* obj) {
+ bool ok = true;
+
+#ifdef INCLUDE_MOZILLA_DTRACE
+ if (JAVASCRIPT_OBJECT_FINALIZE_ENABLED()) {
+ const JSClass* clasp = obj->getClass();
+
+ /* the first arg is nullptr - reserved for future use (filename?) */
+ JAVASCRIPT_OBJECT_FINALIZE(nullptr, (char*)clasp->name, (uintptr_t)obj);
+ }
+#endif
+
+ return ok;
+}
+
+} /* namespace js */
+
+#endif /* vm_Probes_h */