## Node.js Patch Update to v24.10.0
This PR updates the Node.js patch to version 24.10.0.
The workflow automatically attempts to resolve patch conflicts using AI
when the OpenAI API key is available.
### AI Resolution Details
Processing section 1/1 for ./src/node_contextify.cc...
Found 1 reject files to process
Processing: ./src/node_contextify.cc.rej -> ./src/node_contextify.cc
Prompt for OpenAI API:
I have a Git patch that failed to apply. Here's the specific section
that needs to be fixed:
REJECTED PATCH HUNK:
```
@@ -1118,6 +1134,10 @@
.IsNothing())
return;
+ if (sourceless && produce_cached_data) {
+ V8::DisableCompilationForSourcelessUse();
+ }
+
TRACE_EVENT_END0(TRACING_CATEGORY_NODE2(vm, script), "ContextifyScript::New");
}
```
CURRENT FILE SECTION (lines 1113-1128):
```
return;
}
if (StoreCodeCacheResult(env,
self,
compile_options,
source,
produce_cached_data,
std::move(new_cached_data))
.IsNothing()) {
return;
}
if (self->Set(env->context(),
env->source_url_string(),
v8_script->GetSourceURL())
.IsNothing()) {
return;
```
Please apply the intended changes from the rejected hunk to this file
section. Return ONLY the corrected file section content, preserving the
exact line structure and formatting. Do not add explanations or markdown
formatting.
RESOLVED CONTENT for ./src/node_contextify.cc:
```
return;
}
if (StoreCodeCacheResult(env,
self,
compile_options,
source,
produce_cached_data,
std::move(new_cached_data))
.IsNothing()) {
return;
}
if (sourceless && produce_cached_data) {
V8::DisableCompilationForSourcelessUse();
}
if (self->Set(env->context(),
env->source_url_string(),
v8_script->GetSourceURL())
.IsNothing()) {
return;
```
✅ Successfully resolved ./src/node_contextify.cc
CONFLICTS_RESOLVED=1
TOTAL_CONFLICTS=1
HAS_UNRESOLVED=False
Resolution summary: 1/1 conflicts resolved
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Daniel Lando <daniel.sorridi@gmail.com>
864 lines
32 KiB
Diff
864 lines
32 KiB
Diff
diff --git node/common.gypi node/common.gypi
|
|
index 7727dfc4c6..3ab611dc48 100644
|
|
--- node/common.gypi
|
|
+++ node/common.gypi
|
|
@@ -192,7 +192,7 @@
|
|
['clang==1', {
|
|
'lto': ' -flto ', # Clang
|
|
}, {
|
|
- 'lto': ' -flto=4 -fuse-linker-plugin -ffat-lto-objects ', # GCC
|
|
+ 'lto': ' -flto=4 -ffat-lto-objects ', # GCC
|
|
}],
|
|
],
|
|
},
|
|
diff --git node/deps/ngtcp2/nghttp3/lib/nghttp3_ringbuf.c node/deps/ngtcp2/nghttp3/lib/nghttp3_ringbuf.c
|
|
index 7d3ab39bf8..67a48dee53 100644
|
|
--- node/deps/ngtcp2/nghttp3/lib/nghttp3_ringbuf.c
|
|
+++ node/deps/ngtcp2/nghttp3/lib/nghttp3_ringbuf.c
|
|
@@ -34,10 +34,7 @@
|
|
#include "nghttp3_macro.h"
|
|
|
|
static int ispow2(size_t n) {
|
|
-#if defined(_MSC_VER) && !defined(__clang__) && \
|
|
- (defined(_M_ARM) || (defined(_M_ARM64) && _MSC_VER < 1941))
|
|
- return n && !(n & (n - 1));
|
|
-#elif defined(WIN32)
|
|
+#if defined(WIN32)
|
|
return 1 == __popcnt((unsigned int)n);
|
|
#else /* !((defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || \
|
|
(defined(_M_ARM64) && _MSC_VER < 1941))) || defined(WIN32)) */
|
|
diff --git node/deps/ngtcp2/ngtcp2/lib/ngtcp2_ringbuf.c node/deps/ngtcp2/ngtcp2/lib/ngtcp2_ringbuf.c
|
|
index 353afca4d4..dea944aed5 100644
|
|
--- node/deps/ngtcp2/ngtcp2/lib/ngtcp2_ringbuf.c
|
|
+++ node/deps/ngtcp2/ngtcp2/lib/ngtcp2_ringbuf.c
|
|
@@ -33,10 +33,7 @@
|
|
|
|
#ifndef NDEBUG
|
|
static int ispow2(size_t n) {
|
|
-# if defined(_MSC_VER) && !defined(__clang__) && \
|
|
- (defined(_M_ARM) || (defined(_M_ARM64) && _MSC_VER < 1941))
|
|
- return n && !(n & (n - 1));
|
|
-# elif defined(WIN32)
|
|
+#if defined(WIN32)
|
|
return 1 == __popcnt((unsigned int)n);
|
|
# else /* !((defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || \
|
|
(defined(_M_ARM64) && _MSC_VER < 1941))) || defined(WIN32)) */
|
|
diff --git node/deps/v8/include/v8-initialization.h node/deps/v8/include/v8-initialization.h
|
|
index 46a21a02cb..fdb0edf42a 100644
|
|
--- node/deps/v8/include/v8-initialization.h
|
|
+++ node/deps/v8/include/v8-initialization.h
|
|
@@ -98,6 +98,10 @@ class V8_EXPORT V8 {
|
|
static void SetFlagsFromCommandLine(int* argc, char** argv,
|
|
bool remove_flags);
|
|
|
|
+ static void EnableCompilationForSourcelessUse();
|
|
+ static void DisableCompilationForSourcelessUse();
|
|
+ static void FixSourcelessScript(Isolate* v8_isolate, Local<UnboundScript> script);
|
|
+
|
|
/** Get the version string. */
|
|
static const char* GetVersion();
|
|
|
|
diff --git node/deps/v8/src/api/api.cc node/deps/v8/src/api/api.cc
|
|
index ba759168aa..f052c8b5a4 100644
|
|
--- node/deps/v8/src/api/api.cc
|
|
+++ node/deps/v8/src/api/api.cc
|
|
@@ -443,6 +443,28 @@ void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
|
|
HelpOptions(HelpOptions::kDontExit));
|
|
}
|
|
|
|
+bool save_lazy;
|
|
+bool save_predictable;
|
|
+
|
|
+void V8::EnableCompilationForSourcelessUse() {
|
|
+ save_lazy = i::v8_flags.lazy;
|
|
+ i::v8_flags.lazy = false;
|
|
+ save_predictable = i::v8_flags.predictable;
|
|
+ i::v8_flags.predictable = true;
|
|
+}
|
|
+
|
|
+void V8::DisableCompilationForSourcelessUse() {
|
|
+ i::v8_flags.lazy = save_lazy;
|
|
+ i::v8_flags.predictable = save_predictable;
|
|
+}
|
|
+
|
|
+void V8::FixSourcelessScript(Isolate* v8_isolate, Local<UnboundScript> unbound_script) {
|
|
+ auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
|
|
+ auto function_info = i::Cast<i::SharedFunctionInfo>(Utils::OpenHandle(*unbound_script));
|
|
+ i::Handle<i::Script> script(i::Cast<i::Script>(function_info->script()), isolate);
|
|
+ script->SetSource(isolate, script, isolate->factory()->empty_string());
|
|
+}
|
|
+
|
|
RegisteredExtension* RegisteredExtension::first_extension_ = nullptr;
|
|
|
|
RegisteredExtension::RegisteredExtension(std::unique_ptr<Extension> extension)
|
|
diff --git node/deps/v8/src/codegen/compiler.cc node/deps/v8/src/codegen/compiler.cc
|
|
index e31937f042..fa8c37072f 100644
|
|
--- node/deps/v8/src/codegen/compiler.cc
|
|
+++ node/deps/v8/src/codegen/compiler.cc
|
|
@@ -3945,7 +3945,7 @@ MaybeDirectHandle<SharedFunctionInfo> GetSharedFunctionInfoForScriptImpl(
|
|
maybe_script = lookup_result.script();
|
|
maybe_result = lookup_result.toplevel_sfi();
|
|
is_compiled_scope = lookup_result.is_compiled_scope();
|
|
- if (!maybe_result.is_null()) {
|
|
+ if (!maybe_result.is_null() && source->length()) {
|
|
compile_timer.set_hit_isolate_cache();
|
|
} else if (can_consume_code_cache) {
|
|
compile_timer.set_consuming_code_cache();
|
|
diff --git node/deps/v8/src/codegen/define-code-stub-assembler-macros.inc node/deps/v8/src/codegen/define-code-stub-assembler-macros.inc
|
|
index fb272f6afd..eb7c237530 100644
|
|
--- node/deps/v8/src/codegen/define-code-stub-assembler-macros.inc
|
|
+++ node/deps/v8/src/codegen/define-code-stub-assembler-macros.inc
|
|
@@ -21,7 +21,7 @@
|
|
// This is a check that always calls into the runtime if it aborts.
|
|
// This also exits silently when --hole-fuzzing is enabled.
|
|
#define CSA_HOLE_SECURITY_CHECK(csa, x) \
|
|
- (csa)->Check([&]() -> TNode<BoolT> { return x; }, #x, __FILE__, __LINE__)
|
|
+ (csa)->Check([&]() -> TNode<BoolT> { return x; }, #x, "placeholder", 1)
|
|
|
|
#ifdef DEBUG
|
|
// CSA_DCHECK_ARGS generates an
|
|
diff --git node/deps/v8/src/compiler/wasm-compiler.cc node/deps/v8/src/compiler/wasm-compiler.cc
|
|
index 87a194b5c2..06270d0c6e 100644
|
|
--- node/deps/v8/src/compiler/wasm-compiler.cc
|
|
+++ node/deps/v8/src/compiler/wasm-compiler.cc
|
|
@@ -1096,11 +1096,15 @@ wasm::WasmCompilationResult CompileWasmImportCallWrapper(
|
|
"wasm-to-js-%d-", static_cast<int>(kind));
|
|
PrintSignature(base::VectorOf(func_name, kMaxNameLen) + name_prefix_len, sig,
|
|
'-');
|
|
+ wasm::WrapperCompilationInfo info;
|
|
+ info.code_kind = CodeKind::WASM_TO_JS_FUNCTION;
|
|
+ info.import_kind = kind;
|
|
+ info.expected_arity = expected_arity;
|
|
+ info.suspend = suspend;
|
|
|
|
auto result = Pipeline::GenerateCodeForWasmNativeStubFromTurboshaft(
|
|
sig,
|
|
- wasm::WrapperCompilationInfo{CodeKind::WASM_TO_JS_FUNCTION, kind,
|
|
- expected_arity, suspend},
|
|
+ info,
|
|
func_name, WasmStubAssemblerOptions(), nullptr);
|
|
|
|
if (V8_UNLIKELY(v8_flags.trace_wasm_compilation_times)) {
|
|
diff --git node/deps/v8/src/heap/marking-visitor-inl.h node/deps/v8/src/heap/marking-visitor-inl.h
|
|
index c38e02da07..6d6d7b33ed 100644
|
|
--- node/deps/v8/src/heap/marking-visitor-inl.h
|
|
+++ node/deps/v8/src/heap/marking-visitor-inl.h
|
|
@@ -464,6 +464,13 @@ bool MarkingVisitorBase<ConcreteVisitor>::HasBytecodeArrayForFlushing(
|
|
template <typename ConcreteVisitor>
|
|
bool MarkingVisitorBase<ConcreteVisitor>::ShouldFlushCode(
|
|
Tagged<SharedFunctionInfo> sfi) const {
|
|
+ auto script_obj = sfi->script();
|
|
+ if (!IsUndefined(script_obj)) {
|
|
+ auto script = Cast<Script>(script_obj);
|
|
+ if (IsUndefined(script->source())) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
// This method is used both for flushing bytecode and baseline code.
|
|
// During last resort GCs and stress testing we consider all code old.
|
|
return IsOld(sfi) || V8_UNLIKELY(IsForceFlushingEnabled(code_flush_mode_));
|
|
diff --git node/deps/v8/src/objects/js-function.cc node/deps/v8/src/objects/js-function.cc
|
|
index 22df966c8f..8c1835e0b6 100644
|
|
--- node/deps/v8/src/objects/js-function.cc
|
|
+++ node/deps/v8/src/objects/js-function.cc
|
|
@@ -1454,6 +1454,9 @@ DirectHandle<String> JSFunction::ToString(DirectHandle<JSFunction> function) {
|
|
DirectHandle<Object> maybe_class_positions = JSReceiver::GetDataProperty(
|
|
isolate, function, isolate->factory()->class_positions_symbol());
|
|
if (IsClassPositions(*maybe_class_positions)) {
|
|
+ if (IsUndefined(Cast<String>(Cast<Script>(shared_info->script())->source()))) {
|
|
+ return isolate->factory()->NewStringFromAsciiChecked("class {}");
|
|
+ }
|
|
Tagged<ClassPositions> class_positions =
|
|
Cast<ClassPositions>(*maybe_class_positions);
|
|
int start_position = class_positions->start();
|
|
diff --git node/deps/v8/src/objects/objects.cc node/deps/v8/src/objects/objects.cc
|
|
index 14013579bd..1e9bc653e0 100644
|
|
--- node/deps/v8/src/objects/objects.cc
|
|
+++ node/deps/v8/src/objects/objects.cc
|
|
@@ -4347,7 +4347,11 @@ void Script::InitLineEndsInternal(IsolateT* isolate,
|
|
|
|
void Script::SetSource(Isolate* isolate, DirectHandle<Script> script,
|
|
DirectHandle<String> source) {
|
|
- script->set_source(*source);
|
|
+ if (source->length() > 0) {
|
|
+ script->set_source(*source);
|
|
+ } else {
|
|
+ script->set_source(*isolate->factory()->undefined_value());
|
|
+ }
|
|
if (isolate->NeedsSourcePositions()) {
|
|
InitLineEnds(isolate, script);
|
|
} else if (script->line_ends() ==
|
|
diff --git node/deps/v8/src/parsing/parsing.cc node/deps/v8/src/parsing/parsing.cc
|
|
index 31758fdfed..483192fc35 100644
|
|
--- node/deps/v8/src/parsing/parsing.cc
|
|
+++ node/deps/v8/src/parsing/parsing.cc
|
|
@@ -42,6 +42,7 @@ bool ParseProgram(ParseInfo* info, DirectHandle<Script> script,
|
|
DCHECK(info->flags().is_toplevel());
|
|
DCHECK_NULL(info->literal());
|
|
|
|
+ if (IsUndefined(Cast<String>(script->source()))) return false;
|
|
VMState<PARSER> state(isolate);
|
|
|
|
// Create a character stream for the parser.
|
|
@@ -75,6 +76,8 @@ bool ParseFunction(ParseInfo* info,
|
|
|
|
// Create a character stream for the parser.
|
|
DirectHandle<Script> script(Cast<Script>(shared_info->script()), isolate);
|
|
+ if (IsUndefined(Cast<String>(script->source()))) return false;
|
|
+
|
|
Handle<String> source(Cast<String>(script->source()), isolate);
|
|
uint32_t start_pos = shared_info->StartPosition();
|
|
uint32_t end_pos = shared_info->EndPosition();
|
|
diff --git node/deps/v8/src/snapshot/code-serializer.cc node/deps/v8/src/snapshot/code-serializer.cc
|
|
index 11ced93c08..1f4b534415 100644
|
|
--- node/deps/v8/src/snapshot/code-serializer.cc
|
|
+++ node/deps/v8/src/snapshot/code-serializer.cc
|
|
@@ -771,10 +771,6 @@ SerializedCodeSanityCheckResult SerializedCodeData::SanityCheck(
|
|
|
|
SerializedCodeSanityCheckResult SerializedCodeData::SanityCheckJustSource(
|
|
uint32_t expected_source_hash) const {
|
|
- uint32_t source_hash = GetHeaderValue(kSourceHashOffset);
|
|
- if (source_hash != expected_source_hash) {
|
|
- return SerializedCodeSanityCheckResult::kSourceMismatch;
|
|
- }
|
|
return SerializedCodeSanityCheckResult::kSuccess;
|
|
}
|
|
|
|
@@ -791,13 +787,12 @@ SerializedCodeSanityCheckResult SerializedCodeData::SanityCheckWithoutSource(
|
|
if (version_hash != Version::Hash()) {
|
|
return SerializedCodeSanityCheckResult::kVersionMismatch;
|
|
}
|
|
- uint32_t flags_hash = GetHeaderValue(kFlagHashOffset);
|
|
- if (flags_hash != FlagList::Hash()) {
|
|
- return SerializedCodeSanityCheckResult::kFlagsMismatch;
|
|
- }
|
|
uint32_t ro_snapshot_checksum =
|
|
GetHeaderValue(kReadOnlySnapshotChecksumOffset);
|
|
if (ro_snapshot_checksum != expected_ro_snapshot_checksum) {
|
|
+ // for debugging snapshot checkum issues
|
|
+ // PrintF("[pkg] ReadOnlySnapshotChecksum mismatch: code=%08x built=%08x\n",
|
|
+ // ro_snapshot_checksum, expected_ro_snapshot_checksum);
|
|
return SerializedCodeSanityCheckResult::kReadOnlySnapshotChecksumMismatch;
|
|
}
|
|
uint32_t payload_length = GetHeaderValue(kPayloadLengthOffset);
|
|
diff --git node/deps/v8/src/snapshot/read-only-serializer.cc node/deps/v8/src/snapshot/read-only-serializer.cc
|
|
index fa60b3d07e..a4f06a25c4 100644
|
|
--- node/deps/v8/src/snapshot/read-only-serializer.cc
|
|
+++ node/deps/v8/src/snapshot/read-only-serializer.cc
|
|
@@ -12,6 +12,9 @@
|
|
#include "src/objects/slots.h"
|
|
#include "src/snapshot/read-only-serializer-deserializer.h"
|
|
|
|
+// for debugging readonly heap serialization
|
|
+// #define PKG_TRACE_READONLY_HEAP 1
|
|
+
|
|
namespace v8 {
|
|
namespace internal {
|
|
|
|
@@ -160,6 +163,10 @@ ro::EncodedTagged Encode(Isolate* isolate, Tagged<HeapObject> o) {
|
|
uint32_t offset = static_cast<int>(chunk->Offset(o_address));
|
|
DCHECK(IsAligned(offset, kTaggedSize));
|
|
|
|
+ #ifdef PKG_TRACE_READONLY_HEAP
|
|
+ PrintF(" [PKGTRACE] encode tagged page_index=%d offset=%u offidx=%u\n",
|
|
+ index, offset, offset / kTaggedSize);
|
|
+ #endif
|
|
return ro::EncodedTagged(index, offset / kTaggedSize);
|
|
}
|
|
|
|
@@ -247,6 +254,11 @@ class EncodeRelocationsVisitor final : public ObjectVisitor {
|
|
|
|
// Encode:
|
|
ro::EncodedTagged encoded = Encode(isolate_, o.GetHeapObject());
|
|
+
|
|
+ #ifndef V8_COMPRESS_POINTERS
|
|
+ memset(segment_->contents.get() + slot_offset, 0, kTaggedSize);
|
|
+ #endif
|
|
+
|
|
memcpy(segment_->contents.get() + slot_offset, &encoded,
|
|
ro::EncodedTagged::kSize);
|
|
|
|
@@ -279,8 +291,18 @@ void ReadOnlySegmentForSerialization::EncodeTaggedSlots(Isolate* isolate) {
|
|
const Address segment_end = segment_start + segment_size;
|
|
ReadOnlyPageObjectIterator it(page, segment_start,
|
|
SkipFreeSpaceOrFiller::kNo);
|
|
+
|
|
+ #ifdef PKG_TRACE_READONLY_HEAP
|
|
+ uint32_t counter = 0;
|
|
+ #endif
|
|
+
|
|
for (Tagged<HeapObject> o = it.Next(); !o.is_null(); o = it.Next()) {
|
|
if (o.address() >= segment_end) break;
|
|
+ #ifdef PKG_TRACE_READONLY_HEAP
|
|
+ Tagged<Map> map = o->map(isolate);
|
|
+ PrintF(" [PKGTRACE] tag heapobj i=%d so=%zu s=%d t=%d\n",
|
|
+ counter++, o.address()-segment_start, o->Size(), map->instance_type());
|
|
+ #endif
|
|
VisitObject(isolate, o, &v);
|
|
}
|
|
}
|
|
@@ -307,7 +329,14 @@ class ReadOnlyHeapImageSerializer {
|
|
DCHECK_EQ(sink_->Position(), 0);
|
|
|
|
ReadOnlySpace* ro_space = isolate_->read_only_heap()->read_only_space();
|
|
-
|
|
+ #ifdef PKG_TRACE_READONLY_HEAP
|
|
+ #ifdef V8_COMPRESS_POINTERS
|
|
+ bool pce = true;
|
|
+ #else
|
|
+ bool pce = false;
|
|
+ #endif
|
|
+ PrintF("[PKGTRACE] BEGIN SERIALIZE READONLY ro_space=%p pce=%d\n", ro_space, pce);
|
|
+ #endif
|
|
// Allocate all pages first s.t. the deserializer can easily handle forward
|
|
// references (e.g.: an object on page i points at an object on page i+1).
|
|
for (const ReadOnlyPageMetadata* page : ro_space->pages()) {
|
|
@@ -321,6 +350,10 @@ class ReadOnlyHeapImageSerializer {
|
|
|
|
EmitReadOnlyRootsTable();
|
|
sink_->Put(Bytecode::kFinalizeReadOnlySpace, "space end");
|
|
+
|
|
+ #ifdef PKG_TRACE_READONLY_HEAP
|
|
+ PrintF("[PKGTRACE] END SERIALIZE READONLY\n");
|
|
+ #endif
|
|
}
|
|
|
|
uint32_t IndexOf(const ReadOnlyPageMetadata* page) {
|
|
@@ -339,6 +372,13 @@ class ReadOnlyHeapImageSerializer {
|
|
sink_->PutUint30(
|
|
static_cast<uint32_t>(page->HighWaterMark() - page->area_start()),
|
|
"area size in bytes");
|
|
+ #ifdef PKG_TRACE_READONLY_HEAP
|
|
+ PrintF("[PKGTRACE] emit allocate page area_ro_space_off=%zu area_start=%lx idx=%d size=%d \n",
|
|
+ ((uint8_t*)(page->area_start()))-((uint8_t*)(isolate_->read_only_heap()->read_only_space())),
|
|
+ page->area_start(),
|
|
+ IndexOf(page),
|
|
+ static_cast<uint32_t>(page->HighWaterMark() - page->area_start()));
|
|
+ #endif
|
|
if (V8_STATIC_ROOTS_BOOL) {
|
|
auto page_addr = page->ChunkAddress();
|
|
sink_->PutUint32(V8HeapCompressionScheme::CompressAny(page_addr),
|
|
@@ -350,6 +390,9 @@ class ReadOnlyHeapImageSerializer {
|
|
const std::vector<MemoryRegion>& unmapped_regions) {
|
|
Address pos = page->area_start();
|
|
|
|
+ #ifdef PKG_TRACE_READONLY_HEAP
|
|
+ PrintF("[PKGTRACE] serialize page addr=%lx\n");
|
|
+ #endif
|
|
// If this page contains unmapped regions split it into multiple segments.
|
|
for (auto r = unmapped_regions.begin(); r != unmapped_regions.end(); ++r) {
|
|
// Regions must be sorted and non-overlapping.
|
|
@@ -372,9 +415,17 @@ class ReadOnlyHeapImageSerializer {
|
|
ReadOnlySegmentForSerialization segment(isolate_, page, pos, segment_size,
|
|
&pre_processor_);
|
|
EmitSegment(&segment);
|
|
+ #ifdef PKG_TRACE_READONLY_HEAP
|
|
+ PrintF("[PKGTRACE] last segment\n");
|
|
+ #endif
|
|
}
|
|
|
|
void EmitSegment(const ReadOnlySegmentForSerialization* segment) {
|
|
+ #ifdef PKG_TRACE_READONLY_HEAP
|
|
+ PrintF(" [PKGTRACE] segment segment_start=%lx page_index=%d offset=%zu size=%zu tagged_slots=%zu\n",
|
|
+ segment->segment_start, IndexOf(segment->page), segment->segment_offset,
|
|
+ segment->segment_size, segment->tagged_slots.size_in_bytes());
|
|
+ #endif
|
|
sink_->Put(Bytecode::kSegment, "segment begin");
|
|
sink_->PutUint30(IndexOf(segment->page), "page index");
|
|
sink_->PutUint30(static_cast<uint32_t>(segment->segment_offset),
|
|
@@ -383,11 +434,29 @@ class ReadOnlyHeapImageSerializer {
|
|
"segment byte size");
|
|
sink_->PutRaw(segment->contents.get(),
|
|
static_cast<int>(segment->segment_size), "page");
|
|
+ #ifdef PKG_TRACE_READONLY_HEAP
|
|
+ PrintF(" [PKGTRACE] segment_contents: ");
|
|
+ const uint8_t* cdata = reinterpret_cast<const uint8_t*>(segment->contents.get());
|
|
+ for (size_t i = 0; i < segment->segment_size; i++) {
|
|
+ if (i%128==0) {PrintF("\n [PKGTRACE] ");}
|
|
+ PrintF("%02x", cdata[i]);
|
|
+ }
|
|
+ PrintF("\n");
|
|
+ #endif
|
|
if (!V8_STATIC_ROOTS_BOOL) {
|
|
sink_->Put(Bytecode::kRelocateSegment, "relocate segment");
|
|
sink_->PutRaw(segment->tagged_slots.data(),
|
|
static_cast<int>(segment->tagged_slots.size_in_bytes()),
|
|
"tagged_slots");
|
|
+ #ifdef PKG_TRACE_READONLY_HEAP
|
|
+ PrintF(" [PKGTRACE] tagged_slots: ");
|
|
+ const uint8_t* tdata = segment->tagged_slots.data();
|
|
+ for (size_t i = 0; i < segment->tagged_slots.size_in_bytes(); i++) {
|
|
+ if (i%128==0) {PrintF("\n [PKGTRACE] ");}
|
|
+ PrintF("%02x", tdata[i]);
|
|
+ }
|
|
+ PrintF("\n");
|
|
+ #endif
|
|
}
|
|
}
|
|
|
|
@@ -395,11 +464,20 @@ class ReadOnlyHeapImageSerializer {
|
|
sink_->Put(Bytecode::kReadOnlyRootsTable, "read only roots table");
|
|
if (!V8_STATIC_ROOTS_BOOL) {
|
|
ReadOnlyRoots roots(isolate_);
|
|
+ #ifdef PKG_TRACE_READONLY_HEAP
|
|
+ PrintF("[PKGTRACE] readonly roots %lu\n", ReadOnlyRoots::kEntriesCount);
|
|
+ #endif
|
|
for (size_t i = 0; i < ReadOnlyRoots::kEntriesCount; i++) {
|
|
RootIndex rudi = static_cast<RootIndex>(i);
|
|
Tagged<HeapObject> rudolf = Cast<HeapObject>(roots.object_at(rudi));
|
|
ro::EncodedTagged encoded = Encode(isolate_, rudolf);
|
|
sink_->PutUint32(encoded.ToUint32(), "read only roots entry");
|
|
+ #ifdef PKG_TRACE_READONLY_HEAP
|
|
+ Tagged<Map> map = rudolf->map(isolate_);
|
|
+ InstanceType instance_type = map->instance_type();
|
|
+ PrintF(" [PKGTRACE] readonly root i=%zu e=%x s=%d t=%d\n",
|
|
+ i, encoded.ToUint32(), rudolf->Size(), instance_type);
|
|
+ #endif
|
|
}
|
|
}
|
|
}
|
|
diff --git node/lib/child_process.js node/lib/child_process.js
|
|
index 17c6b69c11..59f5e241af 100644
|
|
--- node/lib/child_process.js
|
|
+++ node/lib/child_process.js
|
|
@@ -171,7 +171,7 @@ function fork(modulePath, args = [], options) {
|
|
throw new ERR_CHILD_PROCESS_IPC_REQUIRED('options.stdio');
|
|
}
|
|
|
|
- return spawn(options.execPath, args, options);
|
|
+ return module.exports.spawn(options.execPath, args, options);
|
|
}
|
|
|
|
function _forkChild(fd, serializationMode) {
|
|
diff --git node/lib/internal/bootstrap/pkg.js node/lib/internal/bootstrap/pkg.js
|
|
new file mode 100644
|
|
index 0000000000..a697294fdf
|
|
--- /dev/null
|
|
+++ node/lib/internal/bootstrap/pkg.js
|
|
@@ -0,0 +1,49 @@
|
|
+'use strict';
|
|
+
|
|
+const {
|
|
+ prepareWorkerThreadExecution,
|
|
+ prepareMainThreadExecution
|
|
+} = require('internal/process/pre_execution');
|
|
+
|
|
+if (internalBinding('worker').isMainThread) {
|
|
+ prepareMainThreadExecution(true);
|
|
+} else {
|
|
+ prepareWorkerThreadExecution();
|
|
+}
|
|
+
|
|
+(function () {
|
|
+ var __require__ = require;
|
|
+ var fs = __require__('fs');
|
|
+ var vm = __require__('vm');
|
|
+ function readPrelude (fd) {
|
|
+ var PAYLOAD_POSITION = '// PAYLOAD_POSITION //' | 0;
|
|
+ var PAYLOAD_SIZE = '// PAYLOAD_SIZE //' | 0;
|
|
+ var PRELUDE_POSITION = '// PRELUDE_POSITION //' | 0;
|
|
+ var PRELUDE_SIZE = '// PRELUDE_SIZE //' | 0;
|
|
+ if (!PRELUDE_POSITION) {
|
|
+ // no prelude - remove entrypoint from argv[1]
|
|
+ process.argv.splice(1, 1);
|
|
+ return { undoPatch: true };
|
|
+ }
|
|
+ var prelude = Buffer.alloc(PRELUDE_SIZE);
|
|
+ var read = fs.readSync(fd, prelude, 0, PRELUDE_SIZE, PRELUDE_POSITION);
|
|
+ if (read !== PRELUDE_SIZE) {
|
|
+ console.error('Pkg: Error reading from file.');
|
|
+ process.exit(1);
|
|
+ }
|
|
+ var s = new vm.Script(prelude, { filename: 'pkg/prelude/bootstrap.js' });
|
|
+ var fn = s.runInThisContext();
|
|
+ return fn(process, __require__,
|
|
+ console, fd, PAYLOAD_POSITION, PAYLOAD_SIZE);
|
|
+ }
|
|
+ (function () {
|
|
+ var fd = fs.openSync(process.execPath, 'r');
|
|
+ var result = readPrelude(fd);
|
|
+ if (result && result.undoPatch) {
|
|
+ var bindingFs = process.binding('fs');
|
|
+ fs.internalModuleStat = bindingFs.internalModuleStat;
|
|
+ fs.internalModuleReadJSON = bindingFs.internalModuleReadJSON;
|
|
+ fs.closeSync(fd);
|
|
+ }
|
|
+ }());
|
|
+}());
|
|
diff --git node/lib/internal/modules/cjs/loader.js node/lib/internal/modules/cjs/loader.js
|
|
index 8a28cd0e49..5534402a24 100644
|
|
--- node/lib/internal/modules/cjs/loader.js
|
|
+++ node/lib/internal/modules/cjs/loader.js
|
|
@@ -260,12 +260,15 @@ function stat(filename) {
|
|
// Guard against internal bugs where a non-string filename is passed in by mistake.
|
|
assert(typeof filename === 'string');
|
|
|
|
+ const origFilename = filename;
|
|
filename = path.toNamespacedPath(filename);
|
|
if (statCache !== null) {
|
|
const result = statCache.get(filename);
|
|
if (result !== undefined) { return result; }
|
|
}
|
|
- const result = internalFsBinding.internalModuleStat(filename);
|
|
+ const fs = require('fs');
|
|
+ const result = fs.existsSync(origFilename) ?
|
|
+ (fs.statSync(origFilename).isDirectory() ? 1 : 0) : -1;
|
|
if (statCache !== null && result >= 0) {
|
|
// Only set cache when `internalModuleStat(filename)` succeeds.
|
|
statCache.set(filename, result);
|
|
diff --git node/lib/internal/modules/package_json_reader.js node/lib/internal/modules/package_json_reader.js
|
|
index 43a131f57c..6fe7afd784 100644
|
|
--- node/lib/internal/modules/package_json_reader.js
|
|
+++ node/lib/internal/modules/package_json_reader.js
|
|
@@ -111,17 +111,20 @@ const requiresJSONParse = (value) => (value !== undefined && (value[0] === '[' |
|
|
* @returns {PackageConfig}
|
|
*/
|
|
function read(jsonPath, { base, specifier, isESM } = kEmptyObject) {
|
|
- // This function will be called by both CJS and ESM, so we need to make sure
|
|
- // non-null attributes are converted to strings.
|
|
- const parsed = modulesBinding.readPackageJSON(
|
|
- jsonPath,
|
|
- isESM,
|
|
- base == null ? undefined : `${base}`,
|
|
- specifier == null ? undefined : `${specifier}`,
|
|
- );
|
|
-
|
|
- const result = deserializePackageJSON(jsonPath, parsed);
|
|
-
|
|
+ const fs = require('fs');
|
|
+ let result;
|
|
+ if (fs.existsSync(jsonPath)) {
|
|
+ const json = JSONParse(fs.readFileSync(jsonPath, { encoding: "utf8" }).trim());
|
|
+ result = deserializePackageJSON(jsonPath, [
|
|
+ json['name'],
|
|
+ json['main'],
|
|
+ json['type'],
|
|
+ json['imports'],
|
|
+ json['exports'],
|
|
+ ]);
|
|
+ } else {
|
|
+ result = deserializePackageJSON(jsonPath, undefined);
|
|
+ }
|
|
return {
|
|
__proto__: null,
|
|
...result.data,
|
|
diff --git node/lib/internal/process/pre_execution.js node/lib/internal/process/pre_execution.js
|
|
index c7f86098bd..32eac7d2ee 100644
|
|
--- node/lib/internal/process/pre_execution.js
|
|
+++ node/lib/internal/process/pre_execution.js
|
|
@@ -42,7 +42,11 @@ const {
|
|
runDeserializeCallbacks,
|
|
} = require('internal/v8/startup_snapshot');
|
|
|
|
+let _alreadyPrepared = false;
|
|
+
|
|
function prepareMainThreadExecution(expandArgv1 = false, initializeModules = true) {
|
|
+ if (_alreadyPrepared === true) return;
|
|
+ _alreadyPrepared = true;
|
|
return prepareExecution({
|
|
expandArgv1,
|
|
initializeModules,
|
|
@@ -241,7 +245,8 @@ function patchProcessObject(expandArgv1) {
|
|
let mainEntry;
|
|
// If requested, update process.argv[1] to replace whatever the user provided with the resolved absolute file path of
|
|
// the entry point.
|
|
- if (expandArgv1 && process.argv[1] && process.argv[1][0] !== '-') {
|
|
+ if (expandArgv1 && process.argv[1] && process.argv[1][0] !== '-' &&
|
|
+ process.argv[1] !== 'PKG_DUMMY_ENTRYPOINT') {
|
|
// Expand process.argv[1] into a full path.
|
|
const path = require('path');
|
|
try {
|
|
@@ -678,6 +683,7 @@ function loadPreloadModules() {
|
|
// For user code, we preload modules if `-r` is passed
|
|
const preloadModules = getOptionValue('--require');
|
|
if (preloadModules && preloadModules.length > 0) {
|
|
+ assert(false, '--require is not supported');
|
|
const {
|
|
Module: {
|
|
_preloadModules,
|
|
diff --git node/lib/vm.js node/lib/vm.js
|
|
index ae71080620..b05638de75 100644
|
|
--- node/lib/vm.js
|
|
+++ node/lib/vm.js
|
|
@@ -98,6 +98,7 @@ class Script extends ContextifyScript {
|
|
produceCachedData = false,
|
|
importModuleDynamically,
|
|
[kParsingContext]: parsingContext,
|
|
+ sourceless = false,
|
|
} = options;
|
|
|
|
validateString(filename, 'options.filename');
|
|
@@ -121,7 +122,8 @@ class Script extends ContextifyScript {
|
|
cachedData,
|
|
produceCachedData,
|
|
parsingContext,
|
|
- hostDefinedOptionId);
|
|
+ hostDefinedOptionId,
|
|
+ sourceless);
|
|
} catch (e) {
|
|
throw e; /* node-do-not-add-exception-line */
|
|
}
|
|
diff --git node/src/inspector_agent.cc node/src/inspector_agent.cc
|
|
index f62eb36b57..8ccc42dbd4 100644
|
|
--- node/src/inspector_agent.cc
|
|
+++ node/src/inspector_agent.cc
|
|
@@ -833,11 +833,6 @@ bool Agent::Start(const std::string& path,
|
|
StartIoThreadAsyncCallback));
|
|
uv_unref(reinterpret_cast<uv_handle_t*>(&start_io_thread_async));
|
|
start_io_thread_async.data = this;
|
|
- if (parent_env_->should_start_debug_signal_handler()) {
|
|
- // Ignore failure, SIGUSR1 won't work, but that should not block node
|
|
- // start.
|
|
- StartDebugSignalHandler();
|
|
- }
|
|
|
|
parent_env_->AddCleanupHook([](void* data) {
|
|
Environment* env = static_cast<Environment*>(data);
|
|
diff --git node/src/node.cc node/src/node.cc
|
|
index c70bec82a2..4f807cd526 100644
|
|
--- node/src/node.cc
|
|
+++ node/src/node.cc
|
|
@@ -355,6 +355,8 @@ MaybeLocal<Value> StartExecution(Environment* env, StartExecutionCallback cb) {
|
|
return env->RunSnapshotDeserializeMain();
|
|
}
|
|
|
|
+ StartExecution(env, "internal/bootstrap/pkg");
|
|
+
|
|
if (env->worker_context() != nullptr) {
|
|
return StartExecution(env, "internal/main/worker_thread");
|
|
}
|
|
@@ -579,14 +581,6 @@ static void PlatformInit(ProcessInitializationFlags::Flags flags) {
|
|
}
|
|
|
|
if (!(flags & ProcessInitializationFlags::kNoDefaultSignalHandling)) {
|
|
-#if HAVE_INSPECTOR
|
|
- sigset_t sigmask;
|
|
- sigemptyset(&sigmask);
|
|
- sigaddset(&sigmask, SIGUSR1);
|
|
- const int err = pthread_sigmask(SIG_SETMASK, &sigmask, nullptr);
|
|
- CHECK_EQ(err, 0);
|
|
-#endif // HAVE_INSPECTOR
|
|
-
|
|
ResetSignalHandlers();
|
|
}
|
|
|
|
diff --git node/src/node_contextify.cc node/src/node_contextify.cc
|
|
index 3c234205e8..5d2152be2e 100644
|
|
--- node/src/node_contextify.cc
|
|
+++ node/src/node_contextify.cc
|
|
@@ -88,6 +88,7 @@ using v8::Symbol;
|
|
using v8::Uint32;
|
|
using v8::UnboundScript;
|
|
using v8::Value;
|
|
+using v8::V8;
|
|
|
|
// The vm module executes code in a sandboxed environment with a different
|
|
// global object than the rest of the code. This is achieved by applying
|
|
@@ -995,13 +996,13 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) {
|
|
Local<ArrayBufferView> cached_data_buf;
|
|
bool produce_cached_data = false;
|
|
Local<Context> parsing_context = context;
|
|
-
|
|
+ bool sourceless = false;
|
|
Local<Symbol> id_symbol;
|
|
if (argc > 2) {
|
|
// new ContextifyScript(code, filename, lineOffset, columnOffset,
|
|
// cachedData, produceCachedData, parsingContext,
|
|
- // hostDefinedOptionId)
|
|
- CHECK_EQ(argc, 8);
|
|
+ // hostDefinedOptionId, sourceless)
|
|
+ CHECK_GE(argc, 8);
|
|
CHECK(args[2]->IsNumber());
|
|
line_offset = args[2].As<Int32>()->Value();
|
|
CHECK(args[3]->IsNumber());
|
|
@@ -1022,6 +1023,11 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) {
|
|
}
|
|
CHECK(args[7]->IsSymbol());
|
|
id_symbol = args[7].As<Symbol>();
|
|
+
|
|
+ if (argc > 8) {
|
|
+ CHECK(args[8]->IsBoolean());
|
|
+ sourceless = args[8]->IsTrue();
|
|
+ }
|
|
}
|
|
|
|
ContextifyScript* contextify_script = New(env, args.This());
|
|
@@ -1068,6 +1074,10 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) {
|
|
ShouldNotAbortOnUncaughtScope no_abort_scope(env);
|
|
Context::Scope scope(parsing_context);
|
|
|
|
+ if (sourceless && produce_cached_data) {
|
|
+ V8::EnableCompilationForSourcelessUse();
|
|
+ }
|
|
+
|
|
MaybeLocal<UnboundScript> maybe_v8_script =
|
|
ScriptCompiler::CompileUnboundScript(isolate, &source, compile_options);
|
|
|
|
@@ -1082,6 +1092,12 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) {
|
|
return;
|
|
}
|
|
|
|
+ if (sourceless && compile_options == ScriptCompiler::kConsumeCodeCache) {
|
|
+ if (!source.GetCachedData()->rejected) {
|
|
+ V8::FixSourcelessScript(env->isolate(), v8_script);
|
|
+ }
|
|
+ }
|
|
+
|
|
contextify_script->set_unbound_script(v8_script);
|
|
|
|
std::unique_ptr<ScriptCompiler::CachedData> new_cached_data;
|
|
@@ -1094,7 +1110,7 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) {
|
|
if (contextify_script->object()
|
|
->SetPrivate(context, env->host_defined_option_symbol(), id_symbol)
|
|
.IsNothing()) {
|
|
- return;
|
|
+return;
|
|
}
|
|
if (StoreCodeCacheResult(env,
|
|
self,
|
|
@@ -1105,6 +1121,9 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) {
|
|
.IsNothing()) {
|
|
return;
|
|
}
|
|
+ if (sourceless && produce_cached_data) {
|
|
+ V8::DisableCompilationForSourcelessUse();
|
|
+ }
|
|
if (self->Set(env->context(),
|
|
env->source_url_string(),
|
|
v8_script->GetSourceURL())
|
|
diff --git node/src/node_main.cc node/src/node_main.cc
|
|
index 3295121b87..bfe838b8c1 100644
|
|
--- node/src/node_main.cc
|
|
+++ node/src/node_main.cc
|
|
@@ -22,6 +22,8 @@
|
|
#include "node.h"
|
|
#include <cstdio>
|
|
|
|
+int reorder(int argc, char** argv);
|
|
+
|
|
#ifdef _WIN32
|
|
#include <windows.h>
|
|
#include <VersionHelpers.h>
|
|
@@ -88,12 +90,95 @@ int wmain(int argc, wchar_t* wargv[]) {
|
|
}
|
|
argv[argc] = nullptr;
|
|
// Now that conversion is done, we can finally start.
|
|
- return node::Start(argc, argv);
|
|
+ return reorder(argc, argv);
|
|
}
|
|
#else
|
|
// UNIX
|
|
|
|
int main(int argc, char* argv[]) {
|
|
+ return reorder(argc, argv);
|
|
+}
|
|
+#endif
|
|
+
|
|
+#include <string.h>
|
|
+
|
|
+int strlen2 (char* s) {
|
|
+ int len = 0;
|
|
+ while (*s) {
|
|
+ len += 1;
|
|
+ s += 1;
|
|
+ }
|
|
+ return len;
|
|
+}
|
|
+
|
|
+bool should_set_dummy() {
|
|
+#ifdef _WIN32
|
|
+ #define MAX_ENV_LENGTH 32767
|
|
+ wchar_t execpath_env[MAX_ENV_LENGTH];
|
|
+ DWORD result = GetEnvironmentVariableW(L"PKG_EXECPATH", execpath_env, MAX_ENV_LENGTH);
|
|
+ if (result == 0 && GetLastError() != ERROR_SUCCESS) return true;
|
|
+ return wcscmp(execpath_env, L"PKG_INVOKE_NODEJS") != 0;
|
|
+#else
|
|
+ const char* execpath_env = getenv("PKG_EXECPATH");
|
|
+ if (!execpath_env) return true;
|
|
+ return strcmp(execpath_env, "PKG_INVOKE_NODEJS") != 0;
|
|
+#endif
|
|
+}
|
|
+
|
|
+// for uv_setup_args
|
|
+int adjacent(int argc, char** argv) {
|
|
+ size_t size = 0;
|
|
+ for (int i = 0; i < argc; i++) {
|
|
+ size += strlen(argv[i]) + 1;
|
|
+ }
|
|
+ char* args = new char[size];
|
|
+ size_t pos = 0;
|
|
+ for (int i = 0; i < argc; i++) {
|
|
+ memcpy(&args[pos], argv[i], strlen(argv[i]) + 1);
|
|
+ argv[i] = &args[pos];
|
|
+ pos += strlen(argv[i]) + 1;
|
|
+ }
|
|
return node::Start(argc, argv);
|
|
}
|
|
+
|
|
+volatile char* BAKERY = (volatile char*) "\0// BAKERY // BAKERY " \
|
|
+ "// BAKERY // BAKERY // BAKERY // BAKERY // BAKERY // BAKERY " \
|
|
+ "// BAKERY // BAKERY // BAKERY // BAKERY // BAKERY // BAKERY " \
|
|
+ "// BAKERY // BAKERY // BAKERY // BAKERY // BAKERY // BAKERY ";
|
|
+
|
|
+#ifdef __clang__
|
|
+__attribute__((optnone))
|
|
+#elif defined(__GNUC__)
|
|
+__attribute__((optimize(0)))
|
|
#endif
|
|
+
|
|
+int load_baked(char** nargv) {
|
|
+ int c = 1;
|
|
+
|
|
+ char* bakery = (char*) BAKERY;
|
|
+ while (true) {
|
|
+ size_t width = strlen2(bakery);
|
|
+ if (width == 0) break;
|
|
+ nargv[c++] = bakery;
|
|
+ bakery += width + 1;
|
|
+ }
|
|
+
|
|
+ return c;
|
|
+}
|
|
+
|
|
+int reorder(int argc, char** argv) {
|
|
+ char** nargv = new char*[argc + 64];
|
|
+
|
|
+ nargv[0] = argv[0];
|
|
+ int c = load_baked(nargv);
|
|
+
|
|
+ if (should_set_dummy()) {
|
|
+ nargv[c++] = (char*) "PKG_DUMMY_ENTRYPOINT";
|
|
+ }
|
|
+
|
|
+ for (int i = 1; i < argc; i++) {
|
|
+ nargv[c++] = argv[i];
|
|
+ }
|
|
+
|
|
+ return adjacent(c, nargv);
|
|
+}
|
|
diff --git node/src/node_options.cc node/src/node_options.cc
|
|
index 2a3ab5e73c..00b61629f2 100644
|
|
--- node/src/node_options.cc
|
|
+++ node/src/node_options.cc
|
|
@@ -422,6 +422,7 @@ void Parse(
|
|
// TODO(addaleax): Make that unnecessary.
|
|
|
|
DebugOptionsParser::DebugOptionsParser() {
|
|
+ return;
|
|
AddOption("--inspect-port",
|
|
"set host:port for inspector",
|
|
&DebugOptions::host_port,
|
|
diff --git node/tools/icu/icu-generic.gyp node/tools/icu/icu-generic.gyp
|
|
index f007c65232..002a00a6ae 100644
|
|
--- node/tools/icu/icu-generic.gyp
|
|
+++ node/tools/icu/icu-generic.gyp
|
|
@@ -52,7 +52,7 @@
|
|
'conditions': [
|
|
[ 'os_posix == 1 and OS != "mac" and OS != "ios"', {
|
|
'cflags': [ '-Wno-deprecated-declarations', '-Wno-strict-aliasing' ],
|
|
- 'cflags_cc': [ '-frtti' ],
|
|
+ 'cflags_cc': [ '-frtti', '-fno-lto' ],
|
|
'cflags_cc!': [ '-fno-rtti' ],
|
|
}],
|
|
[ 'OS == "mac" or OS == "ios"', {
|