Commit c6ce0b25 authored by Igor Sheludko's avatar Igor Sheludko Committed by V8 LUCI CQ

[ext-code-space] Use cage-friendly HeapObject::map() in serializer

This will allow making HeapObject::IsBlah() checks faster when external
code space is enabled.

Bug: v8:11880
Change-Id: Ibee4e19859c23f11316e3cfd7961f58d8e58240a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3301478
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78153}
parent f83320fd
......@@ -448,6 +448,8 @@ void Code::CopyRelocInfoToByteArray(ByteArray dest, const CodeDesc& desc) {
int Code::CodeSize() const { return SizeFor(raw_body_size()); }
DEF_GETTER(Code, Size, int) { return CodeSize(); }
CodeKind Code::kind() const {
STATIC_ASSERT(FIELD_SIZE(kFlagsOffset) == kInt32Size);
const uint32_t flags = RELAXED_READ_UINT32_FIELD(*this, kFlagsOffset);
......
......@@ -519,11 +519,14 @@ class Code : public HeapObject {
return RoundUp(kHeaderSize + body_size, kCodeAlignment);
}
inline int CodeSize() const;
// Hides HeapObject::Size(...) and redirects queries to CodeSize().
DECL_GETTER(Size, int)
DECL_CAST(Code)
// Dispatched behavior.
inline int CodeSize() const;
DECL_PRINTER(Code)
DECL_VERIFIER(Code)
......
......@@ -198,12 +198,12 @@ class HeapObject : public Object {
// content depends on FLAG_hash_seed. When the object is deserialized into
// a heap with a different hash seed, these objects need to adapt.
bool NeedsRehashing(InstanceType instance_type) const;
bool NeedsRehashing() const;
bool NeedsRehashing(PtrComprCageBase cage_base) const;
// Rehashing support is not implemented for all objects that need rehashing.
// With objects that need rehashing but cannot be rehashed, rehashing has to
// be disabled.
bool CanBeRehashed() const;
bool CanBeRehashed(PtrComprCageBase cage_base) const;
// Rehash the object based on the layout inferred from its map.
template <typename IsolateT>
......
......@@ -2316,12 +2316,18 @@ int HeapObject::SizeFromMap(Map map) const {
EmbedderDataArray::unchecked_cast(*this).length());
}
bool HeapObject::NeedsRehashing() const {
return NeedsRehashing(map().instance_type());
bool HeapObject::NeedsRehashing(PtrComprCageBase cage_base) const {
return NeedsRehashing(map(cage_base).instance_type());
}
bool HeapObject::NeedsRehashing(InstanceType instance_type) const {
DCHECK_EQ(instance_type, map().instance_type());
if (V8_EXTERNAL_CODE_SPACE_BOOL) {
// Use map() only when it's guaranteed that it's not a Code object.
DCHECK_IMPLIES(instance_type != CODE_TYPE,
instance_type == map().instance_type());
} else {
DCHECK_EQ(instance_type, map().instance_type());
}
switch (instance_type) {
case DESCRIPTOR_ARRAY_TYPE:
case STRONG_DESCRIPTOR_ARRAY_TYPE:
......@@ -2348,9 +2354,9 @@ bool HeapObject::NeedsRehashing(InstanceType instance_type) const {
}
}
bool HeapObject::CanBeRehashed() const {
DCHECK(NeedsRehashing());
switch (map().instance_type()) {
bool HeapObject::CanBeRehashed(PtrComprCageBase cage_base) const {
DCHECK(NeedsRehashing(cage_base));
switch (map(cage_base).instance_type()) {
case JS_MAP_TYPE:
case JS_SET_TYPE:
return true;
......@@ -2383,7 +2389,7 @@ bool HeapObject::CanBeRehashed() const {
template <typename IsolateT>
void HeapObject::RehashBasedOnMap(IsolateT* isolate) {
switch (map().instance_type()) {
switch (map(isolate).instance_type()) {
case HASH_TABLE_TYPE:
UNREACHABLE();
case NAME_DICTIONARY_TYPE:
......@@ -2442,7 +2448,7 @@ template void HeapObject::RehashBasedOnMap(Isolate* isolate);
template void HeapObject::RehashBasedOnMap(LocalIsolate* isolate);
bool HeapObject::IsExternal(Isolate* isolate) const {
return map().FindRootMap(isolate) == isolate->heap()->external_map();
return map(isolate).FindRootMap(isolate) == isolate->heap()->external_map();
}
void DescriptorArray::GeneralizeAllFields() {
......
......@@ -139,7 +139,7 @@ void CodeSerializer::SerializeObjectImpl(Handle<HeapObject> obj) {
if (SerializeReadOnlyObject(obj)) return;
CHECK(!obj->IsCode());
CHECK(!obj->IsCode(cage_base()));
ReadOnlyRoots roots(isolate());
if (ElideObject(*obj)) {
......@@ -218,7 +218,8 @@ void CodeSerializer::SerializeObjectImpl(Handle<HeapObject> obj) {
// There should be no references to the global object embedded.
CHECK(!obj->IsJSGlobalProxy() && !obj->IsJSGlobalObject());
// Embedded FixedArrays that need rehashing must support rehashing.
CHECK_IMPLIES(obj->NeedsRehashing(), obj->CanBeRehashed());
CHECK_IMPLIES(obj->NeedsRehashing(cage_base()),
obj->CanBeRehashed(cage_base()));
// We expect no instantiated function objects or contexts.
CHECK(!obj->IsJSFunction() && !obj->IsContext());
......
......@@ -225,7 +225,7 @@ bool ContextSerializer::SerializeJSObjectWithEmbedderFields(
int embedder_fields_count = js_obj->GetEmbedderFieldCount();
if (embedder_fields_count == 0) return false;
CHECK_GT(embedder_fields_count, 0);
DCHECK(!js_obj->NeedsRehashing());
DCHECK(!js_obj->NeedsRehashing(cage_base()));
DisallowGarbageCollection no_gc;
DisallowJavascriptExecution no_js(isolate());
......@@ -310,8 +310,8 @@ bool ContextSerializer::SerializeJSObjectWithEmbedderFields(
void ContextSerializer::CheckRehashability(HeapObject obj) {
if (!can_be_rehashed_) return;
if (!obj.NeedsRehashing()) return;
if (obj.CanBeRehashed()) return;
if (!obj.NeedsRehashing(cage_base())) return;
if (obj.CanBeRehashed(cage_base())) return;
can_be_rehashed_ = false;
}
......
......@@ -395,7 +395,7 @@ template <typename IsolateT>
void Deserializer<IsolateT>::PostProcessNewObject(Handle<Map> map,
Handle<HeapObject> obj,
SnapshotSpace space) {
DCHECK_EQ(*map, obj->map());
DCHECK_EQ(*map, obj->map(isolate_));
DisallowGarbageCollection no_gc;
InstanceType instance_type = map->instance_type();
......@@ -1261,7 +1261,7 @@ HeapObject Deserializer<IsolateT>::Allocate(AllocationType allocation, int size,
if (!previous_allocation_obj_.is_null()) {
// Make sure that the previous object is initialized sufficiently to
// be iterated over by the GC.
int object_size = previous_allocation_obj_->Size();
int object_size = previous_allocation_obj_->Size(isolate_);
DCHECK_LE(object_size, previous_allocation_size_);
}
#endif
......
......@@ -60,8 +60,8 @@ void RootsSerializer::VisitRootPointers(Root root, const char* description,
void RootsSerializer::CheckRehashability(HeapObject obj) {
if (!can_be_rehashed_) return;
if (!obj.NeedsRehashing()) return;
if (obj.CanBeRehashed()) return;
if (!obj.NeedsRehashing(cage_base())) return;
if (obj.CanBeRehashed(cage_base())) return;
can_be_rehashed_ = false;
}
......
......@@ -26,6 +26,9 @@ namespace internal {
Serializer::Serializer(Isolate* isolate, Snapshot::SerializerFlags flags)
: isolate_(isolate),
#if V8_COMPRESS_POINTERS
cage_base_(isolate),
#endif // V8_COMPRESS_POINTERS
hot_objects_(isolate->heap()),
reference_map_(isolate),
external_reference_encoder_(isolate),
......@@ -764,8 +767,8 @@ SnapshotSpace GetSnapshotSpace(Handle<HeapObject> object) {
} // namespace
void Serializer::ObjectSerializer::SerializeObject() {
int size = object_->Size();
Map map = object_->map();
Map map = object_->map(serializer_->cage_base());
int size = object_->SizeFromMap(map);
// Descriptor arrays have complex element weakness, that is dependent on the
// maps pointing to them. During deserialization, this can cause them to get
......
......@@ -183,6 +183,16 @@ class Serializer : public SerializerDeserializer {
Isolate* isolate() const { return isolate_; }
// The pointer compression cage base value used for decompression of all
// tagged values except references to Code objects.
PtrComprCageBase cage_base() const {
#if V8_COMPRESS_POINTERS
return cage_base_;
#else
return PtrComprCageBase{};
#endif // V8_COMPRESS_POINTERS
}
int TotalAllocationSize() const;
protected:
......@@ -353,6 +363,9 @@ class Serializer : public SerializerDeserializer {
DISALLOW_GARBAGE_COLLECTION(no_gc_)
Isolate* isolate_;
#if V8_COMPRESS_POINTERS
const PtrComprCageBase cage_base_;
#endif // V8_COMPRESS_POINTERS
HotObjectsList hot_objects_;
SerializerReferenceMap reference_map_;
ExternalReferenceEncoder external_reference_encoder_;
......
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