Skip to content

Commit 7875cdf

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 5a58972 commit 7875cdf

File tree

5 files changed

+151
-9
lines changed

5 files changed

+151
-9
lines changed

lib/internal/http.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ const {
88
} = primordials;
99

1010
const { setUnrefTimeout } = require('internal/timers');
11-
const { trace, isTraceCategoryEnabled } = internalBinding('trace_events');
11+
// The trace variable must not be destructured
12+
// because it might break node snapshot serialization
13+
// ref: https://github.com/nodejs/node/pull/48142#discussion_r1204128367
14+
const trace_events = internalBinding('trace_events');
1215
const {
1316
CHAR_LOWERCASE_B,
1417
CHAR_LOWERCASE_E,
@@ -38,17 +41,17 @@ function getNextTraceEventId() {
3841
}
3942

4043
function isTraceHTTPEnabled() {
41-
return isTraceCategoryEnabled('node.http');
44+
return trace_events.tracingCategories[0] > 0;
4245
}
4346

4447
const traceEventCategory = 'node,node.http';
4548

4649
function traceBegin(...args) {
47-
trace(CHAR_LOWERCASE_B, traceEventCategory, ...args);
50+
trace_events.trace(CHAR_LOWERCASE_B, traceEventCategory, ...args);
4851
}
4952

5053
function traceEnd(...args) {
51-
trace(CHAR_LOWERCASE_E, traceEventCategory, ...args);
54+
trace_events.trace(CHAR_LOWERCASE_E, traceEventCategory, ...args);
5255
}
5356

5457
module.exports = {

src/base_object_types.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ namespace node {
1717
V(blob_binding_data, BlobBindingData) \
1818
V(process_binding_data, process::BindingData) \
1919
V(timers_binding_data, timers::BindingData) \
20-
V(url_binding_data, url::BindingData)
20+
V(url_binding_data, url::BindingData) \
21+
V(trace_events_binding_data, trace_events::BindingData)
2122

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

src/node_snapshotable.cc

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "node_metadata.h"
2121
#include "node_process.h"
2222
#include "node_snapshot_builder.h"
23+
#include "node_trace_events.h"
2324
#include "node_url.h"
2425
#include "node_util.h"
2526
#include "node_v8.h"

src/node_trace_events.cc

+96-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include "node_trace_events.h"
12
#include "base_object-inl.h"
23
#include "env-inl.h"
34
#include "memory_tracker-inl.h"
@@ -20,11 +21,14 @@ using v8::Context;
2021
using v8::Function;
2122
using v8::FunctionCallbackInfo;
2223
using v8::FunctionTemplate;
24+
using v8::HandleScope;
2325
using v8::Isolate;
2426
using v8::Local;
2527
using v8::NewStringType;
2628
using v8::Object;
29+
using v8::ObjectTemplate;
2730
using v8::String;
31+
using v8::Uint8Array;
2832
using v8::Value;
2933

3034
class NodeCategorySet : public BaseObject {
@@ -165,9 +169,97 @@ void NodeCategorySet::RegisterExternalReferences(
165169
registry->Register(NodeCategorySet::Disable);
166170
}
167171

172+
namespace trace_events {
173+
174+
void BindingData::MemoryInfo(MemoryTracker* tracker) const {}
175+
176+
BindingData::BindingData(Realm* realm, v8::Local<v8::Object> object)
177+
: SnapshotableObject(realm, object, type_int) {
178+
// Get the pointer of the memory for the flag that
179+
// store if trace is enabled for http the pointer will
180+
// always be the same and if the category does not exist
181+
// it creates:
182+
// https://github.com/nodejs/node/blob/6bbf2a57fcf33266c5859497f8cc32e1389a358a/deps/v8/src/libplatform/tracing/tracing-controller.cc#L322-L342
183+
auto p = const_cast<uint8_t*>(
184+
TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("node.http"));
185+
186+
// NO_OP deleter
187+
// the idea of this chunk of code is to construct
188+
auto nop = [](void*, size_t, void*) {};
189+
auto bs = v8::ArrayBuffer::NewBackingStore(p, 1, nop, nullptr);
190+
auto ab = v8::ArrayBuffer::New(realm->isolate(), std::move(bs));
191+
v8::Local<Uint8Array> u8 = v8::Uint8Array::New(ab, 0, 1);
192+
193+
object
194+
->Set(realm->context(),
195+
FIXED_ONE_BYTE_STRING(realm->isolate(), "tracingCategories"),
196+
u8)
197+
.Check();
198+
}
199+
200+
bool BindingData::PrepareForSerialization(v8::Local<v8::Context> context,
201+
v8::SnapshotCreator* creator) {
202+
return true;
203+
}
204+
205+
InternalFieldInfoBase* BindingData::Serialize(int index) {
206+
DCHECK_EQ(index, BaseObject::kEmbedderType);
207+
InternalFieldInfo* info =
208+
InternalFieldInfoBase::New<InternalFieldInfo>(type());
209+
return info;
210+
}
211+
212+
void BindingData::Deserialize(v8::Local<v8::Context> context,
213+
v8::Local<v8::Object> holder,
214+
int index,
215+
InternalFieldInfoBase* info) {
216+
DCHECK_EQ(index, BaseObject::kEmbedderType);
217+
v8::HandleScope scope(context->GetIsolate());
218+
Realm* realm = Realm::GetCurrent(context);
219+
BindingData* binding = realm->AddBindingData<BindingData>(context, holder);
220+
CHECK_NOT_NULL(binding);
221+
}
222+
223+
void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data,
224+
Local<ObjectTemplate> ctor) {}
225+
226+
void BindingData::CreatePerContextProperties(Local<Object> target,
227+
Local<Value> unused,
228+
Local<Context> context,
229+
void* priv) {
230+
Realm* realm = Realm::GetCurrent(context);
231+
realm->AddBindingData<BindingData>(context, target);
232+
}
233+
234+
void BindingData::RegisterExternalReferences(
235+
ExternalReferenceRegistry* registry) {}
236+
237+
static void CreatePerIsolateProperties(IsolateData* isolate_data,
238+
Local<ObjectTemplate> ctor) {
239+
BindingData::CreatePerIsolateProperties(isolate_data, ctor);
240+
}
241+
242+
static void CreatePerContextProperties(Local<Object> target,
243+
Local<Value> unused,
244+
Local<Context> context,
245+
void* priv) {
246+
BindingData::CreatePerContextProperties(target, unused, context, priv);
247+
248+
NodeCategorySet::Initialize(target, unused, context, priv);
249+
}
250+
251+
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
252+
NodeCategorySet::RegisterExternalReferences(registry);
253+
BindingData::RegisterExternalReferences(registry);
254+
}
255+
256+
} // namespace trace_events
257+
168258
} // namespace node
169259

170-
NODE_BINDING_CONTEXT_AWARE_INTERNAL(trace_events,
171-
node::NodeCategorySet::Initialize)
172-
NODE_BINDING_EXTERNAL_REFERENCE(
173-
trace_events, node::NodeCategorySet::RegisterExternalReferences)
260+
NODE_BINDING_CONTEXT_AWARE_INTERNAL(
261+
trace_events, node::trace_events::CreatePerContextProperties)
262+
NODE_BINDING_PER_ISOLATE_INIT(trace_events,
263+
node::trace_events::CreatePerIsolateProperties)
264+
NODE_BINDING_EXTERNAL_REFERENCE(trace_events,
265+
node::trace_events::RegisterExternalReferences)

src/node_trace_events.h

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#ifndef SRC_NODE_TRACE_EVENTS_H_
2+
#define SRC_NODE_TRACE_EVENTS_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 trace_events {
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(trace_events_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::ObjectTemplate> 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 trace_events
42+
43+
} // namespace node
44+
45+
#endif // SRC_NODE_TRACE_EVENTS_H_

0 commit comments

Comments
 (0)