mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
b743b2d61e
commit
139d2a2a71
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
||||
|
@ -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 */
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -94,7 +94,7 @@
|
||||
#include "jsxdrapi.h"
|
||||
#endif
|
||||
|
||||
#include "jsdtracef.h"
|
||||
#include "jsprobes.h"
|
||||
#include "jsatominlines.h"
|
||||
#include "jsobjinlines.h"
|
||||
#include "jsscriptinlines.h"
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
221
js/src/jsprobes.h
Normal 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 */
|
Loading…
Reference in New Issue
Block a user