Commit 8d695a44 authored by Maciej Goszczycki's avatar Maciej Goszczycki Committed by Commit Bot

[snapshot][roheap] Abstract away read-only object cache storage

The read_only_object_cache call cannot return a vector when it is backed
by the embedded heap, so this adds a few methods to abstract this away.

ExtendReadOnlyObjectCache will eventually have a check to reject adding
objects to the embedded read-only object cache.

Prior to this change the read-only object cache would only be extended
conditionally if needed. Since it started out empty it was always
extended, so this removes this logic.

Bug: v8:7464
Change-Id: I5b172f629ac48be5cbb8f78b03a0a213ebd570e9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1619745Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarDan Elphick <delphick@chromium.org>
Commit-Queue: Maciej Goszczycki <goszczycki@google.com>
Cr-Commit-Position: refs/heads/master@{#61661}
parent e6bef62c
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "src/heap/spaces.h" #include "src/heap/spaces.h"
#include "src/objects-inl.h" #include "src/objects-inl.h"
#include "src/objects/heap-object-inl.h" #include "src/objects/heap-object-inl.h"
#include "src/objects/smi.h"
#include "src/snapshot/read-only-deserializer.h" #include "src/snapshot/read-only-deserializer.h"
namespace v8 { namespace v8 {
...@@ -119,6 +120,20 @@ ReadOnlyRoots ReadOnlyHeap::GetReadOnlyRoots(HeapObject object) { ...@@ -119,6 +120,20 @@ ReadOnlyRoots ReadOnlyHeap::GetReadOnlyRoots(HeapObject object) {
return ReadOnlyRoots(GetHeapFromWritableObject(object)); return ReadOnlyRoots(GetHeapFromWritableObject(object));
} }
Object* ReadOnlyHeap::ExtendReadOnlyObjectCache() {
read_only_object_cache_.push_back(Smi::kZero);
return &read_only_object_cache_.back();
}
Object ReadOnlyHeap::cached_read_only_object(size_t i) const {
DCHECK_LE(i, read_only_object_cache_.size());
return read_only_object_cache_[i];
}
bool ReadOnlyHeap::read_only_object_cache_is_initialized() const {
return read_only_object_cache_.size() > 0;
}
ReadOnlyHeapIterator::ReadOnlyHeapIterator(ReadOnlyHeap* ro_heap) ReadOnlyHeapIterator::ReadOnlyHeapIterator(ReadOnlyHeap* ro_heap)
: ReadOnlyHeapIterator(ro_heap->read_only_space()) {} : ReadOnlyHeapIterator(ro_heap->read_only_space()) {}
......
...@@ -50,9 +50,13 @@ class ReadOnlyHeap final { ...@@ -50,9 +50,13 @@ class ReadOnlyHeap final {
// heap to be re-created on next set up. // heap to be re-created on next set up.
V8_EXPORT_PRIVATE static void ClearSharedHeapForTest(); V8_EXPORT_PRIVATE static void ClearSharedHeapForTest();
std::vector<Object>* read_only_object_cache() { // Extends the read-only object cache with new zero smi and returns a
return &read_only_object_cache_; // reference to it.
} Object* ExtendReadOnlyObjectCache();
// 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;
ReadOnlySpace* read_only_space() const { return read_only_space_; } ReadOnlySpace* read_only_space() const { return read_only_space_; }
private: private:
......
...@@ -832,7 +832,7 @@ TSlot Deserializer::ReadDataCase(Isolate* isolate, TSlot current, ...@@ -832,7 +832,7 @@ TSlot Deserializer::ReadDataCase(Isolate* isolate, TSlot current,
} else if (bytecode == kReadOnlyObjectCache) { } else if (bytecode == kReadOnlyObjectCache) {
int cache_index = source_.GetInt(); int cache_index = source_.GetInt();
heap_object = HeapObject::cast( heap_object = HeapObject::cast(
isolate->heap()->read_only_heap()->read_only_object_cache()->at( isolate->heap()->read_only_heap()->cached_read_only_object(
cache_index)); cache_index));
DCHECK(!Heap::InYoungGeneration(heap_object)); DCHECK(!Heap::InYoungGeneration(heap_object));
emit_write_barrier = false; emit_write_barrier = false;
......
...@@ -21,12 +21,15 @@ void ReadOnlyDeserializer::DeserializeInto(Isolate* isolate) { ...@@ -21,12 +21,15 @@ void ReadOnlyDeserializer::DeserializeInto(Isolate* isolate) {
V8::FatalProcessOutOfMemory(isolate, "ReadOnlyDeserializer"); V8::FatalProcessOutOfMemory(isolate, "ReadOnlyDeserializer");
} }
ReadOnlyHeap* ro_heap = isolate->heap()->read_only_heap();
// No active threads. // No active threads.
DCHECK_NULL(isolate->thread_manager()->FirstThreadStateInUse()); DCHECK_NULL(isolate->thread_manager()->FirstThreadStateInUse());
// No active handles. // No active handles.
DCHECK(isolate->handle_scope_implementer()->blocks()->empty()); DCHECK(isolate->handle_scope_implementer()->blocks()->empty());
// Read-only object cache is not yet populated.
DCHECK(!ro_heap->read_only_object_cache_is_initialized());
// Partial snapshot cache is not yet populated. // Partial snapshot cache is not yet populated.
DCHECK(isolate->heap()->read_only_heap()->read_only_object_cache()->empty());
DCHECK(isolate->partial_snapshot_cache()->empty()); DCHECK(isolate->partial_snapshot_cache()->empty());
// Builtins are not yet created. // Builtins are not yet created.
DCHECK(!isolate->builtins()->is_initialized()); DCHECK(!isolate->builtins()->is_initialized());
...@@ -36,22 +39,16 @@ void ReadOnlyDeserializer::DeserializeInto(Isolate* isolate) { ...@@ -36,22 +39,16 @@ void ReadOnlyDeserializer::DeserializeInto(Isolate* isolate) {
ReadOnlyRoots roots(isolate); ReadOnlyRoots roots(isolate);
roots.Iterate(this); roots.Iterate(this);
isolate->heap() ro_heap->read_only_space()->RepairFreeListsAfterDeserialization();
->read_only_heap()
->read_only_space()
->RepairFreeListsAfterDeserialization();
// Deserialize the Read-only Object Cache. // Deserialize the Read-only Object Cache.
std::vector<Object>* cache =
isolate->heap()->read_only_heap()->read_only_object_cache();
for (size_t i = 0;; ++i) { for (size_t i = 0;; ++i) {
// Extend the array ready to get a value when deserializing. Object* object = ro_heap->ExtendReadOnlyObjectCache();
if (cache->size() <= i) cache->push_back(Smi::kZero);
// During deserialization, the visitor populates the read-only object // During deserialization, the visitor populates the read-only object
// cache and eventually terminates the cache with undefined. // cache and eventually terminates the cache with undefined.
VisitRootPointer(Root::kReadOnlyObjectCache, nullptr, VisitRootPointer(Root::kReadOnlyObjectCache, nullptr,
FullObjectSlot(&cache->at(i))); FullObjectSlot(object));
if (cache->at(i)->IsUndefined(roots)) break; if (object->IsUndefined(roots)) break;
} }
DeserializeDeferredObjects(); DeserializeDeferredObjects();
} }
......
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