[build] Reduce dependencies on deserializer.h

Several headers in the large inline objects header cycle were depending
on deserializer.h to access Deserializer::uninitialized_field_value().
Unfortunately this meant that a change to many snapshot headers caused a
rebuild of over 1480 files.

This moves the constant into smi.h which would always be included by the
objects inline headers.

Bug: v8:11879
Change-Id: I2efd1c42efd43e6cd4630cea7fd76dd2bd29ae3d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2992717
Commit-Queue: Dan Elphick <delphick@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Auto-Submit: Dan Elphick <delphick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75439}
This commit is contained in:
Dan Elphick 2021-06-28 22:33:02 +01:00 committed by V8 LUCI CQ
parent 4d43ab04a4
commit bf096ec960
8 changed files with 34 additions and 30 deletions

View File

@ -50,6 +50,7 @@
#include "src/objects/js-objects-inl.h"
#include "src/objects/maybe-object.h"
#include "src/objects/slots-inl.h"
#include "src/objects/smi.h"
#include "src/objects/transitions-inl.h"
#include "src/tasks/cancelable-task.h"
#include "src/tracing/tracing-category-observer.h"
@ -2311,7 +2312,7 @@ void MarkCompactCollector::ClearFullMapTransitions() {
if (constructor_or_back_pointer.IsSmi()) {
DCHECK(isolate()->has_active_deserializer());
DCHECK_EQ(constructor_or_back_pointer,
Deserializer::uninitialized_field_value());
Smi::uninitialized_deserialization_value());
continue;
}
Map parent = Map::cast(map.constructor_or_back_pointer());
@ -2339,7 +2340,7 @@ bool MarkCompactCollector::TransitionArrayNeedsCompaction(
if (raw_target.IsSmi()) {
// This target is still being deserialized,
DCHECK(isolate()->has_active_deserializer());
DCHECK_EQ(raw_target.ToSmi(), Deserializer::uninitialized_field_value());
DCHECK_EQ(raw_target.ToSmi(), Smi::uninitialized_deserialization_value());
#ifdef DEBUG
// Targets can only be dead iff this array is fully deserialized.
for (int i = 0; i < num_transitions; ++i) {

View File

@ -10,7 +10,7 @@
#include "src/heap/objects-visiting.h"
#include "src/heap/spaces.h"
#include "src/objects/objects.h"
#include "src/snapshot/deserializer.h"
#include "src/objects/smi.h"
namespace v8 {
namespace internal {
@ -413,7 +413,7 @@ int MarkingVisitorBase<ConcreteVisitor, MarkingState>::VisitDescriptorsForMap(
// If the descriptors are a Smi, then this Map is in the process of being
// deserialized, and doesn't yet have an initialized descriptor field.
if (maybe_descriptors.IsSmi()) {
DCHECK_EQ(maybe_descriptors, Deserializer::uninitialized_field_value());
DCHECK_EQ(maybe_descriptors, Smi::uninitialized_deserialization_value());
return 0;
}

View File

@ -13,6 +13,7 @@
#include "src/logging/counters.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-promise-inl.h"
#include "src/objects/smi.h"
#include "src/tasks/task-utils.h"
namespace v8 {
@ -355,7 +356,7 @@ bool NativeContextInferrer::InferForJSFunction(Isolate* isolate,
function);
// The context may be a smi during deserialization.
if (maybe_context.IsSmi()) {
DCHECK_EQ(maybe_context, Deserializer::uninitialized_field_value());
DCHECK_EQ(maybe_context, Smi::uninitialized_deserialization_value());
return false;
}
if (!maybe_context.IsContext()) {

View File

@ -95,6 +95,21 @@ class Smi : public Object {
static inline constexpr Smi zero() { return Smi::FromInt(0); }
static constexpr int kMinValue = kSmiMinValue;
static constexpr int kMaxValue = kSmiMaxValue;
// Smi value for filling in not-yet initialized tagged field values with a
// valid tagged pointer. A field value equal to this doesn't necessarily
// indicate that a field is uninitialized, but an uninitialized field should
// definitely equal this value.
//
// This _has_ to be kNullAddress, so that an uninitialized field value read as
// an embedded pointer field is interpreted as nullptr. This is so that
// uninitialised embedded pointers are not forwarded to the embedder as part
// of embedder tracing (and similar mechanisms), as nullptrs are skipped for
// those cases and otherwise the embedder would try to dereference the
// uninitialized pointer value.
static constexpr Smi uninitialized_deserialization_value() {
return Smi(kNullAddress);
}
};
CAST_ACCESSOR(Smi)

View File

@ -10,7 +10,6 @@
#include "src/objects/slots.h"
#include "src/objects/smi.h"
#include "src/objects/transitions.h"
#include "src/snapshot/deserializer.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@ -161,7 +160,7 @@ bool TransitionArray::GetTargetIfExists(int transition_number, Isolate* isolate,
// transition.
if (raw.IsSmi()) {
DCHECK(isolate->has_active_deserializer());
DCHECK_EQ(raw.ToSmi(), Deserializer::uninitialized_field_value());
DCHECK_EQ(raw.ToSmi(), Smi::uninitialized_deserialization_value());
return false;
}
if (raw->GetHeapObjectIfStrong(&heap_object) &&

View File

@ -27,7 +27,6 @@
#include "src/objects/objects-body-descriptors-inl.h"
#include "src/objects/objects.h"
#include "src/objects/slots.h"
#include "src/objects/smi.h"
#include "src/objects/string.h"
#include "src/roots/roots.h"
#include "src/snapshot/embedded/embedded-data.h"
@ -528,9 +527,9 @@ Handle<HeapObject> Deserializer::ReadObject(SnapshotSpace space) {
// * The rest of the object is filled with a fixed Smi value
// - This is a Smi so that tagged fields become initialized to a valid
// tagged value.
// - It's a fixed value, "uninitialized_field_value", so that we can
// DCHECK for it when reading objects that are assumed to be partially
// initialized objects.
// - It's a fixed value, "Smi::uninitialized_deserialization_value()", so
// that we can DCHECK for it when reading objects that are assumed to be
// partially initialized objects.
// * The fields of the object are deserialized in order, under the
// assumption that objects are laid out in such a way that any fields
// required for object iteration (e.g. length fields) are deserialized
@ -540,8 +539,8 @@ Handle<HeapObject> Deserializer::ReadObject(SnapshotSpace space) {
HeapObject raw_obj =
Allocate(space, size_in_bytes, HeapObject::RequiredAlignment(*map));
raw_obj.set_map_after_allocation(*map);
MemsetTagged(raw_obj.RawField(kTaggedSize), uninitialized_field_value(),
size_in_tagged - 1);
MemsetTagged(raw_obj.RawField(kTaggedSize),
Smi::uninitialized_deserialization_value(), size_in_tagged - 1);
// Make sure BytecodeArrays have a valid age, so that the marker doesn't
// break when making them older.
@ -599,8 +598,8 @@ Handle<HeapObject> Deserializer::ReadMetaMap() {
HeapObject raw_obj = Allocate(space, size_in_bytes, kWordAligned);
raw_obj.set_map_after_allocation(Map::unchecked_cast(raw_obj));
MemsetTagged(raw_obj.RawField(kTaggedSize), uninitialized_field_value(),
size_in_tagged - 1);
MemsetTagged(raw_obj.RawField(kTaggedSize),
Smi::uninitialized_deserialization_value(), size_in_tagged - 1);
Handle<HeapObject> obj = handle(raw_obj, isolate());
back_refs_.push_back(obj);

View File

@ -15,6 +15,7 @@
#include "src/objects/code.h"
#include "src/objects/js-array.h"
#include "src/objects/map.h"
#include "src/objects/smi.h"
#include "src/objects/string-table.h"
#include "src/objects/string.h"
#include "src/snapshot/serializer-deserializer.h"
@ -40,19 +41,6 @@ class Object;
// A Deserializer reads a snapshot and reconstructs the Object graph it defines.
class V8_EXPORT_PRIVATE Deserializer : public SerializerDeserializer {
public:
// Smi value for filling in not-yet initialized tagged field values with a
// valid tagged pointer. A field value equal to this doesn't necessarily
// indicate that a field is uninitialized, but an uninitialized field should
// definitely equal this value.
//
// This _has_ to be kNullAddress, so that an uninitialized_field_value read as
// an embedded pointer field is interpreted as nullptr. This is so that
// uninitialised embedded pointers are not forwarded to the embedded as part
// of embedder tracing (and similar mechanisms), as nullptrs are skipped for
// those cases and otherwise the embedder would try to dereference the
// uninitialized pointer value.
static constexpr Smi uninitialized_field_value() { return Smi(kNullAddress); }
~Deserializer() override;
Deserializer(const Deserializer&) = delete;
Deserializer& operator=(const Deserializer&) = delete;

View File

@ -4,6 +4,7 @@
#include "src/heap/memory-measurement-inl.h"
#include "src/heap/memory-measurement.h"
#include "src/objects/smi.h"
#include "test/cctest/cctest.h"
#include "test/cctest/heap/heap-tester.h"
#include "test/cctest/heap/heap-utils.h"
@ -239,7 +240,7 @@ TEST(PartiallyInitializedJSFunction) {
isolate->RegisterDeserializerStarted();
// 2. Set the context field to the uninitialized sentintel.
TaggedField<Object, JSFunction::kContextOffset>::store(
*js_function, Deserializer::uninitialized_field_value());
*js_function, Smi::uninitialized_deserialization_value());
// 3. Request memory meaurement and run all tasks. GC that runs as part
// of the measurement should not crash.
CcTest::isolate()->MeasureMemory(
@ -269,7 +270,7 @@ TEST(PartiallyInitializedContext) {
isolate->RegisterDeserializerStarted();
// 2. Set the native context field to the uninitialized sentintel.
TaggedField<Object, Map::kConstructorOrBackPointerOrNativeContextOffset>::
store(*map, Deserializer::uninitialized_field_value());
store(*map, Smi::uninitialized_deserialization_value());
// 3. Request memory meaurement and run all tasks. GC that runs as part
// of the measurement should not crash.
CcTest::isolate()->MeasureMemory(