[snapshot] Add serializer option to reconstruct the RO object cache
This option is used for --stress-snapshot when sharing the RO heap. The RO heap is shared, so deserializing non-startup snapshots need to ensure they use the same RO object cache mapping as the startup snapshot. Cq-Include-Trybots: luci.v8.try:v8_linux64_gc_stress_custom_snapshot_dbg_ng Bug: v8:11750 Change-Id: Ia2baa24d5b7d494ef5b7ff3c9cbcee846881182e Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2897945 Reviewed-by: Dan Elphick <delphick@chromium.org> Commit-Queue: Shu-yu Guo <syg@chromium.org> Cr-Commit-Position: refs/heads/master@{#74574}
This commit is contained in:
parent
34dc2607db
commit
aebe382ab7
@ -249,6 +249,10 @@ bool ReadOnlyHeap::read_only_object_cache_is_initialized() const {
|
||||
return read_only_object_cache_.size() > 0;
|
||||
}
|
||||
|
||||
size_t ReadOnlyHeap::read_only_object_cache_size() const {
|
||||
return read_only_object_cache_.size();
|
||||
}
|
||||
|
||||
ReadOnlyHeapObjectIterator::ReadOnlyHeapObjectIterator(ReadOnlyHeap* ro_heap)
|
||||
: ReadOnlyHeapObjectIterator(ro_heap->read_only_space()) {}
|
||||
|
||||
|
@ -81,6 +81,7 @@ class ReadOnlyHeap {
|
||||
// Returns a read-only cache entry at a particular index.
|
||||
Object cached_read_only_object(size_t i) const;
|
||||
bool read_only_object_cache_is_initialized() const;
|
||||
size_t read_only_object_cache_size() const;
|
||||
|
||||
ReadOnlySpace* read_only_space() const { return read_only_space_; }
|
||||
|
||||
|
@ -74,6 +74,10 @@ void ReadOnlySerializer::SerializeReadOnlyRoots() {
|
||||
isolate()->handle_scope_implementer()->blocks()->empty());
|
||||
|
||||
ReadOnlyRoots(isolate()).Iterate(this);
|
||||
|
||||
if (reconstruct_read_only_object_cache_for_testing()) {
|
||||
ReconstructReadOnlyObjectCacheForTesting();
|
||||
}
|
||||
}
|
||||
|
||||
void ReadOnlySerializer::FinalizeSerialization() {
|
||||
@ -129,5 +133,18 @@ bool ReadOnlySerializer::SerializeUsingReadOnlyObjectCache(
|
||||
return true;
|
||||
}
|
||||
|
||||
void ReadOnlySerializer::ReconstructReadOnlyObjectCacheForTesting() {
|
||||
ReadOnlyHeap* ro_heap = isolate()->read_only_heap();
|
||||
DCHECK(ro_heap->read_only_object_cache_is_initialized());
|
||||
for (size_t i = 0, size = ro_heap->read_only_object_cache_size(); i < size;
|
||||
i++) {
|
||||
Handle<HeapObject> obj(
|
||||
HeapObject::cast(ro_heap->cached_read_only_object(i)), isolate());
|
||||
int cache_index = SerializeInObjectCache(obj);
|
||||
USE(cache_index);
|
||||
DCHECK_EQ(cache_index, i);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -37,6 +37,8 @@ class V8_EXPORT_PRIVATE ReadOnlySerializer : public RootsSerializer {
|
||||
Handle<HeapObject> obj);
|
||||
|
||||
private:
|
||||
void ReconstructReadOnlyObjectCacheForTesting();
|
||||
|
||||
void SerializeObjectImpl(Handle<HeapObject> o) override;
|
||||
bool MustBeDeferred(HeapObject object) override;
|
||||
|
||||
|
@ -298,6 +298,10 @@ class Serializer : public SerializerDeserializer {
|
||||
return (flags_ & Snapshot::kAllowActiveIsolateForTesting) != 0;
|
||||
}
|
||||
|
||||
bool reconstruct_read_only_object_cache_for_testing() const {
|
||||
return (flags_ & Snapshot::kReconstructReadOnlyObjectCacheForTesting) != 0;
|
||||
}
|
||||
|
||||
private:
|
||||
// A circular queue of hot objects. This is added to in the same order as in
|
||||
// Deserializer::HotObjectsList, but this stores the objects as an array of
|
||||
|
@ -286,7 +286,10 @@ void Snapshot::SerializeDeserializeAndVerifyForTesting(
|
||||
|
||||
Snapshot::SerializerFlags flags(
|
||||
Snapshot::kAllowUnknownExternalReferencesForTesting |
|
||||
Snapshot::kAllowActiveIsolateForTesting);
|
||||
Snapshot::kAllowActiveIsolateForTesting |
|
||||
(ReadOnlyHeap::IsReadOnlySpaceShared()
|
||||
? Snapshot::kReconstructReadOnlyObjectCacheForTesting
|
||||
: 0));
|
||||
serialized_data = Snapshot::Create(isolate, *default_context, no_gc, flags);
|
||||
auto_delete_serialized_data.reset(serialized_data.data);
|
||||
}
|
||||
|
@ -36,6 +36,15 @@ 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
|
||||
// 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,
|
||||
};
|
||||
using SerializerFlags = base::Flags<SerializerFlag>;
|
||||
V8_EXPORT_PRIVATE static constexpr SerializerFlags kDefaultSerializerFlags =
|
||||
|
Loading…
Reference in New Issue
Block a user