| Index: src/compiler/effect-control-linearizer.cc
|
| diff --git a/src/compiler/effect-control-linearizer.cc b/src/compiler/effect-control-linearizer.cc
|
| index 865e909ad83108c3657eae7a53eeb276999c122a..ee8a69e6f1556f1f383336c61fb39defb81826ec 100644
|
| --- a/src/compiler/effect-control-linearizer.cc
|
| +++ b/src/compiler/effect-control-linearizer.cc
|
| @@ -13,7 +13,6 @@
|
| #include "src/compiler/node-properties.h"
|
| #include "src/compiler/node.h"
|
| #include "src/compiler/schedule.h"
|
| -#include "src/objects-inl.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
| @@ -739,8 +738,11 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
|
| case IrOpcode::kObjectIsUndetectable:
|
| result = LowerObjectIsUndetectable(node);
|
| break;
|
| - case IrOpcode::kNewRestParameterElements:
|
| - result = LowerNewRestParameterElements(node);
|
| + case IrOpcode::kArgumentsFrame:
|
| + result = LowerArgumentsFrame(node);
|
| + break;
|
| + case IrOpcode::kArgumentsLength:
|
| + result = LowerArgumentsLength(node);
|
| break;
|
| case IrOpcode::kNewUnmappedArgumentsElements:
|
| result = LowerNewUnmappedArgumentsElements(node);
|
| @@ -1839,21 +1841,83 @@ Node* EffectControlLinearizer::LowerObjectIsUndetectable(Node* node) {
|
| return done.PhiAt(0);
|
| }
|
|
|
| -Node* EffectControlLinearizer::LowerNewRestParameterElements(Node* node) {
|
| - int const formal_parameter_count = ParameterCountOf(node->op());
|
| +Node* EffectControlLinearizer::LowerArgumentsLength(Node* node) {
|
| + Node* arguments_frame = NodeProperties::GetValueInput(node, 0);
|
| + int formal_parameter_count = FormalParameterCountOf(node->op());
|
| + bool is_rest_length = IsRestLengthOf(node->op());
|
| + DCHECK(formal_parameter_count >= 0);
|
|
|
| - Callable const callable = CodeFactory::NewRestParameterElements(isolate());
|
| - Operator::Properties const properties = node->op()->properties();
|
| - CallDescriptor::Flags const flags = CallDescriptor::kNoFlags;
|
| - CallDescriptor* desc = Linkage::GetStubCallDescriptor(
|
| - isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
|
| - return __ Call(desc, __ HeapConstant(callable.code()),
|
| - __ IntPtrConstant(formal_parameter_count),
|
| - __ NoContextConstant());
|
| + if (is_rest_length) {
|
| + // The ArgumentsLength node is computing the number of rest parameters,
|
| + // which is max(0, actual_parameter_count - formal_parameter_count).
|
| + // We have to distinguish the case, when there is an arguments adaptor frame
|
| + // (i.e., arguments_frame != LoadFramePointer()).
|
| + auto if_adaptor_frame = __ MakeLabel<1>();
|
| + auto done = __ MakeLabel<3>(MachineRepresentation::kTaggedSigned);
|
| +
|
| + Node* frame = __ LoadFramePointer();
|
| + __ GotoIf(__ WordEqual(arguments_frame, frame), &done, __ SmiConstant(0));
|
| + __ Goto(&if_adaptor_frame);
|
| +
|
| + __ Bind(&if_adaptor_frame);
|
| + Node* arguments_length = __ Load(
|
| + MachineType::TaggedSigned(), arguments_frame,
|
| + __ IntPtrConstant(ArgumentsAdaptorFrameConstants::kLengthOffset));
|
| +
|
| + Node* rest_length =
|
| + __ IntSub(arguments_length, __ SmiConstant(formal_parameter_count));
|
| + __ GotoIf(__ IntLessThan(rest_length, __ SmiConstant(0)), &done,
|
| + __ SmiConstant(0));
|
| + __ Goto(&done, rest_length);
|
| +
|
| + __ Bind(&done);
|
| + return done.PhiAt(0);
|
| + } else {
|
| + // The ArgumentsLength node is computing the actual number of arguments.
|
| + // We have to distinguish the case when there is an arguments adaptor frame
|
| + // (i.e., arguments_frame != LoadFramePointer()).
|
| + auto if_adaptor_frame = __ MakeLabel<1>();
|
| + auto done = __ MakeLabel<2>(MachineRepresentation::kTaggedSigned);
|
| +
|
| + Node* frame = __ LoadFramePointer();
|
| + __ GotoIf(__ WordEqual(arguments_frame, frame), &done,
|
| + __ SmiConstant(formal_parameter_count));
|
| + __ Goto(&if_adaptor_frame);
|
| +
|
| + __ Bind(&if_adaptor_frame);
|
| + Node* arguments_length = __ Load(
|
| + MachineType::TaggedSigned(), arguments_frame,
|
| + __ IntPtrConstant(ArgumentsAdaptorFrameConstants::kLengthOffset));
|
| + __ Goto(&done, arguments_length);
|
| +
|
| + __ Bind(&done);
|
| + return done.PhiAt(0);
|
| + }
|
| +}
|
| +
|
| +Node* EffectControlLinearizer::LowerArgumentsFrame(Node* node) {
|
| + auto done = __ MakeLabel<2>(MachineType::PointerRepresentation());
|
| +
|
| + Node* frame = __ LoadFramePointer();
|
| + Node* parent_frame =
|
| + __ Load(MachineType::AnyTagged(), frame,
|
| + __ IntPtrConstant(StandardFrameConstants::kCallerFPOffset));
|
| + Node* parent_frame_type = __ Load(
|
| + MachineType::AnyTagged(), parent_frame,
|
| + __ IntPtrConstant(CommonFrameConstants::kContextOrFrameTypeOffset));
|
| + __ GotoIf(__ WordEqual(parent_frame_type,
|
| + __ IntPtrConstant(StackFrame::TypeToMarker(
|
| + StackFrame::ARGUMENTS_ADAPTOR))),
|
| + &done, parent_frame);
|
| + __ Goto(&done, frame);
|
| +
|
| + __ Bind(&done);
|
| + return done.PhiAt(0);
|
| }
|
|
|
| Node* EffectControlLinearizer::LowerNewUnmappedArgumentsElements(Node* node) {
|
| - int const formal_parameter_count = ParameterCountOf(node->op());
|
| + Node* frame = NodeProperties::GetValueInput(node, 0);
|
| + Node* length = NodeProperties::GetValueInput(node, 1);
|
|
|
| Callable const callable =
|
| CodeFactory::NewUnmappedArgumentsElements(isolate());
|
| @@ -1861,8 +1925,7 @@ Node* EffectControlLinearizer::LowerNewUnmappedArgumentsElements(Node* node) {
|
| CallDescriptor::Flags const flags = CallDescriptor::kNoFlags;
|
| CallDescriptor* desc = Linkage::GetStubCallDescriptor(
|
| isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
|
| - return __ Call(desc, __ HeapConstant(callable.code()),
|
| - __ IntPtrConstant(formal_parameter_count),
|
| + return __ Call(desc, __ HeapConstant(callable.code()), frame, length,
|
| __ NoContextConstant());
|
| }
|
|
|
|
|