Imported Upstream version 1.0.0
[platform/upstream/js.git] / js / src / jsprobes.h
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  * Copyright (C) 2007  Sun Microsystems, Inc. All Rights Reserved.
18  *
19  * Contributor(s):
20  *      Brendan Eich <brendan@mozilla.org>
21  *
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.
33  *
34  * ***** END LICENSE BLOCK ***** */
35
36 #ifdef INCLUDE_MOZILLA_DTRACE
37 #include "javascript-trace.h"
38 #endif
39 #include "jspubtd.h"
40 #include "jsprvtd.h"
41
42 #ifndef _JSPROBES_H
43 #define _JSPROBES_H
44
45 namespace js {
46
47 class Probes {
48     static const char nullName[];
49
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);
54
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);
58   public:
59     static bool callTrackingActive(JSContext *);
60
61     static void enterJSFun(JSContext *, JSFunction *, JSScript *, int counter = 1);
62     static void exitJSFun(JSContext *, JSFunction *, JSScript *, int counter = 0);
63
64     static void startExecution(JSContext *cx, JSScript *script);
65     static void stopExecution(JSContext *cx, JSScript *script);
66
67     static void resizeHeap(JSCompartment *compartment, size_t oldSize, size_t newSize);
68
69     /* |obj| must exist (its class and size are computed) */
70     static void createObject(JSContext *cx, JSObject *obj);
71
72     static void resizeObject(JSContext *cx, JSObject *obj, size_t oldSize, size_t newSize);
73
74     /* |obj| must still exist (its class is accessed) */
75     static void finalizeObject(JSObject *obj);
76
77     /*
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
83      * consideration.)
84      */
85     static void createString(JSContext *cx, JSString *string, size_t length);
86
87     /*
88      * |string| must still have a valid length.
89      */
90     static void finalizeString(JSString *string);
91
92     static void compileScriptBegin(JSContext *cx, const char *filename, int lineno);
93     static void compileScriptEnd(JSContext *cx, JSScript *script, const char *filename, int lineno);
94
95     static void calloutBegin(JSContext *cx, JSFunction *fun);
96     static void calloutEnd(JSContext *cx, JSFunction *fun);
97
98     static void acquireMemory(JSContext *cx, void *address, size_t nbytes);
99     static void releaseMemory(JSContext *cx, void *address, size_t nbytes);
100
101     static void GCStart(JSCompartment *compartment);
102     static void GCEnd(JSCompartment *compartment);
103     static void GCStartMarkPhase(JSCompartment *compartment);
104
105     static void GCEndMarkPhase(JSCompartment *compartment);
106     static void GCStartSweepPhase(JSCompartment *compartment);
107     static void GCEndSweepPhase(JSCompartment *compartment);
108
109     static bool CustomMark(JSString *string);
110     static bool CustomMark(const char *string);
111     static bool CustomMark(int marker);
112
113     static bool startProfiling();
114     static void stopProfiling();
115 };
116
117 inline bool
118 Probes::callTrackingActive(JSContext *cx)
119 {
120 #ifdef INCLUDE_MOZILLA_DTRACE
121     if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED() || JAVASCRIPT_FUNCTION_RETURN_ENABLED())
122         return true;
123 #endif
124 #ifdef MOZ_TRACE_JSCALLS
125     if (cx->functionCallback)
126         return true;
127 #endif
128 #ifdef MOZ_ETW
129     if (ProfilingActive && MCGEN_ENABLE_CHECK(MozillaSpiderMonkey_Context, EvtFunctionEntry))
130         return true;
131 #endif
132     return false;
133 }
134
135 inline void
136 Probes::enterJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int counter)
137 {
138 #ifdef INCLUDE_MOZILLA_DTRACE
139     if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED())
140         enterJSFunImpl(cx, fun, script);
141 #endif
142 #ifdef MOZ_TRACE_JSCALLS
143     cx->doFunctionCallback(fun, script, counter);
144 #endif
145 }
146
147 inline void
148 Probes::exitJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int counter)
149 {
150 #ifdef INCLUDE_MOZILLA_DTRACE
151     if (JAVASCRIPT_FUNCTION_RETURN_ENABLED())
152         handleFunctionReturn(cx, fun, script);
153 #endif
154 #ifdef MOZ_TRACE_JSCALLS
155     if (counter > 0)
156         counter = -counter;
157     cx->doFunctionCallback(fun, script, counter);
158 #endif
159 }
160
161 inline void
162 Probes::createObject(JSContext *cx, JSObject *obj)
163 {
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);
168     }
169 #endif
170 }
171
172 inline void
173 Probes::finalizeObject(JSObject *obj)
174 {
175 #ifdef INCLUDE_MOZILLA_DTRACE
176     if (JAVASCRIPT_OBJECT_FINALIZE_ENABLED()) {
177         Class *clasp = obj->getClass();
178
179         /* the first arg is NULL - reserved for future use (filename?) */
180         JAVASCRIPT_OBJECT_FINALIZE(NULL, (char *)clasp->name, (uintptr_t)obj);
181     }
182 #endif
183 }
184
185 inline void
186 Probes::startExecution(JSContext *cx, JSScript *script)
187 {
188 #ifdef INCLUDE_MOZILLA_DTRACE
189     if (JAVASCRIPT_EXECUTE_START_ENABLED())
190         JAVASCRIPT_EXECUTE_START((script->filename ? (char *)script->filename : nullName),
191                                  script->lineno);
192 #endif
193 #ifdef MOZ_TRACE_JSCALLS
194     cx->doFunctionCallback(NULL, script, 1);
195 #endif
196 }
197
198 inline void
199 Probes::stopExecution(JSContext *cx, JSScript *script)
200 {
201 #ifdef INCLUDE_MOZILLA_DTRACE
202     if (JAVASCRIPT_EXECUTE_DONE_ENABLED())
203         JAVASCRIPT_EXECUTE_DONE((script->filename ? (char *)script->filename : nullName),
204                                 script->lineno);
205 #endif
206 #ifdef MOZ_TRACE_JSCALLS
207     cx->doFunctionCallback(NULL, script, 0);
208 #endif
209 }
210
211 /*
212  * New probes with no implementations, yet. Next patch will implement
213  * them. These are here just to make all intermediate patches compile
214  * and run.
215  */
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; }
235
236 struct AutoFunctionCallProbe {
237     JSContext * const cx;
238     JSFunction *fun;
239     JSScript *script;
240     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
241
242     AutoFunctionCallProbe(JSContext *cx, JSFunction *fun, JSScript *script
243                           JS_GUARD_OBJECT_NOTIFIER_PARAM)
244       : cx(cx), fun(fun), script(script)
245     {
246         JS_GUARD_OBJECT_NOTIFIER_INIT;
247         Probes::enterJSFun(cx, fun, script);
248     }
249
250     ~AutoFunctionCallProbe() {
251         Probes::exitJSFun(cx, fun, script);
252     }
253 };
254
255 } /* namespace js */
256     
257 #endif /* _JSPROBES_H */