Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bootstrap: include bootstrapped Environment in builtin snapshot #32984

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions node.gyp
Expand Up @@ -594,6 +594,7 @@
'src/node_dir.cc',
'src/node_env_var.cc',
'src/node_errors.cc',
'src/node_external_reference.cc',
'src/node_file.cc',
'src/node_http_parser.cc',
'src/node_http2.cc',
Expand Down Expand Up @@ -688,6 +689,7 @@
'src/node_contextify.h',
'src/node_dir.h',
'src/node_errors.h',
'src/node_external_reference.h',
'src/node_file.h',
'src/node_file-inl.h',
'src/node_http_common.h',
Expand Down
66 changes: 57 additions & 9 deletions src/aliased_buffer.h
Expand Up @@ -4,11 +4,14 @@
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

#include <cinttypes>
#include <iostream>
#include "util-inl.h"
#include "v8.h"

namespace node {

typedef size_t AliasedBufferInfo;

/**
* Do not use this class directly when creating instances of it - use the
* Aliased*Array defined at the end of this file instead.
Expand All @@ -32,9 +35,15 @@ template <class NativeT,
typename = std::enable_if_t<std::is_scalar<NativeT>::value>>
class AliasedBufferBase {
public:
AliasedBufferBase(v8::Isolate* isolate, const size_t count)
: isolate_(isolate), count_(count), byte_offset_(0) {
AliasedBufferBase(v8::Isolate* isolate,
const size_t count,
const AliasedBufferInfo* info = nullptr)
: isolate_(isolate), count_(count), byte_offset_(0), info_(info) {
CHECK_GT(count, 0);
if (info != nullptr) {
// Will be deserialized later.
return;
}
const v8::HandleScope handle_scope(isolate_);
const size_t size_in_bytes =
MultiplyWithOverflowCheck(sizeof(NativeT), count);
Expand Down Expand Up @@ -62,10 +71,17 @@ class AliasedBufferBase {
v8::Isolate* isolate,
const size_t byte_offset,
const size_t count,
const AliasedBufferBase<uint8_t, v8::Uint8Array>& backing_buffer)
: isolate_(isolate), count_(count), byte_offset_(byte_offset) {
const AliasedBufferBase<uint8_t, v8::Uint8Array>& backing_buffer,
const AliasedBufferInfo* info = nullptr)
: isolate_(isolate),
count_(count),
byte_offset_(byte_offset),
info_(info) {
if (info != nullptr) {
// Will be deserialized later.
return;
}
const v8::HandleScope handle_scope(isolate_);

v8::Local<v8::ArrayBuffer> ab = backing_buffer.GetArrayBuffer();

// validate that the byte_offset is aligned with sizeof(NativeT)
Expand All @@ -86,10 +102,33 @@ class AliasedBufferBase {
count_(that.count_),
byte_offset_(that.byte_offset_),
buffer_(that.buffer_) {
DCHECK_NULL(info_);
js_array_ = v8::Global<V8T>(that.isolate_, that.GetJSArray());
}

AliasedBufferInfo Serialize(v8::Local<v8::Context> context,
v8::SnapshotCreator* creator) {
DCHECK_NULL(info_);
return creator->AddData(context, GetJSArray());
}

inline void Deserialize(v8::Local<v8::Context> context) {
DCHECK_NOT_NULL(info_);
v8::Local<V8T> arr =
context->GetDataFromSnapshotOnce<V8T>(*info_).ToLocalChecked();
// These may not hold true for AliasedBuffers that have grown, so should
// be removed when we expand the snapshot support.
DCHECK_EQ(count_, arr->Length());
DCHECK_EQ(byte_offset_, arr->ByteOffset());
uint8_t* raw =
static_cast<uint8_t*>(arr->Buffer()->GetBackingStore()->Data());
buffer_ = reinterpret_cast<NativeT*>(raw + byte_offset_);
js_array_.Reset(isolate_, arr);
info_ = nullptr;
}

AliasedBufferBase& operator=(AliasedBufferBase&& that) noexcept {
DCHECK_NULL(info_);
this->~AliasedBufferBase();
isolate_ = that.isolate_;
count_ = that.count_;
Expand Down Expand Up @@ -155,6 +194,7 @@ class AliasedBufferBase {
* Get the underlying v8 TypedArray overlayed on top of the native buffer
*/
v8::Local<V8T> GetJSArray() const {
DCHECK_NULL(info_);
return js_array_.Get(isolate_);
}

Expand All @@ -171,6 +211,7 @@ class AliasedBufferBase {
* through the GetValue/SetValue/operator[] methods
*/
inline const NativeT* GetNativeBuffer() const {
DCHECK_NULL(info_);
return buffer_;
}

Expand All @@ -186,13 +227,15 @@ class AliasedBufferBase {
*/
inline void SetValue(const size_t index, NativeT value) {
DCHECK_LT(index, count_);
DCHECK_NULL(info_);
buffer_[index] = value;
}

/**
* Get value at position index
*/
inline const NativeT GetValue(const size_t index) const {
DCHECK_NULL(info_);
DCHECK_LT(index, count_);
return buffer_[index];
}
Expand All @@ -201,6 +244,7 @@ class AliasedBufferBase {
* Effectively, a synonym for GetValue/SetValue
*/
Reference operator[](size_t index) {
DCHECK_NULL(info_);
return Reference(this, index);
}

Expand All @@ -216,6 +260,7 @@ class AliasedBufferBase {
// Should only be used on an owning array, not one created as a sub array of
// an owning `AliasedBufferBase`.
void reserve(size_t new_capacity) {
DCHECK_NULL(info_);
DCHECK_GE(new_capacity, count_);
DCHECK_EQ(byte_offset_, 0);
const v8::HandleScope handle_scope(isolate_);
Expand Down Expand Up @@ -244,11 +289,14 @@ class AliasedBufferBase {
}

private:
v8::Isolate* isolate_;
size_t count_;
size_t byte_offset_;
NativeT* buffer_;
v8::Isolate* isolate_ = nullptr;
size_t count_ = 0;
size_t byte_offset_ = 0;
NativeT* buffer_ = nullptr;
v8::Global<V8T> js_array_;

// Deserialize data
const AliasedBufferInfo* info_ = nullptr;
};

typedef AliasedBufferBase<int32_t, v8::Int32Array> AliasedInt32Array;
Expand Down
11 changes: 1 addition & 10 deletions src/api/environment.cc
Expand Up @@ -350,16 +350,7 @@ Environment* CreateEnvironment(
// TODO(addaleax): This is a much better place for parsing per-Environment
// options than the global parse call.
Environment* env = new Environment(
isolate_data,
context,
args,
exec_args,
flags,
thread_id);
if (flags & EnvironmentFlags::kOwnsProcessState) {
env->set_abort_on_uncaught_exception(false);
}

isolate_data, context, args, exec_args, nullptr, flags, thread_id);
#if HAVE_INSPECTOR
if (inspector_parent_handle) {
env->InitializeInspector(
Expand Down
3 changes: 2 additions & 1 deletion src/debug_utils.h
Expand Up @@ -46,7 +46,8 @@ void FWrite(FILE* file, const std::string& str);
V(INSPECTOR_PROFILER) \
V(CODE_CACHE) \
V(NGTCP2_DEBUG) \
V(WASI)
V(WASI) \
V(MKSNAPSHOT)

enum class DebugCategory {
#define V(name) name,
Expand Down
29 changes: 0 additions & 29 deletions src/env-inl.h
Expand Up @@ -70,29 +70,6 @@ inline v8::Local<v8::String> IsolateData::async_wrap_provider(int index) const {
return async_wrap_providers_[index].Get(isolate_);
}

inline AsyncHooks::AsyncHooks()
: async_ids_stack_(env()->isolate(), 16 * 2),
fields_(env()->isolate(), kFieldsCount),
async_id_fields_(env()->isolate(), kUidFieldsCount) {
clear_async_id_stack();

// Always perform async_hooks checks, not just when async_hooks is enabled.
// TODO(AndreasMadsen): Consider removing this for LTS releases.
// See discussion in https://github.com/nodejs/node/pull/15454
// When removing this, do it by reverting the commit. Otherwise the test
// and flag changes won't be included.
fields_[kCheck] = 1;

// kDefaultTriggerAsyncId should be -1, this indicates that there is no
// specified default value and it should fallback to the executionAsyncId.
// 0 is not used as the magic value, because that indicates a missing context
// which is different from a default context.
async_id_fields_[AsyncHooks::kDefaultTriggerAsyncId] = -1;

// kAsyncIdCounter should start at 1 because that'll be the id the execution
// context during bootstrap (code that runs before entering uv_run()).
async_id_fields_[AsyncHooks::kAsyncIdCounter] = 1;
}
inline AliasedUint32Array& AsyncHooks::fields() {
return fields_;
}
Expand Down Expand Up @@ -277,9 +254,6 @@ inline void Environment::PopAsyncCallbackScope() {
async_callback_scope_depth_--;
}

inline ImmediateInfo::ImmediateInfo(v8::Isolate* isolate)
: fields_(isolate, kFieldsCount) {}

inline AliasedUint32Array& ImmediateInfo::fields() {
return fields_;
}
Expand All @@ -304,9 +278,6 @@ inline void ImmediateInfo::ref_count_dec(uint32_t decrement) {
fields_[kRefCount] -= decrement;
}

inline TickInfo::TickInfo(v8::Isolate* isolate)
: fields_(isolate, kFieldsCount) {}

inline AliasedUint8Array& TickInfo::fields() {
return fields_;
}
Expand Down