Skip to content

Commit d69c793

Browse files
jameslahmV8 LUCI CQ
authored andcommitted
[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 <[email protected]> Commit-Queue: 王澳 <[email protected]> Cr-Commit-Position: refs/heads/main@{#82254}
1 parent f2d98b2 commit d69c793

3 files changed

Lines changed: 50 additions & 2 deletions

File tree

src/snapshot/deserializer.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,8 @@ void Deserializer<IsolateT>::PostProcessNewJSReceiver(
380380
}
381381
} else if (InstanceTypeChecker::IsJSTypedArray(instance_type)) {
382382
auto typed_array = JSTypedArray::cast(raw_obj);
383+
// Note: ByteArray objects must not be deferred s.t. they are
384+
// available here for is_on_heap(). See also: CanBeDeferred.
383385
// Fixup typed array pointers.
384386
if (typed_array.is_on_heap()) {
385387
typed_array.AddExternalPointerCompensationForDeserialization(
@@ -468,7 +470,10 @@ void Deserializer<IsolateT>::PostProcessNewObject(Handle<Map> map,
468470
// to |ObjectDeserializer::CommitPostProcessedObjects()|.
469471
new_allocation_sites_.push_back(Handle<AllocationSite>::cast(obj));
470472
} else {
471-
DCHECK(CanBeDeferred(*obj));
473+
// We dont defer ByteArray because JSTypedArray needs the base_pointer
474+
// ByteArray immediately if it's on heap.
475+
DCHECK(CanBeDeferred(*obj) ||
476+
InstanceTypeChecker::IsByteArray(instance_type));
472477
}
473478
}
474479
}

src/snapshot/serializer-deserializer.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,13 @@ bool SerializerDeserializer::CanBeDeferred(HeapObject o) {
5050
// 3. JS objects with embedder fields cannot be deferred because the
5151
// serialize/deserialize callbacks need the back reference immediately to
5252
// identify the object.
53+
// 4. ByteArray cannot be deferred as JSTypedArray needs the base_pointer
54+
// ByteArray immediately if it's on heap.
5355
// TODO(leszeks): Could we defer string serialization if forward references
5456
// were resolved after object post processing?
5557
return !o.IsMap() && !o.IsInternalizedString() &&
56-
!(o.IsJSObject() && JSObject::cast(o).GetEmbedderFieldCount() > 0);
58+
!(o.IsJSObject() && JSObject::cast(o).GetEmbedderFieldCount() > 0) &&
59+
!o.IsByteArray();
5760
}
5861

5962
void SerializerDeserializer::RestoreExternalReferenceRedirector(

test/cctest/test-serialize.cc

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4969,6 +4969,46 @@ UNINITIALIZED_TEST(SnapshotCreatorAnonClassWithKeep) {
49694969
delete[] blob.data;
49704970
}
49714971

4972+
UNINITIALIZED_TEST(SnapshotCreatorDontDeferByteArrayForTypedArray) {
4973+
DisableAlwaysOpt();
4974+
v8::StartupData blob;
4975+
{
4976+
v8::SnapshotCreator creator;
4977+
v8::Isolate* isolate = creator.GetIsolate();
4978+
{
4979+
v8::HandleScope handle_scope(isolate);
4980+
4981+
v8::Local<v8::Context> context = v8::Context::New(isolate);
4982+
v8::Context::Scope context_scope(context);
4983+
CompileRun(
4984+
"const z = new Uint8Array(1);\n"
4985+
"class A { \n"
4986+
" static x() { \n"
4987+
" } \n"
4988+
"} \n"
4989+
"class B extends A {} \n"
4990+
"B.foo = ''; \n"
4991+
"class C extends B {} \n"
4992+
"class D extends C {} \n"
4993+
"class E extends B {} \n"
4994+
"function F() {} \n"
4995+
"Object.setPrototypeOf(F, D); \n");
4996+
creator.SetDefaultContext(context);
4997+
}
4998+
4999+
blob =
5000+
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
5001+
CHECK(blob.raw_size > 0 && blob.data != nullptr);
5002+
}
5003+
{
5004+
SnapshotCreator creator(nullptr, &blob);
5005+
v8::Isolate* isolate = creator.GetIsolate();
5006+
v8::HandleScope scope(isolate);
5007+
USE(v8::Context::New(isolate));
5008+
}
5009+
delete[] blob.data;
5010+
}
5011+
49725012
class V8_NODISCARD DisableLazySourcePositionScope {
49735013
public:
49745014
DisableLazySourcePositionScope()

0 commit comments

Comments
 (0)