Chromium Code Reviews| Index: src/code-stubs-hydrogen.cc |
| diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc |
| index 6e837ddb956c09c0fb56bd687185d7d75f176c25..49d6799a0962596848290d0c8c5244d4f3b7b165 100644 |
| --- a/src/code-stubs-hydrogen.cc |
| +++ b/src/code-stubs-hydrogen.cc |
| @@ -100,7 +100,22 @@ class CodeStubGraphBuilderBase : public HGraphBuilder { |
| IfBuilder checker_; |
| }; |
| + enum ArgumentClass { |
| + NONE, |
| + SINGLE, |
| + MULTIPLE |
| + }; |
| + |
| + HValue* BuildArrayConstructor(ElementsKind kind, AllocationSiteMode mode, |
| + ArgumentClass argument_class); |
| + HValue* BuildInternalArrayConstructor(ElementsKind kind, |
| + ArgumentClass argument_class); |
| + |
| private: |
| + HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder); |
| + HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder, |
| + ElementsKind kind); |
| + |
| SmartArrayPointer<HParameter*> parameters_; |
| HValue* arguments_length_; |
| CompilationInfoWithZone info_; |
| @@ -536,40 +551,45 @@ Handle<Code> TransitionElementsKindStub::GenerateCode() { |
| return DoGenerateCode(this); |
| } |
| - |
| -template <> |
| -HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() { |
| - // ----------- S t a t e ------------- |
| - // -- Parameter 1 : type info cell |
| - // -- Parameter 0 : constructor |
| - // ----------------------------------- |
| +HValue* CodeStubGraphBuilderBase::BuildArrayConstructor( |
| + ElementsKind kind, AllocationSiteMode mode, |
| + ArgumentClass argument_class) { |
| + HValue* constructor = GetParameter(ArrayConstructorStubBase::kConstructor); |
| + HValue* property_cell = GetParameter(ArrayConstructorStubBase::kPropertyCell); |
| HInstruction* array_function = BuildGetArrayFunction(context()); |
| - ArrayContextChecker(this, |
| - GetParameter(ArrayConstructorStubBase::kConstructor), |
| - array_function); |
| - // Get the right map |
| - // Should be a constant |
| - JSArrayBuilder array_builder( |
| - this, |
| - casted_stub()->elements_kind(), |
| - GetParameter(ArrayConstructorStubBase::kPropertyCell), |
| - casted_stub()->mode()); |
| - return array_builder.AllocateEmptyArray(); |
| + ArrayContextChecker(this, constructor, array_function); |
| + JSArrayBuilder array_builder(this, kind, property_cell, mode); |
| + |
| + if (argument_class == NONE) { |
|
Michael Starzinger
2013/05/23 09:16:49
Can we model that as a switch without a default ca
mvstanton
2013/05/23 14:46:05
Cool, didn't think about that good trick. Done.
|
| + return array_builder.AllocateEmptyArray(); |
| + } else if (argument_class == SINGLE) { |
| + return BuildArraySingleArgumentConstructor(&array_builder); |
| + } |
| + |
| + ASSERT(argument_class == MULTIPLE); |
| + return BuildArrayNArgumentsConstructor(&array_builder, kind); |
| } |
| -Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() { |
| - return DoGenerateCode(this); |
| +HValue* CodeStubGraphBuilderBase::BuildInternalArrayConstructor( |
| + ElementsKind kind, ArgumentClass argument_class) { |
| + HValue* constructor = GetParameter( |
| + InternalArrayConstructorStubBase::kConstructor); |
| + JSArrayBuilder array_builder(this, kind, constructor); |
| + |
| + if (argument_class == NONE) { |
|
Michael Starzinger
2013/05/23 09:16:49
Likewise.
mvstanton
2013/05/23 14:46:05
Done.
|
| + return array_builder.AllocateEmptyArray(); |
| + } else if (argument_class == SINGLE) { |
| + return BuildArraySingleArgumentConstructor(&array_builder); |
| + } |
| + |
| + ASSERT(argument_class == MULTIPLE); |
| + return BuildArrayNArgumentsConstructor(&array_builder, kind); |
| } |
| -template <> |
| -HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>:: |
| - BuildCodeStub() { |
| - HInstruction* array_function = BuildGetArrayFunction(context()); |
| - ArrayContextChecker(this, |
| - GetParameter(ArrayConstructorStubBase::kConstructor), |
| - array_function); |
| +HValue* CodeStubGraphBuilderBase::BuildArraySingleArgumentConstructor( |
| + JSArrayBuilder* array_builder) { |
| // Smi check and range check on the input arg. |
| HValue* constant_one = graph()->GetConstant1(); |
| HValue* constant_zero = graph()->GetConstant0(); |
| @@ -606,46 +626,23 @@ HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>:: |
| // Figure out total size |
| HValue* length = Pop(); |
| HValue* capacity = Pop(); |
| - |
| - JSArrayBuilder array_builder( |
| - this, |
| - casted_stub()->elements_kind(), |
| - GetParameter(ArrayConstructorStubBase::kPropertyCell), |
| - casted_stub()->mode()); |
| - return array_builder.AllocateArray(capacity, length, true); |
| -} |
| - |
| - |
| -Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() { |
| - return DoGenerateCode(this); |
| + return array_builder->AllocateArray(capacity, length, true); |
| } |
| -template <> |
| -HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() { |
| - HInstruction* array_function = BuildGetArrayFunction(context()); |
| - ArrayContextChecker(this, |
| - GetParameter(ArrayConstructorStubBase::kConstructor), |
| - array_function); |
| - ElementsKind kind = casted_stub()->elements_kind(); |
| - HValue* length = GetArgumentsLength(); |
| - |
| - JSArrayBuilder array_builder( |
| - this, |
| - kind, |
| - GetParameter(ArrayConstructorStubBase::kPropertyCell), |
| - casted_stub()->mode()); |
| - |
| +HValue* CodeStubGraphBuilderBase::BuildArrayNArgumentsConstructor( |
| + JSArrayBuilder* array_builder, ElementsKind kind) { |
| // 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. |
| + HValue* length = GetArgumentsLength(); |
| bool fill_with_hole = IsFastSmiElementsKind(kind); |
| - HValue* new_object = array_builder.AllocateArray(length, |
| - length, |
| - fill_with_hole); |
| - HValue* elements = array_builder.GetElementsLocation(); |
| + HValue* new_object = array_builder->AllocateArray(length, |
| + length, |
| + fill_with_hole); |
| + HValue* elements = array_builder->GetElementsLocation(); |
| ASSERT(elements != NULL); |
| // Now populate the elements correctly. |
| @@ -670,12 +667,86 @@ HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() { |
| } |
| +template <> |
| +HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() { |
| + ElementsKind kind = casted_stub()->elements_kind(); |
| + AllocationSiteMode mode = casted_stub()->mode(); |
| + return BuildArrayConstructor(kind, mode, NONE); |
| +} |
| + |
| + |
| +Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() { |
| + return DoGenerateCode(this); |
| +} |
| + |
| + |
| +template <> |
| +HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>:: |
| + BuildCodeStub() { |
| + ElementsKind kind = casted_stub()->elements_kind(); |
| + AllocationSiteMode mode = casted_stub()->mode(); |
| + return BuildArrayConstructor(kind, mode, SINGLE); |
| +} |
| + |
| + |
| +Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() { |
| + return DoGenerateCode(this); |
| +} |
| + |
| + |
| +template <> |
| +HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() { |
| + ElementsKind kind = casted_stub()->elements_kind(); |
| + AllocationSiteMode mode = casted_stub()->mode(); |
| + return BuildArrayConstructor(kind, mode, MULTIPLE); |
| +} |
| + |
| + |
| Handle<Code> ArrayNArgumentsConstructorStub::GenerateCode() { |
| return DoGenerateCode(this); |
| } |
| template <> |
| +HValue* CodeStubGraphBuilder<InternalArrayNoArgumentConstructorStub>:: |
| + BuildCodeStub() { |
| + ElementsKind kind = casted_stub()->elements_kind(); |
| + return BuildInternalArrayConstructor(kind, NONE); |
| +} |
| + |
| + |
| +Handle<Code> InternalArrayNoArgumentConstructorStub::GenerateCode() { |
| + return DoGenerateCode(this); |
| +} |
| + |
| + |
| +template <> |
| +HValue* CodeStubGraphBuilder<InternalArraySingleArgumentConstructorStub>:: |
| + BuildCodeStub() { |
| + ElementsKind kind = casted_stub()->elements_kind(); |
| + return BuildInternalArrayConstructor(kind, SINGLE); |
| +} |
| + |
| + |
| +Handle<Code> InternalArraySingleArgumentConstructorStub::GenerateCode() { |
| + return DoGenerateCode(this); |
| +} |
| + |
| + |
| +template <> |
| +HValue* CodeStubGraphBuilder<InternalArrayNArgumentsConstructorStub>:: |
| + BuildCodeStub() { |
| + ElementsKind kind = casted_stub()->elements_kind(); |
| + return BuildInternalArrayConstructor(kind, MULTIPLE); |
| +} |
| + |
| + |
| +Handle<Code> InternalArrayNArgumentsConstructorStub::GenerateCode() { |
| + return DoGenerateCode(this); |
| +} |
| + |
| + |
| +template <> |
| HValue* CodeStubGraphBuilder<CompareNilICStub>::BuildCodeUninitializedStub() { |
| CompareNilICStub* stub = casted_stub(); |
| HIfContinuation continuation; |