| Index: src/code-stubs-hydrogen.cc
|
| diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
|
| index 18dfcac11f510975bcf10c0effd500317149b9bc..f0841f9ae5f0012fa12d4155663762a7c4b1f137 100644
|
| --- a/src/code-stubs-hydrogen.cc
|
| +++ b/src/code-stubs-hydrogen.cc
|
| @@ -132,9 +132,13 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
|
| HParameter::REGISTER_PARAMETER,
|
| Representation::Integer32());
|
| // it's essential to bind this value to the environment in case of deopt
|
| - start_environment->Bind(param_count, stack_parameter_count);
|
| AddInstruction(stack_parameter_count);
|
| - arguments_length_ = stack_parameter_count;
|
| + start_environment->Bind(param_count, stack_parameter_count);
|
| + arguments_length_ = AddInstruction(new(zone) HChange(
|
| + stack_parameter_count,
|
| + Representation::Tagged(),
|
| + true,
|
| + false));
|
| } else {
|
| ASSERT(descriptor_->environment_length() == param_count);
|
| stack_parameter_count = graph()->GetConstantMinus1();
|
| @@ -402,12 +406,29 @@ Handle<Code> TransitionElementsKindStub::GenerateCode() {
|
| }
|
|
|
|
|
| +// #define NOARG_DEOPT
|
| +// #define ONEARG_DEOPT
|
| +// #define NARG_DEOPT
|
| template <>
|
| HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() {
|
| + // ----------- S t a t e -------------
|
| + // -- Parameter 1 : type info cell
|
| + // -- Parameter 0 : constructor
|
| + // -----------------------------------
|
| +#ifdef NOARG_DEOPT
|
| HInstruction* deopt = new(zone()) HSoftDeoptimize();
|
| AddInstruction(deopt);
|
| current_block()->MarkAsDeoptimizing();
|
| return GetParameter(0);
|
| +#else
|
| + // Get the right map
|
| + // Should be a constant
|
| + JSArrayBuilder array_builder(this,
|
| + casted_stub()->elements_kind(),
|
| + GetParameter(ArrayConstructorStubBase::kPropertyCell));
|
| + HValue* new_object = array_builder.AllocateEmptyArray();
|
| + return new_object;
|
| +#endif
|
| }
|
|
|
|
|
| @@ -419,10 +440,58 @@ Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() {
|
| template <>
|
| HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>::
|
| BuildCodeStub() {
|
| +#ifdef ONEARG_DEOPT
|
| HInstruction* deopt = new(zone()) HSoftDeoptimize();
|
| AddInstruction(deopt);
|
| current_block()->MarkAsDeoptimizing();
|
| return GetParameter(0);
|
| +#else
|
| + // Smi check and range check on the input arg.
|
| + HValue* constant_one = graph()->GetConstant1();
|
| + HValue* constant_zero = graph()->GetConstant0();
|
| +
|
| + HInstruction* elements = AddInstruction(
|
| + new(zone()) HArgumentsElements(false));
|
| + HInstruction* argument = AddInstruction(
|
| + new(zone()) HAccessArgumentsAt(elements, constant_one, constant_zero));
|
| +
|
| + HConstant* max_alloc_length =
|
| + new(zone()) HConstant(JSObject::kInitialMaxFastElementArray,
|
| + Representation::Tagged());
|
| + AddInstruction(max_alloc_length);
|
| + const int initial_capacity = JSArray::kPreallocatedArrayElements;
|
| + HConstant* initial_capacity_node =
|
| + new(zone()) HConstant(initial_capacity, Representation::Tagged());
|
| + AddInstruction(initial_capacity_node);
|
| +
|
| + // Since we're forcing Integer32 representation for this HBoundsCheck,
|
| + // there's no need to Smi-check the index.
|
| + HBoundsCheck* checked_arg = AddBoundsCheck(argument, max_alloc_length,
|
| + ALLOW_SMI_KEY,
|
| + Representation::Tagged());
|
| + IfBuilder if_builder(this);
|
| + if_builder.BeginIf(checked_arg, constant_zero, Token::EQ);
|
| + Push(initial_capacity_node); // capacity
|
| + Push(constant_zero); // length
|
| + if_builder.BeginElse();
|
| + Push(checked_arg); // capacity
|
| + Push(checked_arg); // length
|
| + if_builder.End();
|
| +
|
| + // Figure out total size
|
| + HValue* length = Pop();
|
| + HValue* capacity = Pop();
|
| +
|
| + JSArrayBuilder array_builder(this,
|
| + casted_stub()->elements_kind(),
|
| + GetParameter(ArrayConstructorStubBase::kPropertyCell));
|
| + HValue* size_in_bytes = array_builder.EstablishAllocationSize(capacity);
|
| + HValue* new_object = array_builder.AllocateArray(size_in_bytes,
|
| + capacity,
|
| + length,
|
| + true);
|
| + return new_object;
|
| +#endif
|
| }
|
|
|
|
|
| @@ -433,10 +502,54 @@ Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() {
|
|
|
| template <>
|
| HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() {
|
| +#ifdef NARG_DEOPT
|
| HInstruction* deopt = new(zone()) HSoftDeoptimize();
|
| AddInstruction(deopt);
|
| current_block()->MarkAsDeoptimizing();
|
| return GetParameter(0);
|
| +#else
|
| + ElementsKind kind = casted_stub()->elements_kind();
|
| + HValue* length = GetArgumentsLength();
|
| +
|
| + JSArrayBuilder array_builder(this,
|
| + kind,
|
| + GetParameter(ArrayConstructorStubBase::kPropertyCell));
|
| +
|
| + HValue* total_size = array_builder.EstablishAllocationSize(length);
|
| + // We need to fill with the hole if it's a smi array in the multi-argument
|
| + // case because we might have to bail out while copying arguments into
|
| + // the array because they aren't compatible with a smi array.
|
| + // If it's a double array, no problem, and if it's fast then no
|
| + // problem either because doubles are boxed.
|
| + bool fill_with_hole = IsFastSmiElementsKind(kind);
|
| + HValue* new_object = array_builder.AllocateArray(total_size,
|
| + length,
|
| + length,
|
| + fill_with_hole);
|
| + HValue* elements = array_builder.GetElementsLocation();
|
| + ASSERT(elements != NULL);
|
| +
|
| + // Now populate the elements correctly.
|
| + LoopBuilder builder(this,
|
| + context(),
|
| + LoopBuilder::kPostIncrement);
|
| + HValue* start = graph()->GetConstant0();
|
| + HValue* key = builder.BeginBody(start, length, Token::LT);
|
| + HInstruction* argument_elements = AddInstruction(
|
| + new(zone()) HArgumentsElements(false));
|
| + HInstruction* argument = AddInstruction(new(zone()) HAccessArgumentsAt(
|
| + argument_elements, length, key));
|
| +
|
| + // Checks to prevent incompatible stores
|
| + if (IsFastSmiElementsKind(kind)) {
|
| + AddInstruction(new(zone()) HCheckSmi(argument));
|
| + }
|
| +
|
| + AddInstruction(new(zone()) HStoreKeyed(elements, key, argument, kind));
|
| + AddSimulate(BailoutId::StubEntry(), REMOVABLE_SIMULATE);
|
| + builder.EndBody();
|
| + return new_object;
|
| +#endif
|
| }
|
|
|
|
|
|
|