[snapshot] Seal read-only space earlier
Seal read-only space before startup deserialization. This is necessary for fully isolating read-only space creation. Strings within read-only space are now eagerly rehashed. Bug: v8:7464 Change-Id: I8b91a6f6b31e03e69d80109b1ca30c675a495c36 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1511485 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Dan Elphick <delphick@chromium.org> Commit-Queue: Maciej Goszczycki <goszczycki@google.com> Cr-Commit-Position: refs/heads/master@{#60182}
This commit is contained in:
parent
e162eb4443
commit
c420b34fe1
@ -4696,7 +4696,6 @@ void Heap::NotifyDeserializationComplete() {
|
|||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
}
|
}
|
||||||
|
|
||||||
read_only_space()->MarkAsReadOnly();
|
|
||||||
deserialization_complete_ = true;
|
deserialization_complete_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,8 @@ void ReadOnlyHeap::MaybeDeserialize(Isolate* isolate,
|
|||||||
des->DeserializeInto(isolate);
|
des->DeserializeInto(isolate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ReadOnlyHeap::NotifySetupComplete() { read_only_space_->MarkAsReadOnly(); }
|
||||||
|
|
||||||
void ReadOnlyHeap::OnHeapTearDown() {
|
void ReadOnlyHeap::OnHeapTearDown() {
|
||||||
delete read_only_space_;
|
delete read_only_space_;
|
||||||
delete this;
|
delete this;
|
||||||
|
@ -24,6 +24,9 @@ class ReadOnlyHeap {
|
|||||||
// If necessary, deserialize read-only objects and set up read-only object
|
// If necessary, deserialize read-only objects and set up read-only object
|
||||||
// cache.
|
// cache.
|
||||||
void MaybeDeserialize(Isolate* isolate, ReadOnlyDeserializer* des);
|
void MaybeDeserialize(Isolate* isolate, ReadOnlyDeserializer* des);
|
||||||
|
// Notify read-only heap that all read-only space objects have been
|
||||||
|
// initialized and will not be written to.
|
||||||
|
void NotifySetupComplete();
|
||||||
// Frees ReadOnlySpace and itself when sharing is disabled. No-op otherwise.
|
// Frees ReadOnlySpace and itself when sharing is disabled. No-op otherwise.
|
||||||
// Read-only data should not be used within the current isolate after this is
|
// Read-only data should not be used within the current isolate after this is
|
||||||
// called.
|
// called.
|
||||||
|
@ -3408,7 +3408,10 @@ bool Isolate::Init(ReadOnlyDeserializer* read_only_deserializer,
|
|||||||
|
|
||||||
if (!create_heap_objects) {
|
if (!create_heap_objects) {
|
||||||
read_only_heap->MaybeDeserialize(this, read_only_deserializer);
|
read_only_heap->MaybeDeserialize(this, read_only_deserializer);
|
||||||
|
read_only_heap->NotifySetupComplete();
|
||||||
startup_deserializer->DeserializeInto(this);
|
startup_deserializer->DeserializeInto(this);
|
||||||
|
} else {
|
||||||
|
read_only_heap->NotifySetupComplete();
|
||||||
}
|
}
|
||||||
load_stub_cache_->Initialize();
|
load_stub_cache_->Initialize();
|
||||||
store_stub_cache_->Initialize();
|
store_stub_cache_->Initialize();
|
||||||
|
@ -2360,7 +2360,8 @@ bool HeapObject::CanBeRehashed() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HeapObject::RehashBasedOnMap(ReadOnlyRoots roots) {
|
void HeapObject::RehashBasedOnMap(Heap* heap) {
|
||||||
|
ReadOnlyRoots roots(heap);
|
||||||
switch (map()->instance_type()) {
|
switch (map()->instance_type()) {
|
||||||
case HASH_TABLE_TYPE:
|
case HASH_TABLE_TYPE:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -2396,8 +2397,14 @@ void HeapObject::RehashBasedOnMap(ReadOnlyRoots roots) {
|
|||||||
case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
|
case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
|
||||||
DCHECK_EQ(0, SmallOrderedNameDictionary::cast(*this)->NumberOfElements());
|
DCHECK_EQ(0, SmallOrderedNameDictionary::cast(*this)->NumberOfElements());
|
||||||
break;
|
break;
|
||||||
default:
|
case ONE_BYTE_INTERNALIZED_STRING_TYPE:
|
||||||
|
case INTERNALIZED_STRING_TYPE:
|
||||||
|
// Rare case, rehash read-only space strings before they are sealed.
|
||||||
|
DCHECK(heap->InReadOnlySpace(*this));
|
||||||
|
String::cast(*this)->Hash();
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
class Heap;
|
||||||
|
|
||||||
// HeapObject is the superclass for all classes describing heap allocated
|
// HeapObject is the superclass for all classes describing heap allocated
|
||||||
// objects.
|
// objects.
|
||||||
class HeapObject : public Object {
|
class HeapObject : public Object {
|
||||||
@ -173,7 +175,7 @@ class HeapObject : public Object {
|
|||||||
bool CanBeRehashed() const;
|
bool CanBeRehashed() const;
|
||||||
|
|
||||||
// Rehash the object based on the layout inferred from its map.
|
// Rehash the object based on the layout inferred from its map.
|
||||||
void RehashBasedOnMap(ReadOnlyRoots roots);
|
void RehashBasedOnMap(Heap* heap);
|
||||||
|
|
||||||
// Layout description.
|
// Layout description.
|
||||||
#define HEAP_OBJECT_FIELDS(V) \
|
#define HEAP_OBJECT_FIELDS(V) \
|
||||||
|
@ -64,8 +64,7 @@ void Deserializer::Initialize(Isolate* isolate) {
|
|||||||
|
|
||||||
void Deserializer::Rehash() {
|
void Deserializer::Rehash() {
|
||||||
DCHECK(can_rehash() || deserializing_user_code());
|
DCHECK(can_rehash() || deserializing_user_code());
|
||||||
for (HeapObject item : to_rehash_)
|
for (HeapObject item : to_rehash_) item->RehashBasedOnMap(isolate_->heap());
|
||||||
item->RehashBasedOnMap(ReadOnlyRoots(isolate()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Deserializer::~Deserializer() {
|
Deserializer::~Deserializer() {
|
||||||
@ -180,6 +179,11 @@ HeapObject Deserializer::PostProcessNewObject(HeapObject obj, int space) {
|
|||||||
// Uninitialize hash field as we need to recompute the hash.
|
// Uninitialize hash field as we need to recompute the hash.
|
||||||
String string = String::cast(obj);
|
String string = String::cast(obj);
|
||||||
string->set_hash_field(String::kEmptyHashField);
|
string->set_hash_field(String::kEmptyHashField);
|
||||||
|
// Rehash strings before read-only space is sealed. Strings outside
|
||||||
|
// read-only space are rehashed lazily. (e.g. when rehashing dictionaries)
|
||||||
|
if (space == RO_SPACE) {
|
||||||
|
to_rehash_.push_back(obj);
|
||||||
|
}
|
||||||
} else if (obj->NeedsRehashing()) {
|
} else if (obj->NeedsRehashing()) {
|
||||||
to_rehash_.push_back(obj);
|
to_rehash_.push_back(obj);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user