Skip to content

Commit b935c4f

Browse files
RaisinTendanielleadams
authored andcommitted
src: use a typed array internally for process._exiting
This would prevent manual writes to the _exiting JS property on the process object by passing the data directly via a typed array for performance. This change partially addresses this TODO: https://github.com/nodejs/node/blob/3d575a4f1bd197c3ce669758a2a3c763462a883a/src/api/hooks.cc#L68-L71 Signed-off-by: Darshan Sen <raisinten@gmail.com> PR-URL: #43883 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
1 parent d8a03cc commit b935c4f

File tree

7 files changed

+68
-17
lines changed

7 files changed

+68
-17
lines changed

lib/internal/bootstrap/node.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,32 @@ const {
6060
deprecate,
6161
exposeInterface,
6262
} = require('internal/util');
63+
const {
64+
exiting_aliased_Uint32Array,
65+
getHiddenValue,
66+
} = internalBinding('util');
6367

6468
setupProcessObject();
6569

6670
setupGlobalProxy();
6771
setupBuffer();
6872

6973
process.domain = null;
74+
{
75+
const exitingAliasedUint32Array =
76+
getHiddenValue(process, exiting_aliased_Uint32Array);
77+
ObjectDefineProperty(process, '_exiting', {
78+
__proto__: null,
79+
get() {
80+
return exitingAliasedUint32Array[0] === 1;
81+
},
82+
set(value) {
83+
exitingAliasedUint32Array[0] = value ? 1 : 0;
84+
},
85+
enumerable: true,
86+
configurable: true,
87+
});
88+
}
7089
process._exiting = false;
7190

7291
// process.config is serialized config.gypi

