[turbofan] Create new Operator LoadDataViewElement
This CL creates a new Operator called LoadDataViewElement, similar to LoadTypedArray, for DataView getters. This operator will be used as a wrapper around all the computations that DataViews need to do when loading values, due to the endianness parameter of DataView loads. Change-Id: Ie67d63c9669142e539a5c8d7ae82dc1018ce5858 Reviewed-on: https://chromium-review.googlesource.com/1125928 Commit-Queue: Théotime Grohens <theotime@google.com> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Cr-Commit-Position: refs/heads/master@{#54217}
This commit is contained in:
parent
417f8ee62c
commit
9b2358d689
@ -935,6 +935,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
|
||||
case IrOpcode::kLoadTypedElement:
|
||||
result = LowerLoadTypedElement(node);
|
||||
break;
|
||||
case IrOpcode::kLoadDataViewElement:
|
||||
result = LowerLoadDataViewElement(node);
|
||||
break;
|
||||
case IrOpcode::kStoreTypedElement:
|
||||
LowerStoreTypedElement(node);
|
||||
break;
|
||||
@ -3742,6 +3745,22 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) {
|
||||
return done.PhiAt(0);
|
||||
}
|
||||
|
||||
Node* EffectControlLinearizer::LowerLoadDataViewElement(Node* node) {
|
||||
ExternalArrayType element_type = ExternalArrayTypeOf(node->op());
|
||||
Node* buffer = node->InputAt(0);
|
||||
Node* storage = node->InputAt(1);
|
||||
Node* index = node->InputAt(2);
|
||||
|
||||
// We need to keep the {buffer} alive so that the GC will not release the
|
||||
// ArrayBuffer (if there's any) as long as we are still operating on it.
|
||||
__ Retain(buffer);
|
||||
|
||||
// Perform the actual data view element access.
|
||||
return __ LoadElement(AccessBuilder::ForTypedArrayElement(
|
||||
element_type, true, LoadSensitivity::kCritical),
|
||||
storage, index);
|
||||
}
|
||||
|
||||
Node* EffectControlLinearizer::LowerLoadTypedElement(Node* node) {
|
||||
ExternalArrayType array_type = ExternalArrayTypeOf(node->op());
|
||||
Node* buffer = node->InputAt(0);
|
||||
|
@ -151,6 +151,7 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer {
|
||||
void LowerTransitionElementsKind(Node* node);
|
||||
Node* LowerLoadFieldByIndex(Node* node);
|
||||
Node* LowerLoadTypedElement(Node* node);
|
||||
Node* LowerLoadDataViewElement(Node* node);
|
||||
void LowerStoreTypedElement(Node* node);
|
||||
void LowerStoreSignedSmallElement(Node* node);
|
||||
Node* LowerFindOrderedHashMapEntry(Node* node);
|
||||
|
@ -6563,6 +6563,20 @@ Reduction JSCallReducer::ReduceArrayBufferViewAccessor(
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
namespace {
|
||||
int ExternalArrayElementSize(const ExternalArrayType element_type) {
|
||||
switch (element_type) {
|
||||
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
|
||||
case kExternal##Type##Array: \
|
||||
return size;
|
||||
TYPED_ARRAYS(TYPED_ARRAY_CASE)
|
||||
default:
|
||||
UNREACHABLE();
|
||||
#undef TYPED_ARRAY_CASE
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Reduction JSCallReducer::ReduceDataViewPrototypeGet(
|
||||
Node* node, ExternalArrayType element_type) {
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
@ -6641,9 +6655,9 @@ Reduction JSCallReducer::ReduceDataViewPrototypeGet(
|
||||
|
||||
// The end offset is the offset plus the element size
|
||||
// of the type that we want to load.
|
||||
// Since we only load int8 and uint8 for now, that size is 1.
|
||||
int element_size = ExternalArrayElementSize(element_type);
|
||||
Node* end_offset = graph()->NewNode(simplified()->NumberAdd(), offset,
|
||||
jsgraph()->OneConstant());
|
||||
jsgraph()->Constant(element_size));
|
||||
|
||||
// We need to check that {end_offset} <= {byte_length}, ie
|
||||
// throw a RangeError if {byte_length} < {end_offset}.
|
||||
@ -6679,8 +6693,7 @@ Reduction JSCallReducer::ReduceDataViewPrototypeGet(
|
||||
|
||||
// Perform the load.
|
||||
vfalse_range = efalse_range = graph()->NewNode(
|
||||
simplified()->LoadElement(AccessBuilder::ForTypedArrayElement(
|
||||
element_type, true, LoadSensitivity::kCritical)),
|
||||
simplified()->LoadDataViewElement(element_type), buffer,
|
||||
backing_store, buffer_index, efalse_range, if_false_range);
|
||||
}
|
||||
|
||||
@ -6699,7 +6712,7 @@ Reduction JSCallReducer::ReduceDataViewPrototypeGet(
|
||||
if_true_range); // We threw because out of bounds.
|
||||
if_true_range = graph()->NewNode(common()->IfSuccess(), if_true_range);
|
||||
|
||||
// We can't throw in LoadTypedElement(),
|
||||
// We can't throw in LoadDataViewElement(),
|
||||
// so we don't need to handle that path here.
|
||||
|
||||
// Join the exception edges.
|
||||
|
@ -380,6 +380,7 @@
|
||||
V(LoadField) \
|
||||
V(LoadElement) \
|
||||
V(LoadTypedElement) \
|
||||
V(LoadDataViewElement) \
|
||||
V(StoreField) \
|
||||
V(StoreElement) \
|
||||
V(StoreTypedElement) \
|
||||
|
@ -2630,6 +2630,16 @@ class RepresentationSelector {
|
||||
SetOutput(node, rep);
|
||||
return;
|
||||
}
|
||||
case IrOpcode::kLoadDataViewElement: {
|
||||
MachineRepresentation const rep =
|
||||
MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
|
||||
ProcessInput(node, 0, UseInfo::AnyTagged()); // buffer
|
||||
ProcessInput(node, 1, UseInfo::PointerInt()); // external pointer
|
||||
ProcessInput(node, 2, UseInfo::TruncatingWord32()); // index
|
||||
ProcessRemainingInputs(node, 3);
|
||||
SetOutput(node, rep);
|
||||
return;
|
||||
}
|
||||
case IrOpcode::kStoreTypedElement: {
|
||||
MachineRepresentation const rep =
|
||||
MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
|
||||
|
@ -141,6 +141,7 @@ const ElementAccess& ElementAccessOf(const Operator* op) {
|
||||
|
||||
ExternalArrayType ExternalArrayTypeOf(const Operator* op) {
|
||||
DCHECK(op->opcode() == IrOpcode::kLoadTypedElement ||
|
||||
op->opcode() == IrOpcode::kLoadDataViewElement ||
|
||||
op->opcode() == IrOpcode::kStoreTypedElement);
|
||||
return OpParameter<ExternalArrayType>(op);
|
||||
}
|
||||
@ -1529,7 +1530,8 @@ SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP)
|
||||
V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \
|
||||
V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) \
|
||||
V(LoadTypedElement, ExternalArrayType, Operator::kNoWrite, 4, 1, 1) \
|
||||
V(StoreTypedElement, ExternalArrayType, Operator::kNoRead, 5, 1, 0)
|
||||
V(StoreTypedElement, ExternalArrayType, Operator::kNoRead, 5, 1, 0) \
|
||||
V(LoadDataViewElement, ExternalArrayType, Operator::kNoWrite, 3, 1, 1)
|
||||
|
||||
#define ACCESS(Name, Type, properties, value_input_count, control_input_count, \
|
||||
output_count) \
|
||||
|
@ -759,6 +759,9 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
|
||||
// load-typed-element buffer, [base + external + index]
|
||||
const Operator* LoadTypedElement(ExternalArrayType const&);
|
||||
|
||||
// load-data-view-element buffer, [base + index]
|
||||
const Operator* LoadDataViewElement(ExternalArrayType const&);
|
||||
|
||||
// store-typed-element buffer, [base + external + index], value
|
||||
const Operator* StoreTypedElement(ExternalArrayType const&);
|
||||
|
||||
|
@ -2043,6 +2043,17 @@ Type Typer::Visitor::TypeLoadTypedElement(Node* node) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
Type Typer::Visitor::TypeLoadDataViewElement(Node* node) {
|
||||
switch (ExternalArrayTypeOf(node->op())) {
|
||||
#define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype, size) \
|
||||
case kExternal##ElemType##Array: \
|
||||
return typer_->cache_.k##ElemType;
|
||||
TYPED_ARRAYS(TYPED_ARRAY_CASE)
|
||||
#undef TYPED_ARRAY_CASE
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
Type Typer::Visitor::TypeStoreField(Node* node) { UNREACHABLE(); }
|
||||
|
||||
Type Typer::Visitor::TypeStoreElement(Node* node) { UNREACHABLE(); }
|
||||
|
@ -1498,6 +1498,8 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
|
||||
break;
|
||||
case IrOpcode::kLoadTypedElement:
|
||||
break;
|
||||
case IrOpcode::kLoadDataViewElement:
|
||||
break;
|
||||
case IrOpcode::kStoreField:
|
||||
// (Object, fieldtype) -> _|_
|
||||
// TODO(rossberg): activate once machine ops are typed.
|
||||
|
Loading…
Reference in New Issue
Block a user