зеркало из https://github.com/mozilla/pjs.git
Landing fix for bug 388564. Adding Dtrace probes to the JS engine. Patch by padraig.obriain@sun.com and brendan@sun.com, and some intergration work done by jst@mozilla.org. r=brendan@mozilla.org, igor@mir2.org, sayrer@gmail.com, and r+a=ted.mielczarek@gmail.com.
This commit is contained in:
Родитель
781819308e
Коммит
68fa078d79
|
@ -1048,6 +1048,15 @@ ifdef NO_LD_ARCHIVE_FLAGS
|
|||
SUB_SHLOBJS = $(SUB_LOBJS)
|
||||
endif
|
||||
|
||||
ifdef HAVE_DTRACE
|
||||
ifdef DTRACE_PROBE_OBJ
|
||||
ifndef DTRACE_LIB_DEPENDENT
|
||||
$(DTRACE_PROBE_OBJ): $(OBJS)
|
||||
dtrace -G -C -32 -s $(MOZILLA_DTRACE_SRC) -o $(DTRACE_PROBE_OBJ) $(OBJS)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# On Darwin (Mac OS X), dwarf2 debugging uses debug info left in .o files,
|
||||
# so instead of deleting .o files after repacking them into a dylib, we make
|
||||
# symlinks back to the originals. The symlinks are a no-op for stabs debugging,
|
||||
|
@ -1078,17 +1087,17 @@ ifdef SHARED_LIBRARY_LIBS
|
|||
@for lib in $(SHARED_LIBRARY_LIBS); do $(AR_EXTRACT) $${lib}; $(CLEANUP2); done
|
||||
endif # SHARED_LIBRARY_LIBS
|
||||
endif # NO_LD_ARCHIVE_FLAGS
|
||||
ifdef NEED_DTRACE_PROBE_OBJ
|
||||
ifdef DTRACE_LIB_DEPENDENT
|
||||
@rm -f $(PROBE_LOBJS)
|
||||
@for lib in $(MOZILLA_PROBE_LIBS); do $(AR_EXTRACT) $${lib}; $(CLEANUP2); done
|
||||
dtrace -G -C -32 -s $(MOZILLA_DTRACE_SRC) -o $(NEED_DTRACE_PROBE_OBJ) $(PROBE_LOBJS)
|
||||
dtrace -G -C -32 -s $(MOZILLA_DTRACE_SRC) -o $(DTRACE_PROBE_OBJ) $(PROBE_LOBJS)
|
||||
@for lib in $(MOZILLA_PROBE_LIBS); do \
|
||||
ofiles=`$(AR_LIST) $${lib}`; \
|
||||
$(AR_DELETE) $${lib} $$ofiles; \
|
||||
done
|
||||
$(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(LOBJS) $(SUB_SHLOBJS) $(NEED_DTRACE_PROBE_OBJ) $(PROBE_LOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE)
|
||||
$(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(LOBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(PROBE_LOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE)
|
||||
@rm -f $(PROBE_LOBJS)
|
||||
@rm -f $(NEED_DTRACE_PROBE_OBJ)
|
||||
@rm -f $(DTRACE_PROBE_OBJ)
|
||||
@for lib in $(MOZILLA_PROBE_LIBS); do \
|
||||
if [ -L $${lib} ]; then rm -f `readlink $${lib}`; fi; \
|
||||
done
|
||||
|
@ -1096,7 +1105,7 @@ ifdef NEED_DTRACE_PROBE_OBJ
|
|||
|
||||
else
|
||||
$(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(DTRACE_PROBE_OBJ) $(LOBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE)
|
||||
endif # NEED_DTRACE_PROBE_OBJ
|
||||
endif # DTRACE_LIB_DEPENDENT
|
||||
|
||||
ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
|
||||
ifdef MSMANIFEST_TOOL
|
||||
|
|
|
@ -103,6 +103,11 @@ CSRCS = \
|
|||
prmjtime.c \
|
||||
$(NULL)
|
||||
|
||||
ifdef HAVE_DTRACE
|
||||
CSRCS += \
|
||||
jsdtracef.c
|
||||
endif
|
||||
|
||||
EXPORTS = \
|
||||
jsautocfg.h \
|
||||
jsautokw.h \
|
||||
|
@ -152,6 +157,13 @@ EXPORTS = \
|
|||
jsxml.h \
|
||||
$(NULL)
|
||||
|
||||
ifdef HAVE_DTRACE
|
||||
EXPORTS += \
|
||||
jsdtracef.h \
|
||||
javascript-trace.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifeq (,$(filter-out WINNT WINCE,$(OS_ARCH)))
|
||||
EXPORTS += jscpucfg.h
|
||||
endif
|
||||
|
@ -202,6 +214,11 @@ JSJAVA_CFLAGS = \
|
|||
HOST_SIMPLE_PROGRAMS += host_jskwgen$(HOST_BIN_SUFFIX)
|
||||
GARBAGE += jsautokw.h host_jskwgen$(HOST_BIN_SUFFIX)
|
||||
|
||||
ifdef HAVE_DTRACE
|
||||
DTRACE_PROBE_OBJ = $(LIBRARY_NAME)-dtrace.$(OBJ_SUFFIX)
|
||||
MOZILLA_DTRACE_SRC = $(srcdir)/javascript-trace.d
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
DEFINES += -DEXPORT_JS_API
|
||||
|
@ -392,3 +409,11 @@ host_jskwgen.$(OBJ_SUFFIX): jsconfig.h jskeyword.tbl
|
|||
|
||||
jsautokw.h: host_jskwgen$(HOST_BIN_SUFFIX)
|
||||
./host_jskwgen$(HOST_BIN_SUFFIX) $@
|
||||
|
||||
ifdef HAVE_DTRACE
|
||||
javascript-trace.h: $(srcdir)/javascript-trace.d
|
||||
dtrace -h -s $(srcdir)/javascript-trace.d -o javascript-trace.h.in
|
||||
sed 's/if _DTRACE_VERSION/ifdef INCLUDE_MOZILLA_DTRACE/' \
|
||||
javascript-trace.h.in > javascript-trace.h
|
||||
endif
|
||||
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** 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.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either 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 ***** */
|
||||
|
||||
/*
|
||||
* 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-finalize (NULL, classname, *object)
|
||||
* execute-start (filename, lineno)
|
||||
* execute-done (filename, lineno)
|
||||
*/
|
||||
|
||||
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 *);
|
||||
probe object__create(char *, char *, uintptr_t, int);
|
||||
probe object__finalize(char *, char *, uintptr_t);
|
||||
probe execute__start(char *, int);
|
||||
probe execute__done(char *, int);
|
||||
};
|
||||
|
||||
/*
|
||||
#pragma D attributes Unstable/Unstable/Common provider mozilla provider
|
||||
#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
|
||||
*/
|
||||
|
|
@ -0,0 +1,311 @@
|
|||
/* -*- 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 ***** */
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsatom.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "jsfun.h"
|
||||
#include "jsinterp.h"
|
||||
#include "jsobj.h"
|
||||
#include "jsscript.h"
|
||||
#include "jsstr.h"
|
||||
|
||||
#include "jsdtracef.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
#define TYPEOF(cx,v) (JSVAL_IS_NULL(v) ? JSTYPE_NULL : JS_TypeOfValue(cx,v))
|
||||
|
||||
static char dempty[] = "<null>";
|
||||
|
||||
char *
|
||||
jsdtrace_filename(JSStackFrame *fp)
|
||||
{
|
||||
while (fp && fp->script == NULL)
|
||||
fp = fp->down;
|
||||
return (fp && fp->script && fp->script->filename)
|
||||
? (char *)fp->script->filename
|
||||
: dempty;
|
||||
}
|
||||
|
||||
int
|
||||
jsdtrace_linenumber(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
while (fp && fp->script == NULL)
|
||||
fp = fp->down;
|
||||
return (fp && fp->script && fp->pc)
|
||||
? js_PCToLineNumber(cx, fp->script, fp->pc)
|
||||
: -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is used to convert function arguments and return value (jsval)
|
||||
* into the following based on each value's type tag:
|
||||
*
|
||||
* jsval returned
|
||||
* -------------------
|
||||
* STRING -> char *
|
||||
* INT -> int
|
||||
* DOUBLE -> double *
|
||||
* BOOLEAN -> int
|
||||
* OBJECT -> void *
|
||||
*
|
||||
* All are presented as void * for DTrace consumers to use, after shifting or
|
||||
* masking out the JavaScript type bits. This allows D scripts to use ints and
|
||||
* booleans directly and copyinstr() for string arguments, when types are known
|
||||
* beforehand.
|
||||
*
|
||||
* This is used by the function-args and function-rval probes, which also
|
||||
* provide raw (unmasked) jsvals should type info be useful from D scripts.
|
||||
*/
|
||||
void *
|
||||
jsdtrace_jsvaltovoid(JSContext *cx, jsval argval)
|
||||
{
|
||||
JSType type = TYPEOF(cx, argval);
|
||||
|
||||
switch (type) {
|
||||
case JSTYPE_NULL:
|
||||
case JSTYPE_VOID:
|
||||
return JS_TYPE_STR(type);
|
||||
|
||||
case JSTYPE_BOOLEAN:
|
||||
return (void *)JSVAL_TO_BOOLEAN(argval);
|
||||
|
||||
case JSTYPE_STRING:
|
||||
return (void *)js_GetStringBytes(cx, JSVAL_TO_STRING(argval));
|
||||
|
||||
case JSTYPE_NUMBER:
|
||||
if (JSVAL_IS_INT(argval))
|
||||
return (void *)JSVAL_TO_INT(argval);
|
||||
return JSVAL_TO_DOUBLE(argval);
|
||||
|
||||
default:
|
||||
return JSVAL_TO_GCTHING(argval);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
char *
|
||||
jsdtrace_function_name(JSContext *cx, JSStackFrame *fp, JSFunction *fun)
|
||||
{
|
||||
JSAtom *atom;
|
||||
JSScript *script;
|
||||
jsbytecode *pc;
|
||||
char *name;
|
||||
|
||||
atom = fun->atom;
|
||||
if (!atom) {
|
||||
if (fp->fun != fun || !fp->down)
|
||||
return dempty;
|
||||
|
||||
script = fp->down->script;
|
||||
pc = fp->down->pc;
|
||||
if (!script || !pc)
|
||||
return dempty;
|
||||
|
||||
/*
|
||||
* An anonymous function called from an active script or interpreted
|
||||
* function: try to fetch the variable or property name by which the
|
||||
* anonymous function was invoked. First handle call ops by recovering
|
||||
* the generating pc for the callee expression at argv[-2].
|
||||
*/
|
||||
switch ((JSOp) *pc) {
|
||||
case JSOP_CALL:
|
||||
case JSOP_EVAL:
|
||||
JS_ASSERT(fp->argv == fp->down->sp - (int)GET_ARGC(pc));
|
||||
|
||||
pc = (jsbytecode *) fp->argv[-2 - (int)script->depth];
|
||||
|
||||
/*
|
||||
* Be paranoid about bugs to-do with generating pc storage when
|
||||
* attempting to descend into the operand stack basement.
|
||||
*/
|
||||
if ((uintptr_t)(pc - script->code) >= script->length)
|
||||
return dempty;
|
||||
break;
|
||||
}
|
||||
|
||||
switch ((JSOp) *pc) {
|
||||
case JSOP_CALLNAME:
|
||||
case JSOP_CALLPROP:
|
||||
case JSOP_NAME:
|
||||
case JSOP_SETNAME:
|
||||
case JSOP_GETPROP:
|
||||
case JSOP_SETPROP:
|
||||
GET_ATOM_FROM_BYTECODE(script, pc, 0, atom);
|
||||
break;
|
||||
|
||||
case JSOP_CALLELEM:
|
||||
case JSOP_GETELEM:
|
||||
case JSOP_SETELEM:
|
||||
case JSOP_CALLGVAR:
|
||||
case JSOP_GETGVAR:
|
||||
case JSOP_SETGVAR:
|
||||
case JSOP_CALLVAR:
|
||||
case JSOP_CALLARG:
|
||||
case JSOP_CALLLOCAL:
|
||||
/* FIXME: try to recover a name from these ops. */
|
||||
/* FALL THROUGH */
|
||||
|
||||
default:
|
||||
return dempty;
|
||||
}
|
||||
}
|
||||
|
||||
name = (char *)js_GetStringBytes(cx, ATOM_TO_STRING(atom));
|
||||
return name ? name : dempty;
|
||||
}
|
||||
|
||||
/*
|
||||
* These functions call the DTrace macros for the JavaScript USDT probes.
|
||||
* Originally this code was inlined in the JavaScript code; however since
|
||||
* a number of operations are called, these have been placed into functions
|
||||
* to reduce any negative compiler optimization effect that the addition of
|
||||
* a number of usually unused lines of code would cause.
|
||||
*/
|
||||
void
|
||||
jsdtrace_function_entry(JSContext *cx, JSStackFrame *fp, JSFunction *fun)
|
||||
{
|
||||
JAVASCRIPT_FUNCTION_ENTRY(
|
||||
jsdtrace_filename(fp),
|
||||
fun->clasp ? (char *)fun->clasp->name : dempty,
|
||||
jsdtrace_function_name(cx, fp, fun)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
jsdtrace_function_info(JSContext *cx, JSStackFrame *fp, JSStackFrame *dfp,
|
||||
JSFunction *fun)
|
||||
{
|
||||
JAVASCRIPT_FUNCTION_INFO(
|
||||
jsdtrace_filename(fp),
|
||||
fun->clasp ? (char *)fun->clasp->name : dempty,
|
||||
jsdtrace_function_name(cx, fp, fun),
|
||||
fp->script->lineno,
|
||||
jsdtrace_filename(dfp),
|
||||
jsdtrace_linenumber(cx, dfp)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
jsdtrace_function_args(JSContext *cx, JSStackFrame *fp, JSFunction *fun)
|
||||
{
|
||||
JAVASCRIPT_FUNCTION_ARGS(
|
||||
jsdtrace_filename(fp),
|
||||
fun->clasp ? (char *)fun->clasp->name : dempty,
|
||||
jsdtrace_function_name(cx, fp, fun),
|
||||
fp->argc, (void *)fp->argv,
|
||||
(fp->argc > 0) ? jsdtrace_jsvaltovoid(cx, fp->argv[0]) : 0,
|
||||
(fp->argc > 1) ? jsdtrace_jsvaltovoid(cx, fp->argv[1]) : 0,
|
||||
(fp->argc > 2) ? jsdtrace_jsvaltovoid(cx, fp->argv[2]) : 0,
|
||||
(fp->argc > 3) ? jsdtrace_jsvaltovoid(cx, fp->argv[3]) : 0,
|
||||
(fp->argc > 4) ? jsdtrace_jsvaltovoid(cx, fp->argv[4]) : 0
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
jsdtrace_function_rval(JSContext *cx, JSStackFrame *fp, JSFunction *fun)
|
||||
{
|
||||
JAVASCRIPT_FUNCTION_RVAL(
|
||||
jsdtrace_filename(fp),
|
||||
fun->clasp ? (char *)fun->clasp->name : dempty,
|
||||
jsdtrace_function_name(cx, fp, fun),
|
||||
jsdtrace_linenumber(cx, fp), (void *)fp->rval,
|
||||
jsdtrace_jsvaltovoid(cx, fp->rval)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
jsdtrace_function_return(JSContext *cx, JSStackFrame *fp, JSFunction *fun)
|
||||
{
|
||||
JAVASCRIPT_FUNCTION_RETURN(
|
||||
jsdtrace_filename(fp),
|
||||
fun->clasp ? (char *)fun->clasp->name : dempty,
|
||||
jsdtrace_function_name(cx, fp, fun)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
jsdtrace_object_create_start(JSStackFrame *fp, JSClass *clasp)
|
||||
{
|
||||
JAVASCRIPT_OBJECT_CREATE_START(jsdtrace_filename(fp), (char *)clasp->name);
|
||||
}
|
||||
|
||||
void
|
||||
jsdtrace_object_create_done(JSStackFrame *fp, JSClass *clasp)
|
||||
{
|
||||
JAVASCRIPT_OBJECT_CREATE_DONE(jsdtrace_filename(fp), (char *)clasp->name);
|
||||
}
|
||||
|
||||
void
|
||||
jsdtrace_object_create(JSContext *cx, JSClass *clasp, JSObject *obj)
|
||||
{
|
||||
JAVASCRIPT_OBJECT_CREATE(
|
||||
jsdtrace_filename(cx->fp),
|
||||
(char *)clasp->name,
|
||||
(uintptr_t)obj,
|
||||
jsdtrace_linenumber(cx, cx->fp)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
jsdtrace_object_finalize(JSObject *obj)
|
||||
{
|
||||
JSClass *clasp;
|
||||
|
||||
clasp = LOCKED_OBJ_GET_CLASS(obj);
|
||||
|
||||
/* the first arg is NULL - reserved for future use (filename?) */
|
||||
JAVASCRIPT_OBJECT_FINALIZE(NULL, (char *)clasp->name, (uintptr_t)obj);
|
||||
}
|
||||
|
||||
void
|
||||
jsdtrace_execute_start(JSScript *script)
|
||||
{
|
||||
JAVASCRIPT_EXECUTE_START(
|
||||
script->filename ? (char *)script->filename : dempty,
|
||||
script->lineno
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
jsdtrace_execute_done(JSScript *script)
|
||||
{
|
||||
JAVASCRIPT_EXECUTE_DONE(
|
||||
script->filename ? (char *)script->filename : dempty,
|
||||
script->lineno
|
||||
);
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/* -*- 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 ***** */
|
||||
|
||||
#include "javascript-trace.h"
|
||||
#include "jspubtd.h"
|
||||
#include "jsprvtd.h"
|
||||
|
||||
#ifndef _JSDTRACEF_H
|
||||
#define _JSDTRACEF_H
|
||||
|
||||
extern void
|
||||
jsdtrace_function_entry(JSContext *cx, JSStackFrame *fp, JSFunction *fun);
|
||||
|
||||
extern void
|
||||
jsdtrace_function_info(JSContext *cx, JSStackFrame *fp, JSStackFrame *dfp,
|
||||
JSFunction *fun);
|
||||
|
||||
extern void
|
||||
jsdtrace_function_args(JSContext *cx, JSStackFrame *fp, JSFunction *fun);
|
||||
|
||||
extern void
|
||||
jsdtrace_function_rval(JSContext *cx, JSStackFrame *fp, JSFunction *fun);
|
||||
|
||||
extern void
|
||||
jsdtrace_function_return(JSContext *cx, JSStackFrame *fp, JSFunction *fun);
|
||||
|
||||
extern void
|
||||
jsdtrace_object_create_start(JSStackFrame *fp, JSClass *clasp);
|
||||
|
||||
extern void
|
||||
jsdtrace_object_create_done(JSStackFrame *fp, JSClass *clasp);
|
||||
|
||||
extern void
|
||||
jsdtrace_object_create(JSContext *cx, JSClass *clasp, JSObject *obj);
|
||||
|
||||
extern void
|
||||
jsdtrace_object_finalize(JSObject *obj);
|
||||
|
||||
extern void
|
||||
jsdtrace_execute_start(JSScript *script);
|
||||
|
||||
extern void
|
||||
jsdtrace_execute_done(JSScript *script);
|
||||
|
||||
#endif /* _JSDTRACE_H */
|
|
@ -69,6 +69,10 @@
|
|||
#include "jsscript.h"
|
||||
#include "jsstr.h"
|
||||
|
||||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
#include "jsdtracef.h"
|
||||
#endif
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
#include "jsxml.h"
|
||||
#endif
|
||||
|
@ -1533,6 +1537,11 @@ js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
|||
JSObject *obj, *tmp;
|
||||
JSBool ok;
|
||||
|
||||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
if (JAVASCRIPT_EXECUTE_START_ENABLED())
|
||||
jsdtrace_execute_start(script);
|
||||
#endif
|
||||
|
||||
hook = cx->debugHooks->executeHook;
|
||||
hookData = mark = NULL;
|
||||
oldfp = cx->fp;
|
||||
|
@ -1569,8 +1578,10 @@ js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
|||
frame.nvars += JS_SCRIPT_REGEXPS(script)->length;
|
||||
if (frame.nvars != 0) {
|
||||
frame.vars = js_AllocRawStack(cx, frame.nvars, &mark);
|
||||
if (!frame.vars)
|
||||
return JS_FALSE;
|
||||
if (!frame.vars) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
memset(frame.vars, 0, frame.nvars * sizeof(jsval));
|
||||
} else {
|
||||
frame.vars = NULL;
|
||||
|
@ -1637,6 +1648,11 @@ js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
|||
oldfp->dormantNext = NULL;
|
||||
}
|
||||
|
||||
out:
|
||||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
if (JAVASCRIPT_EXECUTE_DONE_ENABLED())
|
||||
jsdtrace_execute_done(script);
|
||||
#endif
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@ -2614,6 +2630,14 @@ interrupt:
|
|||
ok &= js_PutArgsObject(cx, fp);
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
/* DTrace function return, inlines */
|
||||
if (JAVASCRIPT_FUNCTION_RVAL_ENABLED())
|
||||
jsdtrace_function_rval(cx, fp, fp->fun);
|
||||
if (JAVASCRIPT_FUNCTION_RETURN_ENABLED())
|
||||
jsdtrace_function_return(cx, fp, fp->fun);
|
||||
#endif
|
||||
|
||||
/* Restore context version only if callee hasn't set version. */
|
||||
if (JS_LIKELY(cx->version == currentVersion)) {
|
||||
currentVersion = ifp->callerVersion;
|
||||
|
@ -4038,6 +4062,16 @@ interrupt:
|
|||
inlineCallCount++;
|
||||
JS_RUNTIME_METER(rt, inlineCalls);
|
||||
|
||||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
/* DTrace function entry, inlines */
|
||||
if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED())
|
||||
jsdtrace_function_entry(cx, fp, fun);
|
||||
if (JAVASCRIPT_FUNCTION_INFO_ENABLED())
|
||||
jsdtrace_function_info(cx, fp, fp->down, fun);
|
||||
if (JAVASCRIPT_FUNCTION_ARGS_ENABLED())
|
||||
jsdtrace_function_args(cx, fp, fun);
|
||||
#endif
|
||||
|
||||
/* Load first op and dispatch it (safe since JSOP_STOP). */
|
||||
op = (JSOp) *pc;
|
||||
DO_OP();
|
||||
|
@ -4053,6 +4087,18 @@ interrupt:
|
|||
goto out;
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
/* DTrace function entry, non-inlines */
|
||||
if (VALUE_IS_FUNCTION(cx, lval)) {
|
||||
if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED())
|
||||
jsdtrace_function_entry(cx, fp, fun);
|
||||
if (JAVASCRIPT_FUNCTION_INFO_ENABLED())
|
||||
jsdtrace_function_info(cx, fp, fp, fun);
|
||||
if (JAVASCRIPT_FUNCTION_ARGS_ENABLED())
|
||||
jsdtrace_function_args(cx, fp, fun);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fun->flags & JSFUN_FAST_NATIVE) {
|
||||
JS_ASSERT(fun->u.n.extra == 0);
|
||||
if (argc < fun->u.n.minargs) {
|
||||
|
@ -4080,6 +4126,14 @@ interrupt:
|
|||
PRIMITIVE_THIS_TEST(fun, vp[1]));
|
||||
|
||||
ok = ((JSFastNative) fun->u.n.native)(cx, argc, vp);
|
||||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
if (VALUE_IS_FUNCTION(cx, lval)) {
|
||||
if (JAVASCRIPT_FUNCTION_RVAL_ENABLED())
|
||||
jsdtrace_function_rval(cx, fp, fun);
|
||||
if (JAVASCRIPT_FUNCTION_RETURN_ENABLED())
|
||||
jsdtrace_function_return(cx, fp, fun);
|
||||
}
|
||||
#endif
|
||||
if (!ok)
|
||||
goto out;
|
||||
sp = vp + 1;
|
||||
|
@ -4090,6 +4144,15 @@ interrupt:
|
|||
|
||||
do_invoke:
|
||||
ok = js_Invoke(cx, argc, vp, 0);
|
||||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
/* DTrace function return, non-inlines */
|
||||
if (VALUE_IS_FUNCTION(cx, lval)) {
|
||||
if (JAVASCRIPT_FUNCTION_RVAL_ENABLED())
|
||||
jsdtrace_function_rval(cx, fp, fun);
|
||||
if (JAVASCRIPT_FUNCTION_RETURN_ENABLED())
|
||||
jsdtrace_function_return(cx, fp, fun);
|
||||
}
|
||||
#endif
|
||||
sp = vp + 1;
|
||||
vp[-depth] = (jsval)pc;
|
||||
LOAD_INTERRUPT_HANDLER(cx);
|
||||
|
|
|
@ -83,6 +83,10 @@
|
|||
#include "jsxdrapi.h"
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
#include "jsdtracef.h"
|
||||
#endif
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
#define NATIVE_DROP_PROPERTY js_DropProperty
|
||||
|
||||
|
@ -2511,16 +2515,21 @@ js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent)
|
|||
uint32 nslots, i;
|
||||
JSTempValueRooter tvr;
|
||||
|
||||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
if (JAVASCRIPT_OBJECT_CREATE_START_ENABLED())
|
||||
jsdtrace_object_create_start(cx->fp, clasp);
|
||||
#endif
|
||||
|
||||
/* Bootstrap the ur-object, and make it the default prototype object. */
|
||||
if (!proto) {
|
||||
if (!js_GetClassId(cx, clasp, &id))
|
||||
return NULL;
|
||||
goto earlybad;
|
||||
if (!js_GetClassPrototype(cx, parent, id, &proto))
|
||||
return NULL;
|
||||
goto earlybad;
|
||||
if (!proto &&
|
||||
!js_GetClassPrototype(cx, parent, INT_TO_JSID(JSProto_Object),
|
||||
&proto)) {
|
||||
return NULL;
|
||||
goto earlybad;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2536,7 +2545,7 @@ js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent)
|
|||
*/
|
||||
obj = (JSObject *) js_NewGCThing(cx, GCX_OBJECT, sizeof(JSObject));
|
||||
if (!obj)
|
||||
return NULL;
|
||||
goto earlybad;
|
||||
|
||||
/*
|
||||
* Initialize all JSObject fields before doing any operation that can
|
||||
|
@ -2621,11 +2630,26 @@ js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent)
|
|||
out:
|
||||
JS_POP_TEMP_ROOT(cx, &tvr);
|
||||
cx->weakRoots.newborn[GCX_OBJECT] = obj;
|
||||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
if (JAVASCRIPT_OBJECT_CREATE_ENABLED())
|
||||
jsdtrace_object_create(cx, clasp, obj);
|
||||
if (JAVASCRIPT_OBJECT_CREATE_DONE_ENABLED())
|
||||
jsdtrace_object_create_done(cx->fp, clasp);
|
||||
#endif
|
||||
return obj;
|
||||
|
||||
bad:
|
||||
obj = NULL;
|
||||
goto out;
|
||||
|
||||
earlybad:
|
||||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
if (JAVASCRIPT_OBJECT_CREATE_ENABLED())
|
||||
jsdtrace_object_create(cx, clasp, NULL);
|
||||
if (JAVASCRIPT_OBJECT_CREATE_DONE_ENABLED())
|
||||
jsdtrace_object_create_done(cx->fp, clasp);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
@ -2874,6 +2898,11 @@ js_FinalizeObject(JSContext *cx, JSObject *obj)
|
|||
/* Finalize obj first, in case it needs map and slots. */
|
||||
GC_AWARE_GET_CLASS(cx, obj)->finalize(cx, obj);
|
||||
|
||||
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||
if (JAVASCRIPT_OBJECT_FINALIZE_ENABLED())
|
||||
jsdtrace_object_finalize(obj);
|
||||
#endif
|
||||
|
||||
/* Drop map and free slots. */
|
||||
js_DropObjectMap(cx, map, obj);
|
||||
FreeSlots(cx, obj);
|
||||
|
|
Загрузка…
Ссылка в новой задаче