Commit 7437c690 authored by Shu-yu Guo's avatar Shu-yu Guo Committed by V8 LUCI CQ

[snapshot] Support shared string table with --stress-snapshot

Bug: v8:12584, v8:12007
Change-Id: Iac3c8b1c5935142742dddc7e12293fd7640c06a3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3419736
Auto-Submit: Shu-yu Guo <syg@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78804}
parent 3b233c9f
......@@ -74,7 +74,7 @@ void ReadOnlySerializer::SerializeReadOnlyRoots() {
ReadOnlyRoots(isolate()).Iterate(this);
if (reconstruct_read_only_object_cache_for_testing()) {
if (reconstruct_read_only_and_shared_object_caches_for_testing()) {
ReconstructReadOnlyObjectCacheForTesting();
}
}
......
......@@ -309,8 +309,9 @@ class Serializer : public SerializerDeserializer {
return (flags_ & Snapshot::kAllowActiveIsolateForTesting) != 0;
}
bool reconstruct_read_only_object_cache_for_testing() const {
return (flags_ & Snapshot::kReconstructReadOnlyObjectCacheForTesting) != 0;
bool reconstruct_read_only_and_shared_object_caches_for_testing() const {
return (flags_ &
Snapshot::kReconstructReadOnlyAndSharedObjectCachesForTesting) != 0;
}
private:
......
......@@ -65,10 +65,6 @@ void SharedHeapSerializer::FinalizeSerialization() {
Pad();
#ifdef DEBUG
// During snapshotting there is no shared heap.
CHECK(!isolate()->is_shared());
CHECK_NULL(isolate()->shared_isolate());
// Check that all serialized object are in shared heap and not RO. RO objects
// should be in the RO snapshot.
IdentityMap<int, base::DefaultAllocationPolicy>::IteratableScope it_scope(
......@@ -90,6 +86,20 @@ bool SharedHeapSerializer::SerializeUsingSharedHeapObjectCache(
SnapshotByteSink* sink, Handle<HeapObject> obj) {
if (!ShouldBeInSharedHeapObjectCache(*obj)) return false;
int cache_index = SerializeInObjectCache(obj);
// When testing deserialization of a snapshot from a live isolate, the shared
// object cache needs to be extended because the live isolate may have had new
// internalized strings that were not present in the startup snapshot to be
// serialized.
if (reconstruct_read_only_and_shared_object_caches_for_testing()) {
const size_t existing_cache_size =
isolate()->shared_heap_object_cache()->size();
DCHECK_LE(base::checked_cast<size_t>(cache_index), existing_cache_size);
if (base::checked_cast<size_t>(cache_index) == existing_cache_size) {
isolate()->shared_heap_object_cache()->push_back(*obj);
}
}
sink->Put(kSharedHeapObjectCache, "SharedHeapObjectCache");
sink->PutInt(cache_index, "shared_heap_object_cache_index");
return true;
......@@ -170,5 +180,18 @@ void SharedHeapSerializer::SerializeObjectImpl(Handle<HeapObject> obj) {
#endif
}
void SharedHeapSerializer::
ReconstructSharedHeapObjectCacheForTestingIfNeeded() {
if (!reconstruct_read_only_and_shared_object_caches_for_testing()) return;
std::vector<Object>* cache = isolate()->shared_heap_object_cache();
DCHECK_EQ(isolate()->shared_isolate()->shared_heap_object_cache(), cache);
for (size_t i = 0, size = cache->size(); i < size; i++) {
Handle<HeapObject> obj(HeapObject::cast(cache->at(i)), isolate());
int cache_index = SerializeInObjectCache(obj);
USE(cache_index);
DCHECK_EQ(cache_index, i);
}
}
} // namespace internal
} // namespace v8
......@@ -43,6 +43,8 @@ class V8_EXPORT_PRIVATE SharedHeapSerializer : public RootsSerializer {
bool SerializeUsingSharedHeapObjectCache(SnapshotByteSink* sink,
Handle<HeapObject> obj);
void ReconstructSharedHeapObjectCacheForTestingIfNeeded();
static bool CanBeInSharedOldSpace(HeapObject obj);
static bool ShouldBeInSharedHeapObjectCache(HeapObject obj);
......
......@@ -313,13 +313,17 @@ void Snapshot::SerializeDeserializeAndVerifyForTesting(
// Test serialization.
{
GlobalSafepointScope global_safepoint(isolate);
base::Optional<SafepointScope> shared_isolate_safepoint_scope;
if (Isolate* shared_isolate = isolate->shared_isolate()) {
shared_isolate_safepoint_scope.emplace(shared_isolate->heap());
}
DisallowGarbageCollection no_gc;
Snapshot::SerializerFlags flags(
Snapshot::kAllowUnknownExternalReferencesForTesting |
Snapshot::kAllowActiveIsolateForTesting |
(ReadOnlyHeap::IsReadOnlySpaceShared()
? Snapshot::kReconstructReadOnlyObjectCacheForTesting
((isolate->shared_isolate() || ReadOnlyHeap::IsReadOnlySpaceShared())
? Snapshot::kReconstructReadOnlyAndSharedObjectCachesForTesting
: 0));
serialized_data = Snapshot::Create(isolate, *default_context,
global_safepoint, no_gc, flags);
......@@ -337,6 +341,9 @@ void Snapshot::SerializeDeserializeAndVerifyForTesting(
new_isolate->set_snapshot_blob(&serialized_data);
new_isolate->set_array_buffer_allocator(
v8::ArrayBuffer::Allocator::NewDefaultAllocator());
if (Isolate* shared_isolate = isolate->shared_isolate()) {
new_isolate->set_shared_isolate(shared_isolate);
}
CHECK(Snapshot::Initialize(new_isolate));
HandleScope scope(new_isolate);
......@@ -376,6 +383,7 @@ v8::StartupData Snapshot::Create(
SharedHeapSerializer shared_heap_serializer(isolate, flags,
&read_only_serializer);
shared_heap_serializer.ReconstructSharedHeapObjectCacheForTestingIfNeeded();
StartupSerializer startup_serializer(isolate, flags, &read_only_serializer,
&shared_heap_serializer);
......
......@@ -39,15 +39,17 @@ class Snapshot : public AllStatic {
// after deserialization.
// If unset, we assert that these previously mentioned areas are empty.
kAllowActiveIsolateForTesting = 1 << 1,
// If set, the ReadOnlySerializer reconstructs the read-only object cache
// from the existing ReadOnlyHeap's read-only object cache so the same
// If set, the ReadOnlySerializer and the SharedHeapSerializer reconstructs
// their respective object caches from the existing ReadOnlyHeap's read-only
// object cache or the existing shared heap's object cache so the same
// mapping is used. This mode is used for testing deserialization of a
// snapshot from a live isolate that's using a shared
// ReadOnlyHeap. Otherwise during deserialization the indices will mismatch,
// causing deserialization crashes when e.g. types mismatch.
// If unset, the read-only object cache is populated as read-only objects
// are serialized.
kReconstructReadOnlyObjectCacheForTesting = 1 << 2,
// snapshot from a live isolate that's using a shared ReadOnlyHeap or is
// attached to a shared isolate. Otherwise during deserialization the
// indices will mismatch, causing deserialization crashes when e.g. types
// mismatch. If unset, the read-only object cache is populated as read-only
// objects are serialized, and the shared heap object cache is populated as
// shared heap objects are serialized.
kReconstructReadOnlyAndSharedObjectCachesForTesting = 1 << 2,
};
using SerializerFlags = base::Flags<SerializerFlag>;
V8_EXPORT_PRIVATE static constexpr SerializerFlags kDefaultSerializerFlags =
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment