Bug 584175 - Unify various JS probes into a single set of static probe points. r=gal

Part 1: Change dtrace-specific names to probes
Part 2: Stop using the frame pointer for probes.
Part 3: Update the set of available probes

r=gal@uci.edu
a=NPOTB

--HG--
rename : js/src/jsdtracef.cpp => js/src/jsprobes.cpp
rename : js/src/jsdtracef.h => js/src/jsprobes.h
This commit is contained in:
Steve Fink 2010-09-01 14:09:54 -07:00
parent b743b2d61e
commit 139d2a2a71
10 changed files with 287 additions and 344 deletions

View File

@ -155,6 +155,7 @@ CPPSRCS = \
jsparse.cpp \
jsproxy.cpp \
jsprf.cpp \
jsprobes.cpp \
jspropertycache.cpp \
jspropertytree.cpp \
jsreflect.cpp \
@ -172,11 +173,6 @@ CPPSRCS = \
prmjtime.cpp \
$(NULL)
ifdef HAVE_DTRACE
CPPSRCS += \
jsdtracef.cpp
endif
INSTALLED_HEADERS = \
js-config.h \
jsautocfg.h \
@ -216,6 +212,7 @@ INSTALLED_HEADERS = \
jsparse.h \
jsproxy.h \
jsprf.h \
jsprobes.h \
jspropertycache.h \
jspropertycacheinlines.h \
jspropertytree.h \
@ -430,7 +427,6 @@ endif # JS_HAS_CTYPES
ifdef HAVE_DTRACE
INSTALLED_HEADERS += \
jsdtracef.h \
$(CURDIR)/javascript-trace.h \
$(NULL)
endif
@ -834,7 +830,7 @@ $(CURDIR)/javascript-trace.h: $(srcdir)/javascript-trace.d
# We can't automatically generate dependencies on auto-generated headers;
# we have to list them explicitly.
$(addsuffix .$(OBJ_SUFFIX),jsdtracef jsinterp jsobj): $(CURDIR)/javascript-trace.h
$(addsuffix .$(OBJ_SUFFIX),jsprobes jsinterp jsobj): $(CURDIR)/javascript-trace.h
endif
ifdef ENABLE_TRACEJIT

View File

