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