diff --git a/graal-nodejs/deps/v8/src/snapshot/deserializer.cc b/graal-nodejs/deps/v8/src/snapshot/deserializer.cc index e1383ca2b7f..96e8427efa6 100644 --- a/graal-nodejs/deps/v8/src/snapshot/deserializer.cc +++ b/graal-nodejs/deps/v8/src/snapshot/deserializer.cc @@ -427,6 +427,8 @@ void Deserializer::PostProcessNewJSReceiver( reinterpret_cast(backing_store) + data_view.byte_offset()); } else if (InstanceTypeChecker::IsJSTypedArray(instance_type)) { auto typed_array = JSTypedArray::cast(raw_obj); + // Note: ByteArray objects must not be deferred s.t. they are + // available here for is_on_heap(). See also: CanBeDeferred. // Fixup typed array pointers. if (typed_array.is_on_heap()) { typed_array.AddExternalPointerCompensationForDeserialization( @@ -517,7 +519,10 @@ void Deserializer::PostProcessNewObject(Handle map, // to |ObjectDeserializer::CommitPostProcessedObjects()|. new_allocation_sites_.push_back(Handle::cast(obj)); } else { - DCHECK(CanBeDeferred(*obj)); + // We dont defer ByteArray because JSTypedArray needs the base_pointer + // ByteArray immediately if it's on heap. + DCHECK(CanBeDeferred(*obj) || + InstanceTypeChecker::IsByteArray(instance_type)); } } } diff --git a/graal-nodejs/deps/v8/src/snapshot/serializer-deserializer.cc b/graal-nodejs/deps/v8/src/snapshot/serializer-deserializer.cc index d32de12ec05..5d758cd8253 100644 --- a/graal-nodejs/deps/v8/src/snapshot/serializer-deserializer.cc +++ b/graal-nodejs/deps/v8/src/snapshot/serializer-deserializer.cc @@ -51,10 +51,13 @@ bool SerializerDeserializer::CanBeDeferred(HeapObject o) { // 3. JS objects with embedder fields cannot be deferred because the // serialize/deserialize callbacks need the back reference immediately to // identify the object. + // 4. ByteArray cannot be deferred as JSTypedArray needs the base_pointer + // ByteArray immediately if it's on heap. // TODO(leszeks): Could we defer string serialization if forward references // were resolved after object post processing? return !o.IsMap() && !o.IsInternalizedString() && - !(o.IsJSObject() && JSObject::cast(o).GetEmbedderFieldCount() > 0); + !(o.IsJSObject() && JSObject::cast(o).GetEmbedderFieldCount() > 0) && + !o.IsByteArray(); } void SerializerDeserializer::RestoreExternalReferenceRedirector( diff --git a/graal-nodejs/deps/v8/test/cctest/test-serialize.cc b/graal-nodejs/deps/v8/test/cctest/test-serialize.cc index 4252d4bd652..e7f1dd4760c 100644 --- a/graal-nodejs/deps/v8/test/cctest/test-serialize.cc +++ b/graal-nodejs/deps/v8/test/cctest/test-serialize.cc @@ -4990,6 +4990,46 @@ UNINITIALIZED_TEST(SnapshotCreatorAnonClassWithKeep) { delete[] blob.data; } +UNINITIALIZED_TEST(SnapshotCreatorDontDeferByteArrayForTypedArray) { + DisableAlwaysOpt(); + v8::StartupData blob; + { + v8::SnapshotCreator creator; + v8::Isolate* isolate = creator.GetIsolate(); + { + v8::HandleScope handle_scope(isolate); + + v8::Local context = v8::Context::New(isolate); + v8::Context::Scope context_scope(context); + CompileRun( + "const z = new Uint8Array(1);\n" + "class A { \n" + " static x() { \n" + " } \n" + "} \n" + "class B extends A {} \n" + "B.foo = ''; \n" + "class C extends B {} \n" + "class D extends C {} \n" + "class E extends B {} \n" + "function F() {} \n" + "Object.setPrototypeOf(F, D); \n"); + creator.SetDefaultContext(context); + } + + blob = + creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear); + CHECK(blob.raw_size > 0 && blob.data != nullptr); + } + { + SnapshotCreator creator(nullptr, &blob); + v8::Isolate* isolate = creator.GetIsolate(); + v8::HandleScope scope(isolate); + USE(v8::Context::New(isolate)); + } + delete[] blob.data; +} + class V8_NODISCARD DisableLazySourcePositionScope { public: DisableLazySourcePositionScope()