Chromium Code Reviews| Index: src/code-stubs-hydrogen.cc |
| diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc |
| index b3899826167c13243cc4433ac281ee3d12066449..2b45050262683762658e6a7faf8997bacf679045 100644 |
| --- a/src/code-stubs-hydrogen.cc |
| +++ b/src/code-stubs-hydrogen.cc |
| @@ -74,7 +74,9 @@ class CodeStubGraphBuilderBase : public HGraphBuilder { |
| MULTIPLE |
| }; |
| - HValue* UnmappedCase(HValue* elements, HValue* key); |
| + HValue* UnmappedCase(HValue* elements, HValue* key, HValue* value); |
| + HValue* EmitKeyedSloppyArguments(HValue* receiver, HValue* key, |
| + HValue* value); |
| HValue* BuildArrayConstructor(ElementsKind kind, |
| AllocationSiteOverrideMode override_mode, |
| @@ -796,8 +798,9 @@ HValue* CodeStubGraphBuilder<LoadConstantStub>::BuildCodeStub() { |
| Handle<Code> LoadConstantStub::GenerateCode() { return DoGenerateCode(this); } |
| -HValue* CodeStubGraphBuilderBase::UnmappedCase(HValue* elements, HValue* key) { |
| - HValue* result; |
| +HValue* CodeStubGraphBuilderBase::UnmappedCase(HValue* elements, HValue* key, |
| + HValue* value) { |
| + HValue* result = NULL; |
| HInstruction* backing_store = |
| Add<HLoadKeyed>(elements, graph()->GetConstant1(), nullptr, FAST_ELEMENTS, |
| ALLOW_RETURN_HOLE); |
| @@ -809,8 +812,12 @@ HValue* CodeStubGraphBuilderBase::UnmappedCase(HValue* elements, HValue* key) { |
| Token::LT); |
| in_unmapped_range.Then(); |
| { |
| - result = Add<HLoadKeyed>(backing_store, key, nullptr, FAST_HOLEY_ELEMENTS, |
| - NEVER_RETURN_HOLE); |
| + if (value == NULL) { |
| + result = Add<HLoadKeyed>(backing_store, key, nullptr, FAST_HOLEY_ELEMENTS, |
| + NEVER_RETURN_HOLE); |
| + } else { |
| + Add<HStoreKeyed>(backing_store, key, value, FAST_HOLEY_ELEMENTS); |
| + } |
| } |
| in_unmapped_range.ElseDeopt(Deoptimizer::kOutsideOfRange); |
| in_unmapped_range.End(); |
| @@ -818,11 +825,9 @@ HValue* CodeStubGraphBuilderBase::UnmappedCase(HValue* elements, HValue* key) { |
| } |
| -template <> |
| -HValue* CodeStubGraphBuilder<KeyedLoadSloppyArgumentsStub>::BuildCodeStub() { |
| - HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex); |
| - HValue* key = GetParameter(LoadDescriptor::kNameIndex); |
| - |
| +HValue* CodeStubGraphBuilderBase::EmitKeyedSloppyArguments(HValue* receiver, |
| + HValue* key, |
| + HValue* value) { |
| // Mapped arguments are actual arguments. Unmapped arguments are values added |
| // to the arguments object after it was created for the call. Mapped arguments |
| // are stored in the context at indexes given by elements[key + 2]. Unmapped |
| @@ -849,6 +854,8 @@ HValue* CodeStubGraphBuilder<KeyedLoadSloppyArgumentsStub>::BuildCodeStub() { |
| // index into the context array given at elements[0]. Return the value at |
| // context[t]. |
| + bool is_load = value == NULL; |
| + |
| key = AddUncasted<HForceRepresentation>(key, Representation::Smi()); |
| IfBuilder positive_smi(this); |
| positive_smi.If<HCompareNumericAndBranch>(key, graph()->GetConstant0(), |
| @@ -880,25 +887,39 @@ HValue* CodeStubGraphBuilder<KeyedLoadSloppyArgumentsStub>::BuildCodeStub() { |
| HValue* the_context = Add<HLoadKeyed>(elements, graph()->GetConstant0(), |
| nullptr, FAST_ELEMENTS); |
| STATIC_ASSERT(Context::kHeaderSize == FixedArray::kHeaderSize); |
| - HValue* result = Add<HLoadKeyed>(the_context, mapped_index, nullptr, |
| - FAST_ELEMENTS, ALLOW_RETURN_HOLE); |
| - environment()->Push(result); |
| + if (is_load) { |
| + HValue* result = Add<HLoadKeyed>(the_context, mapped_index, nullptr, |
| + FAST_ELEMENTS, ALLOW_RETURN_HOLE); |
| + environment()->Push(result); |
| + } else { |
| + DCHECK(value != NULL); |
| + Add<HStoreKeyed>(the_context, mapped_index, value, FAST_ELEMENTS); |
| + } |
| } |
| is_valid.Else(); |
| { |
| - HValue* result = UnmappedCase(elements, key); |
| - environment()->Push(result); |
| + HValue* result = UnmappedCase(elements, key, value); |
| + if (is_load) environment()->Push(result); |
|
Jakob Kummerow
2015/05/28 11:55:00
Doesn't the store stub need to return the value to
mvstanton
2015/05/28 13:23:52
Good idea, it's much cleaner that way.
|
| } |
| is_valid.End(); |
| } |
| in_range.Else(); |
| { |
| - HValue* result = UnmappedCase(elements, key); |
| - environment()->Push(result); |
| + HValue* result = UnmappedCase(elements, key, value); |
| + if (is_load) environment()->Push(result); |
| } |
| in_range.End(); |
| - return environment()->Pop(); |
| + return is_load ? environment()->Pop() : NULL; |
| +} |
| + |
| + |
| +template <> |
| +HValue* CodeStubGraphBuilder<KeyedLoadSloppyArgumentsStub>::BuildCodeStub() { |
| + HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex); |
| + HValue* key = GetParameter(LoadDescriptor::kNameIndex); |
| + |
| + return EmitKeyedSloppyArguments(receiver, key, NULL); |
| } |
| @@ -907,6 +928,22 @@ Handle<Code> KeyedLoadSloppyArgumentsStub::GenerateCode() { |
| } |
| +template <> |
| +HValue* CodeStubGraphBuilder<KeyedStoreSloppyArgumentsStub>::BuildCodeStub() { |
| + HValue* receiver = GetParameter(StoreDescriptor::kReceiverIndex); |
| + HValue* key = GetParameter(StoreDescriptor::kNameIndex); |
| + HValue* value = GetParameter(StoreDescriptor::kValueIndex); |
| + |
| + EmitKeyedSloppyArguments(receiver, key, value); |
| + return value; |
| +} |
| + |
| + |
| +Handle<Code> KeyedStoreSloppyArgumentsStub::GenerateCode() { |
| + return DoGenerateCode(this); |
| +} |
| + |
| + |
| void CodeStubGraphBuilderBase::BuildStoreNamedField( |
| HValue* object, HValue* value, FieldIndex index, |
| Representation representation, bool transition_to_field) { |