| Index: src/compiler/effect-control-linearizer.cc
|
| diff --git a/src/compiler/effect-control-linearizer.cc b/src/compiler/effect-control-linearizer.cc
|
| index 27da109b500a56e7fea89a5949a447ff9adacda8..b734255efac41bf7de8842c7b0d91c0849f5e259 100644
|
| --- a/src/compiler/effect-control-linearizer.cc
|
| +++ b/src/compiler/effect-control-linearizer.cc
|
| @@ -791,6 +791,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
|
| case IrOpcode::kTransitionElementsKind:
|
| LowerTransitionElementsKind(node);
|
| break;
|
| + case IrOpcode::kLoadFieldByIndex:
|
| + result = LowerLoadFieldByIndex(node);
|
| + break;
|
| case IrOpcode::kLoadTypedElement:
|
| result = LowerLoadTypedElement(node);
|
| break;
|
| @@ -2554,6 +2557,107 @@ void EffectControlLinearizer::LowerTransitionElementsKind(Node* node) {
|
| __ Bind(&done);
|
| }
|
|
|
| +Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) {
|
| + Node* object = node->InputAt(0);
|
| + Node* index = node->InputAt(1);
|
| + Node* zero = __ IntPtrConstant(0);
|
| + Node* one = __ IntPtrConstant(1);
|
| +
|
| + // Sign-extend the {index} on 64-bit architectures.
|
| + if (machine()->Is64()) {
|
| + index = __ ChangeInt32ToInt64(index);
|
| + }
|
| +
|
| + auto if_double = __ MakeDeferredLabel<1>();
|
| + auto done = __ MakeLabel<3>(MachineRepresentation::kTagged);
|
| +
|
| + // Check if field is a mutable double field.
|
| + __ GotoUnless(__ WordEqual(__ WordAnd(index, one), zero), &if_double);
|
| +
|
| + // The field is a proper Tagged field on {object}. The {index} is shifted
|
| + // to the left by one in the code below.
|
| + {
|
| + // Check if field is in-object or out-of-object.
|
| + auto if_outofobject = __ MakeLabel<1>();
|
| + __ GotoIf(__ IntLessThan(index, zero), &if_outofobject);
|
| +
|
| + // The field is located in the {object} itself.
|
| + {
|
| + Node* offset =
|
| + __ IntAdd(__ WordShl(index, __ IntPtrConstant(kPointerSizeLog2 - 1)),
|
| + __ IntPtrConstant(JSObject::kHeaderSize - kHeapObjectTag));
|
| + Node* result = __ Load(MachineType::AnyTagged(), object, offset);
|
| + __ Goto(&done, result);
|
| + }
|
| +
|
| + // The field is located in the properties backing store of {object}.
|
| + // The {index} is equal to the negated out of property index plus 1.
|
| + __ Bind(&if_outofobject);
|
| + {
|
| + Node* properties =
|
| + __ LoadField(AccessBuilder::ForJSObjectProperties(), object);
|
| + Node* offset =
|
| + __ IntAdd(__ WordShl(__ IntSub(zero, index),
|
| + __ IntPtrConstant(kPointerSizeLog2 - 1)),
|
| + __ IntPtrConstant((FixedArray::kHeaderSize - kPointerSize) -
|
| + kHeapObjectTag));
|
| + Node* result = __ Load(MachineType::AnyTagged(), properties, offset);
|
| + __ Goto(&done, result);
|
| + }
|
| + }
|
| +
|
| + // The field is a Double field, either unboxed in the object on 64-bit
|
| + // architectures, or as MutableHeapNumber.
|
| + __ Bind(&if_double);
|
| + {
|
| + auto done_double = __ MakeLabel<2>(MachineRepresentation::kFloat64);
|
| +
|
| + index = __ WordSar(index, one);
|
| +
|
| + // Check if field is in-object or out-of-object.
|
| + auto if_outofobject = __ MakeLabel<1>();
|
| + __ GotoIf(__ IntLessThan(index, zero), &if_outofobject);
|
| +
|
| + // The field is located in the {object} itself.
|
| + {
|
| + Node* offset =
|
| + __ IntAdd(__ WordShl(index, __ IntPtrConstant(kPointerSizeLog2)),
|
| + __ IntPtrConstant(JSObject::kHeaderSize - kHeapObjectTag));
|
| + if (FLAG_unbox_double_fields) {
|
| + Node* result = __ Load(MachineType::Float64(), object, offset);
|
| + __ Goto(&done_double, result);
|
| + } else {
|
| + Node* result = __ Load(MachineType::AnyTagged(), object, offset);
|
| + result = __ LoadField(AccessBuilder::ForHeapNumberValue(), result);
|
| + __ Goto(&done_double, result);
|
| + }
|
| + }
|
| +
|
| + __ Bind(&if_outofobject);
|
| + {
|
| + Node* properties =
|
| + __ LoadField(AccessBuilder::ForJSObjectProperties(), object);
|
| + Node* offset =
|
| + __ IntAdd(__ WordShl(__ IntSub(zero, index),
|
| + __ IntPtrConstant(kPointerSizeLog2)),
|
| + __ IntPtrConstant((FixedArray::kHeaderSize - kPointerSize) -
|
| + kHeapObjectTag));
|
| + Node* result = __ Load(MachineType::AnyTagged(), properties, offset);
|
| + result = __ LoadField(AccessBuilder::ForHeapNumberValue(), result);
|
| + __ Goto(&done_double, result);
|
| + }
|
| +
|
| + __ Bind(&done_double);
|
| + {
|
| + Node* result = AllocateHeapNumberWithValue(done_double.PhiAt(0));
|
| + __ Goto(&done, result);
|
| + }
|
| + }
|
| +
|
| + __ Bind(&done);
|
| + return done.PhiAt(0);
|
| +}
|
| +
|
| Node* EffectControlLinearizer::LowerLoadTypedElement(Node* node) {
|
| ExternalArrayType array_type = ExternalArrayTypeOf(node->op());
|
| Node* buffer = node->InputAt(0);
|
|
|