src/api/hooks.cc

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,11 @@ Maybe<int> EmitProcessExit(Environment* env) {
6565
Context::Scope context_scope(context);
6666
Local<Object> process_object = env->process_object();
6767

68-
// TODO(addaleax): It might be nice to share process._exiting and
69-
// process.exitCode via getter/setter pairs that pass data directly to the
70-
// native side, so that we don't manually have to read and write JS properties
71-
// here. These getters could use e.g. a typed array for performance.
72-
if (process_object
73-
->Set(context,
74-
FIXED_ONE_BYTE_STRING(isolate, "_exiting"),
75-
True(isolate)).IsNothing()) return Nothing<int>();
68+
// TODO(addaleax): It might be nice to share process.exitCode via
69+
// getter/setter pairs that pass data directly to the native side, so that we
70+
// don't manually have to read and write JS properties here. These getters
71+
// could use e.g. a typed array for performance.
72+
env->set_exiting(true);
7673

7774
Local<String> exit_code = env->exit_code_string();
7875
Local<Value> code_v;

src/env-inl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,14 @@ inline bool Environment::force_context_aware() const {
371371
return options_->force_context_aware;
372372
}
373373

374+
inline void Environment::set_exiting(bool value) {
375+
exiting_[0] = value ? 1 : 0;
376+
}
377+
378+
inline AliasedUint32Array& Environment::exiting() {
379+
return exiting_;
380+
}
381+
374382
inline void Environment::set_abort_on_uncaught_exception(bool value) {
375383
options_->abort_on_uncaught_exception = value;
376384
}

src/env.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,7 @@ Environment::Environment(IsolateData* isolate_data,
813813
exec_argv_(exec_args),
814814
argv_(args),
815815
exec_path_(GetExecPath(args)),
816+
exiting_(isolate_, 1, MAYBE_FIELD_PTR(env_info, exiting)),
816817
should_abort_on_uncaught_toggle_(
817818
isolate_,
818819
1,
@@ -919,6 +920,9 @@ void Environment::InitializeMainContext(Local<Context> context,
919920
// By default, always abort when --abort-on-uncaught-exception was passed.
920921
should_abort_on_uncaught_toggle_[0] = 1;
921922

923+
// The process is not exiting by default.
924+
set_exiting(false);
925+
922926
performance_state_->Mark(performance::NODE_PERFORMANCE_MILESTONE_ENVIRONMENT,
923927
environment_start_time_);
924928
performance_state_->Mark(performance::NODE_PERFORMANCE_MILESTONE_NODE_START,
@@ -1810,6 +1814,7 @@ EnvSerializeInfo Environment::Serialize(SnapshotCreator* creator) {
18101814
info.immediate_info = immediate_info_.Serialize(ctx, creator);
18111815
info.tick_info = tick_info_.Serialize(ctx, creator);
18121816
info.performance_state = performance_state_->Serialize(ctx, creator);
1817+
info.exiting = exiting_.Serialize(ctx, creator);
18131818
info.stream_base_state = stream_base_state_.Serialize(ctx, creator);
18141819
info.should_abort_on_uncaught_toggle =
18151820
should_abort_on_uncaught_toggle_.Serialize(ctx, creator);
@@ -1857,6 +1862,7 @@ std::ostream& operator<<(std::ostream& output, const EnvSerializeInfo& i) {
18571862
<< "// -- performance_state begins --\n"
18581863
<< i.performance_state << ",\n"
18591864
<< "// -- performance_state ends --\n"
1865+
<< i.exiting << ", // exiting\n"
18601866
<< i.stream_base_state << ", // stream_base_state\n"
18611867
<< i.should_abort_on_uncaught_toggle
18621868
<< ", // should_abort_on_uncaught_toggle\n"
@@ -1900,6 +1906,7 @@ void Environment::DeserializeProperties(const EnvSerializeInfo* info) {
19001906
immediate_info_.Deserialize(ctx);
19011907
tick_info_.Deserialize(ctx);
19021908
performance_state_->Deserialize(ctx);
1909+
exiting_.Deserialize(ctx);
19031910
stream_base_state_.Deserialize(ctx);
19041911
should_abort_on_uncaught_toggle_.Deserialize(ctx);
19051912

@@ -2120,6 +2127,7 @@ void Environment::MemoryInfo(MemoryTracker* tracker) const {
21202127
native_modules_without_cache);
21212128
tracker->TrackField("destroy_async_id_list", destroy_async_id_list_);
21222129
tracker->TrackField("exec_argv", exec_argv_);
2130+
tracker->TrackField("exiting", exiting_);
21232131
tracker->TrackField("should_abort_on_uncaught_toggle",
21242132
should_abort_on_uncaught_toggle_);
21252133
tracker->TrackField("stream_base_state", stream_base_state_);

src/env.h

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -164,15 +164,16 @@ class NoArrayBufferZeroFillScope {
164164
// Private symbols are per-isolate primitives but Environment proxies them
165165
// for the sake of convenience. Strings should be ASCII-only and have a
166166
// "node:" prefix to avoid name clashes with third-party code.
167-
#define PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V) \
168-
V(alpn_buffer_private_symbol, "node:alpnBuffer") \
169-
V(arrow_message_private_symbol, "node:arrowMessage") \
170-
V(contextify_context_private_symbol, "node:contextify:context") \
171-
V(contextify_global_private_symbol, "node:contextify:global") \
172-
V(decorated_private_symbol, "node:decorated") \
173-
V(napi_type_tag, "node:napi:type_tag") \
174-
V(napi_wrapper, "node:napi:wrapper") \
175-
V(untransferable_object_private_symbol, "node:untransferableObject") \
167+
#define PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V) \
168+
V(alpn_buffer_private_symbol, "node:alpnBuffer") \
169+
V(arrow_message_private_symbol, "node:arrowMessage") \
170+
V(contextify_context_private_symbol, "node:contextify:context") \
171+
V(contextify_global_private_symbol, "node:contextify:global") \
172+
V(decorated_private_symbol, "node:decorated") \
173+
V(napi_type_tag, "node:napi:type_tag") \
174+
V(napi_wrapper, "node:napi:wrapper") \
175+
V(untransferable_object_private_symbol, "node:untransferableObject") \
176+
V(exiting_aliased_Uint32Array, "node:exiting_aliased_Uint32Array")
176177

177178
// Symbols are per-isolate primitives but Environment proxies them
178179
// for the sake of convenience.
@@ -973,6 +974,7 @@ struct EnvSerializeInfo {
973974
TickInfo::SerializeInfo tick_info;
974975
ImmediateInfo::SerializeInfo immediate_info;
975976
performance::PerformanceState::SerializeInfo performance_state;
977+
AliasedBufferIndex exiting;
976978
AliasedBufferIndex stream_base_state;
977979
AliasedBufferIndex should_abort_on_uncaught_toggle;
978980

@@ -1173,6 +1175,11 @@ class Environment : public MemoryRetainer {
11731175
inline void set_force_context_aware(bool value);
11741176
inline bool force_context_aware() const;
11751177

1178+
// This is a pseudo-boolean that keeps track of whether the process is
1179+
// exiting.
1180+
inline void set_exiting(bool value);
1181+
inline AliasedUint32Array& exiting();
1182+
11761183
// This stores whether the --abort-on-uncaught-exception flag was passed
11771184
// to Node.
11781185
inline bool abort_on_uncaught_exception() const;
@@ -1563,6 +1570,8 @@ class Environment : public MemoryRetainer {
15631570
uint32_t script_id_counter_ = 0;
15641571
uint32_t function_id_counter_ = 0;
15651572

1573+
AliasedUint32Array exiting_;
1574+
15661575
AliasedUint32Array should_abort_on_uncaught_toggle_;
15671576
int should_not_abort_scope_counter_ = 0;
15681577

src/node_process_object.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,15 @@ MaybeLocal<Object> CreateProcessObject(Environment* env) {
9191
return MaybeLocal<Object>();
9292
}
9393

94+
// process[exiting_aliased_Uint32Array]
95+
if (process
96+
->SetPrivate(context,
97+
env->exiting_aliased_Uint32Array(),
98+
env->exiting().GetJSArray())
99+
.IsNothing()) {
100+
return {};
101+
}
102+
94103
// process.version
95104
READONLY_PROPERTY(process,
96105
"version",

typings/internalBinding/util.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ declare function InternalBinding(binding: 'util'): {
1717
napi_type_tag: 5;
1818
napi_wrapper: 6;
1919
untransferable_object_private_symbol: 7;
20+
exiting_aliased_Uint32Array: 8;
2021

2122
kPending: 0;
2223
kFulfilled: 1;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy