Skip to content

Commit 13ef5a2

Browse files
committed
fixup: use typed array
Signed-off-by: Daeyeon Jeong <[email protected]>
1 parent eef1c86 commit 13ef5a2

File tree

10 files changed

+147
-67
lines changed

10 files changed

+147
-67
lines changed

lib/internal/bootstrap/node.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,9 @@ const {
8181
} = require('internal/validators');
8282
const {
8383
exiting_aliased_Uint32Array,
84+
exit_info_private_symbol,
8485
getHiddenValue,
8586
} = internalBinding('util');
86-
const {
87-
exit_code_symbol: kExitCode,
88-
} = internalBinding('symbols');
8987

9088
setupProcessObject();
9189

@@ -111,6 +109,11 @@ process.domain = null;
111109
process._exiting = false;
112110

113111
{
112+
// Must match `Environment::ExitInfo::Fields` in `src/env.h`.
113+
const kExitCode = 0;
114+
const kHasExitCode = 1;
115+
const fields = getHiddenValue(process, exit_info_private_symbol);
116+
114117
let exitCode;
115118

116119
ObjectDefineProperty(process, 'exitCode', {
@@ -126,10 +129,10 @@ process._exiting = false;
126129
value = code;
127130
}
128131
validateInteger(value, 'code');
129-
process[kExitCode] = value;
132+
fields[kExitCode] = value;
133+
fields[kHasExitCode] = 1;
130134
} else {
131-
// unset exit code
132-
process[kExitCode] = code;
135+
fields[kHasExitCode] = 0;
133136
}
134137
exitCode = code;
135138
},

src/api/hooks.cc

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,11 @@ Maybe<bool> EmitProcessBeforeExit(Environment* env) {
3737

3838
Isolate* isolate = env->isolate();
3939
HandleScope handle_scope(isolate);
40-
Local<Context> context = env->context();
41-
Context::Scope context_scope(context);
40+
Context::Scope context_scope(env->context());
4241

4342
Local<Integer> exit_code = v8::Integer::New(
4443
isolate,
45-
env->exit_code().value_or(static_cast<int32_t>(ExitCode::kNoFailure)));
44+
env->maybe_exit_code(static_cast<int32_t>(ExitCode::kNoFailure)));
4645

4746
return ProcessEmit(env, "beforeExit", exit_code).IsEmpty() ?
4847
Nothing<bool>() : Just(true);
@@ -60,21 +59,19 @@ Maybe<ExitCode> EmitProcessExitInternal(Environment* env) {
6059
// process.emit('exit')
6160
Isolate* isolate = env->isolate();
6261
HandleScope handle_scope(isolate);
63-
Local<Context> context = env->context();
64-
Context::Scope context_scope(context);
62+
Context::Scope context_scope(env->context());
6563

6664
env->set_exiting(true);
6765

68-
const std::optional<int32_t>& exit_code = env->exit_code();
6966
const int no_failure = static_cast<int32_t>(ExitCode::kNoFailure);
7067

7168
if (ProcessEmit(
72-
env, "exit", Integer::New(isolate, exit_code.value_or(no_failure)))
69+
env, "exit", Integer::New(isolate, env->maybe_exit_code(no_failure)))
7370
.IsEmpty()) {
7471
return Nothing<ExitCode>();
7572
}
7673
// Reload exit code, it may be changed by `emit('exit')`
77-
return Just(static_cast<ExitCode>(exit_code.value_or(no_failure)));
74+
return Just(static_cast<ExitCode>(env->maybe_exit_code(no_failure)));
7875
}
7976

8077
Maybe<int> EmitProcessExit(Environment* env) {

src/env-inl.h

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,18 @@ inline bool TickInfo::has_rejection_to_warn() const {
171171
return fields_[kHasRejectionToWarn] == 1;
172172
}
173173

174+
inline const AliasedInt32Array& ExitInfo::fields() {
175+
return fields_;
176+
}
177+
178+
inline bool ExitInfo::has_exit_code() const {
179+
return fields_[kHasExitCode] == 1;
180+
}
181+
182+
inline int32_t ExitInfo::exit_code() const {
183+
return fields_[kExitCode];
184+
}
185+
174186
inline Environment* Environment::GetCurrent(v8::Isolate* isolate) {
175187
if (UNLIKELY(!isolate->InContext())) return nullptr;
176188
v8::HandleScope handle_scope(isolate);
@@ -327,6 +339,14 @@ inline TickInfo* Environment::tick_info() {
327339
return &tick_info_;
328340
}
329341

342+
inline ExitInfo* Environment::exit_info() {
343+
return &exit_info_;
344+
}
345+
346+
inline int32_t Environment::maybe_exit_code(const int32_t default_code) const {
347+
return exit_info_.has_exit_code() ? exit_info_.exit_code() : default_code;
348+
}
349+
330350
inline uint64_t Environment::timer_base() const {
331351
return timer_base_;
332352
}
@@ -371,14 +391,6 @@ inline AliasedUint32Array& Environment::exiting() {
371391
return exiting_;
372392
}
373393

374-
inline void Environment::set_exit_code(const std::optional<int32_t> value) {
375-
exit_code_ = value;
376-
}
377-
378-
inline const std::optional<int32_t>& Environment::exit_code() const {
379-
return exit_code_;
380-
}
381-
382394
inline void Environment::set_abort_on_uncaught_exception(bool value) {
383395
options_->abort_on_uncaught_exception = value;
384396
}

src/env.cc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,7 @@ Environment::Environment(IsolateData* isolate_data,
640640
async_hooks_(isolate, MAYBE_FIELD_PTR(env_info, async_hooks)),
641641
immediate_info_(isolate, MAYBE_FIELD_PTR(env_info, immediate_info)),
642642
tick_info_(isolate, MAYBE_FIELD_PTR(env_info, tick_info)),
643+
exit_info_(isolate, MAYBE_FIELD_PTR(env_info, exit_info)),
643644
timer_base_(uv_now(isolate_data->event_loop())),
644645
exec_argv_(exec_args),
645646
argv_(args),
@@ -1507,6 +1508,29 @@ void AsyncHooks::FailWithCorruptedAsyncStack(double expected_async_id) {
15071508
ABORT_NO_BACKTRACE();
15081509
}
15091510

1511+
ExitInfo::SerializeInfo ExitInfo::Serialize(Local<Context> context,
1512+
SnapshotCreator* creator) {
1513+
return {fields_.Serialize(context, creator)};
1514+
}
1515+
1516+
void ExitInfo::Deserialize(Local<Context> context) {
1517+
fields_.Deserialize(context);
1518+
}
1519+
1520+
std::ostream& operator<<(std::ostream& output,
1521+
const ExitInfo::SerializeInfo& i) {
1522+
output << "{ " << i.fields << " }";
1523+
return output;
1524+
}
1525+
1526+
void ExitInfo::MemoryInfo(MemoryTracker* tracker) const {
1527+
tracker->TrackField("fields", fields_);
1528+
}
1529+
1530+
ExitInfo::ExitInfo(Isolate* isolate, const SerializeInfo* info)
1531+
: fields_(
1532+
isolate, kFieldsCount, info == nullptr ? nullptr : &(info->fields)) {}
1533+
15101534
void Environment::Exit(ExitCode exit_code) {
15111535
if (options()->trace_exit) {
15121536
HandleScope handle_scope(isolate());
@@ -1595,6 +1619,7 @@ EnvSerializeInfo Environment::Serialize(SnapshotCreator* creator) {
15951619
info.async_hooks = async_hooks_.Serialize(ctx, creator);
15961620
info.immediate_info = immediate_info_.Serialize(ctx, creator);
15971621
info.tick_info = tick_info_.Serialize(ctx, creator);
1622+
info.exit_info = exit_info_.Serialize(ctx, creator);
15981623
info.performance_state = performance_state_->Serialize(ctx, creator);
15991624
info.exiting = exiting_.Serialize(ctx, creator);
16001625
info.stream_base_state = stream_base_state_.Serialize(ctx, creator);
@@ -1637,6 +1662,7 @@ void Environment::DeserializeProperties(const EnvSerializeInfo* info) {
16371662
async_hooks_.Deserialize(ctx);
16381663
immediate_info_.Deserialize(ctx);
16391664
tick_info_.Deserialize(ctx);
1665+
exit_info_.Deserialize(ctx);
16401666
performance_state_->Deserialize(ctx);
16411667
exiting_.Deserialize(ctx);
16421668
stream_base_state_.Deserialize(ctx);
@@ -1833,6 +1859,7 @@ void Environment::MemoryInfo(MemoryTracker* tracker) const {
18331859
tracker->TrackField("async_hooks", async_hooks_);
18341860
tracker->TrackField("immediate_info", immediate_info_);
18351861
tracker->TrackField("tick_info", tick_info_);
1862+
tracker->TrackField("exit_info", exit_info_);
18361863
tracker->TrackField("principal_realm", principal_realm_);
18371864

18381865
// FIXME(joyeecheung): track other fields in Environment.

src/env.h

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
#include <functional>
5555
#include <list>
5656
#include <memory>
57-
#include <optional>
5857
#include <ostream>
5958
#include <set>
6059
#include <string>
@@ -460,6 +459,38 @@ class TickInfo : public MemoryRetainer {
460459
AliasedUint8Array fields_;
461460
};
462461

462+
class ExitInfo : public MemoryRetainer {
463+
public:
464+
inline const AliasedInt32Array& fields();
465+
inline bool has_exit_code() const;
466+
inline int32_t exit_code() const;
467+
468+
SET_MEMORY_INFO_NAME(ExitInfo)
469+
SET_SELF_SIZE(ExitInfo)
470+
void MemoryInfo(MemoryTracker* tracker) const override;
471+
472+
ExitInfo(const ExitInfo&) = delete;
473+
ExitInfo& operator=(const ExitInfo&) = delete;
474+
ExitInfo(ExitInfo&&) = delete;
475+
ExitInfo& operator=(ExitInfo&&) = delete;
476+
~ExitInfo() = default;
477+
478+
struct SerializeInfo {
479+
AliasedBufferIndex fields;
480+
};
481+
SerializeInfo Serialize(v8::Local<v8::Context> context,
482+
v8::SnapshotCreator* creator);
483+
void Deserialize(v8::Local<v8::Context> context);
484+
485+
enum Fields { kExitCode = 0, kHasExitCode, kFieldsCount };
486+
487+
private:
488+
friend class Environment; // So we can call the constructor.
489+
explicit ExitInfo(v8::Isolate* isolate, const SerializeInfo* info);
490+
491+
AliasedInt32Array fields_;
492+
};
493+
463494
class TrackingTraceStateObserver :
464495
public v8::TracingController::TraceStateObserver {
465496
public:
@@ -515,6 +546,7 @@ struct EnvSerializeInfo {
515546
TickInfo::SerializeInfo tick_info;
516547
ImmediateInfo::SerializeInfo immediate_info;
517548
performance::PerformanceState::SerializeInfo performance_state;
549+
ExitInfo::SerializeInfo exit_info;
518550
AliasedBufferIndex exiting;
519551
AliasedBufferIndex stream_base_state;
520552
AliasedBufferIndex should_abort_on_uncaught_toggle;
@@ -727,6 +759,8 @@ class Environment : public MemoryRetainer {
727759
inline AsyncHooks* async_hooks();
728760
inline ImmediateInfo* immediate_info();
729761
inline TickInfo* tick_info();
762+
inline ExitInfo* exit_info();
763+
inline int32_t maybe_exit_code(const int32_t default_code) const;
730764
inline uint64_t timer_base() const;
731765
inline std::shared_ptr<KVStore> env_vars();
732766
inline void set_env_vars(std::shared_ptr<KVStore> env_vars);
@@ -747,9 +781,6 @@ class Environment : public MemoryRetainer {
747781
inline void set_exiting(bool value);
748782
inline AliasedUint32Array& exiting();
749783

750-
inline void set_exit_code(const std::optional<int32_t> value);
751-
inline const std::optional<int32_t>& exit_code() const;
752-
753784
// This stores whether the --abort-on-uncaught-exception flag was passed
754785
// to Node.
755786
inline bool abort_on_uncaught_exception() const;
@@ -1058,6 +1089,7 @@ class Environment : public MemoryRetainer {
10581089
AsyncHooks async_hooks_;
10591090
ImmediateInfo immediate_info_;
10601091
TickInfo tick_info_;
1092+
ExitInfo exit_info_;
10611093
const uint64_t timer_base_;
10621094
std::shared_ptr<KVStore> env_vars_;
10631095
bool printed_error_ = false;
@@ -1105,8 +1137,8 @@ class Environment : public MemoryRetainer {
11051137
uint32_t script_id_counter_ = 0;
11061138
uint32_t function_id_counter_ = 0;
11071139

1140+
// TODO(daeyeon): merge into `exit_info_`
11081141
AliasedUint32Array exiting_;
1109-
std::optional<int32_t> exit_code_;
11101142

11111143
AliasedUint32Array should_abort_on_uncaught_toggle_;
11121144
int should_not_abort_scope_counter_ = 0;

src/env_properties.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
V(napi_type_tag, "node:napi:type_tag") \
2626
V(napi_wrapper, "node:napi:wrapper") \
2727
V(untransferable_object_private_symbol, "node:untransferableObject") \
28-
V(exiting_aliased_Uint32Array, "node:exiting_aliased_Uint32Array")
28+
V(exiting_aliased_Uint32Array, "node:exiting_aliased_Uint32Array") \
29+
V(exit_info_private_symbol, "node:exit_info_private_symbol")
2930

3031
// Symbols are per-isolate primitives but Environment proxies them
3132
// for the sake of convenience.
@@ -41,8 +42,7 @@
4142
V(owner_symbol, "owner_symbol") \
4243
V(onpskexchange_symbol, "onpskexchange") \
4344
V(resource_symbol, "resource_symbol") \
44-
V(trigger_async_id_symbol, "trigger_async_id_symbol") \
45-
V(exit_code_symbol, "exit_code_symbol")
45+
V(trigger_async_id_symbol, "trigger_async_id_symbol")
4646

4747
// Strings are per-isolate primitives but Environment proxies them
4848
// for the sake of convenience. Strings should be ASCII-only.

src/node_errors.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,8 +1152,8 @@ void TriggerUncaughtException(Isolate* isolate,
11521152

11531153
// If the global uncaught exception handler sets process.exitCode,
11541154
// exit with that code. Otherwise, exit with `ExitCode::kGenericUserError`.
1155-
env->Exit(static_cast<ExitCode>(env->exit_code().value_or(
1156-
static_cast<int32_t>(ExitCode::kGenericUserError))));
1155+
env->Exit(static_cast<ExitCode>(
1156+
env->maybe_exit_code(static_cast<int>(ExitCode::kGenericUserError))));
11571157
}
11581158

11591159
void TriggerUncaughtException(Isolate* isolate, const v8::TryCatch& try_catch) {

src/node_internals.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,8 @@ std::ostream& operator<<(std::ostream& output,
414414
std::ostream& operator<<(std::ostream& output,
415415
const AsyncHooks::SerializeInfo& d);
416416
std::ostream& operator<<(std::ostream& output, const SnapshotMetadata& d);
417+
std::ostream& operator<<(std::ostream& output,
418+
const ExitInfo::SerializeInfo& d);
417419

418420
namespace performance {
419421
std::ostream& operator<<(std::ostream& output,

0 commit comments

Comments
 (0)