Commit d430856d authored by Jakob Gruber's avatar Jakob Gruber Committed by V8 LUCI CQ

[compiler] Audit all remaining SerializeFoo methods

.. and explicitly mark behavior through tags/naming conventions:

 // This method is never called when concurrent inlining is enabled.
 void SerializeFoo(NotConcurrentInliningTag);

 // This method is thread-safe and may be called at any time.
 void CacheBar();

It turns out that all our remaining SerializeFoo methods are already
either of the former or latter category and thus do not block removal
of the serialization phase for concurrent inlining.

Bug: v8:7790
Change-Id: If8f3bc2e407bc2824f83bfcd1f520f3b14dc58ec
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3026709
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75804}
parent 607f1fdb
......@@ -451,8 +451,11 @@ PropertyAccessInfo AccessInfoFactory::ComputeDataFieldAccessInfo(
if (!map_ref.has_value()) return Invalid();
ZoneVector<CompilationDependency const*> unrecorded_dependencies(zone());
if (!map_ref->TrySerializeOwnDescriptor(descriptor)) {
return Invalid();
if (!broker()->is_concurrent_inlining()) {
if (!map_ref->TrySerializeOwnDescriptor(
descriptor, NotConcurrentInliningTag{broker()})) {
return Invalid();
}
}
if (details_representation.IsSmi()) {
field_type = Type::SignedSmall();
......@@ -857,7 +860,11 @@ PropertyAccessInfo AccessInfoFactory::ComputePropertyAccessInfo(
// Walk up the prototype chain.
base::Optional<MapRef> map_ref = TryMakeRef(broker(), map);
if (!map_ref.has_value()) return Invalid();
if (!map_ref->TrySerializePrototype()) return Invalid();
if (!broker()->is_concurrent_inlining()) {
if (!map_ref->TrySerializePrototype(NotConcurrentInliningTag{broker()})) {
return Invalid();
}
}
// Acquire synchronously the map's prototype's map to guarantee that every
// time we use it, we use the same Map.
......@@ -1112,16 +1119,22 @@ PropertyAccessInfo AccessInfoFactory::LookupTransition(
ZoneVector<CompilationDependency const*> unrecorded_dependencies(zone());
if (details_representation.IsSmi()) {
field_type = Type::SignedSmall();
if (!transition_map_ref->TrySerializeOwnDescriptor(number)) {
return Invalid();
if (!broker()->is_concurrent_inlining()) {
if (!transition_map_ref->TrySerializeOwnDescriptor(
number, NotConcurrentInliningTag{broker()})) {
return Invalid();
}
}
unrecorded_dependencies.push_back(
dependencies()->FieldRepresentationDependencyOffTheRecord(
*transition_map_ref, number));
} else if (details_representation.IsDouble()) {
field_type = type_cache_->kFloat64;
if (!transition_map_ref->TrySerializeOwnDescriptor(number)) {
return Invalid();
if (!broker()->is_concurrent_inlining()) {
if (!transition_map_ref->TrySerializeOwnDescriptor(
number, NotConcurrentInliningTag{broker()})) {
return Invalid();
}
}
unrecorded_dependencies.push_back(
dependencies()->FieldRepresentationDependencyOffTheRecord(
......@@ -1135,8 +1148,11 @@ PropertyAccessInfo AccessInfoFactory::LookupTransition(
// Store is not safe if the field type was cleared.
return Invalid();
}
if (!transition_map_ref->TrySerializeOwnDescriptor(number)) {
return Invalid();
if (!broker()->is_concurrent_inlining()) {
if (!transition_map_ref->TrySerializeOwnDescriptor(
number, NotConcurrentInliningTag{broker()})) {
return Invalid();
}
}
unrecorded_dependencies.push_back(
dependencies()->FieldRepresentationDependencyOffTheRecord(
......@@ -1156,7 +1172,10 @@ PropertyAccessInfo AccessInfoFactory::LookupTransition(
}
unrecorded_dependencies.push_back(
dependencies()->TransitionDependencyOffTheRecord(*transition_map_ref));
transition_map_ref->SerializeBackPointer(); // For BuildPropertyStore.
if (!broker()->is_concurrent_inlining()) {
transition_map_ref->SerializeBackPointer(
NotConcurrentInliningTag{broker()}); // For BuildPropertyStore.
}
// Transitioning stores *may* store to const fields. The resulting
// DataConstant access infos can be distinguished from later, i.e. redundant,
// stores to the same constant field by the presence of a transition map.
......
......@@ -732,7 +732,7 @@ void CompilationDependencies::DependOnGlobalProperty(
}
bool CompilationDependencies::DependOnProtector(const PropertyCellRef& cell) {
cell.SerializeAsProtector();
cell.CacheAsProtector();
if (cell.value().AsSmi() != Protectors::kProtectorValid) return false;
RecordDependency(zone_->New<ProtectorDependency>(cell));
return true;
......
......@@ -87,6 +87,10 @@ bool IsReadOnlyHeapObjectForCompiler(HeapObject object) {
} // namespace
NotConcurrentInliningTag::NotConcurrentInliningTag(JSHeapBroker* broker) {
CHECK(!broker->is_concurrent_inlining());
}
class ObjectData : public ZoneObject {
public:
ObjectData(JSHeapBroker* broker, ObjectData** storage, Handle<Object> object,
......@@ -180,7 +184,7 @@ class PropertyCellData : public HeapObjectData {
Handle<PropertyCell> object,
ObjectDataKind kind = ObjectDataKind::kSerializedHeapObject);
bool Serialize(JSHeapBroker* broker);
bool Cache(JSHeapBroker* broker);
PropertyDetails property_details() const {
CHECK(serialized());
......@@ -199,10 +203,6 @@ class PropertyCellData : public HeapObjectData {
bool serialized() const { return value_ != nullptr; }
};
// TODO(mslekova): Once we have real-world usage data, we might want to
// reimplement this as sorted vector instead, to reduce the memory overhead.
typedef ZoneMap<ObjectData*, HolderLookupResult> KnownReceiversMap;
class FunctionTemplateInfoData : public HeapObjectData {
public:
FunctionTemplateInfoData(JSHeapBroker* broker, ObjectData** storage,
......@@ -260,7 +260,7 @@ PropertyCellData::PropertyCellData(JSHeapBroker* broker, ObjectData** storage,
ObjectDataKind kind)
: HeapObjectData(broker, storage, object, kind) {}
bool PropertyCellData::Serialize(JSHeapBroker* broker) {
bool PropertyCellData::Cache(JSHeapBroker* broker) {
if (serialized()) return true;
TraceScope tracer(broker, this, "PropertyCellData::Serialize");
......@@ -332,17 +332,18 @@ class JSObjectData : public JSReceiverData {
// Recursive serialization of all reachable JSObjects.
bool SerializeAsBoilerplateRecursive(JSHeapBroker* broker,
NotConcurrentInliningTag,
int max_depth = kMaxFastLiteralDepth);
ObjectData* GetInobjectField(int property_index) const;
// Shallow serialization of {elements}.
void SerializeElements(JSHeapBroker* broker);
void SerializeElements(JSHeapBroker* broker, NotConcurrentInliningTag);
bool serialized_elements() const { return serialized_elements_; }
ObjectData* elements() const;
ObjectData* raw_properties_or_hash() const { return raw_properties_or_hash_; }
void SerializeObjectCreateMap(JSHeapBroker* broker);
void SerializeObjectCreateMap(JSHeapBroker* broker, NotConcurrentInliningTag);
// Can be nullptr.
ObjectData* object_create_map(JSHeapBroker* broker) const {
......@@ -402,7 +403,8 @@ class JSObjectData : public JSReceiverData {
ZoneUnorderedMap<int, ObjectData*> own_properties_;
};
void JSObjectData::SerializeObjectCreateMap(JSHeapBroker* broker) {
void JSObjectData::SerializeObjectCreateMap(JSHeapBroker* broker,
NotConcurrentInliningTag) {
if (serialized_object_create_map_) return;
serialized_object_create_map_ = true;
......@@ -597,7 +599,7 @@ class JSTypedArrayData : public JSObjectData {
Handle<JSTypedArray> object, ObjectDataKind kind)
: JSObjectData(broker, storage, object, kind) {}
void Serialize(JSHeapBroker* broker);
void Serialize(JSHeapBroker* broker, NotConcurrentInliningTag tag);
bool serialized() const { return serialized_; }
bool is_on_heap() const { return is_on_heap_; }
......@@ -614,7 +616,8 @@ class JSTypedArrayData : public JSObjectData {
ObjectData* buffer_ = nullptr;
};
void JSTypedArrayData::Serialize(JSHeapBroker* broker) {
void JSTypedArrayData::Serialize(JSHeapBroker* broker,
NotConcurrentInliningTag) {
if (serialized_) return;
serialized_ = true;
......@@ -673,8 +676,7 @@ class JSBoundFunctionData : public JSObjectData {
ObjectDataKind kind = kSerializedHeapObject)
: JSObjectData(broker, storage, object, kind) {}
// For main-thread serialization only.
bool Serialize(JSHeapBroker* broker);
bool Serialize(JSHeapBroker* broker, NotConcurrentInliningTag tag);
ObjectData* bound_target_function() const {
DCHECK(!broker()->is_concurrent_inlining());
......@@ -703,7 +705,7 @@ class JSFunctionData : public JSObjectData {
Handle<JSFunction> object,
ObjectDataKind kind = kSerializedHeapObject)
: JSObjectData(broker, storage, object, kind) {
Serialize(broker);
Cache(broker);
}
bool IsConsistentWithHeapState(JSHeapBroker* broker) const;
......@@ -762,7 +764,7 @@ class JSFunctionData : public JSObjectData {
}
private:
void Serialize(JSHeapBroker* broker);
void Cache(JSHeapBroker* broker);
bool serialized_ = false;
bool recorded_dependency_ = false;
......@@ -893,7 +895,7 @@ class AllocationSiteData : public HeapObjectData {
public:
AllocationSiteData(JSHeapBroker* broker, ObjectData** storage,
Handle<AllocationSite> object);
void Serialize(JSHeapBroker* broker);
void Serialize(JSHeapBroker* broker, NotConcurrentInliningTag tag);
bool PointsToLiteral() const { return PointsToLiteral_; }
AllocationType GetAllocationType() const { return GetAllocationType_; }
......@@ -974,40 +976,45 @@ class MapData : public HeapObjectData {
// Serialize a single (or all) own slot(s) of the descriptor array and recurse
// on field owner(s).
bool TrySerializeOwnDescriptor(JSHeapBroker* broker,
InternalIndex descriptor_index);
InternalIndex descriptor_index,
NotConcurrentInliningTag tag);
void SerializeOwnDescriptor(JSHeapBroker* broker,
InternalIndex descriptor_index) {
CHECK(TrySerializeOwnDescriptor(broker, descriptor_index));
InternalIndex descriptor_index,
NotConcurrentInliningTag tag) {
CHECK(TrySerializeOwnDescriptor(broker, descriptor_index, tag));
}
void SerializeOwnDescriptors(JSHeapBroker* broker);
void SerializeOwnDescriptors(JSHeapBroker* broker,
NotConcurrentInliningTag tag);
ObjectData* GetStrongValue(InternalIndex descriptor_index) const;
ObjectData* instance_descriptors() const { return instance_descriptors_; }
void SerializeRootMap(JSHeapBroker* broker);
void SerializeRootMap(JSHeapBroker* broker, NotConcurrentInliningTag tag);
ObjectData* FindRootMap() const;
void SerializeConstructor(JSHeapBroker* broker);
void SerializeConstructor(JSHeapBroker* broker, NotConcurrentInliningTag tag);
ObjectData* GetConstructor() const {
CHECK(serialized_constructor_);
return constructor_;
}
void SerializeBackPointer(JSHeapBroker* broker);
void SerializeBackPointer(JSHeapBroker* broker, NotConcurrentInliningTag tag);
ObjectData* GetBackPointer() const {
CHECK(serialized_backpointer_);
return backpointer_;
}
bool TrySerializePrototype(JSHeapBroker* broker);
void SerializePrototype(JSHeapBroker* broker) {
CHECK(TrySerializePrototype(broker));
bool TrySerializePrototype(JSHeapBroker* broker,
NotConcurrentInliningTag tag);
void SerializePrototype(JSHeapBroker* broker, NotConcurrentInliningTag tag) {
CHECK(TrySerializePrototype(broker, tag));
}
ObjectData* prototype() const {
DCHECK_EQ(serialized_prototype_, prototype_ != nullptr);
return prototype_;
}
void SerializeForElementStore(JSHeapBroker* broker);
void SerializeForElementStore(JSHeapBroker* broker,
NotConcurrentInliningTag tag);
bool has_extra_serialized_data() const {
return serialized_own_descriptors_ || serialized_constructor_ ||
......@@ -1063,11 +1070,11 @@ class MapData : public HeapObjectData {
};
// IMPORTANT: Keep this sync'd with JSFunctionData::IsConsistentWithHeapState.
void JSFunctionData::Serialize(JSHeapBroker* broker) {
void JSFunctionData::Cache(JSHeapBroker* broker) {
CHECK(!serialized_);
CHECK(!broker->ObjectMayBeUninitialized(HeapObject::cast(*object())));
TraceScope tracer(broker, this, "JSFunctionData::Serialize");
TraceScope tracer(broker, this, "JSFunctionData::Cache");
Handle<JSFunction> function = Handle<JSFunction>::cast(object());
// This function may run on the background thread and thus must be individual
......@@ -1115,8 +1122,10 @@ void JSFunctionData::Serialize(JSHeapBroker* broker) {
// TODO(neis): This is currently only needed for native_context's
// object_function, as used by GetObjectCreateMap. If no further use
// sites show up, we should move this into NativeContextData::Serialize.
initial_map_->SerializePrototype(broker);
initial_map_->SerializeConstructor(broker);
initial_map_->SerializePrototype(broker,
NotConcurrentInliningTag{broker});
initial_map_->SerializeConstructor(broker,
NotConcurrentInliningTag{broker});
}
}
......@@ -1148,7 +1157,7 @@ void JSFunctionData::Serialize(JSHeapBroker* broker) {
serialized_ = true;
}
// IMPORTANT: Keep this sync'd with JSFunctionData::Serialize.
// IMPORTANT: Keep this sync'd with JSFunctionData::Cache.
bool JSFunctionData::IsConsistentWithHeapState(JSHeapBroker* broker) const {
CHECK(serialized_);
......@@ -1258,7 +1267,8 @@ AllocationSiteData::AllocationSiteData(JSHeapBroker* broker,
}
}
void AllocationSiteData::Serialize(JSHeapBroker* broker) {
void AllocationSiteData::Serialize(JSHeapBroker* broker,
NotConcurrentInliningTag) {
if (serialized_) return;
serialized_ = true;
......@@ -1449,7 +1459,8 @@ class DescriptorArrayData : public HeapObjectData {
}
void SerializeDescriptor(JSHeapBroker* broker, Handle<Map> map,
InternalIndex descriptor_index);
InternalIndex descriptor_index,
NotConcurrentInliningTag tag);
private:
ZoneMap<int, PropertyDescriptor> contents_;
......@@ -1457,7 +1468,8 @@ class DescriptorArrayData : public HeapObjectData {
void DescriptorArrayData::SerializeDescriptor(JSHeapBroker* broker,
Handle<Map> map,
InternalIndex descriptor_index) {
InternalIndex descriptor_index,
NotConcurrentInliningTag tag) {
CHECK_LT(descriptor_index.as_int(), map->NumberOfOwnDescriptors());
if (contents_.find(descriptor_index.as_int()) != contents_.end()) return;
......@@ -1484,7 +1496,8 @@ void DescriptorArrayData::SerializeDescriptor(JSHeapBroker* broker,
if (d.details.location() == kField && !d.field_owner->should_access_heap()) {
// Recurse on the owner map.
d.field_owner->AsMap()->SerializeOwnDescriptor(broker, descriptor_index);
d.field_owner->AsMap()->SerializeOwnDescriptor(broker, descriptor_index,
tag);
}
TRACE(broker, "Copied descriptor " << descriptor_index.as_int() << " into "
......@@ -1524,7 +1537,7 @@ class FeedbackVectorData : public HeapObjectData {
return shared_function_info_;
}
void Serialize(JSHeapBroker* broker);
void Serialize(JSHeapBroker* broker, NotConcurrentInliningTag tag);
bool serialized() const { return serialized_; }
ObjectData* GetClosureFeedbackCell(JSHeapBroker* broker, int index) const;
......@@ -1560,7 +1573,8 @@ ObjectData* FeedbackVectorData::GetClosureFeedbackCell(JSHeapBroker* broker,
return closure_feedback_cell_array_[index];
}
void FeedbackVectorData::Serialize(JSHeapBroker* broker) {
void FeedbackVectorData::Serialize(JSHeapBroker* broker,
NotConcurrentInliningTag tag) {
if (serialized_) return;
serialized_ = true;
......@@ -1622,7 +1636,8 @@ class ScriptContextTableData : public FixedArrayData {
: FixedArrayData(broker, storage, object, kind) {}
};
bool JSBoundFunctionData::Serialize(JSHeapBroker* broker) {
bool JSBoundFunctionData::Serialize(JSHeapBroker* broker,
NotConcurrentInliningTag tag) {
DCHECK(!broker->is_concurrent_inlining());
if (serialized_) return true;
......@@ -1641,7 +1656,7 @@ bool JSBoundFunctionData::Serialize(JSHeapBroker* broker) {
if (!bound_target_function_->should_access_heap()) {
if (bound_target_function_->IsJSBoundFunction()) {
serialized_nested =
bound_target_function_->AsJSBoundFunction()->Serialize(broker);
bound_target_function_->AsJSBoundFunction()->Serialize(broker, tag);
}
}
if (!serialized_nested) {
......@@ -1704,7 +1719,7 @@ class JSArrayData : public JSObjectData {
: JSObjectData(broker, storage, object, kind),
own_elements_(broker->zone()) {}
void Serialize(JSHeapBroker* broker);
void Serialize(JSHeapBroker* broker, NotConcurrentInliningTag tag);
ObjectData* length() const {
CHECK(serialized_);
return length_;
......@@ -1725,9 +1740,8 @@ class JSArrayData : public JSObjectData {
ZoneVector<std::pair<uint32_t, ObjectData*>> own_elements_;
};
void JSArrayData::Serialize(JSHeapBroker* broker) {
CHECK(!broker->is_concurrent_inlining());
void JSArrayData::Serialize(JSHeapBroker* broker,
NotConcurrentInliningTag tag) {
if (serialized_) return;
serialized_ = true;
......@@ -1877,7 +1891,7 @@ ObjectData* JSGlobalObjectData::GetPropertyCell(JSHeapBroker* broker,
if (cell.has_value()) {
result = cell->data();
if (!result->should_access_heap()) {
result->AsPropertyCell()->Serialize(broker);
result->AsPropertyCell()->Cache(broker);
}
}
properties_.push_back({name, result});
......@@ -1954,7 +1968,8 @@ ObjectData* JSObjectData::elements() const {
return elements_;
}
void JSObjectData::SerializeElements(JSHeapBroker* broker) {
void JSObjectData::SerializeElements(JSHeapBroker* broker,
NotConcurrentInliningTag) {
if (serialized_elements_) return;
serialized_elements_ = true;
......@@ -1967,9 +1982,8 @@ void JSObjectData::SerializeElements(JSHeapBroker* broker) {
DCHECK(elements_->IsFixedArrayBase());
}
void MapData::SerializeConstructor(JSHeapBroker* broker) {
CHECK(!broker->is_concurrent_inlining());
void MapData::SerializeConstructor(JSHeapBroker* broker,
NotConcurrentInliningTag tag) {
if (serialized_constructor_) return;
serialized_constructor_ = true;
......@@ -1980,9 +1994,8 @@ void MapData::SerializeConstructor(JSHeapBroker* broker) {
constructor_ = broker->GetOrCreateData(map->GetConstructor());
}
void MapData::SerializeBackPointer(JSHeapBroker* broker) {
CHECK(!broker->is_concurrent_inlining());
void MapData::SerializeBackPointer(JSHeapBroker* broker,
NotConcurrentInliningTag tag) {
if (serialized_backpointer_) return;
serialized_backpointer_ = true;
......@@ -1993,9 +2006,8 @@ void MapData::SerializeBackPointer(JSHeapBroker* broker) {
backpointer_ = broker->GetOrCreateData(map->GetBackPointer());
}
bool MapData::TrySerializePrototype(JSHeapBroker* broker) {
CHECK(!broker->is_concurrent_inlining());
bool MapData::TrySerializePrototype(JSHeapBroker* broker,
NotConcurrentInliningTag tag) {
if (serialized_prototype_) return true;
TraceScope tracer(broker, this, "MapData::SerializePrototype");
......@@ -2007,7 +2019,8 @@ bool MapData::TrySerializePrototype(JSHeapBroker* broker) {
return true;
}
void MapData::SerializeOwnDescriptors(JSHeapBroker* broker) {
void MapData::SerializeOwnDescriptors(JSHeapBroker* broker,
NotConcurrentInliningTag tag) {
if (serialized_own_descriptors_) return;
serialized_own_descriptors_ = true;
......@@ -2015,12 +2028,13 @@ void MapData::SerializeOwnDescriptors(JSHeapBroker* broker) {
Handle<Map> map = Handle<Map>::cast(object());
for (InternalIndex i : map->IterateOwnDescriptors()) {
SerializeOwnDescriptor(broker, i);
SerializeOwnDescriptor(broker, i, tag);
}
}
bool MapData::TrySerializeOwnDescriptor(JSHeapBroker* broker,
InternalIndex descriptor_index) {
InternalIndex descriptor_index,
NotConcurrentInliningTag tag) {
TraceScope tracer(broker, this, "MapData::SerializeOwnDescriptor");
Handle<Map> map = Handle<Map>::cast(object());
Isolate* isolate = broker->isolate();
......@@ -2044,19 +2058,20 @@ bool MapData::TrySerializeOwnDescriptor(JSHeapBroker* broker,
if (!owner.equals(map)) {
ObjectData* data = broker->TryGetOrCreateData(owner);
if (data == nullptr) return false;
data->AsMap()->SerializeOwnDescriptor(broker, descriptor_index);
data->AsMap()->SerializeOwnDescriptor(broker, descriptor_index, tag);
}
}
} else {
DescriptorArrayData* descriptors =
instance_descriptors()->AsDescriptorArray();
descriptors->SerializeDescriptor(broker, map, descriptor_index);
descriptors->SerializeDescriptor(broker, map, descriptor_index, tag);
}
return true;
}
void MapData::SerializeRootMap(JSHeapBroker* broker) {
void MapData::SerializeRootMap(JSHeapBroker* broker,
NotConcurrentInliningTag tag) {
if (serialized_root_map_) return;
serialized_root_map_ = true;
......@@ -2069,6 +2084,7 @@ void MapData::SerializeRootMap(JSHeapBroker* broker) {
ObjectData* MapData::FindRootMap() const { return root_map_; }
bool JSObjectData::SerializeAsBoilerplateRecursive(JSHeapBroker* broker,
NotConcurrentInliningTag tag,
int max_depth) {
if (serialized_as_boilerplate_) return true;
// If serialization succeeds, we set this to true at the end.
......@@ -2107,7 +2123,7 @@ bool JSObjectData::SerializeAsBoilerplateRecursive(JSHeapBroker* broker,
}
if (!map()->should_access_heap()) {
map()->AsMap()->SerializeOwnDescriptors(broker);
map()->AsMap()->SerializeOwnDescriptors(broker, tag);
}
// Check the in-object properties.
......@@ -2129,7 +2145,7 @@ bool JSObjectData::SerializeAsBoilerplateRecursive(JSHeapBroker* broker,
inobject_fields_.push_back(value_data);
if (value_data->IsJSObject() && !value_data->should_access_heap()) {
if (!value_data->AsJSObject()->SerializeAsBoilerplateRecursive(
broker, max_depth - 1))
broker, tag, max_depth - 1))
return false;
}
}
......@@ -2149,7 +2165,7 @@ bool JSObjectData::SerializeAsBoilerplateRecursive(JSHeapBroker* broker,
ObjectData* value_data = broker->GetOrCreateData(value);
if (!value_data->should_access_heap()) {
if (!value_data->AsJSObject()->SerializeAsBoilerplateRecursive(
broker, max_depth - 1)) {
broker, tag, max_depth - 1)) {
return false;
}
}
......@@ -2162,7 +2178,7 @@ bool JSObjectData::SerializeAsBoilerplateRecursive(JSHeapBroker* broker,
}
if (IsJSArray() && !broker->is_concurrent_inlining()) {
AsJSArray()->Serialize(broker);
AsJSArray()->Serialize(broker, NotConcurrentInliningTag{broker});
}
serialized_as_boilerplate_ = true;
......@@ -2303,30 +2319,48 @@ void JSHeapBroker::InitializeAndStartSerializing() {
CollectArrayAndObjectPrototypes();
SetTargetNativeContextRef(target_native_context().object());
target_native_context().Serialize();
Factory* const f = isolate()->factory();
SetTargetNativeContextRef(target_native_context().object());
if (!is_concurrent_inlining()) {
target_native_context().Serialize(NotConcurrentInliningTag{this});
ObjectData* data;
data = GetOrCreateData(f->array_buffer_detaching_protector());
if (!data->should_access_heap()) data->AsPropertyCell()->Serialize(this);
if (!data->should_access_heap()) {
data->AsPropertyCell()->Cache(this);
}
data = GetOrCreateData(f->array_constructor_protector());
if (!data->should_access_heap()) data->AsPropertyCell()->Serialize(this);
if (!data->should_access_heap()) {
data->AsPropertyCell()->Cache(this);
}
data = GetOrCreateData(f->array_iterator_protector());
if (!data->should_access_heap()) data->AsPropertyCell()->Serialize(this);
if (!data->should_access_heap()) {
data->AsPropertyCell()->Cache(this);
}
data = GetOrCreateData(f->array_species_protector());
if (!data->should_access_heap()) data->AsPropertyCell()->Serialize(this);
if (!data->should_access_heap()) {
data->AsPropertyCell()->Cache(this);
}
data = GetOrCreateData(f->no_elements_protector());
if (!data->should_access_heap()) data->AsPropertyCell()->Serialize(this);
if (!data->should_access_heap()) {
data->AsPropertyCell()->Cache(this);
}
data = GetOrCreateData(f->promise_hook_protector());
if (!data->should_access_heap()) data->AsPropertyCell()->Serialize(this);
if (!data->should_access_heap()) {
data->AsPropertyCell()->Cache(this);
}
data = GetOrCreateData(f->promise_species_protector());
if (!data->should_access_heap()) data->AsPropertyCell()->Serialize(this);
if (!data->should_access_heap()) {
data->AsPropertyCell()->Cache(this);
}
data = GetOrCreateData(f->promise_then_protector());
if (!data->should_access_heap()) data->AsPropertyCell()->Serialize(this);
if (!data->should_access_heap()) {
data->AsPropertyCell()->Cache(this);
}
data = GetOrCreateData(f->string_length_protector());
if (!data->should_access_heap()) data->AsPropertyCell()->Serialize(this);
if (!data->should_access_heap()) {
data->AsPropertyCell()->Cache(this);
}
}
GetOrCreateData(f->many_closures_cell());
GetOrCreateData(CodeFactory::CEntry(isolate(), 1, SaveFPRegsMode::kIgnore,
......@@ -2438,14 +2472,12 @@ void JSHeapBroker::ClearReconstructibleData() {
ObjectData* value = p->value;
p = refs_->Next(p);
if (value->IsMap() &&
value->kind() == ObjectDataKind::kBackgroundSerializedHeapObject &&
value->AsMap()->has_extra_serialized_data()) {
continue;
value->kind() == ObjectDataKind::kBackgroundSerializedHeapObject) {
CHECK(!value->AsMap()->has_extra_serialized_data());
}
if (value->IsJSObject() &&
value->kind() == ObjectDataKind::kBackgroundSerializedHeapObject &&
value->AsJSObject()->has_extra_serialized_data()) {
continue;
value->kind() == ObjectDataKind::kBackgroundSerializedHeapObject) {
CHECK(!value->AsJSObject()->has_extra_serialized_data());
}
// Can be reconstructed from the background thread.
CHECK_NOT_NULL(refs_->Remove(key));
......@@ -2552,13 +2584,14 @@ base::Optional<MapRef> MapRef::AsElementsKind(ElementsKind kind) const {
return native_context.GetInitialJSArrayMap(kind);
}
void MapRef::SerializeForElementStore() {
void MapRef::SerializeForElementStore(NotConcurrentInliningTag tag) {
if (data()->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsMap()->SerializeForElementStore(broker());
data()->AsMap()->SerializeForElementStore(broker(), tag);
}
void MapData::SerializeForElementStore(JSHeapBroker* broker) {
void MapData::SerializeForElementStore(JSHeapBroker* broker,
NotConcurrentInliningTag tag) {
if (serialized_for_element_store_) return;
serialized_for_element_store_ = true;
......@@ -2568,7 +2601,7 @@ void MapData::SerializeForElementStore(JSHeapBroker* broker) {
// method should go away anyway once the compiler is fully concurrent.
MapRef map(broker, this);
do {
map.SerializePrototype();
map.SerializePrototype(tag);
map = map.prototype().value().map();
} while (map.IsJSObjectMap() && map.is_stable() &&
IsFastElementsKind(map.elements_kind()));
......@@ -2652,7 +2685,7 @@ FeedbackCellRef FeedbackVectorRef::GetClosureFeedbackCell(int index) const {
}
base::Optional<ObjectRef> JSObjectRef::raw_properties_or_hash() const {
if (data_->should_access_heap()) {
if (data_->should_access_heap() || broker()->is_concurrent_inlining()) {
return TryMakeRef(broker(), object()->raw_properties_or_hash());
}
return ObjectRef(broker(), data()->AsJSObject()->raw_properties_or_hash());
......@@ -2686,29 +2719,30 @@ base::Optional<ObjectRef> JSObjectRef::RawInobjectPropertyAt(
object_data->GetInobjectField(index.property_index()));
}
void JSObjectRef::SerializeAsBoilerplateRecursive() {
void JSObjectRef::SerializeAsBoilerplateRecursive(
NotConcurrentInliningTag tag) {
if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsJSObject()->SerializeAsBoilerplateRecursive(broker());
data()->AsJSObject()->SerializeAsBoilerplateRecursive(broker(), tag);
}
void AllocationSiteRef::SerializeRecursive() {
void AllocationSiteRef::SerializeRecursive(NotConcurrentInliningTag tag) {
if (!data_->should_access_heap()) {
data()->AsAllocationSite()->Serialize(broker());
data()->AsAllocationSite()->Serialize(broker(), tag);
}
if (boilerplate().has_value()) {
boilerplate()->SerializeAsBoilerplateRecursive();
boilerplate()->SerializeAsBoilerplateRecursive(tag);
}
if (nested_site().IsAllocationSite()) {
nested_site().AsAllocationSite().SerializeRecursive();
nested_site().AsAllocationSite().SerializeRecursive(tag);
}
}
void JSObjectRef::SerializeElements() {
void JSObjectRef::SerializeElements(NotConcurrentInliningTag tag) {
if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsJSObject()->SerializeElements(broker());
data()->AsJSObject()->SerializeElements(broker(), tag);
}
bool JSObjectRef::IsElementsTenured(const FixedArrayBaseRef& elements) {
......@@ -3097,7 +3131,7 @@ HolderLookupResult FunctionTemplateInfoRef::LookupHolderOfExpectedType(
if (!receiver_map.IsJSGlobalProxyMap()) return not_found;
if (policy == SerializationPolicy::kSerializeIfNeeded) {
receiver_map.SerializePrototype();
receiver_map.SerializePrototype(NotConcurrentInliningTag{broker()});
}
base::Optional<HeapObjectRef> prototype = receiver_map.prototype();
if (!prototype.has_value()) return not_found;
......@@ -3184,10 +3218,10 @@ base::Optional<HeapObjectRef> MapRef::prototype() const {
return HeapObjectRef(broker(), prototype_data);
}
void MapRef::SerializeRootMap() {
if (data_->should_access_heap() || broker()->is_concurrent_inlining()) return;
void MapRef::SerializeRootMap(NotConcurrentInliningTag tag) {
if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsMap()->SerializeRootMap(broker());
data()->AsMap()->SerializeRootMap(broker(), tag);
}
// TODO(solanes, v8:7790): Remove base::Optional from the return type when
......@@ -3313,21 +3347,19 @@ ZoneVector<const CFunctionInfo*> FunctionTemplateInfoRef::c_signatures() const {
bool StringRef::IsSeqString() const { return object()->IsSeqString(); }
void NativeContextRef::Serialize() {
void NativeContextRef::Serialize(NotConcurrentInliningTag tag) {
// TODO(jgruber): Disable visitation if should_access_heap() once all
// NativeContext element refs can be created on background threads. Until
// then, we *must* iterate them and create refs at serialization-time (even
// though NativeContextRef itself is never-serialized).
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
#define SERIALIZE_MEMBER(type, name) \
{ \
ObjectData* member_data = broker()->GetOrCreateData(object()->name()); \
if (member_data->IsMap() && \
!InstanceTypeChecker::IsContext( \
member_data->AsMap()->instance_type()) && \
!broker()->is_concurrent_inlining()) { \
member_data->AsMap()->SerializeConstructor(broker()); \
} \
#define SERIALIZE_MEMBER(type, name) \
{ \
ObjectData* member_data = broker()->GetOrCreateData(object()->name()); \
if (member_data->IsMap() && !InstanceTypeChecker::IsContext( \
member_data->AsMap()->instance_type())) { \
member_data->AsMap()->SerializeConstructor(broker(), tag); \
} \
}
BROKER_NATIVE_CONTEXT_FIELDS(SERIALIZE_MEMBER)
#undef SERIALIZE_MEMBER
......@@ -3335,9 +3367,8 @@ void NativeContextRef::Serialize() {
for (int i = Context::FIRST_FUNCTION_MAP_INDEX;
i <= Context::LAST_FUNCTION_MAP_INDEX; i++) {
MapData* member_data = broker()->GetOrCreateData(object()->get(i))->AsMap();
if (!InstanceTypeChecker::IsContext(member_data->instance_type()) &&
!broker()->is_concurrent_inlining()) {
member_data->SerializeConstructor(broker());
if (!InstanceTypeChecker::IsContext(member_data->instance_type())) {
member_data->SerializeConstructor(broker(), tag);
}
}
}
......@@ -3767,10 +3798,10 @@ base::Optional<SharedFunctionInfoRef> FeedbackCellRef::shared_function_info()
return base::nullopt;
}
void FeedbackVectorRef::Serialize() {
void FeedbackVectorRef::Serialize(NotConcurrentInliningTag tag) {
if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsFeedbackVector()->Serialize(broker());
data()->AsFeedbackVector()->Serialize(broker(), tag);
}
bool FeedbackVectorRef::serialized() const {
......@@ -3792,7 +3823,7 @@ bool NameRef::IsUniqueName() const {
return IsInternalizedString() || IsSymbol();
}
void RegExpBoilerplateDescriptionRef::Serialize() {
void RegExpBoilerplateDescriptionRef::Serialize(NotConcurrentInliningTag) {
// TODO(jgruber,v8:7790): Remove once member types are also never serialized.
// Until then, we have to call these functions once on the main thread to
// trigger serialization.
......@@ -3854,12 +3885,12 @@ Reduction NoChangeBecauseOfMissingData(JSHeapBroker* broker,
return AdvancedReducer::NoChange();
}
bool JSBoundFunctionRef::Serialize() {
if (data_->should_access_heap() || broker()->is_concurrent_inlining()) {
bool JSBoundFunctionRef::Serialize(NotConcurrentInliningTag tag) {
if (data_->should_access_heap()) {
return true;
}
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
return data()->AsJSBoundFunction()->Serialize(broker());
return data()->AsJSBoundFunction()->Serialize(broker(), tag);
}
void JSFunctionRef::RecordDependencyIfNeeded(
......@@ -3921,13 +3952,13 @@ ScopeInfoRef SharedFunctionInfoRef::scope_info() const {
return MakeRef(broker(), object()->scope_info());
}
void JSObjectRef::SerializeObjectCreateMap() {
if (data_->should_access_heap() || broker()->is_concurrent_inlining()) {
void JSObjectRef::SerializeObjectCreateMap(NotConcurrentInliningTag tag) {
if (data_->should_access_heap()) {
return;
}
CHECK_IMPLIES(!FLAG_turbo_concurrent_get_property_access_info,
broker()->mode() == JSHeapBroker::kSerializing);
data()->AsJSObject()->SerializeObjectCreateMap(broker());
data()->AsJSObject()->SerializeObjectCreateMap(broker(), tag);
}
base::Optional<MapRef> JSObjectRef::GetObjectCreateMap() const {
......@@ -3958,18 +3989,20 @@ base::Optional<MapRef> JSObjectRef::GetObjectCreateMap() const {
return MapRef(broker(), map_data->AsMap());
}
bool MapRef::TrySerializeOwnDescriptor(InternalIndex descriptor_index) {
bool MapRef::TrySerializeOwnDescriptor(InternalIndex descriptor_index,
NotConcurrentInliningTag tag) {
CHECK_LT(descriptor_index.as_int(), NumberOfOwnDescriptors());
if (data_->should_access_heap() || broker()->is_concurrent_inlining()) {
if (data_->should_access_heap()) {
return true;
}
CHECK_IMPLIES(!FLAG_turbo_concurrent_get_property_access_info,
broker()->mode() == JSHeapBroker::kSerializing);
return data()->AsMap()->TrySerializeOwnDescriptor(broker(), descriptor_index);
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
return data()->AsMap()->TrySerializeOwnDescriptor(broker(), descriptor_index,
tag);
}
void MapRef::SerializeOwnDescriptor(InternalIndex descriptor_index) {
CHECK(TrySerializeOwnDescriptor(descriptor_index));
void MapRef::SerializeOwnDescriptor(InternalIndex descriptor_index,
NotConcurrentInliningTag tag) {
CHECK(TrySerializeOwnDescriptor(descriptor_index, tag));
}
bool MapRef::serialized_own_descriptor(InternalIndex descriptor_index) const {
......@@ -3985,28 +4018,30 @@ bool MapRef::serialized_own_descriptor(InternalIndex descriptor_index) const {
return desc_array_data->serialized_descriptor(descriptor_index);
}
void MapRef::SerializeBackPointer() {
if (data_->should_access_heap() || broker()->is_concurrent_inlining()) return;
void MapRef::SerializeBackPointer(NotConcurrentInliningTag tag) {
if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsMap()->SerializeBackPointer(broker());
data()->AsMap()->SerializeBackPointer(broker(), tag);
}
bool MapRef::TrySerializePrototype() {
bool MapRef::TrySerializePrototype(NotConcurrentInliningTag tag) {
if (data_->should_access_heap() || broker()->is_concurrent_inlining()) {
return true;
}
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
return data()->AsMap()->TrySerializePrototype(broker());
return data()->AsMap()->TrySerializePrototype(broker(), tag);
}
void MapRef::SerializePrototype() { CHECK(TrySerializePrototype()); }
void MapRef::SerializePrototype(NotConcurrentInliningTag tag) {
CHECK(TrySerializePrototype(tag));
}
void JSTypedArrayRef::Serialize() {
void JSTypedArrayRef::Serialize(NotConcurrentInliningTag tag) {
if (data_->should_access_heap() || broker()->is_concurrent_inlining()) {
// Nothing to do.
} else {
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsJSTypedArray()->Serialize(broker());
data()->AsJSTypedArray()->Serialize(broker(), tag);
}
}
......@@ -4018,14 +4053,14 @@ bool JSTypedArrayRef::serialized() const {
return false;
}
bool PropertyCellRef::Serialize() const {
bool PropertyCellRef::Cache() const {
if (data_->should_access_heap()) return true;
CHECK(broker()->mode() == JSHeapBroker::kSerializing ||
broker()->mode() == JSHeapBroker::kSerialized);
return data()->AsPropertyCell()->Serialize(broker());
return data()->AsPropertyCell()->Cache(broker());
}
void FunctionTemplateInfoRef::SerializeCallCode() {
void FunctionTemplateInfoRef::SerializeCallCode(NotConcurrentInliningTag tag) {
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
// CallHandlerInfo::data may still hold a serialized heap object, so we
// have to make the broker aware of it.
......
......@@ -57,6 +57,13 @@ inline bool IsAnyStore(AccessMode mode) {
enum class SerializationPolicy { kAssumeSerialized, kSerializeIfNeeded };
// Clarifies in function signatures that a method may only be called when
// concurrent inlining is disabled.
class NotConcurrentInliningTag final {
public:
explicit NotConcurrentInliningTag(JSHeapBroker* broker);
};
enum class OddballType : uint8_t {
kNone, // Not an Oddball.
kBoolean, // True or False.
......@@ -292,13 +299,12 @@ class PropertyCellRef : public HeapObjectRef {
Handle<PropertyCell> object() const;
// Can be called from a background thread.
V8_WARN_UNUSED_RESULT bool Serialize() const;
void SerializeAsProtector() const {
bool serialized = Serialize();
V8_WARN_UNUSED_RESULT bool Cache() const;
void CacheAsProtector() const {
bool cached = Cache();
// A protector always holds a Smi value and its cell type never changes, so
// Serialize can't fail.
CHECK(serialized);
// Cache can't fail.
CHECK(cached);
}
PropertyDetails property_details() const;
......@@ -364,13 +370,13 @@ class JSObjectRef : public JSReceiverRef {
// relaxed read. This is to ease the transition to unserialized (or
// background-serialized) elements.
base::Optional<FixedArrayBaseRef> elements(RelaxedLoadTag) const;
void SerializeElements();
void SerializeElements(NotConcurrentInliningTag tag);
bool IsElementsTenured(const FixedArrayBaseRef& elements);
void SerializeObjectCreateMap();
void SerializeObjectCreateMap(NotConcurrentInliningTag tag);
base::Optional<MapRef> GetObjectCreateMap() const;
void SerializeAsBoilerplateRecursive();
void SerializeAsBoilerplateRecursive(NotConcurrentInliningTag tag);
};
class JSDataViewRef : public JSObjectRef {
......@@ -388,7 +394,7 @@ class JSBoundFunctionRef : public JSObjectRef {
Handle<JSBoundFunction> object() const;
bool Serialize();
bool Serialize(NotConcurrentInliningTag tag);
// TODO(neis): Make return types non-optional once JSFunction is no longer
// fg-serialized.
......@@ -439,7 +445,7 @@ class RegExpBoilerplateDescriptionRef : public HeapObjectRef {
Handle<RegExpBoilerplateDescription> object() const;
void Serialize();
void Serialize(NotConcurrentInliningTag tag);
FixedArrayRef data() const;
StringRef source() const;
......@@ -529,7 +535,7 @@ class NativeContextRef : public ContextRef {
Handle<NativeContext> object() const;
void Serialize();
void Serialize(NotConcurrentInliningTag tag);
#define DECL_ACCESSOR(type, name) type##Ref name() const;
BROKER_NATIVE_CONTEXT_FIELDS(DECL_ACCESSOR)
......@@ -587,7 +593,7 @@ class FeedbackVectorRef : public HeapObjectRef {
SharedFunctionInfoRef shared_function_info() const;
double invocation_count() const;
void Serialize();
void Serialize(NotConcurrentInliningTag tag);
bool serialized() const;
FeedbackCellRef GetClosureFeedbackCell(int index) const;
};
......@@ -619,7 +625,7 @@ class AllocationSiteRef : public HeapObjectRef {
AllocationType GetAllocationType() const;
ObjectRef nested_site() const;
void SerializeRecursive();
void SerializeRecursive(NotConcurrentInliningTag tag);
base::Optional<JSObjectRef> boilerplate() const;
ElementsKind GetElementsKind() const;
......@@ -680,23 +686,25 @@ class V8_EXPORT_PRIVATE MapRef : public HeapObjectRef {
INSTANCE_TYPE_CHECKERS(DEF_TESTER)
#undef DEF_TESTER
void SerializeBackPointer();
void SerializeBackPointer(NotConcurrentInliningTag tag);
HeapObjectRef GetBackPointer() const;
void SerializePrototype();
void SerializePrototype(NotConcurrentInliningTag tag);
// TODO(neis): We should be able to remove TrySerializePrototype once
// concurrent-inlining is always on. Then we can also change the return type
// of prototype() back to HeapObjectRef.
bool TrySerializePrototype();
bool TrySerializePrototype(NotConcurrentInliningTag tag);
base::Optional<HeapObjectRef> prototype() const;
void SerializeForElementStore();
void SerializeForElementStore(NotConcurrentInliningTag tag);
bool HasOnlyStablePrototypesWithFastElements(
ZoneVector<MapRef>* prototype_maps);
// Concerning the underlying instance_descriptors:
bool TrySerializeOwnDescriptor(InternalIndex descriptor_index);
void SerializeOwnDescriptor(InternalIndex descriptor_index);
bool TrySerializeOwnDescriptor(InternalIndex descriptor_index,
NotConcurrentInliningTag tag);
void SerializeOwnDescriptor(InternalIndex descriptor_index,
NotConcurrentInliningTag tag);
bool serialized_own_descriptor(InternalIndex descriptor_index) const;
MapRef FindFieldOwner(InternalIndex descriptor_index) const;
PropertyDetails GetPropertyDetails(InternalIndex descriptor_index) const;
......@@ -708,11 +716,9 @@ class V8_EXPORT_PRIVATE MapRef : public HeapObjectRef {
DescriptorArrayRef instance_descriptors() const;
void SerializeRootMap();
void SerializeRootMap(NotConcurrentInliningTag tag);
base::Optional<MapRef> FindRootMap() const;
// Available after calling JSFunctionRef::Serialize on a function that has
// this map as initial map.
ObjectRef GetConstructor() const;
};
......@@ -736,7 +742,7 @@ class FunctionTemplateInfoRef : public HeapObjectRef {
// The following returns true if the CallHandlerInfo is present.
bool has_call_code() const;
void SerializeCallCode();
void SerializeCallCode(NotConcurrentInliningTag tag);
base::Optional<CallHandlerInfoRef> call_code() const;
ZoneVector<Address> c_functions() const;
ZoneVector<const CFunctionInfo*> c_signatures() const;
......@@ -863,9 +869,7 @@ class ScopeInfoRef : public HeapObjectRef {
bool HasOuterScopeInfo() const;
bool HasContextExtensionSlot() const;
// Only serialized via SerializeScopeInfoChain.
ScopeInfoRef OuterScopeInfo() const;
void SerializeScopeInfoChain();
};
#define BROKER_SFI_FIELDS(V) \
......@@ -953,7 +957,7 @@ class JSTypedArrayRef : public JSObjectRef {
size_t length() const;
void* data_ptr() const;
void Serialize();
void Serialize(NotConcurrentInliningTag tag);
bool serialized() const;
HeapObjectRef buffer() const;
......
......@@ -652,7 +652,7 @@ Reduction JSCreateLowering::ReduceJSCreateArray(Node* node) {
} else {
PropertyCellRef array_constructor_protector =
MakeRef(broker(), factory()->array_constructor_protector());
array_constructor_protector.SerializeAsProtector();
array_constructor_protector.CacheAsProtector();
can_inline_call = array_constructor_protector.value().AsSmi() ==
Protectors::kProtectorValid;
}
......
......@@ -378,8 +378,8 @@ bool GlobalAccessFeedback::immutable() const {
base::Optional<ObjectRef> GlobalAccessFeedback::GetConstantHint() const {
if (IsPropertyCell()) {
bool cell_serialized = property_cell().Serialize();
CHECK(cell_serialized); // Can't fail on the main thread.
bool cell_cached = property_cell().Cache();
CHECK(cell_cached); // Can't fail on the main thread.
return property_cell().value();
} else if (IsScriptContextSlot() && immutable()) {
return script_context().get(slot_index());
......@@ -763,7 +763,9 @@ ProcessedFeedback const& JSHeapBroker::ReadFeedbackForArrayOrObjectLiteral(
}
AllocationSiteRef site = MakeRef(this, AllocationSite::cast(object));
if (site.PointsToLiteral()) site.SerializeRecursive();
if (!is_concurrent_inlining() && site.PointsToLiteral()) {
site.SerializeRecursive(NotConcurrentInliningTag{this});
}
return *zone()->New<LiteralFeedback>(site, nexus.kind());
}
......@@ -779,7 +781,9 @@ ProcessedFeedback const& JSHeapBroker::ReadFeedbackForRegExpLiteral(
RegExpBoilerplateDescriptionRef boilerplate = MakeRef(
this, handle(RegExpBoilerplateDescription::cast(object), isolate()));
boilerplate.Serialize();
if (!is_concurrent_inlining()) {
boilerplate.Serialize(NotConcurrentInliningTag{this});
}
return *zone()->New<RegExpLiteralFeedback>(boilerplate, nexus.kind());
}
......@@ -983,7 +987,9 @@ ElementAccessFeedback const& JSHeapBroker::ProcessFeedbackMapsForElementAccess(
possible_transition_targets.reserve(maps.size());
for (Handle<Map> map : maps) {
MapRef map_ref = MakeRef(this, map);
map_ref.SerializeRootMap();
if (!is_concurrent_inlining()) {
map_ref.SerializeRootMap(NotConcurrentInliningTag{this});
}
if (CanInlineElementAccess(map_ref) &&
IsFastElementsKind(map->elements_kind()) &&
......
......@@ -31,14 +31,15 @@ Reduction JSHeapCopyReducer::Reduce(Node* node) {
FeedbackCellRef cell = MakeRef(broker(), FeedbackCellOf(node->op()));
base::Optional<FeedbackVectorRef> feedback_vector = cell.value();
if (feedback_vector.has_value()) {
feedback_vector->Serialize();
feedback_vector->Serialize(NotConcurrentInliningTag{broker()});
}
break;
}
case IrOpcode::kHeapConstant: {
ObjectRef object = MakeRef(broker(), HeapConstantOf(node->op()));
if (object.IsJSObject()) {
object.AsJSObject().SerializeObjectCreateMap();
object.AsJSObject().SerializeObjectCreateMap(
NotConcurrentInliningTag{broker()});
}
break;
}
......
......@@ -793,7 +793,7 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
Node* node, Node* lookup_start_object, Node* receiver, Node* value,
NameRef const& name, AccessMode access_mode, Node* key,
PropertyCellRef const& property_cell, Node* effect) {
if (!property_cell.Serialize()) {
if (!property_cell.Cache()) {
TRACE_BROKER_MISSING(broker(), "usable data for " << property_cell);
return NoChange();
}
......
......@@ -596,7 +596,7 @@ Reduction JSTypedLowering::ReduceJSAdd(Node* node) {
PropertyCellRef string_length_protector =
MakeRef(broker(), factory()->string_length_protector());
string_length_protector.SerializeAsProtector();
string_length_protector.CacheAsProtector();
if (string_length_protector.value().AsSmi() ==
Protectors::kProtectorValid) {
......
......@@ -1166,7 +1166,6 @@ Hints SerializerForBackgroundCompilation::Run() {
shared.object());
}
feedback_vector_ref.Serialize();
TraverseBytecode();
if (return_value_hints().IsEmpty()) {
......@@ -1344,7 +1343,6 @@ void SerializerForBackgroundCompilation::VisitGetSuperConstructor(
if (!constant->IsJSFunction()) continue;
MapRef map = MakeRef(broker(), handle(HeapObject::cast(*constant).map(),
broker()->isolate()));
map.SerializePrototype();
ObjectRef proto = map.prototype().value();
if (proto.IsHeapObject() && proto.AsHeapObject().map().is_constructor()) {
result_hints.AddConstant(proto.object(), zone(), broker());
......@@ -2060,7 +2058,6 @@ void SerializerForBackgroundCompilation::ProcessCalleeForCallOrConstruct(
if (callee->IsJSBoundFunction()) {
JSBoundFunctionRef bound_function =
MakeRef(broker(), Handle<JSBoundFunction>::cast(callee));
if (!bound_function.Serialize()) return;
callee = UnrollBoundFunction(bound_function, broker(), arguments,
&expanded_arguments, zone())
.object();
......@@ -2105,7 +2102,6 @@ void SerializerForBackgroundCompilation::ProcessCallOrConstruct(
// Call; target is feedback cell or callee.
if (target->IsFeedbackCell() && target->AsFeedbackCell().value()) {
FeedbackVectorRef vector = *target->AsFeedbackCell().value();
vector.Serialize();
VirtualClosure virtual_closure(
vector.shared_function_info().object(), vector.object(),
Hints());
......@@ -2218,7 +2214,6 @@ void SerializerForBackgroundCompilation::ProcessApiCall(
MakeRef(broker(),
FunctionTemplateInfo::cast(target->function_data(kAcquireLoad)));
if (!target_template_info.has_call_code()) return;
target_template_info.SerializeCallCode();
if (target_template_info.accept_any_receiver() &&
target_template_info.is_signature_undefined()) {
......@@ -2263,8 +2258,7 @@ void SerializerForBackgroundCompilation::ProcessReceiverMapForApiCall(
void SerializerForBackgroundCompilation::ProcessHintsForObjectCreate(
Hints const& prototype) {
for (Handle<Object> constant_handle : prototype.constants()) {
ObjectRef constant = MakeRef(broker(), constant_handle);
if (constant.IsJSObject()) constant.AsJSObject().SerializeObjectCreateMap();
MakeRef(broker(), constant_handle);
}
}
......@@ -2520,15 +2514,6 @@ void SerializerForBackgroundCompilation::ProcessBuiltinCall(
result_hints->AddVirtualBoundFunction(
VirtualBoundFunction(bound_target, new_arguments), zone(),
broker());
broker()
->target_native_context()
.bound_function_with_constructor_map()
.SerializePrototype();
broker()
->target_native_context()
.bound_function_without_constructor_map()
.SerializePrototype();
}
break;
case Builtin::kObjectGetPrototypeOf:
......@@ -2583,7 +2568,6 @@ void SerializerForBackgroundCompilation::ProcessHintsForHasInPrototypeChain(
auto processMap = [&](Handle<Map> map_handle) {
MapRef map = MakeRef(broker(), map_handle);
while (map.IsJSObjectMap()) {
map.SerializePrototype();
map = map.prototype().value().map();
}
};
......@@ -2620,17 +2604,6 @@ void SerializerForBackgroundCompilation::ProcessHintsForPromiseResolve(
void SerializerForBackgroundCompilation::ProcessMapHintsForPromises(
Hints const& receiver_hints) {
// We need to serialize the prototypes on each receiver map.
for (auto constant : receiver_hints.constants()) {
if (!constant->IsJSPromise()) continue;
Handle<Map> map(Handle<HeapObject>::cast(constant)->map(),
broker()->isolate());
MakeRef(broker(), map).SerializePrototype();
}
for (auto map : receiver_hints.maps()) {
if (!map->IsJSPromiseMap()) continue;
MakeRef(broker(), map).SerializePrototype();
}
}
PropertyAccessInfo SerializerForBackgroundCompilation::ProcessMapForRegExpTest(
......@@ -2675,54 +2648,23 @@ void SerializerForBackgroundCompilation::ProcessHintsForRegExpTest(
}
}
namespace {
void ProcessMapForFunctionBind(MapRef map) {
map.SerializePrototype();
int min_nof_descriptors = std::max({JSFunction::kLengthDescriptorIndex,
JSFunction::kNameDescriptorIndex}) +
1;
if (map.NumberOfOwnDescriptors() >= min_nof_descriptors) {
map.SerializeOwnDescriptor(
InternalIndex(JSFunctionOrBoundFunction::kLengthDescriptorIndex));
map.SerializeOwnDescriptor(
InternalIndex(JSFunctionOrBoundFunction::kNameDescriptorIndex));
}
}
} // namespace
void SerializerForBackgroundCompilation::ProcessHintsForFunctionBind(
Hints const& receiver_hints) {
for (auto constant : receiver_hints.constants()) {
if (constant->IsJSFunction()) {
JSFunctionRef function =
MakeRef(broker(), Handle<JSFunction>::cast(constant));
ProcessMapForFunctionBind(function.map());
} else if (constant->IsJSBoundFunction()) {
JSBoundFunctionRef function =
MakeRef(broker(), Handle<JSBoundFunction>::cast(constant));
function.Serialize();
ProcessMapForFunctionBind(function.map());
}
}
for (auto map : receiver_hints.maps()) {
if (!map->IsJSFunctionMap() && !map->IsJSBoundFunctionMap()) continue;
ProcessMapForFunctionBind(MakeRef(broker(), map));
}
}
void SerializerForBackgroundCompilation::ProcessHintsForObjectGetPrototype(
Hints const& object_hints) {
for (auto constant : object_hints.constants()) {
if (!constant->IsHeapObject()) continue;
HeapObjectRef object =
MakeRef(broker(), Handle<HeapObject>::cast(constant));
object.map().SerializePrototype();
}
for (auto map : object_hints.maps()) {
MakeRef(broker(), map).SerializePrototype();
}
}
void SerializerForBackgroundCompilation::ContributeToJumpTargetEnvironment(
......@@ -2961,9 +2903,6 @@ void SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess(
}
CHECK(!lookup_start_object_map.is_deprecated());
// For JSNativeContextSpecialization::InferRootMap
lookup_start_object_map.SerializeRootMap();
// For JSNativeContextSpecialization::ReduceNamedAccess.
JSGlobalProxyRef global_proxy =
broker()->target_native_context().global_proxy_object();
......@@ -2973,7 +2912,7 @@ void SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess(
base::Optional<PropertyCellRef> cell = global_object.GetPropertyCell(
name, SerializationPolicy::kSerializeIfNeeded);
if (cell.has_value()) {
CHECK(cell->Serialize());
CHECK(cell->Cache());
if (access_mode == AccessMode::kLoad) {
result_hints->AddConstant(
handle(cell->object()->value(), broker()->isolate()), zone(),
......@@ -3014,20 +2953,15 @@ void SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess(
FunctionTemplateInfoRef fti_ref =
MakeRef(broker(), sfi->get_api_func_data());
if (fti_ref.has_call_code()) {
fti_ref.SerializeCallCode();
ProcessReceiverMapForApiCall(fti_ref, receiver_map->object());
}
}
}
} else if (access_info.constant()->IsJSBoundFunction()) {
// For JSCallReducer::ReduceJSCall.
JSBoundFunctionRef function = MakeRef(
broker(), Handle<JSBoundFunction>::cast(access_info.constant()));
function.Serialize();
MakeRef(broker(), Handle<JSBoundFunction>::cast(access_info.constant()));
} else {
FunctionTemplateInfoRef fti = MakeRef(
broker(), FunctionTemplateInfo::cast(*access_info.constant()));
if (fti.has_call_code()) fti.SerializeCallCode();
MakeRef(broker(), FunctionTemplateInfo::cast(*access_info.constant()));
}
} else if (access_info.IsModuleExport()) {
// For JSNativeContextSpecialization::BuildPropertyLoad
......@@ -3266,35 +3200,13 @@ void SerializerForBackgroundCompilation::ProcessElementAccess(
ElementAccessFeedback const& feedback, AccessMode access_mode) {
for (auto const& group : feedback.transition_groups()) {
for (Handle<Map> map_handle : group) {
MapRef map = MakeRef(broker(), map_handle);
switch (access_mode) {
case AccessMode::kHas:
case AccessMode::kLoad:
map.SerializePrototype();
break;
case AccessMode::kStore:
map.SerializeForElementStore();
break;
case AccessMode::kStoreInLiteral:
// This operation is fairly local and simple, nothing to serialize.
break;
}
MakeRef(broker(), map_handle);
}
}
for (Handle<Object> hint : receiver.constants()) {
ObjectRef receiver_ref = MakeRef(broker(), hint);
// For JSNativeContextSpecialization::InferRootMap
if (receiver_ref.IsHeapObject()) {
receiver_ref.AsHeapObject().map().SerializeRootMap();
}
// For JSNativeContextSpecialization::ReduceElementAccess.
if (receiver_ref.IsJSTypedArray()) {
receiver_ref.AsJSTypedArray().Serialize();
}
// For JSNativeContextSpecialization::ReduceElementLoadFromHeapConstant.
if (access_mode == AccessMode::kLoad || access_mode == AccessMode::kHas) {
for (Handle<Object> hint : key.constants()) {
......@@ -3304,7 +3216,6 @@ void SerializerForBackgroundCompilation::ProcessElementAccess(
base::Optional<ObjectRef> element;
if (receiver_ref.IsJSObject()) {
JSObjectRef jsobject_ref = receiver_ref.AsJSObject();
jsobject_ref.SerializeElements();
element = receiver_ref.AsJSObject().GetOwnConstantElement(
jsobject_ref.elements(kRelaxedLoad).value(), key_ref.AsSmi(),
nullptr, SerializationPolicy::kSerializeIfNeeded);
......@@ -3328,8 +3239,7 @@ void SerializerForBackgroundCompilation::ProcessElementAccess(
// For JSNativeContextSpecialization::InferRootMap
for (Handle<Map> map : receiver.maps()) {
MapRef map_ref = MakeRef(broker(), map);
map_ref.SerializeRootMap();
MakeRef(broker(), map);
}
}
......@@ -3385,7 +3295,6 @@ void SerializerForBackgroundCompilation::VisitTestIn(
void SerializerForBackgroundCompilation::ProcessConstantForOrdinaryHasInstance(
HeapObjectRef const& constructor, bool* walk_prototypes) {
if (constructor.IsJSBoundFunction()) {
constructor.AsJSBoundFunction().Serialize();
ProcessConstantForInstanceOf(
constructor.AsJSBoundFunction().bound_target_function().value(),
walk_prototypes);
......
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