Commit bd7da651 authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

[compiler] Split up GetOwnConstantElement

This method used to be defined on Object and handled Strings and
JSObjects; but only the object hierarchy rooted at JSObject has
'elements', and Strings are handled slightly differently. Thus it
makes sense to split up into

 JSObject::GetOwnConstantElement
 String::GetCharAsString

This way, we can also separate future work on making JSObjects and
Strings never-serialized.

Bug: v8:7790
Change-Id: I8e0f142fbd9cbf8e8abe1e9a189bcd948c2f1fa8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2704080
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Auto-Submit: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72911}
parent 856a39f4
......@@ -199,12 +199,6 @@ class V8_EXPORT_PRIVATE ObjectRef {
bool BooleanValue() const;
Maybe<double> OddballToNumber() const;
// Return the element at key {index} if {index} is known to be an own data
// property of the object that is non-writable and non-configurable.
base::Optional<ObjectRef> GetOwnConstantElement(
uint32_t index, SerializationPolicy policy =
SerializationPolicy::kAssumeSerialized) const;
Isolate* isolate() const;
struct Hash {
......@@ -341,6 +335,12 @@ class JSObjectRef : public JSReceiverRef {
ObjectRef RawFastPropertyAt(FieldIndex index) const;
// Return the element at key {index} if {index} is known to be an own data
// property of the object that is non-writable and non-configurable.
base::Optional<ObjectRef> GetOwnConstantElement(
uint32_t index, SerializationPolicy policy =
SerializationPolicy::kAssumeSerialized) const;
// Return the value of the property identified by the field {index}
// if {index} is known to be an own data property of the object.
base::Optional<ObjectRef> GetOwnDataProperty(
......@@ -917,6 +917,10 @@ class StringRef : public NameRef {
Handle<String> object() const;
base::Optional<StringRef> GetCharAsString(
uint32_t index, SerializationPolicy policy =
SerializationPolicy::kAssumeSerialized) const;
base::Optional<int> length() const;
base::Optional<uint16_t> GetFirstChar();
base::Optional<double> ToNumber();
......
......@@ -3287,6 +3287,24 @@ ObjectRef MapRef::GetFieldType(InternalIndex descriptor_index) const {
return ObjectRef(broker(), descriptors->GetFieldType(descriptor_index));
}
base::Optional<StringRef> StringRef::GetCharAsString(
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);
base::Optional<ObjectRef> maybe_result =
GetOwnElementFromHeap(broker(), object(), index, true);
if (!maybe_result) return {};
return maybe_result->AsString();
}
ObjectData* element =
data()->AsString()->GetCharAsString(broker(), index, policy);
if (element == nullptr) return base::nullopt;
return StringRef(broker(), element);
}
base::Optional<int> StringRef::length() const {
if (data_->should_access_heap()) {
if (data_->kind() == kNeverSerializedHeapObject &&
......@@ -3980,23 +3998,14 @@ Maybe<double> ObjectRef::OddballToNumber() const {
}
}
base::Optional<ObjectRef> ObjectRef::GetOwnConstantElement(
base::Optional<ObjectRef> JSObjectRef::GetOwnConstantElement(
uint32_t index, SerializationPolicy policy) const {
if (!(IsJSObject() || IsString())) return base::nullopt;
if (data_->should_access_heap()) {
// TODO(solanes, neis, v8:7790, v8:11012): Re-enable this optmization for
// concurrent inlining when we have the infrastructure to safely do so.
if (broker()->is_concurrent_inlining() && IsString()) return base::nullopt;
CHECK_EQ(data_->kind(), ObjectDataKind::kUnserializedHeapObject);
return GetOwnElementFromHeap(broker(), object(), index, true);
}
ObjectData* element = nullptr;
if (IsJSObject()) {
element =
ObjectData* element =
data()->AsJSObject()->GetOwnConstantElement(broker(), index, policy);
} else if (IsString()) {
element = data()->AsString()->GetCharAsString(broker(), index, policy);
}
if (element == nullptr) return base::nullopt;
return ObjectRef(broker(), element);
}
......
......@@ -1953,8 +1953,10 @@ Reduction JSNativeContextSpecialization::ReduceElementLoadFromHeapConstant(
NumberMatcher mkey(key);
if (mkey.IsInteger() && mkey.IsInRange(0.0, kMaxUInt32 - 1.0)) {
uint32_t index = static_cast<uint32_t>(mkey.ResolvedValue());
base::Optional<ObjectRef> element =
receiver_ref.GetOwnConstantElement(index);
base::Optional<ObjectRef> element;
if (receiver_ref.IsJSObject()) {
element = receiver_ref.AsJSObject().GetOwnConstantElement(index);
if (!element.has_value() && receiver_ref.IsJSArray()) {
// We didn't find a constant element, but if the receiver is a cow-array
// we can exploit the fact that any future write to the element will
......@@ -1971,11 +1973,16 @@ Reduction JSNativeContextSpecialization::ReduceElementLoadFromHeapConstant(
graph()->NewNode(simplified()->ReferenceEqual(), elements,
jsgraph()->Constant(*array_elements));
effect = graph()->NewNode(
simplified()->CheckIf(DeoptimizeReason::kCowArrayElementsChanged),
simplified()->CheckIf(
DeoptimizeReason::kCowArrayElementsChanged),
check, effect, control);
}
}
}
} else if (receiver_ref.IsString()) {
element = receiver_ref.AsString().GetCharAsString(index);
}
if (element.has_value()) {
Node* value = access_mode == AccessMode::kHas
? jsgraph()->TrueConstant()
......
......@@ -3323,8 +3323,9 @@ void SerializerForBackgroundCompilation::ProcessElementAccess(
ObjectRef key_ref(broker(), hint);
// TODO(neis): Do this for integer-HeapNumbers too?
if (key_ref.IsSmi() && key_ref.AsSmi() >= 0) {
base::Optional<ObjectRef> element =
receiver_ref.GetOwnConstantElement(
base::Optional<ObjectRef> element;
if (receiver_ref.IsJSObject()) {
element = receiver_ref.AsJSObject().GetOwnConstantElement(
key_ref.AsSmi(), SerializationPolicy::kSerializeIfNeeded);
if (!element.has_value() && receiver_ref.IsJSArray()) {
// We didn't find a constant element, but if the receiver is a
......@@ -3332,10 +3333,14 @@ void SerializerForBackgroundCompilation::ProcessElementAccess(
// element will replace the whole elements storage.
JSArrayRef array_ref = receiver_ref.AsJSArray();
array_ref.SerializeElements();
array_ref.GetOwnCowElement(array_ref.elements().value(),
key_ref.AsSmi(),
array_ref.GetOwnCowElement(
array_ref.elements().value(), key_ref.AsSmi(),
SerializationPolicy::kSerializeIfNeeded);
}
} else if (receiver_ref.IsString()) {
element = receiver_ref.AsString().GetCharAsString(
key_ref.AsSmi(), SerializationPolicy::kSerializeIfNeeded);
}
}
}
}
......
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