Reland "[compiler] Make NativeContextRef never-serialized"

This is a reland of 5258364e23

No changes since revert.

Original change's description:
> [compiler] Make NativeContextRef never-serialized
>
> Most NativeContext elements are immutable after initialization;
> additionally, we now use acquire-release semantics to load/store
> elements when possible. Reading and constructing Refs for elements
> is thus possible from the background.
>
> A few notes:
>
> - A few elements are not immutable; if read from the background
> thread, these must use acquire-release semantics.
> - Elements can be stored from generated code; these are not compatible
> with bg-thread accesses.
> - While elements can be read safely from the native context, the
> elements themselves may still require serialization; this is done in
> NativeContextRef::Serialize.
>
> Bug: v8:7790
> Change-Id: I12e9611a292e7dd912438c712390731a5422407d
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2897254
> Auto-Submit: Jakob Gruber <jgruber@chromium.org>
> Commit-Queue: Jakob Gruber <jgruber@chromium.org>
> Commit-Queue: Georg Neis <neis@chromium.org>
> Reviewed-by: Georg Neis <neis@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#74604}

Tbr: neis@chromium.org
Bug: v8:7790
Change-Id: Ica736a4afda2be7276508fe2f734293d0b9eeaf1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2917606
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74774}
This commit is contained in:
Jakob Gruber 2021-05-17 14:05:04 +02:00 committed by V8 LUCI CQ
parent c21d0148d6
commit 6b9c91e78c
3 changed files with 66 additions and 28 deletions

View File

