Commit f0fbdfec authored by Leszek Swirski's avatar Leszek Swirski Committed by V8 LUCI CQ

[maglev] Add representation dependency for double fields

Use the field index to look up the descriptor for double fields, and add
a dependency on them.

Drive-by, fix store field optimisation to only emit the optimised direct
store for tagged fields, so that we don't accidentally insert
HeapNumbers into double fields (making them mutable).

Bug: v8:7700
Change-Id: I699c2a2e4e13194045139b9c995d05eb138c0e7c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3700071Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81077}
parent 239f223f
......@@ -21,6 +21,7 @@
#include "src/objects/literal-objects-inl.h"
#include "src/objects/name-inl.h"
#include "src/objects/property-cell.h"
#include "src/objects/property-details.h"
#include "src/objects/slots-inl.h"
namespace v8 {
......@@ -715,14 +716,24 @@ bool MaglevGraphBuilder::TryBuildMonomorphicLoadFromSmiHandler(
load_source = AddNewNode<LoadTaggedField>(
{object}, JSReceiver::kPropertiesOrHashOffset);
}
int field_index = LoadHandler::FieldIndexBits::decode(handler);
if (LoadHandler::IsDoubleBits::decode(handler)) {
SetAccumulator(AddNewNode<LoadDoubleField>(
{load_source},
LoadHandler::FieldIndexBits::decode(handler) * kTaggedSize));
FieldIndex field = FieldIndex::ForSmiLoadHandler(*map.object(), handler);
DescriptorArray descriptors = *map.instance_descriptors().object();
InternalIndex index =
descriptors.Search(field.property_index(), *map.object());
DCHECK(index.is_found());
DCHECK(descriptors.GetDetails(index).representation().IsDouble());
const compiler::CompilationDependency* dep =
broker()->dependencies()->FieldRepresentationDependencyOffTheRecord(
map, index, Representation::Double());
broker()->dependencies()->RecordDependency(dep);
SetAccumulator(
AddNewNode<LoadDoubleField>({load_source}, field_index * kTaggedSize));
} else {
SetAccumulator(AddNewNode<LoadTaggedField>(
{load_source},
LoadHandler::FieldIndexBits::decode(handler) * kTaggedSize));
SetAccumulator(
AddNewNode<LoadTaggedField>({load_source}, field_index * kTaggedSize));
}
return true;
}
......@@ -835,7 +846,10 @@ void MaglevGraphBuilder::VisitSetNamedProperty() {
if (!handler.is_null() && handler->IsSmi()) {
int smi_handler = handler->ToSmi().value();
StoreHandler::Kind kind = StoreHandler::KindBits::decode(smi_handler);
if (kind == StoreHandler::Kind::kField) {
Representation::Kind representation =
StoreHandler::RepresentationBits::decode(smi_handler);
if (kind == StoreHandler::Kind::kField &&
representation == Representation::kTagged) {
AddNewNode<CheckMaps>({object}, named_feedback.maps()[0]);
ValueNode* value = GetAccumulatorTagged();
AddNewNode<StoreField>({object, value}, smi_handler);
......@@ -884,7 +898,10 @@ void MaglevGraphBuilder::VisitDefineNamedOwnProperty() {
if (!handler.is_null() && handler->IsSmi()) {
int smi_handler = handler->ToSmi().value();
StoreHandler::Kind kind = StoreHandler::KindBits::decode(smi_handler);
if (kind == StoreHandler::Kind::kField) {
Representation::Kind representation =
StoreHandler::RepresentationBits::decode(smi_handler);
if (kind == StoreHandler::Kind::kField &&
representation == Representation::kTagged) {
AddNewNode<CheckMaps>({object}, named_feedback.maps()[0]);
ValueNode* value = GetAccumulatorTagged();
AddNewNode<StoreField>({object, value}, smi_handler);
......
......@@ -71,6 +71,25 @@ InternalIndex DescriptorArray::Search(Name name, Map map,
return Search(name, number_of_own_descriptors, concurrent_search);
}
InternalIndex DescriptorArray::Search(int field_index, int valid_descriptors) {
for (int desc_index = field_index; desc_index < valid_descriptors;
++desc_index) {
PropertyDetails details = GetDetails(InternalIndex(desc_index));
if (details.location() != PropertyLocation::kField) continue;
if (field_index == details.field_index()) {
return InternalIndex(desc_index);
}
DCHECK_LT(details.field_index(), field_index);
}
return InternalIndex::NotFound();
}
InternalIndex DescriptorArray::Search(int field_index, Map map) {
int number_of_own_descriptors = map.NumberOfOwnDescriptors();
if (number_of_own_descriptors == 0) return InternalIndex::NotFound();
return Search(field_index, number_of_own_descriptors);
}
InternalIndex DescriptorArray::SearchWithCache(Isolate* isolate, Name name,
Map map) {
DCHECK(name.IsUniqueName());
......
......@@ -128,6 +128,11 @@ class DescriptorArray
V8_INLINE InternalIndex Search(Name name, Map map,
bool concurrent_search = false);
// Search the instance descriptors for given field offset.
V8_INLINE InternalIndex Search(int field_offset,
int number_of_own_descriptors);
V8_INLINE InternalIndex Search(int field_offset, Map map);
// As the above, but uses DescriptorLookupCache and updates it when
// necessary.
V8_INLINE InternalIndex SearchWithCache(Isolate* isolate, Name name, Map map);
......
......@@ -5,6 +5,7 @@
#ifndef V8_OBJECTS_FIELD_INDEX_INL_H_
#define V8_OBJECTS_FIELD_INDEX_INL_H_
#include "src/ic/handler-configuration.h"
#include "src/objects/descriptor-array-inl.h"
#include "src/objects/field-index.h"
#include "src/objects/map-inl.h"
......@@ -20,6 +21,23 @@ FieldIndex FieldIndex::ForInObjectOffset(int offset, Encoding encoding) {
return FieldIndex(true, offset, encoding, 0, 0);
}
FieldIndex FieldIndex::ForSmiLoadHandler(Map map, int32_t handler) {
DCHECK_EQ(LoadHandler::KindBits::decode(handler), LoadHandler::Kind::kField);
bool is_inobject = LoadHandler::IsInobjectBits::decode(handler);
int inobject_properties = map.GetInObjectProperties();
int first_inobject_offset;
if (is_inobject) {
first_inobject_offset = map.GetInObjectPropertyOffset(0);
} else {
first_inobject_offset = FixedArray::kHeaderSize;
}
return FieldIndex(
is_inobject, LoadHandler::FieldIndexBits::decode(handler) * kTaggedSize,
LoadHandler::IsDoubleBits::decode(handler) ? kDouble : kTagged,
inobject_properties, first_inobject_offset);
}
FieldIndex FieldIndex::ForPropertyIndex(Map map, int property_index,
Representation representation) {
DCHECK(map.instance_type() >= FIRST_NONSTRING_TYPE);
......
......@@ -29,6 +29,7 @@ class FieldIndex final {
Map map, int index,
Representation representation = Representation::Tagged());
static inline FieldIndex ForInObjectOffset(int offset, Encoding encoding);
static inline FieldIndex ForSmiLoadHandler(Map map, int32_t handler);
static inline FieldIndex ForDescriptor(Map map,
InternalIndex descriptor_index);
static inline FieldIndex ForDescriptor(PtrComprCageBase cage_base, Map map,
......
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