Skip to content

Commit 08f75a3

Browse files
committed
src,lib: expose node.http trace flag by array
Instead call the C++ code every time we make a HTTP request, now we get the C++ pointer to the flag that holds the info if the trace is enabled for node.http, then we expose that flag using BindingData, with this change, no C++ call is made and the access to the info happens in JS side, which has no perf penalty.
1 parent 85ac915 commit 08f75a3

9 files changed

+159
-4
lines changed

lib/internal/http.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ const {
88
} = primordials;
99

1010
const { setUnrefTimeout } = require('internal/timers');
11-
const { trace, isTraceCategoryEnabled } = internalBinding('trace_events');
11+
const { trace } = internalBinding('trace_events');
12+
// The trace variable must not be destructured
13+
// because it might break node snapshot serialization
14+
// ref: https://github.com/nodejs/node/pull/48142#discussion_r1204128367
15+
const tracing = internalBinding('tracing');
1216
const {
1317
CHAR_LOWERCASE_B,
1418
CHAR_LOWERCASE_E,
@@ -38,7 +42,7 @@ function getNextTraceEventId() {
3842
}
3943

4044
function isTraceHTTPEnabled() {
41-
return isTraceCategoryEnabled('node.http');
45+
return tracing.tracingCategories[0] > 0;
4246
}
4347

4448
const traceEventCategory = 'node,node.http';

node.gyp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
'src/node_symbols.cc',
129129
'src/node_task_queue.cc',
130130
'src/node_trace_events.cc',
131+
'src/node_tracing.cc',
131132
'src/node_types.cc',
132133
'src/node_url.cc',
133134
'src/node_util.cc',
@@ -248,6 +249,7 @@
248249
'src/node_sockaddr-inl.h',
249250
'src/node_stat_watcher.h',
250251
'src/node_union_bytes.h',
252+
'src/node_tracing.h',
251253
'src/node_url.h',
252254
'src/node_util.h',
253255
'src/node_version.h',

src/base_object_types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ namespace node {
1616
V(blob_binding_data, BlobBindingData) \
1717
V(process_binding_data, process::BindingData) \
1818
V(timers_binding_data, timers::BindingData) \
19-
V(url_binding_data, url::BindingData)
19+
V(url_binding_data, url::BindingData) \
20+
V(tracing_binding_data, tracing::BindingData)
2021

2122
#define UNSERIALIZABLE_BINDING_TYPES(V) \
2223
V(http2_binding_data, http2::BindingData) \

src/node_binding.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
V(task_queue) \
7070
V(tcp_wrap) \
7171
V(timers) \
72+
V(tracing) \
7273
V(trace_events) \
7374
V(tty_wrap) \
7475
V(types) \

src/node_builtins.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ BuiltinLoader::BuiltinCategories BuiltinLoader::GetBuiltinCategories() const {
113113
#endif // !HAVE_INSPECTOR
114114

115115
#if !NODE_USE_V8_PLATFORM || !defined(NODE_HAVE_I18N_SUPPORT)
116-
"trace_events",
116+
"tracing", "trace_events",
117117
#endif // !NODE_USE_V8_PLATFORM || !defined(NODE_HAVE_I18N_SUPPORT)
118118

119119
#if !HAVE_OPENSSL

src/node_external_reference.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ class ExternalReferenceRegistry {
110110
V(string_decoder) \
111111
V(stream_wrap) \
112112
V(signal_wrap) \
113+
V(tracing) \
113114
V(trace_events) \
114115
V(timers) \
115116
V(types) \

src/node_snapshotable.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "node_metadata.h"
2020
#include "node_process.h"
2121
#include "node_snapshot_builder.h"
22+
#include "node_tracing.h"
2223
#include "node_url.h"
2324
#include "node_util.h"
2425
#include "node_v8.h"

src/node_tracing.cc

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#include "node_tracing.h"
2+
#include "base_object-inl.h"
3+
#include "env-inl.h"
4+
#include "memory_tracker-inl.h"
5+
#include "node.h"
6+
#include "node_external_reference.h"
7+
#include "node_internals.h"
8+
#include "node_v8_platform-inl.h"
9+
#include "tracing/agent.h"
10+
#include "util-inl.h"
11+
#include "v8.h"
12+
13+
namespace node {
14+
namespace tracing {
15+
16+
using v8::ArrayBuffer;
17+
using v8::Context;
18+
using v8::FunctionTemplate;
19+
using v8::HandleScope;
20+
using v8::Local;
21+
using v8::Object;
22+
using v8::Uint8Array;
23+
using v8::Value;
24+
25+
void BindingData::MemoryInfo(MemoryTracker* tracker) const {}
26+
27+
BindingData::BindingData(Realm* realm, v8::Local<v8::Object> object)
28+
: SnapshotableObject(realm, object, type_int) {
29+
30+
// Get the pointer of the memory for the flag that
31+
// store if trace is enabled for http the pointer will
32+
// always be the same and if the category does not exist
33+
// it creates: https://github.com/nodejs/node/blob/6bbf2a57fcf33266c5859497f8cc32e1389a358a/deps/v8/src/libplatform/tracing/tracing-controller.cc#L322-L342
34+
uint8_t* http_flag_pointer = const_cast<uint8_t*>(
35+
TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("node.http"));
36+
37+
// NO_OP deleter
38+
// the idea of this chunk of code is to construct
39+
auto nop_deleter = [](void*, size_t, void*) {};
40+
auto backing_store = v8::ArrayBuffer::NewBackingStore(
41+
http_flag_pointer, 1, nop_deleter, nullptr);
42+
v8::Local<ArrayBuffer> array_buffer = v8::ArrayBuffer::New(
43+
realm->isolate(), std::move(backing_store));
44+
v8::Local<Uint8Array> uint8Array = v8::Uint8Array::New(array_buffer, 0, 1);
45+
46+
object
47+
->Set(realm->context(),
48+
FIXED_ONE_BYTE_STRING(realm->isolate(), "tracingCategories"),
49+
uint8Array)
50+
.Check();
51+
}
52+
53+
bool BindingData::PrepareForSerialization(v8::Local<v8::Context> context,
54+
v8::SnapshotCreator* creator) {
55+
return true;
56+
}
57+
58+
InternalFieldInfoBase* BindingData::Serialize(int index) {
59+
DCHECK_EQ(index, BaseObject::kEmbedderType);
60+
InternalFieldInfo* info =
61+
InternalFieldInfoBase::New<InternalFieldInfo>(type());
62+
return info;
63+
}
64+
65+
void BindingData::Deserialize(v8::Local<v8::Context> context,
66+
v8::Local<v8::Object> holder,
67+
int index,
68+
InternalFieldInfoBase* info) {
69+
DCHECK_EQ(index, BaseObject::kEmbedderType);
70+
v8::HandleScope scope(context->GetIsolate());
71+
Realm* realm = Realm::GetCurrent(context);
72+
BindingData* binding = realm->AddBindingData<BindingData>(context, holder);
73+
CHECK_NOT_NULL(binding);
74+
}
75+
76+
void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data,
77+
Local<FunctionTemplate> ctor) {}
78+
79+
void BindingData::CreatePerContextProperties(Local<Object> target,
80+
Local<Value> unused,
81+
Local<Context> context,
82+
void* priv) {
83+
Realm* realm = Realm::GetCurrent(context);
84+
realm->AddBindingData<BindingData>(context, target);
85+
}
86+
87+
void BindingData::RegisterExternalReferences(
88+
ExternalReferenceRegistry* registry
89+
) {}
90+
91+
} // namespace tracing
92+
93+
} // namespace node
94+
95+
NODE_BINDING_CONTEXT_AWARE_INTERNAL(
96+
tracing, node::tracing::BindingData::CreatePerContextProperties)
97+
NODE_BINDING_PER_ISOLATE_INIT(
98+
tracing, node::tracing::BindingData::CreatePerIsolateProperties)
99+
NODE_BINDING_EXTERNAL_REFERENCE(
100+
tracing, node::tracing::BindingData::RegisterExternalReferences)

src/node_tracing.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#ifndef SRC_NODE_TRACING_H_
2+
#define SRC_NODE_TRACING_H_
3+
4+
#include <cinttypes>
5+
#include "aliased_buffer.h"
6+
#include "node.h"
7+
#include "node_snapshotable.h"
8+
#include "util.h"
9+
#include "v8-fast-api-calls.h"
10+
#include "v8.h"
11+
12+
#include <string>
13+
14+
namespace node {
15+
class ExternalReferenceRegistry;
16+
17+
namespace tracing {
18+
19+
class BindingData : public SnapshotableObject {
20+
public:
21+
BindingData(Realm* realm, v8::Local<v8::Object> obj);
22+
23+
using InternalFieldInfo = InternalFieldInfoBase;
24+
25+
SERIALIZABLE_OBJECT_METHODS()
26+
SET_BINDING_ID(tracing_binding_data)
27+
28+
void MemoryInfo(MemoryTracker* tracker) const override;
29+
SET_SELF_SIZE(BindingData)
30+
SET_MEMORY_INFO_NAME(BindingData)
31+
32+
static void CreatePerIsolateProperties(IsolateData* isolate_data,
33+
v8::Local<v8::FunctionTemplate> ctor);
34+
static void CreatePerContextProperties(v8::Local<v8::Object> target,
35+
v8::Local<v8::Value> unused,
36+
v8::Local<v8::Context> context,
37+
void* priv);
38+
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
39+
};
40+
41+
} // namespace tracing
42+
43+
} // namespace node
44+
45+
#endif // SRC_NODE_TRACING_H_

0 commit comments

Comments
 (0)