Skip to content

Commit

Permalink
deps: V8: cherry-pick d69c7937c99d
Browse files Browse the repository at this point in the history
Original commit message:

    [snapshot] Dont defer ByteArray when serializing

    JSTypedArray needs the base_pointer ByteArray immediately
    if it's on heap. JSTypedArray's base_pointer was initialized
    to Smi::uninitialized_deserialization_value at first when
    deserializing, and if base_pointer was deferred, we will
    mistakenly check JSTypedArray not on heap.

    Bug: v8:13149
    Change-Id: I104c83ff9a2017de1c8071a9e116baa602f6977d
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3813068
    Reviewed-by: Jakob Linke <jgruber@chromium.org>
    Commit-Queue: 王澳 <wangao.james@bytedance.com>
    Cr-Commit-Position: refs/heads/main@{#82254}

Refs: v8/v8@d69c793
PR-URL: #46425
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
  • Loading branch information
targos committed Nov 10, 2023
1 parent 1a499c5 commit 23069c3
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 2 deletions.
7 changes: 6 additions & 1 deletion deps/v8/src/snapshot/deserializer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,8 @@ void Deserializer<IsolateT>::PostProcessNewJSReceiver(
reinterpret_cast<uint8_t*>(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(
Expand Down Expand Up @@ -517,7 +519,10 @@ void Deserializer<IsolateT>::PostProcessNewObject(Handle<Map> map,
// to |ObjectDeserializer::CommitPostProcessedObjects()|.
new_allocation_sites_.push_back(Handle<AllocationSite>::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));
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion deps/v8/src/snapshot/serializer-deserializer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
40 changes: 40 additions & 0 deletions deps/v8/test/cctest/test-serialize.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<v8::Context> 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()
Expand Down

0 comments on commit 23069c3

Please sign in to comment.