@ -32,15 +32,8 @@
* javascript provider probes
*
* function-entry (filename, classname, funcname)
* function-info (filename, classname, funcname, lineno,
* runfilename, runlineno)
* function-args (filename, classname, funcname, argc, argv, argv0,
* argv1, argv2, argv3, argv4)
* function-rval (filename, classname, funcname, lineno, rval, rval0)
* function-return (filename, classname, funcname)
* object-create-start (filename, classname)
* object-create (filename, classname, *object, rlineno)
* object-create-done (filename, classname)
* object-create (classname, *object)
* object-finalize (NULL, classname, *object)
* execute-start (filename, lineno)
* execute-done (filename, lineno)
@ -48,16 +41,10 @@
provider javascript {
probe function__entry(char *, char *, char *);
probe function__info(char *, char *, char *, int, char *, int);
probe function__args(char *, char *, char *, int, void *, void *, void *,
void *, void *, void *);
probe function__rval(char *, char *, char *, int, void *, void *);
probe function__return(char *, char *, char *);
probe object__create__start(char *, char *);
probe object__create__done(char *, char *);
/* XXX must use unsigned longs here instead of uintptr_t for OS X
(Apple radar: 5194316 & 5565198) */
probe object__create(char *, char *, unsigned long, int);
probe object__create(char *, unsigned long);
probe object__finalize(char *, char *, unsigned long);
probe execute__start(char *, int);
probe execute__done(char *, int);
@ -68,6 +55,5 @@ provider javascript {
#pragma D attributes Private/Private/Unknown provider mozilla module
#pragma D attributes Private/Private/Unknown provider mozilla function
#pragma D attributes Unstable/Unstable/Common provider mozilla name
#pragma D attributes Unstable/Unstable/Common provider mozilla args
*/

View File

@ -1,200 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sw=4 et tw=80:
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* Copyright (C) 2007 Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Brendan Eich <brendan@mozilla.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifdef INCLUDE_MOZILLA_DTRACE
#include "javascript-trace.h"
#endif
#include "jspubtd.h"
#include "jsprvtd.h"
#ifndef _JSDTRACEF_H
#define _JSDTRACEF_H
namespace js {
class DTrace {
static void enterJSFunImpl(JSContext *cx, JSStackFrame *fp, const JSFunction *fun);
static void handleFunctionInfo(JSContext *cx, JSStackFrame *fp, JSStackFrame *dfp,
JSFunction *fun);
static void handleFunctionArgs(JSContext *cx, JSStackFrame *fp, const JSFunction *fun,
jsuint argc, js::Value *argv);
static void handleFunctionRval(JSContext *cx, JSStackFrame *fp, JSFunction *fun,
const js::Value &rval);
static void handleFunctionReturn(JSContext *cx, JSStackFrame *fp, JSFunction *fun);
static void finalizeObjectImpl(JSObject *obj);
public:
/*
* If |lval| is provided to the enter/exit methods, it is tested to see if
* it is a function as a predicate to the dtrace event emission.
*/
static void enterJSFun(JSContext *cx, JSStackFrame *fp, JSFunction *fun,
JSStackFrame *dfp, jsuint argc, js::Value *argv,
js::Value *lval = NULL);
static void exitJSFun(JSContext *cx, JSStackFrame *fp, JSFunction *fun,
const js::Value &rval,
js::Value *lval = NULL);
static void finalizeObject(JSObject *obj);
class ExecutionScope {
const JSContext *cx;
const JSScript *script;
void startExecution();
void endExecution();
public:
explicit ExecutionScope(JSContext *cx, JSScript *script);
~ExecutionScope();
};
class ObjectCreationScope {
JSContext * const cx;
JSStackFrame * const fp;
js::Class * const clasp;
void handleCreationStart();
void handleCreationImpl(JSObject *obj);
void handleCreationEnd();
public:
ObjectCreationScope(JSContext *cx, JSStackFrame *fp, js::Class *clasp);
void handleCreation(JSObject *obj);
~ObjectCreationScope();
};
};
inline void
DTrace::enterJSFun(JSContext *cx, JSStackFrame *fp, JSFunction *fun, JSStackFrame *dfp,
jsuint argc, js::Value *argv, js::Value *lval)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (!lval || IsFunctionObject(*lval)) {
if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED())
enterJSFunImpl(cx, fp, fun);
if (JAVASCRIPT_FUNCTION_INFO_ENABLED())
handleFunctionInfo(cx, fp, dfp, fun);
if (JAVASCRIPT_FUNCTION_ARGS_ENABLED())
handleFunctionArgs(cx, fp, fun, argc, argv);
}
#endif
#ifdef MOZ_TRACE_JSCALLS
cx->doFunctionCallback(fun, fun ? FUN_SCRIPT(fun) : NULL, true);
#endif
}
inline void
DTrace::exitJSFun(JSContext *cx, JSStackFrame *fp, JSFunction *fun,
const js::Value &rval, js::Value *lval)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (!lval || IsFunctionObject(*lval)) {
if (JAVASCRIPT_FUNCTION_RVAL_ENABLED())
handleFunctionRval(cx, fp, fun, rval);
if (JAVASCRIPT_FUNCTION_RETURN_ENABLED())
handleFunctionReturn(cx, fp, fun);
}
#endif
#ifdef MOZ_TRACE_JSCALLS
cx->doFunctionCallback(fun, fun ? FUN_SCRIPT(fun) : NULL, false);
#endif
}
inline void
DTrace::finalizeObject(JSObject *obj)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_OBJECT_FINALIZE_ENABLED())
finalizeObjectImpl(obj);
#endif
}
/* Execution scope. */
inline
DTrace::ExecutionScope::ExecutionScope(JSContext *cx, JSScript *script)
: cx(cx), script(script)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_EXECUTE_START_ENABLED())
startExecution();
#endif
#ifdef MOZ_TRACE_JSCALLS
cx->doFunctionCallback(NULL, script, true);
#endif
}
inline
DTrace::ExecutionScope::~ExecutionScope()
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_EXECUTE_DONE_ENABLED())
endExecution();
#endif
#ifdef MOZ_TRACE_JSCALLS
cx->doFunctionCallback(NULL, script, false);
#endif
}
/* Object creation scope. */
inline
DTrace::ObjectCreationScope::ObjectCreationScope(JSContext *cx, JSStackFrame *fp, js::Class *clasp)
: cx(cx), fp(fp), clasp(clasp)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_OBJECT_CREATE_START_ENABLED())
handleCreationStart();
#endif
}
inline void
DTrace::ObjectCreationScope::handleCreation(JSObject *obj)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_OBJECT_CREATE_ENABLED())
handleCreationImpl(obj);
#endif
}
inline
DTrace::ObjectCreationScope::~ObjectCreationScope()
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_OBJECT_CREATE_DONE_ENABLED())
handleCreationEnd();
#endif
}
} /* namespace js */
#endif /* _JSDTRACE_H */

