[compiler] Mark Name and its subclasses as NeverEverSerialized

Mark:
 * InternalizedString
 * String
 * Symbol
 * Name

Bug: v8:7790
Change-Id: I17463d51ffe8a50711f5b4916c9beb369bac7f38
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2982480
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75551}
This commit is contained in:
Santiago Aboy Solanes 2021-07-05 09:57:49 +01:00 committed by V8 LUCI CQ
parent 1f66a47a9b
commit 969e1c5ef6

View File

@ -916,87 +916,47 @@ class NameData : public HeapObjectData {
public:
NameData(JSHeapBroker* broker, ObjectData** storage, Handle<Name> object)
: HeapObjectData(broker, storage, object) {
DCHECK(!broker->is_concurrent_inlining());
// StringData is NeverEverSerialize.
// TODO(solanes, v8:7790): Remove this class once all kNeverSerialized types
// are NeverEverSerialize.
UNREACHABLE();
}
};
class StringData : public NameData {
public:
StringData(JSHeapBroker* broker, ObjectData** storage, Handle<String> object);
int length() const { return length_; }
uint16_t first_char() const { return first_char_; }
base::Optional<double> to_number() const { return to_number_; }
bool is_external_string() const { return is_external_string_; }
bool is_seq_string() const { return is_seq_string_; }
ObjectData* GetCharAsStringOrUndefined(
JSHeapBroker* broker, uint32_t index,
SerializationPolicy policy = SerializationPolicy::kAssumeSerialized);
private:
int const length_;
uint16_t const first_char_;
base::Optional<double> to_number_;
bool const is_external_string_;
bool const is_seq_string_;
// Known individual characters as strings, corresponding to the semantics of
// element access (s[i]). The first pair component is always less than
// {length_}. The second component is never nullptr.
ZoneVector<std::pair<uint32_t, ObjectData*>> chars_as_strings_;
StringData(JSHeapBroker* broker, ObjectData** storage, Handle<String> object)
: NameData(broker, storage, object) {
// StringData is NeverEverSerialize.
// TODO(solanes, v8:7790): Remove this class once all kNeverSerialized types
// are NeverEverSerialize.
UNREACHABLE();
}
};
class SymbolData : public NameData {
public:
SymbolData(JSHeapBroker* broker, ObjectData** storage, Handle<Symbol> object)
: NameData(broker, storage, object) {
DCHECK(!broker->is_concurrent_inlining());
// StringData is NeverEverSerialize.
// TODO(solanes, v8:7790): Remove this class once all kNeverSerialized types
// are NeverEverSerialize.
UNREACHABLE();
}
};
StringData::StringData(JSHeapBroker* broker, ObjectData** storage,
Handle<String> object)
: NameData(broker, storage, object),
length_(object->length()),
first_char_(length_ > 0 ? object->Get(0) : 0),
to_number_(TryStringToDouble(broker->local_isolate(), object)),
is_external_string_(object->IsExternalString()),
is_seq_string_(object->IsSeqString()),
chars_as_strings_(broker->zone()) {
DCHECK(!broker->is_concurrent_inlining());
}
class InternalizedStringData : public StringData {
public:
InternalizedStringData(JSHeapBroker* broker, ObjectData** storage,
Handle<InternalizedString> object)
: StringData(broker, storage, object) {
DCHECK(!broker->is_concurrent_inlining());
// InternalizedStringData is NeverEverSerialize.
// TODO(solanes, v8:7790): Remove this class once all kNeverSerialized types
// are NeverEverSerialize.
UNREACHABLE();
}
};
ObjectData* StringData::GetCharAsStringOrUndefined(JSHeapBroker* broker,
uint32_t index,
SerializationPolicy policy) {
if (index >= static_cast<uint32_t>(length())) return nullptr;
for (auto const& p : chars_as_strings_) {
if (p.first == index) return p.second;
}
if (policy == SerializationPolicy::kAssumeSerialized) {
TRACE_MISSING(broker, "knowledge about index " << index << " on " << this);
return nullptr;
}
base::Optional<ObjectRef> element =
GetOwnElementFromHeap(broker, object(), index, true);
ObjectData* result = element.has_value() ? element->data() : nullptr;
chars_as_strings_.push_back({index, result});
return result;
}
namespace {
bool IsFastLiteralHelper(Handle<JSObject> boilerplate, int max_depth,
@ -2623,10 +2583,14 @@ NEVER_EVER_SERIALIZE(BytecodeArray)
NEVER_EVER_SERIALIZE(Cell)
NEVER_EVER_SERIALIZE(Context)
NEVER_EVER_SERIALIZE(NativeContext)
NEVER_EVER_SERIALIZE(InternalizedString)
NEVER_EVER_SERIALIZE(Name)
NEVER_EVER_SERIALIZE(ObjectBoilerplateDescription)
NEVER_EVER_SERIALIZE(RegExpBoilerplateDescription)
NEVER_EVER_SERIALIZE(SharedFunctionInfo)
NEVER_EVER_SERIALIZE(ScopeInfo)
NEVER_EVER_SERIALIZE(String)
NEVER_EVER_SERIALIZE(Symbol)
NEVER_EVER_SERIALIZE(TemplateObjectDescription)
#undef NEVER_EVER_SERIALIZE
@ -2996,70 +2960,55 @@ ObjectRef MapRef::GetFieldType(InternalIndex descriptor_index) const {
base::Optional<ObjectRef> StringRef::GetCharAsStringOrUndefined(
uint32_t index, SerializationPolicy policy) const {
if (data_->should_access_heap()) {
// TODO(solanes, neis, v8:7790, v8:11012): Re-enable this optimization for
// concurrent inlining when we have the infrastructure to safely do so.
if (broker()->is_concurrent_inlining()) return base::nullopt;
CHECK_EQ(data_->kind(), ObjectDataKind::kUnserializedHeapObject);
return GetOwnElementFromHeap(broker(), object(), index, true);
}
ObjectData* element =
data()->AsString()->GetCharAsStringOrUndefined(broker(), index, policy);
if (element == nullptr) return base::nullopt;
return ObjectRef(broker(), element);
}
bool StringRef::SupportedStringKind() const {
DCHECK(broker()->is_concurrent_inlining());
if (!broker()->is_concurrent_inlining()) return true;
return IsInternalizedString() || object()->IsThinString();
}
base::Optional<int> StringRef::length() const {
if (data_->should_access_heap()) {
if (data_->kind() == kNeverSerializedHeapObject && !SupportedStringKind()) {
TRACE_BROKER_MISSING(
broker(),
"length for kNeverSerialized unsupported string kind " << *this);
return base::nullopt;
} else {
return object()->length(kAcquireLoad);
}
if (data_->kind() == kNeverSerializedHeapObject && !SupportedStringKind()) {
TRACE_BROKER_MISSING(
broker(),
"length for kNeverSerialized unsupported string kind " << *this);
return base::nullopt;
} else {
return object()->length(kAcquireLoad);
}
return data()->AsString()->length();
}
base::Optional<uint16_t> StringRef::GetFirstChar() {
if (data_->should_access_heap()) {
if (data_->kind() == kNeverSerializedHeapObject && !SupportedStringKind()) {
TRACE_BROKER_MISSING(
broker(),
"first char for kNeverSerialized unsupported string kind " << *this);
return base::nullopt;
}
if (!broker()->IsMainThread()) {
return object()->Get(0, broker()->local_isolate());
} else {
// TODO(solanes, v8:7790): Remove this case once the inlining phase is
// done concurrently all the time.
return object()->Get(0);
}
if (data_->kind() == kNeverSerializedHeapObject && !SupportedStringKind()) {
TRACE_BROKER_MISSING(
broker(),
"first char for kNeverSerialized unsupported string kind " << *this);
return base::nullopt;
}
if (!broker()->IsMainThread()) {
return object()->Get(0, broker()->local_isolate());
} else {
// TODO(solanes, v8:7790): Remove this case once the inlining phase is
// done concurrently all the time.
return object()->Get(0);
}
return data()->AsString()->first_char();
}
base::Optional<double> StringRef::ToNumber() {
if (data_->should_access_heap()) {
if (data_->kind() == kNeverSerializedHeapObject && !SupportedStringKind()) {
TRACE_BROKER_MISSING(
broker(),
"number for kNeverSerialized unsupported string kind " << *this);
return base::nullopt;
}
return TryStringToDouble(broker()->local_isolate(), object());
if (data_->kind() == kNeverSerializedHeapObject && !SupportedStringKind()) {
TRACE_BROKER_MISSING(
broker(),
"number for kNeverSerialized unsupported string kind " << *this);
return base::nullopt;
}
return data()->AsString()->to_number();
return TryStringToDouble(broker()->local_isolate(), object());
}
int ArrayBoilerplateDescriptionRef::constants_elements_length() const {
@ -3558,8 +3507,7 @@ int MapRef::GetInObjectProperties() const {
}
bool StringRef::IsExternalString() const {
IF_ACCESS_FROM_HEAP_C(IsExternalString);
return data()->AsString()->is_external_string();
return object()->IsExternalString();
}
Address CallHandlerInfoRef::callback() const {
@ -3585,10 +3533,7 @@ ZoneVector<const CFunctionInfo*> FunctionTemplateInfoRef::c_signatures() const {
return HeapObjectRef::data()->AsFunctionTemplateInfo()->c_signatures();
}
bool StringRef::IsSeqString() const {
IF_ACCESS_FROM_HEAP_C(IsSeqString);
return data()->AsString()->is_seq_string();
}
bool StringRef::IsSeqString() const { return object()->IsSeqString(); }
void NativeContextRef::Serialize() {
// TODO(jgruber): Disable visitation if should_access_heap() once all
@ -4083,7 +4028,6 @@ void RegExpBoilerplateDescriptionRef::Serialize() {
// Until then, we have to call these functions once on the main thread to
// trigger serialization.
data();
source();
}
Handle<Object> ObjectRef::object() const {