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;
......
This diff is collapsed.
......@@ -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) {
......
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