View File

@ -85,7 +85,7 @@
#include "jsxml.h"
#endif
#include "jsdtracef.h"
#include "jsprobes.h"
#include "jscntxtinlines.h"
#include "jsobjinlines.h"
#include "jshashtable.h"
@ -2351,7 +2351,7 @@ FinalizeObject(JSContext *cx, JSObject *obj, unsigned thingKind)
if (clasp->finalize)
clasp->finalize(cx, obj);
DTrace::finalizeObject(obj);
Probes::finalizeObject(obj);
obj->finish(cx);
}

View File

@ -79,8 +79,8 @@
#include "jsatominlines.h"
#include "jscntxtinlines.h"
#include "jsdtracef.h"
#include "jsobjinlines.h"
#include "jsprobes.h"
#include "jspropertycacheinlines.h"
#include "jsscopeinlines.h"
#include "jsscriptinlines.h"
@ -614,7 +614,7 @@ InvokeCommon(JSContext *cx, JSFunction *fun, JSScript *script, T native,
if (hook)
hookData = hook(cx, fp, JS_TRUE, 0, cx->debugHooks->callHookData);
DTrace::enterJSFun(cx, fp, fun, fp->down, fp->numActualArgs(), fp->argv);
Probes::enterJSFun(cx, fun);
/* Call the function, either a native method or an interpreted script. */
JSBool ok;
@ -639,7 +639,7 @@ InvokeCommon(JSContext *cx, JSFunction *fun, JSScript *script, T native,
ok = RunScript(cx, script, fun, fp->getScopeChain());
}
DTrace::exitJSFun(cx, fp, fun, fp->getReturnValue());
Probes::exitJSFun(cx, fun);
if (hookData) {
hook = cx->debugHooks->callHook;
@ -829,7 +829,6 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script,
LeaveTrace(cx);
DTrace::ExecutionScope executionScope(cx, script);
/*
* Get a pointer to new frame/slots. This memory is not "claimed", so the
* code before pushExecuteFrame must not reenter the interpreter.
@ -934,6 +933,8 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script,
fp->setThisValue(ObjectValue(*thisp));
}
Probes::startExecution(cx, script);
void *hookData = NULL;
if (JSInterpreterHook hook = cx->debugHooks->executeHook)
hookData = hook(cx, fp, JS_TRUE, 0, cx->debugHooks->executeHookData);
@ -948,6 +949,8 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script,
hook(cx, fp, JS_FALSE, &ok, hookData);
}
Probes::stopExecution(cx, script);
return !!ok;
}
@ -2757,7 +2760,7 @@ BEGIN_CASE(JSOP_STOP)
*/
fp->putActivationObjects(cx);
DTrace::exitJSFun(cx, fp, fp->getFunction(), fp->getReturnValue());
Probes::exitJSFun(cx, fp->maybeFunction());
/* Restore context version only if callee hasn't set version. */
if (JS_LIKELY(cx->version == currentVersion)) {
@ -4739,7 +4742,7 @@ BEGIN_CASE(JSOP_APPLY)
inlineCallCount++;
JS_RUNTIME_METER(rt, inlineCalls);
DTrace::enterJSFun(cx, fp, fun, fp->down, fp->numActualArgs(), fp->argv);
Probes::enterJSFun(cx, fun);
TRACE_0(EnterFrame);
@ -4765,12 +4768,12 @@ BEGIN_CASE(JSOP_APPLY)
}
if (fun->flags & JSFUN_FAST_NATIVE) {
DTrace::enterJSFun(cx, NULL, fun, fp, argc, vp + 2, vp);
Probes::enterJSFun(cx, fun);
JS_ASSERT(fun->u.n.extra == 0);
JS_ASSERT(vp[1].isObjectOrNull() || PrimitiveThisTest(fun, vp[1]));
JSBool ok = ((FastNative) fun->u.n.native)(cx, argc, vp);
DTrace::exitJSFun(cx, NULL, fun, *vp, vp);
Probes::exitJSFun(cx, fun);
regs.sp = vp + 1;
if (!ok)
goto error;

View File

@ -94,7 +94,7 @@
#include "jsxdrapi.h"
#endif
#include "jsdtracef.h"
#include "jsprobes.h"
#include "jsatominlines.h"
#include "jsobjinlines.h"
#include "jsscriptinlines.h"

View File

@ -524,6 +524,9 @@ struct JSObject {
return dslots ? dslots[-1].toPrivateUint32() : uint32(JS_INITIAL_NSLOTS);
}
size_t slotsAndStructSize(uint32 nslots) const;
size_t slotsAndStructSize() const { return slotsAndStructSize(numSlots()); }
private:
static size_t slotsToDynamicWords(size_t nslots) {
JS_ASSERT(nslots > JS_INITIAL_NSLOTS);

View File

@ -47,13 +47,12 @@
#include "jsiter.h"
#include "jslock.h"
#include "jsobj.h"
#include "jsprobes.h"
#include "jspropertytree.h"
#include "jsscope.h"
#include "jsstaticcheck.h"
#include "jsxml.h"
#include "jsdtracef.h"
/* Headers included for inline implementations used by this header. */
#include "jsbool.h"
#include "jscntxt.h"
@ -290,6 +289,24 @@ JSObject::setDenseArrayCapacity(uint32 capacity)
fslots[JSSLOT_DENSE_ARRAY_CAPACITY].setPrivateUint32(capacity);
}
inline size_t
JSObject::slotsAndStructSize(uint32 nslots) const
{
int ndslots;
if (isDenseArray())
ndslots = getDenseArrayCapacity() + 1;
else {
ndslots = nslots - JS_INITIAL_NSLOTS;
if (ndslots <= 0)
ndslots = 0;
else
ndslots++; /* number of total slots is stored at index -1 */
}
return sizeof(js::Value) * ndslots
+ (isFunction() && !getPrivate()) ? sizeof(JSFunction) : sizeof(JSObject);
}
inline const js::Value &
JSObject::getDenseArrayElement(uint32 i) const
{
@ -786,8 +803,6 @@ NewNativeClassInstance(JSContext *cx, Class *clasp, JSObject *proto, JSObject *p
JS_ASSERT(proto->isNative());
JS_ASSERT(parent);
DTrace::ObjectCreationScope objectCreationScope(cx, cx->maybefp(), clasp);
/*
* Allocate an object from the GC heap and initialize all its fields before
* doing any operation that can potentially trigger GC.
@ -812,7 +827,6 @@ NewNativeClassInstance(JSContext *cx, Class *clasp, JSObject *proto, JSObject *p
obj = NULL;
}
objectCreationScope.handleCreation(obj);
return obj;
}
@ -919,8 +933,6 @@ NewObject(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent)
}
DTrace::ObjectCreationScope objectCreationScope(cx, cx->maybefp(), clasp);
/*
* Allocate an object from the GC heap and initialize all its fields before
* doing any operation that can potentially trigger GC. Functions have a
@ -951,7 +963,7 @@ NewObject(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent)
}
out:
objectCreationScope.handleCreation(obj);
Probes::createObject(cx, obj);
return obj;
}
}

View File

@ -44,33 +44,31 @@
#include "jsscript.h"
#include "jsstr.h"
#include "jsdtracef.h"
#include "jsprobes.h"
#include <sys/types.h>
#define TYPEOF(cx,v) (JSVAL_IS_NULL(v) ? JSTYPE_NULL : JS_TypeOfValue(cx,v))
using namespace js;
static char dempty[] = "<null>";
const char Probes::nullName[] = "(null)";
static char *
jsdtrace_fun_classname(const JSFunction *fun)
const char *
Probes::FunctionClassname(const JSFunction *fun)
{
return (fun && !FUN_INTERPRETED(fun) && !(fun->flags & JSFUN_TRCINFO) && FUN_CLASP(fun))
? (char *)FUN_CLASP(fun)->name
: dempty;
: nullName;
}
static char *
jsdtrace_filename(JSStackFrame *fp)
const char *
Probes::ScriptFilename(JSScript *script)
{
return (fp && fp->hasScript() && fp->getScript()->filename)
? (char *)fp->getScript()->filename
: dempty;
return (script && script->filename) ? (char *)script->filename : nullName;
}
static int
jsdtrace_fun_linenumber(JSContext *cx, const JSFunction *fun)
int
Probes::FunctionLineNumber(JSContext *cx, const JSFunction *fun)
{
if (fun && FUN_INTERPRETED(fun))
return (int) JS_GetScriptBaseLineNumber(cx, FUN_SCRIPT(fun));
@ -78,15 +76,6 @@ jsdtrace_fun_linenumber(JSContext *cx, const JSFunction *fun)
return 0;
}
static int
jsdtrace_frame_linenumber(JSContext *cx, JSStackFrame *fp)
{
if (fp)
return (int) js_FramePCToLineNumber(cx, fp);
return 0;
}
/*
* This function is used to convert function arguments and return value (jsval)
* into the following based on each value's type tag:
@ -108,7 +97,7 @@ jsdtrace_frame_linenumber(JSContext *cx, JSStackFrame *fp)
* provide raw (unmasked) jsvals should type info be useful from D scripts.
*/
static void *
jsdtrace_jsvaltovoid(JSContext *cx, const js::Value &argval)
jsprobes_jsvaltovoid(JSContext *cx, const js::Value &argval)
{
if (argval.isNull())
return (void *)JS_TYPE_STR(JSTYPE_NULL);
@ -132,11 +121,11 @@ jsdtrace_jsvaltovoid(JSContext *cx, const js::Value &argval)
return argval.asGCThing();
}
static char *
jsdtrace_fun_name(JSContext *cx, const JSFunction *fun)
const char *
Probes::FunctionName(JSContext *cx, const JSFunction *fun)
{
if (!fun)
return dempty;
return nullName;
JSAtom *atom = fun->atom;
if (!atom) {
@ -145,13 +134,14 @@ jsdtrace_fun_name(JSContext *cx, const JSFunction *fun)
* or variable that held the anonymous function that we're calling, if anyone
* cares; an easy workaround is to just give your anonymous functions names.
*/
return dempty;
return nullName;
}
char *name = (char *)js_GetStringBytes(cx, ATOM_TO_STRING(atom));
return name ? name : dempty;
return name ? name : nullName;
}
#ifdef INCLUDE_MOZILLA_DTRACE
/*
* These functions call the DTrace macros for the JavaScript USDT probes.
* Originally this code was inlined in the JavaScript code; however since
@ -160,85 +150,17 @@ jsdtrace_fun_name(JSContext *cx, const JSFunction *fun)
* a number of usually unused lines of code would cause.
*/
void
DTrace::enterJSFunImpl(JSContext *cx, JSStackFrame *fp, const JSFunction *fun)
Probes::enterJSFunImpl(JSContext *cx, const JSFunction *fun)
{
JAVASCRIPT_FUNCTION_ENTRY(jsdtrace_filename(fp), jsdtrace_fun_classname(fun),
jsdtrace_fun_name(cx, fun));
JAVASCRIPT_FUNCTION_ENTRY(ScriptFilename(FUN_SCRIPT(fun)), FunctionClassname(fun),
FunctionName(cx, fun));
}
void
DTrace::handleFunctionInfo(JSContext *cx, JSStackFrame *fp, JSStackFrame *dfp, JSFunction *fun)
Probes::handleFunctionReturn(JSContext *cx, JSFunction *fun)
{
JAVASCRIPT_FUNCTION_INFO(jsdtrace_filename(fp), jsdtrace_fun_classname(fun),
jsdtrace_fun_name(cx, fun), jsdtrace_fun_linenumber(cx, fun),
jsdtrace_filename(dfp), jsdtrace_frame_linenumber(cx, dfp));
JAVASCRIPT_FUNCTION_RETURN(ScriptFilename(FUN_SCRIPT(fun)), FunctionClassname(fun),
FunctionName(cx, fun));
}
void
DTrace::handleFunctionArgs(JSContext *cx, JSStackFrame *fp, const JSFunction *fun, jsuint argc,
js::Value *argv)
{
JAVASCRIPT_FUNCTION_ARGS(jsdtrace_filename(fp), jsdtrace_fun_classname(fun),
jsdtrace_fun_name(cx, fun), argc, (void *)argv,
(argc > 0) ? jsdtrace_jsvaltovoid(cx, argv[0]) : 0,
(argc > 1) ? jsdtrace_jsvaltovoid(cx, argv[1]) : 0,
(argc > 2) ? jsdtrace_jsvaltovoid(cx, argv[2]) : 0,
(argc > 3) ? jsdtrace_jsvaltovoid(cx, argv[3]) : 0,
(argc > 4) ? jsdtrace_jsvaltovoid(cx, argv[4]) : 0);
}
void
DTrace::handleFunctionRval(JSContext *cx, JSStackFrame *fp, JSFunction *fun, const js::Value &rval)
{
JAVASCRIPT_FUNCTION_RVAL(jsdtrace_filename(fp), jsdtrace_fun_classname(fun),
jsdtrace_fun_name(cx, fun), jsdtrace_fun_linenumber(cx, fun),
NULL, jsdtrace_jsvaltovoid(cx, rval));
}
void
DTrace::handleFunctionReturn(JSContext *cx, JSStackFrame *fp, JSFunction *fun)
{
JAVASCRIPT_FUNCTION_RETURN(jsdtrace_filename(fp), jsdtrace_fun_classname(fun),
jsdtrace_fun_name(cx, fun));
}
void
DTrace::ObjectCreationScope::handleCreationStart()
{
JAVASCRIPT_OBJECT_CREATE_START(jsdtrace_filename(fp), (char *)clasp->name);
}
void
DTrace::ObjectCreationScope::handleCreationEnd()
{
JAVASCRIPT_OBJECT_CREATE_DONE(jsdtrace_filename(fp), (char *)clasp->name);
}
void
DTrace::ObjectCreationScope::handleCreationImpl(JSObject *obj)
{
JAVASCRIPT_OBJECT_CREATE(jsdtrace_filename(fp), (char *)clasp->name, (uintptr_t)obj,
jsdtrace_frame_linenumber(cx, fp));
}
void
DTrace::finalizeObjectImpl(JSObject *obj)
{
Class *clasp = obj->getClass();
/* the first arg is NULL - reserved for future use (filename?) */
JAVASCRIPT_OBJECT_FINALIZE(NULL, (char *)clasp->name, (uintptr_t)obj);
}
void
DTrace::ExecutionScope::startExecution()
{
JAVASCRIPT_EXECUTE_START(script->filename ? (char *)script->filename : dempty,
script->lineno);
}
void
DTrace::ExecutionScope::endExecution()
{
JAVASCRIPT_EXECUTE_DONE(script->filename ? (char *)script->filename : dempty, script->lineno);
}
#endif

221
js/src/jsprobes.h Normal file
View File

@ -0,0 +1,221 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sw=4 et tw=80:
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* Copyright (C) 2007 Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
* Brendan Eich <brendan@mozilla.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifdef INCLUDE_MOZILLA_DTRACE
#include "javascript-trace.h"
#endif
#include "jspubtd.h"
#include "jsprvtd.h"
#ifndef _JSPROBES_H
#define _JSPROBES_H
namespace js {
class Probes {
static const char nullName[];
static const char *FunctionClassname(const JSFunction *fun);
static const char *ScriptFilename(JSScript *script);
static int FunctionLineNumber(JSContext *cx, const JSFunction *fun);
static const char *FunctionName(JSContext *cx, const JSFunction *fun);
static void enterJSFunImpl(JSContext *cx, const JSFunction *fun);
static void handleFunctionReturn(JSContext *cx, JSFunction *fun);
static void finalizeObjectImpl(JSObject *obj);
public:
/*
* If |lval| is provided to the enter/exit methods, it is tested to see if
* it is a function as a predicate to the dtrace event emission.
*/
static void enterJSFun(JSContext *cx, JSFunction *fun, js::Value *lval = NULL);
static void exitJSFun(JSContext *cx, JSFunction *fun, js::Value *lval = NULL);
static void startExecution(JSContext *cx, JSScript *script);
static void stopExecution(JSContext *cx, JSScript *script);
static void resizeHeap(JSCompartment *compartment, size_t oldSize, size_t newSize);
/* |obj| must exist (its class and size are computed) */
static void createObject(JSContext *cx, JSObject *obj);
static void resizeObject(JSContext *cx, JSObject *obj, size_t oldSize, size_t newSize);
/* |obj| must still exist (its class is accessed) */
static void finalizeObject(JSObject *obj);
/*
* |string| does not need to contain any content yet; only its
* pointer value is used. |length| is the length of the string and
* does not imply anything about the amount of storage consumed to
* store the string. (It may be a short string, an external
* string, or a rope, and the encoding is not taken into
* consideration.)
*/
static void createString(JSContext *cx, JSString *string, size_t length);
/*
* |string| must still have a valid length.
*/
static void finalizeString(JSString *string);
static void compileScriptBegin(JSContext *cx, const char *filename, int lineno);
static void compileScriptEnd(JSContext *cx, JSScript *script, const char *filename, int lineno);
static void calloutBegin(JSContext *cx, JSFunction *fun);
static void calloutEnd(JSContext *cx, JSFunction *fun);
static void acquireMemory(JSContext *cx, void *address, size_t nbytes);
static void releaseMemory(JSContext *cx, void *address, size_t nbytes);
static void GCStart(JSCompartment *compartment);
static void GCEnd(JSCompartment *compartment);
static void GCStartMarkPhase(JSCompartment *compartment);
static void GCEndMarkPhase(JSCompartment *compartment);
static void GCStartSweepPhase(JSCompartment *compartment);
static void GCEndSweepPhase(JSCompartment *compartment);
static JSBool CustomMark(JSString *string);
static JSBool CustomMark(const char *string);
static JSBool CustomMark(int marker);
};
inline void
Probes::enterJSFun(JSContext *cx, JSFunction *fun, js::Value *lval)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (!lval || IsFunctionObject(*lval)) {
if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED())
enterJSFunImpl(cx, fun);
}
#endif
#ifdef MOZ_TRACE_JSCALLS
cx->doFunctionCallback(fun, fun ? FUN_SCRIPT(fun) : NULL, true);
#endif
}
inline void
Probes::exitJSFun(JSContext *cx, JSFunction *fun, js::Value *lval)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (!lval || IsFunctionObject(*lval)) {
if (JAVASCRIPT_FUNCTION_RETURN_ENABLED())
handleFunctionReturn(cx, fun);
}
#endif
#ifdef MOZ_TRACE_JSCALLS
cx->doFunctionCallback(fun, fun ? FUN_SCRIPT(fun) : NULL, false);
#endif
}
inline void
Probes::createObject(JSContext *cx, JSObject *obj)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_OBJECT_CREATE_ENABLED()) {
Class *clasp = obj->getClass();
JAVASCRIPT_OBJECT_CREATE((char *)clasp->name, (uintptr_t)obj);
}
#endif
}
inline void
Probes::finalizeObject(JSObject *obj)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_OBJECT_FINALIZE_ENABLED()) {
Class *clasp = obj->getClass();
/* the first arg is NULL - reserved for future use (filename?) */
JAVASCRIPT_OBJECT_FINALIZE(NULL, (char *)clasp->name, (uintptr_t)obj);
}
#endif
}
inline void
Probes::startExecution(JSContext *cx, JSScript *script)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_EXECUTE_START_ENABLED())
JAVASCRIPT_EXECUTE_START(script->filename ? (char *)script->filename : nullName,
script->lineno);
#endif
#ifdef MOZ_TRACE_JSCALLS
cx->doFunctionCallback(NULL, script, true);
#endif
}
inline void
Probes::stopExecution(JSContext *cx, JSScript *script)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_EXECUTE_DONE_ENABLED())
JAVASCRIPT_EXECUTE_DONE(script->filename ? (char *)script->filename : nullName,
script->lineno);
#endif
#ifdef MOZ_TRACE_JSCALLS
cx->doFunctionCallback(NULL, script, false);
#endif
}
/*
* New probes with no implementations, yet. Next patch will implement
* them. These are here just to make all intermediate patches compile
* and run.
*/
inline void Probes::resizeHeap(JSCompartment *compartment, size_t oldSize, size_t newSize) {}
inline void Probes::resizeObject(JSContext *cx, JSObject *obj, size_t oldSize, size_t newSize) {}
inline void Probes::createString(JSContext *cx, JSString *string, size_t length) {}
inline void Probes::finalizeString(JSString *string) {}
inline void Probes::compileScriptBegin(JSContext *cx, const char *filename, int lineno) {}
inline void Probes::compileScriptEnd(JSContext *cx, JSScript *script, const char *filename, int lineno) {}
inline void Probes::calloutBegin(JSContext *cx, JSFunction *fun) {}
inline void Probes::calloutEnd(JSContext *cx, JSFunction *fun) {}
inline void Probes::acquireMemory(JSContext *cx, void *address, size_t nbytes) {}
inline void Probes::releaseMemory(JSContext *cx, void *address, size_t nbytes) {}
inline void Probes::GCStart(JSCompartment *compartment) {}
inline void Probes::GCEnd(JSCompartment *compartment) {}
inline void Probes::GCStartMarkPhase(JSCompartment *compartment) {}
inline void Probes::GCEndMarkPhase(JSCompartment *compartment) {}
inline void Probes::GCStartSweepPhase(JSCompartment *compartment) {}
inline void Probes::GCEndSweepPhase(JSCompartment *compartment) {}
inline JSBool Probes::CustomMark(JSString *string) { return JS_TRUE; }
inline JSBool Probes::CustomMark(const char *string) { return JS_TRUE; }
inline JSBool Probes::CustomMark(int marker) { return JS_TRUE; }
} /* namespace js */
#endif /* _JSPROBES_H */