| Index: src/code-stubs-hydrogen.cc
|
| diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
|
| index 76786d151184ca0391ce82b5dec321b009452192..a992dcb316ea46f78c0a11da1d7f27f2ac3ab058 100644
|
| --- a/src/code-stubs-hydrogen.cc
|
| +++ b/src/code-stubs-hydrogen.cc
|
| @@ -150,26 +150,24 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
|
| next_block->SetJoinId(BailoutId::StubEntry());
|
| set_current_block(next_block);
|
|
|
| + bool runtime_stack_params = descriptor_->stack_parameter_count_.is_valid();
|
| + HInstruction* stack_parameter_count = NULL;
|
| for (int i = 0; i < param_count; ++i) {
|
| - HParameter* param =
|
| - Add<HParameter>(i, HParameter::REGISTER_PARAMETER);
|
| + Representation r = descriptor_->IsParameterCountRegister(i)
|
| + ? Representation::Integer32()
|
| + : Representation::Tagged();
|
| + HParameter* param = Add<HParameter>(i, HParameter::REGISTER_PARAMETER, r);
|
| start_environment->Bind(i, param);
|
| parameters_[i] = param;
|
| + if (descriptor_->IsParameterCountRegister(i)) {
|
| + param->set_type(HType::Smi());
|
| + stack_parameter_count = param;
|
| + arguments_length_ = stack_parameter_count;
|
| + }
|
| }
|
|
|
| - HInstruction* stack_parameter_count;
|
| - if (descriptor_->stack_parameter_count_.is_valid()) {
|
| - ASSERT(descriptor_->environment_length() == (param_count + 1));
|
| - stack_parameter_count = New<HParameter>(param_count,
|
| - HParameter::REGISTER_PARAMETER,
|
| - Representation::Integer32());
|
| - stack_parameter_count->set_type(HType::Smi());
|
| - // It's essential to bind this value to the environment in case of deopt.
|
| - AddInstruction(stack_parameter_count);
|
| - start_environment->Bind(param_count, stack_parameter_count);
|
| - arguments_length_ = stack_parameter_count;
|
| - } else {
|
| - ASSERT(descriptor_->environment_length() == param_count);
|
| + ASSERT(!runtime_stack_params || arguments_length_ != NULL);
|
| + if (!runtime_stack_params) {
|
| stack_parameter_count = graph()->GetConstantMinus1();
|
| arguments_length_ = graph()->GetConstant0();
|
| }
|
| @@ -189,10 +187,11 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
|
| if (descriptor_->function_mode_ == JS_FUNCTION_STUB_MODE) {
|
| if (!stack_parameter_count->IsConstant() &&
|
| descriptor_->hint_stack_parameter_count_ < 0) {
|
| - HInstruction* amount = graph()->GetConstant1();
|
| - stack_pop_count = Add<HAdd>(stack_parameter_count, amount);
|
| - stack_pop_count->ChangeRepresentation(Representation::Integer32());
|
| + HInstruction* constant_one = graph()->GetConstant1();
|
| + stack_pop_count = Add<HAdd>(stack_parameter_count, constant_one);
|
| stack_pop_count->ClearFlag(HValue::kCanOverflow);
|
| + // TODO(mvstanton): verify that stack_parameter_count+1 really fits in a
|
| + // smi.
|
| } else {
|
| int count = descriptor_->hint_stack_parameter_count_;
|
| stack_pop_count = Add<HConstant>(count);
|
| @@ -211,7 +210,7 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
|
| template <class Stub>
|
| class CodeStubGraphBuilder: public CodeStubGraphBuilderBase {
|
| public:
|
| - explicit CodeStubGraphBuilder(Isolate* isolate, Stub* stub)
|
| + CodeStubGraphBuilder(Isolate* isolate, Stub* stub)
|
| : CodeStubGraphBuilderBase(isolate, stub) {}
|
|
|
| protected:
|
| @@ -595,6 +594,32 @@ Handle<Code> KeyedLoadFieldStub::GenerateCode(Isolate* isolate) {
|
| }
|
|
|
|
|
| +template<>
|
| +HValue* CodeStubGraphBuilder<KeyedArrayCallStub>::BuildCodeStub() {
|
| + int argc = casted_stub()->argc() + 1;
|
| + info()->set_parameter_count(argc);
|
| +
|
| + HValue* receiver = Add<HParameter>(1);
|
| +
|
| + // Load the expected initial array map from the context.
|
| + JSArrayBuilder array_builder(this, casted_stub()->elements_kind());
|
| + HValue* map = array_builder.EmitMapCode();
|
| +
|
| + HValue* checked_receiver = Add<HCheckMapValue>(receiver, map);
|
| +
|
| + HValue* function = BuildUncheckedMonomorphicElementAccess(
|
| + checked_receiver, GetParameter(0),
|
| + NULL, true, casted_stub()->elements_kind(),
|
| + false, NEVER_RETURN_HOLE, STANDARD_STORE);
|
| + return Add<HCallFunction>(function, argc, TAIL_CALL);
|
| +}
|
| +
|
| +
|
| +Handle<Code> KeyedArrayCallStub::GenerateCode(Isolate* isolate) {
|
| + return DoGenerateCode(isolate, this);
|
| +}
|
| +
|
| +
|
| template <>
|
| HValue* CodeStubGraphBuilder<KeyedStoreFastElementStub>::BuildCodeStub() {
|
| BuildUncheckedMonomorphicElementAccess(
|
| @@ -695,27 +720,7 @@ HValue* CodeStubGraphBuilderBase::BuildArraySingleArgumentConstructor(
|
| HInstruction* argument = Add<HAccessArgumentsAt>(
|
| elements, constant_one, constant_zero);
|
|
|
| - HConstant* max_alloc_length =
|
| - Add<HConstant>(JSObject::kInitialMaxFastElementArray);
|
| - const int initial_capacity = JSArray::kPreallocatedArrayElements;
|
| - HConstant* initial_capacity_node = Add<HConstant>(initial_capacity);
|
| -
|
| - HInstruction* checked_arg = Add<HBoundsCheck>(argument, max_alloc_length);
|
| - IfBuilder if_builder(this);
|
| - if_builder.If<HCompareNumericAndBranch>(checked_arg, constant_zero,
|
| - Token::EQ);
|
| - if_builder.Then();
|
| - Push(initial_capacity_node); // capacity
|
| - Push(constant_zero); // length
|
| - if_builder.Else();
|
| - Push(checked_arg); // capacity
|
| - Push(checked_arg); // length
|
| - if_builder.End();
|
| -
|
| - // Figure out total size
|
| - HValue* length = Pop();
|
| - HValue* capacity = Pop();
|
| - return array_builder->AllocateArray(capacity, length, true);
|
| + return BuildAllocateArrayFromLength(array_builder, argument);
|
| }
|
|
|
|
|
| @@ -726,11 +731,16 @@ HValue* CodeStubGraphBuilderBase::BuildArrayNArgumentsConstructor(
|
| // 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.
|
| + //
|
| + // TODO(mvstanton): consider an instruction to memset fill the array
|
| + // with zero in this case instead.
|
| HValue* length = GetArgumentsLength();
|
| - bool fill_with_hole = IsFastSmiElementsKind(kind);
|
| + JSArrayBuilder::FillMode fill_mode = IsFastSmiElementsKind(kind)
|
| + ? JSArrayBuilder::FILL_WITH_HOLE
|
| + : JSArrayBuilder::DONT_FILL_WITH_HOLE;
|
| HValue* new_object = array_builder->AllocateArray(length,
|
| length,
|
| - fill_with_hole);
|
| + fill_mode);
|
| HValue* elements = array_builder->GetElementsLocation();
|
| ASSERT(elements != NULL);
|
|
|
| @@ -1293,4 +1303,20 @@ Handle<Code> FastNewClosureStub::GenerateCode(Isolate* isolate) {
|
| }
|
|
|
|
|
| +template<>
|
| +HValue* CodeStubGraphBuilder<KeyedLoadDictionaryElementStub>::BuildCodeStub() {
|
| + HValue* receiver = GetParameter(0);
|
| + HValue* key = GetParameter(1);
|
| +
|
| + Add<HCheckSmi>(key);
|
| +
|
| + return BuildUncheckedDictionaryElementLoad(receiver, key);
|
| +}
|
| +
|
| +
|
| +Handle<Code> KeyedLoadDictionaryElementStub::GenerateCode(Isolate* isolate) {
|
| + return DoGenerateCode(isolate, this);
|
| +}
|
| +
|
| +
|
| } } // namespace v8::internal
|
|
|