mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
build: use zero overhead systemtap probes
Profiling suggested that on Linux sometimes over 10% of CPU time was being spent inside the systemtap probe entry points in the binding layer, even when the process was not actively being traced with the `stap` tool. That's why this commit makes it possible to use the *_ENABLED() macros and bail out early when we're not being traced, reducing the overhead of unused probes to (almost) zero. Said macros were already being generated by `dtrace -h` but were not usable because they rely on external definitions. To remedy that, we now generate the accompanying object files with `dtrace -G`. This commit includes a change to libuv that has been landed upstream in commit joyent/libuv@3c172ea.
This commit is contained in:
21
configure
vendored
21
configure
vendored
@@ -459,24 +459,21 @@ def configure_node(o):
|
||||
if not is_clang and cc_version < (4,0,0):
|
||||
o['variables']['visibility'] = ''
|
||||
|
||||
# By default, enable DTrace on SunOS systems. Don't allow it on other
|
||||
# systems, since it won't work. (The MacOS build process is different than
|
||||
# SunOS, and we haven't implemented it.)
|
||||
if flavor in ('solaris', 'mac'):
|
||||
o['variables']['node_use_dtrace'] = b(not options.without_dtrace)
|
||||
o['variables']['uv_use_dtrace'] = o['variables']['node_use_dtrace']
|
||||
if flavor in ('solaris', 'mac', 'linux'):
|
||||
use_dtrace = not options.without_dtrace
|
||||
# Don't enable by default on linux, it needs the sdt-devel package.
|
||||
if flavor == 'linux':
|
||||
if options.systemtap_includes:
|
||||
o['include_dirs'] += [options.systemtap_includes]
|
||||
use_dtrace = options.with_dtrace
|
||||
o['variables']['node_use_dtrace'] = b(use_dtrace)
|
||||
o['variables']['uv_use_dtrace'] = b(use_dtrace)
|
||||
o['variables']['uv_parent_path'] = '/deps/uv/'
|
||||
elif flavor == 'linux':
|
||||
o['variables']['node_use_dtrace'] = 'false'
|
||||
o['variables']['node_use_systemtap'] = b(options.with_dtrace)
|
||||
if options.systemtap_includes:
|
||||
o['include_dirs'] += [options.systemtap_includes]
|
||||
elif options.with_dtrace:
|
||||
raise Exception(
|
||||
'DTrace is currently only supported on SunOS, MacOS or Linux systems.')
|
||||
else:
|
||||
o['variables']['node_use_dtrace'] = 'false'
|
||||
o['variables']['node_use_systemtap'] = 'false'
|
||||
|
||||
# if we're on illumos based systems wrap the helper library into the
|
||||
# executable
|
||||
|
||||
25
deps/uv/uv.gyp
vendored
25
deps/uv/uv.gyp
vendored
@@ -268,13 +268,17 @@
|
||||
['library=="shared_library"', {
|
||||
'defines': [ 'BUILDING_UV_SHARED=1' ]
|
||||
}],
|
||||
# FIXME(bnoordhuis or tjfontaine) Unify this, it's extremely ugly.
|
||||
['uv_use_dtrace=="true"', {
|
||||
'defines': [ 'HAVE_DTRACE=1' ],
|
||||
'dependencies': [ 'uv_dtrace_header' ],
|
||||
'include_dirs': [ '<(SHARED_INTERMEDIATE_DIR)' ],
|
||||
'conditions': [
|
||||
['OS != "mac"', {
|
||||
'sources': ['src/unix/dtrace.c' ],
|
||||
[ 'OS not in "mac linux"', {
|
||||
'sources': [ 'src/unix/dtrace.c' ],
|
||||
}],
|
||||
[ 'OS=="linux"', {
|
||||
'sources': [ '<(SHARED_INTERMEDIATE_DIR)/dtrace.o' ]
|
||||
}],
|
||||
],
|
||||
}],
|
||||
@@ -480,11 +484,12 @@
|
||||
],
|
||||
},
|
||||
|
||||
# FIXME(bnoordhuis or tjfontaine) Unify this, it's extremely ugly.
|
||||
{
|
||||
'target_name': 'uv_dtrace_provider',
|
||||
'type': 'none',
|
||||
'conditions': [
|
||||
[ 'uv_use_dtrace=="true" and OS!="mac"', {
|
||||
[ 'uv_use_dtrace=="true" and OS not in "mac linux"', {
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'uv_dtrace_o',
|
||||
@@ -499,7 +504,19 @@
|
||||
'-o', '<@(_outputs)' ]
|
||||
}
|
||||
]
|
||||
} ]
|
||||
}],
|
||||
[ 'uv_use_dtrace=="true" and OS=="linux"', {
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'uv_dtrace_o',
|
||||
'inputs': [ 'src/unix/uv-dtrace.d' ],
|
||||
'outputs': [ '<(SHARED_INTERMEDIATE_DIR)/dtrace.o' ],
|
||||
'action': [
|
||||
'dtrace', '-C', '-G', '-s', '<@(_inputs)', '-o', '<@(_outputs)'
|
||||
],
|
||||
}
|
||||
]
|
||||
}],
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
68
node.gyp
68
node.gyp
@@ -14,7 +14,6 @@
|
||||
'node_shared_cares%': 'false',
|
||||
'node_shared_libuv%': 'false',
|
||||
'node_use_openssl%': 'true',
|
||||
'node_use_systemtap%': 'false',
|
||||
'node_shared_openssl%': 'false',
|
||||
'node_use_mdb%': 'false',
|
||||
'library_files': [
|
||||
@@ -186,12 +185,12 @@
|
||||
'dependencies': [ 'node_dtrace_header' ],
|
||||
'include_dirs': [ '<(SHARED_INTERMEDIATE_DIR)' ],
|
||||
#
|
||||
# DTrace is supported on solaris, mac, and bsd. There are three
|
||||
# object files associated with DTrace support, but they're not all
|
||||
# used all the time:
|
||||
# DTrace is supported on linux, solaris, mac, and bsd. There are
|
||||
# three object files associated with DTrace support, but they're
|
||||
# not all used all the time:
|
||||
#
|
||||
# node_dtrace.o all configurations
|
||||
# node_dtrace_ustack.o not supported on OS X
|
||||
# node_dtrace_ustack.o not supported on mac and linux
|
||||
# node_dtrace_provider.o All except OS X. "dtrace -G" is not
|
||||
# used on OS X.
|
||||
#
|
||||
@@ -202,11 +201,15 @@
|
||||
# below, and the GYP-generated Makefiles will properly build them when
|
||||
# needed.
|
||||
#
|
||||
'sources': [
|
||||
'src/node_dtrace.cc',
|
||||
],
|
||||
'conditions': [ [
|
||||
'OS!="mac"', {
|
||||
'sources': [ 'src/node_dtrace.cc' ],
|
||||
'conditions': [
|
||||
[ 'OS=="linux"', {
|
||||
'sources': [
|
||||
'<(SHARED_INTERMEDIATE_DIR)/node_dtrace_provider.o',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/libuv_dtrace_provider.o',
|
||||
],
|
||||
}],
|
||||
[ 'OS!="mac" and OS!="linux"', {
|
||||
'sources': [
|
||||
'src/node_dtrace_ustack.cc',
|
||||
'src/node_dtrace_provider.cc',
|
||||
@@ -221,12 +224,6 @@
|
||||
'src/node_mdb.cc',
|
||||
],
|
||||
} ],
|
||||
[ 'node_use_systemtap=="true"', {
|
||||
'defines': [ 'HAVE_SYSTEMTAP=1', 'STAP_SDT_V1=1' ],
|
||||
'sources': [
|
||||
'src/node_dtrace.cc',
|
||||
],
|
||||
} ],
|
||||
[ 'node_use_etw=="true"', {
|
||||
'defines': [ 'HAVE_ETW=1' ],
|
||||
'dependencies': [ 'node_etw' ],
|
||||
@@ -387,11 +384,8 @@
|
||||
'<(SHARED_INTERMEDIATE_DIR)/node_natives.h',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'node_use_dtrace=="false"'
|
||||
' and node_use_etw=="false"'
|
||||
' and node_use_systemtap=="false"',
|
||||
{
|
||||
'inputs': ['src/notrace_macros.py']
|
||||
[ 'node_use_dtrace=="false" and node_use_etw=="false"', {
|
||||
'inputs': [ 'src/notrace_macros.py' ]
|
||||
}],
|
||||
[ 'node_use_perfctr=="false"', {
|
||||
'inputs': [ 'src/perfctr_macros.py' ]
|
||||
@@ -410,7 +404,7 @@
|
||||
'target_name': 'node_dtrace_header',
|
||||
'type': 'none',
|
||||
'conditions': [
|
||||
[ 'node_use_dtrace=="true" or node_use_systemtap=="true"', {
|
||||
[ 'node_use_dtrace=="true"', {
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'node_dtrace_header',
|
||||
@@ -453,7 +447,7 @@
|
||||
'target_name': 'node_dtrace_provider',
|
||||
'type': 'none',
|
||||
'conditions': [
|
||||
[ 'node_use_dtrace=="true" and OS!="mac"', {
|
||||
[ 'node_use_dtrace=="true" and OS!="mac" and OS!="linux"', {
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'node_dtrace_provider_o',
|
||||
@@ -469,14 +463,38 @@
|
||||
'-o', '<@(_outputs)' ]
|
||||
}
|
||||
]
|
||||
} ]
|
||||
}],
|
||||
[ 'node_use_dtrace=="true" and OS=="linux"', {
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'node_dtrace_provider_o',
|
||||
'inputs': [ 'src/node_provider.d' ],
|
||||
'outputs': [
|
||||
'<(SHARED_INTERMEDIATE_DIR)/node_dtrace_provider.o'
|
||||
],
|
||||
'action': [
|
||||
'dtrace', '-C', '-G', '-s', '<@(_inputs)', '-o', '<@(_outputs)'
|
||||
],
|
||||
},
|
||||
{
|
||||
'action_name': 'libuv_dtrace_provider_o',
|
||||
'inputs': [ 'deps/uv/src/unix/uv-dtrace.d' ],
|
||||
'outputs': [
|
||||
'<(SHARED_INTERMEDIATE_DIR)/libuv_dtrace_provider.o'
|
||||
],
|
||||
'action': [
|
||||
'dtrace', '-C', '-G', '-s', '<@(_inputs)', '-o', '<@(_outputs)'
|
||||
],
|
||||
},
|
||||
],
|
||||
}],
|
||||
]
|
||||
},
|
||||
{
|
||||
'target_name': 'node_dtrace_ustack',
|
||||
'type': 'none',
|
||||
'conditions': [
|
||||
[ 'node_use_dtrace=="true" and OS!="mac"', {
|
||||
[ 'node_use_dtrace=="true" and OS!="mac" and OS!="linux"', {
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'node_dtrace_ustack_constants',
|
||||
|
||||
@@ -35,14 +35,10 @@
|
||||
#include "node_crypto.h"
|
||||
#endif
|
||||
|
||||
#if defined HAVE_DTRACE || defined HAVE_ETW || defined HAVE_SYSTEMTAP
|
||||
#if defined HAVE_DTRACE || defined HAVE_ETW
|
||||
#include "node_dtrace.h"
|
||||
#endif
|
||||
|
||||
#if HAVE_SYSTEMTAP
|
||||
#include "node_provider.h"
|
||||
#endif
|
||||
|
||||
#include "ares.h"
|
||||
#include "env.h"
|
||||
#include "env-inl.h"
|
||||
@@ -2656,7 +2652,7 @@ void Load(Environment* env) {
|
||||
// Add a reference to the global object
|
||||
Local<Object> global = env->context()->Global();
|
||||
|
||||
#if defined HAVE_DTRACE || defined HAVE_ETW || defined HAVE_SYSTEMTAP
|
||||
#if defined HAVE_DTRACE || defined HAVE_ETW
|
||||
InitDTrace(global);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -22,20 +22,13 @@
|
||||
|
||||
#ifdef HAVE_DTRACE
|
||||
#include "node_dtrace.h"
|
||||
#include <string.h>
|
||||
#include "node_provider.h"
|
||||
#include <string.h>
|
||||
#elif HAVE_ETW
|
||||
#include "node_dtrace.h"
|
||||
#include <string.h>
|
||||
#include "node_win32_etw_provider.h"
|
||||
#include "node_win32_etw_provider-inl.h"
|
||||
#elif HAVE_SYSTEMTAP
|
||||
#include <string.h>
|
||||
#include <node.h>
|
||||
#include <v8.h>
|
||||
#include <sys/sdt.h>
|
||||
#include "node_provider.h"
|
||||
#include "node_dtrace.h"
|
||||
#else
|
||||
#define NODE_HTTP_SERVER_REQUEST(arg0, arg1)
|
||||
#define NODE_HTTP_SERVER_REQUEST_ENABLED() (0)
|
||||
@@ -143,10 +136,8 @@ using v8::Value;
|
||||
|
||||
|
||||
void DTRACE_NET_SERVER_CONNECTION(const FunctionCallbackInfo<Value>& args) {
|
||||
#ifndef HAVE_SYSTEMTAP
|
||||
if (!NODE_NET_SERVER_CONNECTION_ENABLED())
|
||||
return;
|
||||
#endif
|
||||
HandleScope scope(node_isolate);
|
||||
SLURP_CONNECTION(args[0], conn);
|
||||
NODE_NET_SERVER_CONNECTION(&conn, conn.remote, conn.port, conn.fd);
|
||||
@@ -154,10 +145,8 @@ void DTRACE_NET_SERVER_CONNECTION(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
|
||||
void DTRACE_NET_STREAM_END(const FunctionCallbackInfo<Value>& args) {
|
||||
#ifndef HAVE_SYSTEMTAP
|
||||
if (!NODE_NET_STREAM_END_ENABLED())
|
||||
return;
|
||||
#endif
|
||||
HandleScope scope(node_isolate);
|
||||
SLURP_CONNECTION(args[0], conn);
|
||||
NODE_NET_STREAM_END(&conn, conn.remote, conn.port, conn.fd);
|
||||
@@ -165,10 +154,8 @@ void DTRACE_NET_STREAM_END(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
|
||||
void DTRACE_NET_SOCKET_READ(const FunctionCallbackInfo<Value>& args) {
|
||||
#ifndef HAVE_SYSTEMTAP
|
||||
if (!NODE_NET_SOCKET_READ_ENABLED())
|
||||
return;
|
||||
#endif
|
||||
HandleScope scope(node_isolate);
|
||||
SLURP_CONNECTION(args[0], conn);
|
||||
|
||||
@@ -182,10 +169,8 @@ void DTRACE_NET_SOCKET_READ(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
|
||||
void DTRACE_NET_SOCKET_WRITE(const FunctionCallbackInfo<Value>& args) {
|
||||
#ifndef HAVE_SYSTEMTAP
|
||||
if (!NODE_NET_SOCKET_WRITE_ENABLED())
|
||||
return;
|
||||
#endif
|
||||
HandleScope scope(node_isolate);
|
||||
SLURP_CONNECTION(args[0], conn);
|
||||
|
||||
@@ -201,10 +186,8 @@ void DTRACE_NET_SOCKET_WRITE(const FunctionCallbackInfo<Value>& args) {
|
||||
void DTRACE_HTTP_SERVER_REQUEST(const FunctionCallbackInfo<Value>& args) {
|
||||
node_dtrace_http_server_request_t req;
|
||||
|
||||
#ifndef HAVE_SYSTEMTAP
|
||||
if (!NODE_HTTP_SERVER_REQUEST_ENABLED())
|
||||
return;
|
||||
#endif
|
||||
|
||||
HandleScope scope(node_isolate);
|
||||
Local<Object> arg0 = Local<Object>::Cast(args[0]);
|
||||
@@ -234,10 +217,8 @@ void DTRACE_HTTP_SERVER_REQUEST(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
|
||||
void DTRACE_HTTP_SERVER_RESPONSE(const FunctionCallbackInfo<Value>& args) {
|
||||
#ifndef HAVE_SYSTEMTAP
|
||||
if (!NODE_HTTP_SERVER_RESPONSE_ENABLED())
|
||||
return;
|
||||
#endif
|
||||
HandleScope scope(node_isolate);
|
||||
SLURP_CONNECTION(args[0], conn);
|
||||
NODE_HTTP_SERVER_RESPONSE(&conn, conn.remote, conn.port, conn.fd);
|
||||
@@ -248,10 +229,8 @@ void DTRACE_HTTP_CLIENT_REQUEST(const FunctionCallbackInfo<Value>& args) {
|
||||
node_dtrace_http_client_request_t req;
|
||||
char *header;
|
||||
|
||||
#ifndef HAVE_SYSTEMTAP
|
||||
if (!NODE_HTTP_CLIENT_REQUEST_ENABLED())
|
||||
return;
|
||||
#endif
|
||||
|
||||
HandleScope scope(node_isolate);
|
||||
|
||||
@@ -286,10 +265,8 @@ void DTRACE_HTTP_CLIENT_REQUEST(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
|
||||
void DTRACE_HTTP_CLIENT_RESPONSE(const FunctionCallbackInfo<Value>& args) {
|
||||
#ifndef HAVE_SYSTEMTAP
|
||||
if (!NODE_HTTP_CLIENT_RESPONSE_ENABLED())
|
||||
return;
|
||||
#endif
|
||||
HandleScope scope(node_isolate);
|
||||
SLURP_CONNECTION_HTTP_CLIENT_RESPONSE(args[0], args[1], conn);
|
||||
NODE_HTTP_CLIENT_RESPONSE(&conn, conn.remote, conn.port, conn.fd);
|
||||
@@ -341,7 +318,7 @@ void InitDTrace(Handle<Object> target) {
|
||||
init_etw();
|
||||
#endif
|
||||
|
||||
#if defined HAVE_DTRACE || defined HAVE_ETW || defined HAVE_SYSTEMTAP
|
||||
#if defined HAVE_DTRACE || defined HAVE_ETW
|
||||
v8::V8::AddGCPrologueCallback((GCPrologueCallback)dtrace_gc_start);
|
||||
v8::V8::AddGCEpilogueCallback((GCEpilogueCallback)dtrace_gc_done);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user