Commit 8ffbf0d2 authored by Nico Hartmann's avatar Nico Hartmann Committed by Commit Bot

[TurboFan] Move SFI and BytecodeArray to kNeverSerialized

This CL moves SharedFunctionInfo and BytecodeArray to the
kNeverSerialized classes, making them directly accessible from the
background thread.

To resolve the dependence on HeapNumber and BigInt objects stored in
the BytecodeArray's constant pool, this CL introduces a new
ObjectDataKind::kPossiblyBackgroundSerializedHeapObject, which allows
for objects to be serialized lazily from the background thread where
we know that this is safe (e.g. because they are constant). BigInt and
HeapNumber are the first members of this new group of objects.

Bug: v8:7790
Change-Id: I1d962d1cb7c36cc3f5baeb9603d5298f32af3363
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2567705Reviewed-by: 's avatarGeorg Neis (ooo until January 5) <neis@chromium.org>
Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71716}
parent 7f240f53
......@@ -1525,8 +1525,9 @@ void BytecodeGraphBuilder::VisitLdaSmi() {
}
void BytecodeGraphBuilder::VisitLdaConstant() {
ObjectRef object(
broker(), bytecode_iterator().GetConstantForIndexOperand(0, isolate()));
ObjectRef object(broker(),
bytecode_iterator().GetConstantForIndexOperand(0, isolate()),
ObjectRef::BackgroundSerialization::kAllowed);
Node* node = jsgraph()->Constant(object);
environment()->BindAccumulator(node);
}
......
......@@ -63,6 +63,8 @@ enum class OddballType : uint8_t {
V(ScopeInfo) \
/* Subtypes of String */ \
V(InternalizedString) \
/* Subtypes of FixedArrayBase */ \
V(BytecodeArray) \
/* Subtypes of Name */ \
V(Symbol) \
/* Subtypes of HeapObject */ \
......@@ -70,8 +72,21 @@ enum class OddballType : uint8_t {
V(ArrayBoilerplateDescription) \
V(CallHandlerInfo) \
V(Cell) \
V(SharedFunctionInfo) \
V(TemplateObjectDescription)
// This list is sorted such that subtypes appear before their supertypes.
// DO NOT VIOLATE THIS PROPERTY!
// Classes in this list behave like serialized classes, but they allow lazy
// serialization from background threads where this is safe (e.g. for objects
// that are immutable and fully initialized once visible). Pass
// ObjectRef::BackgroundSerialization::kAllowed to the ObjectRef constructor
// for objects where serialization from the background thread is safe.
#define HEAP_BROKER_POSSIBLY_BACKGROUND_SERIALIZED_OBJECT_LIST(V) \
/* Subtypes of HeapObject */ \
V(BigInt) \
V(HeapNumber)
// This list is sorted such that subtypes appear before their supertypes.
// DO NOT VIOLATE THIS PROPERTY!
#define HEAP_BROKER_SERIALIZED_OBJECT_LIST(V) \
......@@ -90,7 +105,6 @@ enum class OddballType : uint8_t {
V(Context) \
V(ScriptContextTable) \
/* Subtypes of FixedArrayBase */ \
V(BytecodeArray) \
V(FixedArray) \
V(FixedDoubleArray) \
/* Subtypes of Name */ \
......@@ -99,19 +113,16 @@ enum class OddballType : uint8_t {
V(JSObject) \
/* Subtypes of HeapObject */ \
V(AllocationSite) \
V(BigInt) \
V(Code) \
V(DescriptorArray) \
V(FeedbackCell) \
V(FeedbackVector) \
V(FixedArrayBase) \
V(FunctionTemplateInfo) \
V(HeapNumber) \
V(JSReceiver) \
V(Map) \
V(Name) \
V(PropertyCell) \
V(SharedFunctionInfo) \
V(SourceTextModule) \
/* Subtypes of Object */ \
V(HeapObject)
......@@ -124,18 +135,25 @@ class PerIsolateCompilerCache;
class PropertyAccessInfo;
#define FORWARD_DECL(Name) class Name##Ref;
HEAP_BROKER_SERIALIZED_OBJECT_LIST(FORWARD_DECL)
HEAP_BROKER_POSSIBLY_BACKGROUND_SERIALIZED_OBJECT_LIST(FORWARD_DECL)
HEAP_BROKER_NEVER_SERIALIZED_OBJECT_LIST(FORWARD_DECL)
#undef FORWARD_DECL
class V8_EXPORT_PRIVATE ObjectRef {
public:
enum class BackgroundSerialization {
kDisallowed,
kAllowed,
};
ObjectRef(JSHeapBroker* broker, Handle<Object> object,
BackgroundSerialization background_serialization =
BackgroundSerialization::kDisallowed,
bool check_type = true);
ObjectRef(JSHeapBroker* broker, ObjectData* data, bool check_type = true)
: data_(data), broker_(broker) {
CHECK_NOT_NULL(data_);
}
Handle<Object> object() const;
bool equals(const ObjectRef& other) const;
......@@ -146,11 +164,13 @@ class V8_EXPORT_PRIVATE ObjectRef {
#define HEAP_IS_METHOD_DECL(Name) bool Is##Name() const;
HEAP_BROKER_SERIALIZED_OBJECT_LIST(HEAP_IS_METHOD_DECL)
HEAP_BROKER_POSSIBLY_BACKGROUND_SERIALIZED_OBJECT_LIST(HEAP_IS_METHOD_DECL)
HEAP_BROKER_NEVER_SERIALIZED_OBJECT_LIST(HEAP_IS_METHOD_DECL)
#undef HEAP_IS_METHOD_DECL
#define HEAP_AS_METHOD_DECL(Name) Name##Ref As##Name() const;
HEAP_BROKER_SERIALIZED_OBJECT_LIST(HEAP_AS_METHOD_DECL)
HEAP_BROKER_POSSIBLY_BACKGROUND_SERIALIZED_OBJECT_LIST(HEAP_AS_METHOD_DECL)
HEAP_BROKER_NEVER_SERIALIZED_OBJECT_LIST(HEAP_AS_METHOD_DECL)
#undef HEAP_AS_METHOD_DECL
......@@ -241,8 +261,10 @@ class HeapObjectType {
// the outermost Ref class in the inheritance chain only.
#define DEFINE_REF_CONSTRUCTOR(name, base) \
name##Ref(JSHeapBroker* broker, Handle<Object> object, \
BackgroundSerialization background_serialization = \
BackgroundSerialization::kDisallowed, \
bool check_type = true) \
: base(broker, object, false) { \
: base(broker, object, background_serialization, false) { \
if (check_type) { \
CHECK(Is##name()); \
} \
......
......@@ -48,11 +48,12 @@ Node* JSGraph::CEntryStubConstant(int result_size, SaveFPRegsMode save_doubles,
Node* JSGraph::Constant(const ObjectRef& ref) {
if (ref.IsSmi()) return Constant(ref.AsSmi());
OddballType oddball_type =
ref.AsHeapObject().GetHeapObjectType().oddball_type();
if (ref.IsHeapNumber()) {
return Constant(ref.AsHeapNumber().value());
} else if (oddball_type == OddballType::kUndefined) {
}
OddballType oddball_type =
ref.AsHeapObject().GetHeapObjectType().oddball_type();
if (oddball_type == OddballType::kUndefined) {
DCHECK(ref.object().equals(isolate()->factory()->undefined_value()));
return UndefinedConstant();
} else if (oddball_type == OddballType::kNull) {
......
......@@ -48,6 +48,7 @@ namespace compiler {
HEAP_BROKER_SERIALIZED_OBJECT_LIST(FORWARD_DECL)
// TODO(solanes, v8:10866): Remove once FLAG_turbo_direct_heap_access is
// removed.
HEAP_BROKER_POSSIBLY_BACKGROUND_SERIALIZED_OBJECT_LIST(FORWARD_DECL)
HEAP_BROKER_NEVER_SERIALIZED_OBJECT_LIST(FORWARD_DECL)
#undef FORWARD_DECL
......@@ -62,6 +63,10 @@ HEAP_BROKER_NEVER_SERIALIZED_OBJECT_LIST(FORWARD_DECL)
// data is an instance of the corresponding (most-specific) subclass, e.g.
// JSFunctionData, which provides serialized information about the object.
//
// kPossiblyBackgroundSerializedHeapObject: Like kSerializedHeapObject, but
// allows serialization from the background thread where this is safe
// (indicated by corresponding ObjectRef constructor argument).
//
// kUnserializedHeapObject: The underlying V8 object is a HeapObject and the
// data is an instance of the base class (ObjectData), i.e. it basically
// carries no information other than the handle.
......@@ -79,6 +84,7 @@ HEAP_BROKER_NEVER_SERIALIZED_OBJECT_LIST(FORWARD_DECL)
enum ObjectDataKind {
kSmi,
kSerializedHeapObject,
kPossiblyBackgroundSerializedHeapObject,
kUnserializedHeapObject,
kNeverSerializedHeapObject,
kUnserializedReadOnlyHeapObject
......@@ -117,13 +123,16 @@ class ObjectData : public ZoneObject {
broker->mode() == JSHeapBroker::kSerializing,
broker->isolate()->handle_scope_data()->canonical_scope != nullptr);
CHECK_IMPLIES(broker->mode() == JSHeapBroker::kSerialized,
(kind == kUnserializedReadOnlyHeapObject &&
IsReadOnlyHeapObject(*object)) ||
kind == kNeverSerializedHeapObject);
kind == kUnserializedReadOnlyHeapObject || kind == kSmi ||
kind == kNeverSerializedHeapObject ||
kind == kPossiblyBackgroundSerializedHeapObject);
CHECK_IMPLIES(kind == kUnserializedReadOnlyHeapObject,
IsReadOnlyHeapObject(*object));
}
#define DECLARE_IS(Name) bool Is##Name() const;
HEAP_BROKER_SERIALIZED_OBJECT_LIST(DECLARE_IS)
HEAP_BROKER_POSSIBLY_BACKGROUND_SERIALIZED_OBJECT_LIST(DECLARE_IS)
HEAP_BROKER_NEVER_SERIALIZED_OBJECT_LIST(DECLARE_IS)
#undef DECLARE_IS
......@@ -131,6 +140,7 @@ class ObjectData : public ZoneObject {
HEAP_BROKER_SERIALIZED_OBJECT_LIST(DECLARE_AS)
// TODO(solanes, v8:10866): Remove once FLAG_turbo_direct_heap_access is
// removed.
HEAP_BROKER_POSSIBLY_BACKGROUND_SERIALIZED_OBJECT_LIST(DECLARE_AS)
HEAP_BROKER_NEVER_SERIALIZED_OBJECT_LIST(DECLARE_AS)
#undef DECLARE_AS
......@@ -156,7 +166,8 @@ class ObjectData : public ZoneObject {
class HeapObjectData : public ObjectData {
public:
HeapObjectData(JSHeapBroker* broker, ObjectData** storage,
Handle<HeapObject> object);
Handle<HeapObject> object,
ObjectDataKind kind = ObjectDataKind::kSerializedHeapObject);
bool boolean_value() const { return boolean_value_; }
ObjectData* map() const { return map_; }
......@@ -669,7 +680,9 @@ class HeapNumberData : public HeapObjectData {
public:
HeapNumberData(JSHeapBroker* broker, ObjectData** storage,
Handle<HeapNumber> object)
: HeapObjectData(broker, storage, object), value_(object->value()) {}
: HeapObjectData(broker, storage, object,
kPossiblyBackgroundSerializedHeapObject),
value_(object->value()) {}
double value() const { return value_; }
......@@ -966,7 +979,8 @@ class AllocationSiteData : public HeapObjectData {
class BigIntData : public HeapObjectData {
public:
BigIntData(JSHeapBroker* broker, ObjectData** storage, Handle<BigInt> object)
: HeapObjectData(broker, storage, object),
: HeapObjectData(broker, storage, object,
ObjectDataKind::kPossiblyBackgroundSerializedHeapObject),
as_uint64_(object->AsUint64(nullptr)) {}
uint64_t AsUint64() const { return as_uint64_; }
......@@ -1154,8 +1168,8 @@ void AllocationSiteData::SerializeBoilerplate(JSHeapBroker* broker) {
}
HeapObjectData::HeapObjectData(JSHeapBroker* broker, ObjectData** storage,
Handle<HeapObject> object)
: ObjectData(broker, storage, object, kSerializedHeapObject),
Handle<HeapObject> object, ObjectDataKind kind)
: ObjectData(broker, storage, object, kind),
boolean_value_(object->BooleanValue(broker->isolate())),
// We have to use a raw cast below instead of AsMap() because of
// recursion. AsMap() would call IsMap(), which accesses the
......@@ -1163,7 +1177,10 @@ HeapObjectData::HeapObjectData(JSHeapBroker* broker, ObjectData** storage,
// meta map (whose map is itself), this member has not yet been
// initialized.
map_(broker->GetOrCreateData(object->map())) {
CHECK_EQ(broker->mode(), JSHeapBroker::kSerializing);
CHECK_IMPLIES(kind == kSerializedHeapObject,
broker->mode() == JSHeapBroker::kSerializing);
CHECK_IMPLIES(broker->mode() == JSHeapBroker::kSerialized,
kind == kPossiblyBackgroundSerializedHeapObject);
}
InstanceType HeapObjectData::GetMapInstanceType() const {
......@@ -1985,17 +2002,27 @@ class CodeData : public HeapObjectData {
return InstanceTypeChecker::Is##Name(instance_type); \
}
HEAP_BROKER_SERIALIZED_OBJECT_LIST(DEFINE_IS)
HEAP_BROKER_POSSIBLY_BACKGROUND_SERIALIZED_OBJECT_LIST(DEFINE_IS)
HEAP_BROKER_NEVER_SERIALIZED_OBJECT_LIST(DEFINE_IS)
#undef DEFINE_IS
#define DEFINE_AS(Name) \
Name##Data* ObjectData::As##Name() { \
CHECK(Is##Name()); \
CHECK_EQ(kind_, kSerializedHeapObject); \
CHECK(kind_ == kSerializedHeapObject || \
kind_ == kPossiblyBackgroundSerializedHeapObject); \
return static_cast<Name##Data*>(this); \
}
HEAP_BROKER_SERIALIZED_OBJECT_LIST(DEFINE_AS)
#undef DEFINE_AS
#define DEFINE_AS(Name) \
Name##Data* ObjectData::As##Name() { \
CHECK(Is##Name()); \
CHECK_EQ(kind_, kPossiblyBackgroundSerializedHeapObject); \
return static_cast<Name##Data*>(this); \
}
HEAP_BROKER_POSSIBLY_BACKGROUND_SERIALIZED_OBJECT_LIST(DEFINE_AS)
#undef DEFINE_AS
// TODO(solanes, v8:10866): Remove once FLAG_turbo_direct_heap_access is
// removed.
......@@ -2674,7 +2701,8 @@ void JSHeapBroker::InitializeAndStartSerializing(
}
// clang-format off
ObjectData* JSHeapBroker::GetOrCreateData(Handle<Object> object) {
ObjectData* JSHeapBroker::GetOrCreateData(Handle<Object> object,
ObjectRef::BackgroundSerialization background_serialization) {
RefsMap::Entry* entry = refs_->LookupOrInsert(object.address());
ObjectData* object_data = entry->value;
......@@ -2702,6 +2730,17 @@ ObjectData* JSHeapBroker::GetOrCreateData(Handle<Object> object) {
}
HEAP_BROKER_NEVER_SERIALIZED_OBJECT_LIST(CREATE_DATA_FOR_DIRECT_READ)
#undef CREATE_DATA_FOR_DIRECT_READ
#define CREATE_DATA_FOR_POSSIBLE_SERIALIZATION(name) \
} else if (object->Is##name()) { \
CHECK_IMPLIES(mode() == kSerialized, \
background_serialization \
== ObjectRef::BackgroundSerialization::kAllowed); \
AllowHandleAllocation handle_allocation; \
object_data = zone()->New<name##Data>(this, data_storage, \
Handle<name>::cast(object));
HEAP_BROKER_POSSIBLY_BACKGROUND_SERIALIZED_OBJECT_LIST(
CREATE_DATA_FOR_POSSIBLE_SERIALIZATION)
#undef CREATE_DATA_FOR_POSSIBLE_SERIALIZATION
#define CREATE_DATA_FOR_SERIALIZATION(name) \
} else if (object->Is##name()) { \
CHECK_EQ(mode(), kSerializing); \
......@@ -2721,8 +2760,11 @@ ObjectData* JSHeapBroker::GetOrCreateData(Handle<Object> object) {
}
// clang-format on
ObjectData* JSHeapBroker::GetOrCreateData(Object object) {
return GetOrCreateData(CanonicalPersistentHandle(object));
ObjectData* JSHeapBroker::GetOrCreateData(
Object object,
ObjectRef::BackgroundSerialization background_serialization) {
return GetOrCreateData(CanonicalPersistentHandle(object),
background_serialization);
}
#define DEFINE_IS_AND_AS(Name) \
......@@ -2732,6 +2774,7 @@ ObjectData* JSHeapBroker::GetOrCreateData(Object object) {
return Name##Ref(broker(), data()); \
}
HEAP_BROKER_SERIALIZED_OBJECT_LIST(DEFINE_IS_AND_AS)
HEAP_BROKER_POSSIBLY_BACKGROUND_SERIALIZED_OBJECT_LIST(DEFINE_IS_AND_AS)
HEAP_BROKER_NEVER_SERIALIZED_OBJECT_LIST(DEFINE_IS_AND_AS)
#undef DEFINE_IS_AND_AS
......@@ -3734,6 +3777,7 @@ ObjectRef SourceTextModuleRef::import_meta() const {
}
ObjectRef::ObjectRef(JSHeapBroker* broker, Handle<Object> object,
BackgroundSerialization background_serialization,
bool check_type)
: broker_(broker) {
switch (broker->mode()) {
......@@ -3742,7 +3786,7 @@ ObjectRef::ObjectRef(JSHeapBroker* broker, Handle<Object> object,
// them.
case JSHeapBroker::kSerialized:
case JSHeapBroker::kSerializing:
data_ = broker->GetOrCreateData(object);
data_ = broker->GetOrCreateData(object, background_serialization);
break;
case JSHeapBroker::kDisabled: {
RefsMap::Entry* entry = broker->refs_->LookupOrInsert(object.address());
......@@ -3933,6 +3977,7 @@ Handle<Object> ObjectRef::object() const {
#endif // DEBUG
HEAP_BROKER_SERIALIZED_OBJECT_LIST(DEF_OBJECT_GETTER)
HEAP_BROKER_POSSIBLY_BACKGROUND_SERIALIZED_OBJECT_LIST(DEF_OBJECT_GETTER)
HEAP_BROKER_NEVER_SERIALIZED_OBJECT_LIST(DEF_OBJECT_GETTER)
#undef DEF_OBJECT_GETTER
......
......@@ -149,9 +149,14 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
Handle<Object> GetRootHandle(Object object);
// Never returns nullptr.
ObjectData* GetOrCreateData(Handle<Object>);
ObjectData* GetOrCreateData(
Handle<Object>,
ObjectRef::BackgroundSerialization background_serialization =
ObjectRef::BackgroundSerialization::kDisallowed);
// Like the previous but wraps argument in handle first (for convenience).
ObjectData* GetOrCreateData(Object);
ObjectData* GetOrCreateData(
Object, ObjectRef::BackgroundSerialization background_serialization =
ObjectRef::BackgroundSerialization::kDisallowed);
// Check if {object} is any native context's %ArrayPrototype% or
// %ObjectPrototype%.
......
......@@ -1529,10 +1529,14 @@ void SerializerForBackgroundCompilation::VisitInvokeIntrinsic(
void SerializerForBackgroundCompilation::VisitLdaConstant(
BytecodeArrayIterator* iterator) {
ObjectRef object(
broker(), iterator->GetConstantForIndexOperand(0, broker()->isolate()));
environment()->accumulator_hints() =
Hints::SingleConstant(object.object(), zone());
Handle<Object> constant =
iterator->GetConstantForIndexOperand(0, broker()->isolate());
// TODO(v8:7790): FixedArrays still need to be serialized until they are
// moved to kNeverSerialized.
if (!FLAG_turbo_direct_heap_access || constant->IsFixedArray()) {
ObjectRef(broker(), constant);
}
environment()->accumulator_hints() = Hints::SingleConstant(constant, zone());
}
void SerializerForBackgroundCompilation::VisitPushContext(
......
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