X Tutup
Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
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>
  • Loading branch information
RaisinTen committed Jul 18, 2022
commit 728c0def4b52368efd3385517bbc624b1a929666
11 changes: 11 additions & 0 deletions lib/internal/bootstrap/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,17 @@ setupGlobalProxy();
setupBuffer();

process.domain = null;
ObjectDefineProperty(process, '_exiting', {
__proto__: null,
get() {
return process._exitingAliasedUint32Array[0] === 1;
},
set(value) {
process._exitingAliasedUint32Array[0] = value ? 1 : 0;
},
enumerable: true,
configurable: true,
});
process._exiting = false;

// process.config is serialized config.gypi
Expand Down
13 changes: 5 additions & 8 deletions src/api/hooks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,11 @@ Maybe<int> EmitProcessExit(Environment* env) {
Context::Scope context_scope(context);
Local<Object> process_object = env->process_object();

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

Local<String> exit_code = env->exit_code_string();
Local<Value> code_v;
Expand Down
8 changes: 8 additions & 0 deletions src/env-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,14 @@ inline bool Environment::force_context_aware() const {
return options_->force_context_aware;
}

inline void Environment::set_exiting(bool value) {
exiting_[0] = value ? 1 : 0;
}

inline AliasedUint32Array& Environment::exiting() {
return exiting_;
}

inline void Environment::set_abort_on_uncaught_exception(bool value) {
options_->abort_on_uncaught_exception = value;
}
Expand Down
8 changes: 8 additions & 0 deletions src/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,7 @@ Environment::Environment(IsolateData* isolate_data,
exec_argv_(exec_args),
argv_(args),
exec_path_(GetExecPath(args)),
exiting_(isolate_, 1, MAYBE_FIELD_PTR(env_info, exiting)),
should_abort_on_uncaught_toggle_(
isolate_,
1,
Expand Down Expand Up @@ -843,6 +844,9 @@ void Environment::InitializeMainContext(Local<Context> context,
// By default, always abort when --abort-on-uncaught-exception was passed.
should_abort_on_uncaught_toggle_[0] = 1;

// The process is not exiting by default.
set_exiting(false);

performance_state_->Mark(performance::NODE_PERFORMANCE_MILESTONE_ENVIRONMENT,
time_origin_);
performance_state_->Mark(performance::NODE_PERFORMANCE_MILESTONE_NODE_START,
Expand Down Expand Up @@ -1744,6 +1748,7 @@ EnvSerializeInfo Environment::Serialize(SnapshotCreator* creator) {
info.immediate_info = immediate_info_.Serialize(ctx, creator);
info.tick_info = tick_info_.Serialize(ctx, creator);
info.performance_state = performance_state_->Serialize(ctx, creator);
info.exiting = exiting_.Serialize(ctx, creator);
info.stream_base_state = stream_base_state_.Serialize(ctx, creator);
info.should_abort_on_uncaught_toggle =
should_abort_on_uncaught_toggle_.Serialize(ctx, creator);
Expand Down Expand Up @@ -1815,6 +1820,7 @@ std::ostream& operator<<(std::ostream& output, const EnvSerializeInfo& i) {
<< "// -- performance_state begins --\n"
<< i.performance_state << ",\n"
<< "// -- performance_state ends --\n"
<< i.exiting << ", // exiting\n"
<< i.stream_base_state << ", // stream_base_state\n"
<< i.should_abort_on_uncaught_toggle
<< ", // should_abort_on_uncaught_toggle\n"
Expand Down Expand Up @@ -1861,6 +1867,7 @@ void Environment::DeserializeProperties(const EnvSerializeInfo* info) {
immediate_info_.Deserialize(ctx);
tick_info_.Deserialize(ctx);
performance_state_->Deserialize(ctx);
exiting_.Deserialize(ctx);
stream_base_state_.Deserialize(ctx);
should_abort_on_uncaught_toggle_.Deserialize(ctx);

Expand Down Expand Up @@ -2091,6 +2098,7 @@ void Environment::MemoryInfo(MemoryTracker* tracker) const {
native_modules_without_cache);
tracker->TrackField("destroy_async_id_list", destroy_async_id_list_);
tracker->TrackField("exec_argv", exec_argv_);
tracker->TrackField("exiting", exiting_);
tracker->TrackField("should_abort_on_uncaught_toggle",
should_abort_on_uncaught_toggle_);
tracker->TrackField("stream_base_state", stream_base_state_);
Expand Down
8 changes: 8 additions & 0 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,7 @@ struct EnvSerializeInfo {
TickInfo::SerializeInfo tick_info;
ImmediateInfo::SerializeInfo immediate_info;
performance::PerformanceState::SerializeInfo performance_state;
AliasedBufferIndex exiting;
AliasedBufferIndex stream_base_state;
AliasedBufferIndex should_abort_on_uncaught_toggle;

Expand Down Expand Up @@ -1153,6 +1154,11 @@ class Environment : public MemoryRetainer {
inline void set_force_context_aware(bool value);
inline bool force_context_aware() const;

// This is a pseudo-boolean that keeps track of whether the process is
// exiting.
inline void set_exiting(bool value);
inline AliasedUint32Array& exiting();

// This stores whether the --abort-on-uncaught-exception flag was passed
// to Node.
inline bool abort_on_uncaught_exception() const;
Expand Down Expand Up @@ -1550,6 +1556,8 @@ class Environment : public MemoryRetainer {
uint32_t script_id_counter_ = 0;
uint32_t function_id_counter_ = 0;

AliasedUint32Array exiting_;

AliasedUint32Array should_abort_on_uncaught_toggle_;
int should_not_abort_scope_counter_ = 0;

Expand Down
5 changes: 5 additions & 0 deletions src/node_process_object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ MaybeLocal<Object> CreateProcessObject(Environment* env) {
return MaybeLocal<Object>();
}

// process._exitingAliasedUint32Array
Local<String> exiting_string =
FIXED_ONE_BYTE_STRING(env->isolate(), "_exitingAliasedUint32Array");
process->Set(context, exiting_string, env->exiting().GetJSArray()).FromJust();

// process.version
READONLY_PROPERTY(process,
"version",
Expand Down
X Tutup