1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sw=4 et tw=80:
4 * ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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
17 * Copyright (C) 2007 Sun Microsystems, Inc. All Rights Reserved.
20 * Brendan Eich <brendan@mozilla.org>
22 * Alternatively, the contents of this file may be used under the terms of
23 * either of the GNU General Public License Version 2 or later (the "GPL"),
24 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
25 * in which case the provisions of the GPL or the LGPL are applicable instead
26 * of those above. If you wish to allow use of your version of this file only
27 * under the terms of either the GPL or the LGPL, and not to allow others to
28 * use your version of this file under the terms of the MPL, indicate your
29 * decision by deleting the provisions above and replace them with the notice
30 * and other provisions required by the GPL or the LGPL. If you do not delete
31 * the provisions above, a recipient may use your version of this file under
32 * the terms of any one of the MPL, the GPL or the LGPL.
34 * ***** END LICENSE BLOCK ***** */
36 #ifdef INCLUDE_MOZILLA_DTRACE
37 #include "javascript-trace.h"
48 static const char nullName
[];
50 static const char *FunctionClassname(const JSFunction
*fun
);
51 static const char *ScriptFilename(JSScript
*script
);
52 static int FunctionLineNumber(JSContext
*cx
, const JSFunction
*fun
);
53 static const char *FunctionName(JSContext
*cx
, const JSFunction
*fun
, JSAutoByteString
*bytes
);
55 static void enterJSFunImpl(JSContext
*cx
, JSFunction
*fun
, JSScript
*script
);
56 static void handleFunctionReturn(JSContext
*cx
, JSFunction
*fun
, JSScript
*script
);
57 static void finalizeObjectImpl(JSObject
*obj
);
59 static bool callTrackingActive(JSContext
*);
61 static void enterJSFun(JSContext
*, JSFunction
*, JSScript
*, int counter
= 1);
62 static void exitJSFun(JSContext
*, JSFunction
*, JSScript
*, int counter
= 0);
64 static void startExecution(JSContext
*cx
, JSScript
*script
);
65 static void stopExecution(JSContext
*cx
, JSScript
*script
);
67 static void resizeHeap(JSCompartment
*compartment
, size_t oldSize
, size_t newSize
);
69 /* |obj| must exist (its class and size are computed) */
70 static void createObject(JSContext
*cx
, JSObject
*obj
);
72 static void resizeObject(JSContext
*cx
, JSObject
*obj
, size_t oldSize
, size_t newSize
);
74 /* |obj| must still exist (its class is accessed) */
75 static void finalizeObject(JSObject
*obj
);
78 * |string| does not need to contain any content yet; only its
79 * pointer value is used. |length| is the length of the string and
80 * does not imply anything about the amount of storage consumed to
81 * store the string. (It may be a short string, an external
82 * string, or a rope, and the encoding is not taken into
85 static void createString(JSContext
*cx
, JSString
*string
, size_t length
);
88 * |string| must still have a valid length.
90 static void finalizeString(JSString
*string
);
92 static void compileScriptBegin(JSContext
*cx
, const char *filename
, int lineno
);
93 static void compileScriptEnd(JSContext
*cx
, JSScript
*script
, const char *filename
, int lineno
);
95 static void calloutBegin(JSContext
*cx
, JSFunction
*fun
);
96 static void calloutEnd(JSContext
*cx
, JSFunction
*fun
);
98 static void acquireMemory(JSContext
*cx
, void *address
, size_t nbytes
);
99 static void releaseMemory(JSContext
*cx
, void *address
, size_t nbytes
);
101 static void GCStart(JSCompartment
*compartment
);
102 static void GCEnd(JSCompartment
*compartment
);
103 static void GCStartMarkPhase(JSCompartment
*compartment
);
105 static void GCEndMarkPhase(JSCompartment
*compartment
);
106 static void GCStartSweepPhase(JSCompartment
*compartment
);
107 static void GCEndSweepPhase(JSCompartment
*compartment
);
109 static bool CustomMark(JSString
*string
);
110 static bool CustomMark(const char *string
);
111 static bool CustomMark(int marker
);
113 static bool startProfiling();
114 static void stopProfiling();
118 Probes::callTrackingActive(JSContext
*cx
)
120 #ifdef INCLUDE_MOZILLA_DTRACE
121 if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED() || JAVASCRIPT_FUNCTION_RETURN_ENABLED())
124 #ifdef MOZ_TRACE_JSCALLS
125 if (cx
->functionCallback
)
129 if (ProfilingActive
&& MCGEN_ENABLE_CHECK(MozillaSpiderMonkey_Context
, EvtFunctionEntry
))
136 Probes::enterJSFun(JSContext
*cx
, JSFunction
*fun
, JSScript
*script
, int counter
)
138 #ifdef INCLUDE_MOZILLA_DTRACE
139 if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED())
140 enterJSFunImpl(cx
, fun
, script
);
142 #ifdef MOZ_TRACE_JSCALLS
143 cx
->doFunctionCallback(fun
, script
, counter
);
148 Probes::exitJSFun(JSContext
*cx
, JSFunction
*fun
, JSScript
*script
, int counter
)
150 #ifdef INCLUDE_MOZILLA_DTRACE
151 if (JAVASCRIPT_FUNCTION_RETURN_ENABLED())
152 handleFunctionReturn(cx
, fun
, script
);
154 #ifdef MOZ_TRACE_JSCALLS
157 cx
->doFunctionCallback(fun
, script
, counter
);
162 Probes::createObject(JSContext
*cx
, JSObject
*obj
)
164 #ifdef INCLUDE_MOZILLA_DTRACE
165 if (JAVASCRIPT_OBJECT_CREATE_ENABLED()) {
166 Class
*clasp
= obj
->getClass();
167 JAVASCRIPT_OBJECT_CREATE((char *)clasp
->name
, (uintptr_t)obj
);
173 Probes::finalizeObject(JSObject
*obj
)
175 #ifdef INCLUDE_MOZILLA_DTRACE
176 if (JAVASCRIPT_OBJECT_FINALIZE_ENABLED()) {
177 Class
*clasp
= obj
->getClass();
179 /* the first arg is NULL - reserved for future use (filename?) */
180 JAVASCRIPT_OBJECT_FINALIZE(NULL
, (char *)clasp
->name
, (uintptr_t)obj
);
186 Probes::startExecution(JSContext
*cx
, JSScript
*script
)
188 #ifdef INCLUDE_MOZILLA_DTRACE
189 if (JAVASCRIPT_EXECUTE_START_ENABLED())
190 JAVASCRIPT_EXECUTE_START((script
->filename
? (char *)script
->filename
: nullName
),
193 #ifdef MOZ_TRACE_JSCALLS
194 cx
->doFunctionCallback(NULL
, script
, 1);
199 Probes::stopExecution(JSContext
*cx
, JSScript
*script
)
201 #ifdef INCLUDE_MOZILLA_DTRACE
202 if (JAVASCRIPT_EXECUTE_DONE_ENABLED())
203 JAVASCRIPT_EXECUTE_DONE((script
->filename
? (char *)script
->filename
: nullName
),
206 #ifdef MOZ_TRACE_JSCALLS
207 cx
->doFunctionCallback(NULL
, script
, 0);
212 * New probes with no implementations, yet. Next patch will implement
213 * them. These are here just to make all intermediate patches compile
216 inline void Probes::resizeHeap(JSCompartment
*compartment
, size_t oldSize
, size_t newSize
) {}
217 inline void Probes::resizeObject(JSContext
*cx
, JSObject
*obj
, size_t oldSize
, size_t newSize
) {}
218 inline void Probes::createString(JSContext
*cx
, JSString
*string
, size_t length
) {}
219 inline void Probes::finalizeString(JSString
*string
) {}
220 inline void Probes::compileScriptBegin(JSContext
*cx
, const char *filename
, int lineno
) {}
221 inline void Probes::compileScriptEnd(JSContext
*cx
, JSScript
*script
, const char *filename
, int lineno
) {}
222 inline void Probes::calloutBegin(JSContext
*cx
, JSFunction
*fun
) {}
223 inline void Probes::calloutEnd(JSContext
*cx
, JSFunction
*fun
) {}
224 inline void Probes::acquireMemory(JSContext
*cx
, void *address
, size_t nbytes
) {}
225 inline void Probes::releaseMemory(JSContext
*cx
, void *address
, size_t nbytes
) {}
226 inline void Probes::GCStart(JSCompartment
*compartment
) {}
227 inline void Probes::GCEnd(JSCompartment
*compartment
) {}
228 inline void Probes::GCStartMarkPhase(JSCompartment
*compartment
) {}
229 inline void Probes::GCEndMarkPhase(JSCompartment
*compartment
) {}
230 inline void Probes::GCStartSweepPhase(JSCompartment
*compartment
) {}
231 inline void Probes::GCEndSweepPhase(JSCompartment
*compartment
) {}
232 inline bool Probes::CustomMark(JSString
*string
) { return JS_TRUE
; }
233 inline bool Probes::CustomMark(const char *string
) { return JS_TRUE
; }
234 inline bool Probes::CustomMark(int marker
) { return JS_TRUE
; }
236 struct AutoFunctionCallProbe
{
237 JSContext
* const cx
;
240 JS_DECL_USE_GUARD_OBJECT_NOTIFIER
242 AutoFunctionCallProbe(JSContext
*cx
, JSFunction
*fun
, JSScript
*script
243 JS_GUARD_OBJECT_NOTIFIER_PARAM
)
244 : cx(cx
), fun(fun
), script(script
)
246 JS_GUARD_OBJECT_NOTIFIER_INIT
;
247 Probes::enterJSFun(cx
, fun
, script
);
250 ~AutoFunctionCallProbe() {
251 Probes::exitJSFun(cx
, fun
, script
);
257 #endif /* _JSPROBES_H */