@ -3394,11 +3394,6 @@ BIMODAL_ACCESSOR_WITH_FLAG(Map, Object, GetConstructor)
BIMODAL_ACCESSOR_WITH_FLAG(Map, HeapObject, GetBackPointer)
BIMODAL_ACCESSOR_C(Map, bool, is_abandoned_prototype_map)
#define DEF_NATIVE_CONTEXT_ACCESSOR(type, name) \
BIMODAL_ACCESSOR(NativeContext, type, name)
BROKER_NATIVE_CONTEXT_FIELDS(DEF_NATIVE_CONTEXT_ACCESSOR)
#undef DEF_NATIVE_CONTEXT_ACCESSOR
BIMODAL_ACCESSOR_C(ObjectBoilerplateDescription, int, size)
BIMODAL_ACCESSOR(PropertyCell, Object, value)
@ -3752,6 +3747,39 @@ bool StringRef::IsSeqString() const {
return data()->AsString()->is_seq_string();
}
void NativeContextRef::Serialize() {
// 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);
if (data_->should_access_heap()) {
#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()); \
} \
if (member_data->IsJSFunction()) { \
member_data->AsJSFunction()->Serialize(broker()); \
} \
}
BROKER_COMPULSORY_NATIVE_CONTEXT_FIELDS(SERIALIZE_MEMBER)
BROKER_OPTIONAL_NATIVE_CONTEXT_FIELDS(SERIALIZE_MEMBER)
#undef SERIALIZE_MEMBER
} else {
data()->AsNativeContext()->Serialize(broker());
}
}
void NativeContextRef::SerializeOnBackground() {
if (data_->should_access_heap()) return;
CHECK(broker()->mode() == JSHeapBroker::kSerializing ||
broker()->mode() == JSHeapBroker::kSerialized);
data()->AsNativeContext()->SerializeOnBackground(broker());
}
bool NativeContextRef::is_unserialized_heap_object() const {
return data_->kind() == kUnserializedHeapObject;
}
@ -3764,15 +3792,6 @@ ScopeInfoRef NativeContextRef::scope_info() const {
return ScopeInfoRef(broker(), data()->AsNativeContext()->scope_info());
}
SharedFunctionInfoRef FeedbackVectorRef::shared_function_info() const {
if (data_->should_access_heap()) {
return MakeRef(broker(), object()->shared_function_info());
}
return SharedFunctionInfoRef(
broker(), data()->AsFeedbackVector()->shared_function_info());
}
MapRef NativeContextRef::GetFunctionMapFromIndex(int index) const {
DCHECK_GE(index, Context::FIRST_FUNCTION_MAP_INDEX);
DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX);
@ -3805,6 +3824,18 @@ MapRef NativeContextRef::GetInitialJSArrayMap(ElementsKind kind) const {
}
}
#define DEF_NATIVE_CONTEXT_ACCESSOR(ResultType, Name) \
ResultType##Ref NativeContextRef::Name() const { \
if (data_->should_access_heap()) { \
return MakeRefAssumeMemoryFence( \
broker(), ResultType::cast(object()->Name(kAcquireLoad))); \
} \
return ResultType##Ref(broker(), \
ObjectRef::data()->AsNativeContext()->Name()); \
}
BROKER_NATIVE_CONTEXT_FIELDS(DEF_NATIVE_CONTEXT_ACCESSOR)
#undef DEF_NATIVE_CONTEXT_ACCESSOR
base::Optional<JSFunctionRef> NativeContextRef::GetConstructorFunction(
const MapRef& map) const {
CHECK(map.IsPrimitiveMap());
@ -4184,6 +4215,15 @@ bool FeedbackVectorRef::serialized() const {
return data()->AsFeedbackVector()->serialized();
}
SharedFunctionInfoRef FeedbackVectorRef::shared_function_info() const {
if (data_->should_access_heap()) {
return MakeRef(broker(), object()->shared_function_info());
}
return SharedFunctionInfoRef(
broker(), data()->AsFeedbackVector()->shared_function_info());
}
bool NameRef::IsUniqueName() const {
// Must match Name::IsUniqueName.
return IsInternalizedString() || IsSymbol();
@ -4453,19 +4493,6 @@ void SourceTextModuleRef::Serialize() {
data()->AsSourceTextModule()->Serialize(broker());
}
void NativeContextRef::Serialize() {
if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsNativeContext()->Serialize(broker());
}
void NativeContextRef::SerializeOnBackground() {
if (data_->should_access_heap()) return;
CHECK(broker()->mode() == JSHeapBroker::kSerializing ||
broker()->mode() == JSHeapBroker::kSerialized);
data()->AsNativeContext()->SerializeOnBackground(broker());
}
void JSTypedArrayRef::Serialize() {
if (data_->should_access_heap() || broker()->is_concurrent_inlining()) {
// Even if the typed array object itself is no longer serialized (besides

View File

@ -88,7 +88,7 @@ enum class RefSerializationKind {
V(JSGlobalProxy, RefSerializationKind::kSerialized) \
V(JSTypedArray, RefSerializationKind::kSerialized) \
/* Subtypes of Context */ \
V(NativeContext, RefSerializationKind::kSerialized) \
V(NativeContext, RefSerializationKind::kNeverSerialized) \
/* Subtypes of FixedArray */ \
V(ObjectBoilerplateDescription, RefSerializationKind::kNeverSerialized) \
V(ScriptContextTable, RefSerializationKind::kBackgroundSerialized) \

View File

@ -688,6 +688,17 @@ class NativeContext : public Context {
ScriptContextTable script_context_table);
inline ScriptContextTable synchronized_script_context_table() const;
// Caution, hack: this getter ignores the AcquireLoadTag. The global_object
// slot is safe to read concurrently since it is immutable after
// initialization. This function should *not* be used from anywhere other
// than heap-refs.cc.
// TODO(jgruber): Remove this function after NativeContextRef is actually
// never serialized and BROKER_COMPULSORY_NATIVE_CONTEXT_FIELDS is removed.
JSGlobalObject global_object() { return Context::global_object(); }
JSGlobalObject global_object(AcquireLoadTag) {
return Context::global_object();
}
// Dispatched behavior.
DECL_PRINTER(NativeContext)
DECL_VERIFIER(NativeContext)