Chromium Code Reviews| Index: src/code-stubs-hydrogen.cc |
| diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc |
| index 3a9688a899f8d43597eb95a54a07719207b7da2f..6a33955d38d85294f3c956ccbe2426d04d3605f7 100644 |
| --- a/src/code-stubs-hydrogen.cc |
| +++ b/src/code-stubs-hydrogen.cc |
| @@ -63,7 +63,8 @@ class CodeStubGraphBuilderBase : public HGraphBuilder { |
| HLoadNamedField* BuildLoadNamedField(HValue* object, |
| FieldIndex index); |
| void BuildStoreNamedField(HValue* object, HValue* value, FieldIndex index, |
| - Representation representation); |
| + Representation representation, |
| + bool transition_to_field); |
| enum ArgumentClass { |
| NONE, |
| @@ -602,7 +603,7 @@ Handle<Code> LoadConstantStub::GenerateCode() { return DoGenerateCode(this); } |
| void CodeStubGraphBuilderBase::BuildStoreNamedField( |
| HValue* object, HValue* value, FieldIndex index, |
| - Representation representation) { |
| + Representation representation, bool transition_to_field) { |
| DCHECK(!index.is_double() || representation.IsDouble()); |
| int offset = index.offset(); |
| HObjectAccess access = |
| @@ -611,12 +612,31 @@ void CodeStubGraphBuilderBase::BuildStoreNamedField( |
| : HObjectAccess::ForBackingStoreOffset(offset, representation); |
| if (representation.IsDouble()) { |
| - // Load the heap number. |
| - object = Add<HLoadNamedField>( |
| - object, static_cast<HValue*>(NULL), |
| - access.WithRepresentation(Representation::Tagged())); |
| - // Store the double value into it. |
| - access = HObjectAccess::ForHeapNumberValue(); |
| + HObjectAccess heap_number_access = |
| + access.WithRepresentation(Representation::Tagged()); |
| + if (transition_to_field) { |
| + // The store requires a mutable HeapNumber to be allocated. |
| + NoObservableSideEffectsScope no_side_effects(this); |
| + HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); |
| + |
| + // TODO(hpayer): Allocation site pretenuring support. |
| + HInstruction* heap_number = |
| + Add<HAllocate>(heap_number_size, HType::HeapObject(), NOT_TENURED, |
| + MUTABLE_HEAP_NUMBER_TYPE); |
| + AddStoreMapConstant(heap_number, |
| + isolate()->factory()->mutable_heap_number_map()); |
| + Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(), |
| + value); |
| + // Store the new mutable heap number into the object. |
| + access = heap_number_access; |
| + value = heap_number; |
| + } else { |
| + // Load the heap number. |
| + object = Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), |
| + heap_number_access); |
| + // Store the double value into it. |
| + access = HObjectAccess::ForHeapNumberValue(); |
| + } |
| } else if (representation.IsHeapObject()) { |
| BuildCheckHeapObject(value); |
| } |
| @@ -628,7 +648,7 @@ void CodeStubGraphBuilderBase::BuildStoreNamedField( |
| template <> |
| HValue* CodeStubGraphBuilder<StoreFieldStub>::BuildCodeStub() { |
| BuildStoreNamedField(GetParameter(0), GetParameter(2), casted_stub()->index(), |
| - casted_stub()->representation()); |
| + casted_stub()->representation(), false); |
| return GetParameter(2); |
| } |
| @@ -637,6 +657,49 @@ Handle<Code> StoreFieldStub::GenerateCode() { return DoGenerateCode(this); } |
| template <> |
| +HValue* CodeStubGraphBuilder<ExtendStorageStub>::BuildCodeStub() { |
| + HValue* object = GetParameter(ExtendStorageDescriptor::kReceiverIndex); |
| + HValue* properties = |
| + Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), |
| + HObjectAccess::ForPropertiesPointer()); |
| + HValue* length = AddLoadFixedArrayLength(properties); |
| + HValue* delta = Add<HConstant>(static_cast<int32_t>(JSObject::kFieldsAdded)); |
| + HValue* new_capacity = AddUncasted<HAdd>(length, delta); |
| + |
| + // Grow properties array. |
| + ElementsKind kind = FAST_ELEMENTS; |
| + Add<HBoundsCheck>(new_capacity, |
| + Add<HConstant>((Page::kMaxRegularHeapObjectSize - |
| + FixedArray::kHeaderSize) >> |
| + ElementsKindToShiftSize(kind))); |
| + |
| + // Reuse this code for properties backing store allocation. |
| + HValue* new_properties = |
| + BuildAllocateElementsAndInitializeElementsHeader(kind, new_capacity); |
|
Yang
2014/09/29 11:10:38
The name of that function is now somewhat misleadi
Igor Sheludko
2014/09/29 12:33:11
Done.
|
| + |
| + BuildCopyProperties(properties, new_properties, length, new_capacity); |
| + |
| + // Store the new value into the "extended" object. |
| + Add<HStoreNamedField>(object, HObjectAccess::ForPropertiesPointer(), |
| + new_properties); |
| + |
| + BuildStoreNamedField(GetParameter(ExtendStorageDescriptor::kReceiverIndex), |
|
Yang
2014/09/29 11:10:38
Isn't this just 'object'?
Igor Sheludko
2014/09/29 12:33:11
Done.
|
| + GetParameter(ExtendStorageDescriptor::kValueIndex), |
| + casted_stub()->index(), casted_stub()->representation(), |
| + true); |
| + |
| + // And finally update the map after the new field is added. |
| + Add<HStoreNamedField>(object, HObjectAccess::ForMap(), |
| + GetParameter(ExtendStorageDescriptor::kMapIndex)); |
| + |
| + return GetParameter(ExtendStorageDescriptor::kValueIndex); |
| +} |
| + |
| + |
| +Handle<Code> ExtendStorageStub::GenerateCode() { return DoGenerateCode(this); } |
| + |
| + |
| +template <> |
| HValue* CodeStubGraphBuilder<StringLengthStub>::BuildCodeStub() { |
| HValue* string = BuildLoadNamedField(GetParameter(0), |
| FieldIndex::ForInObjectOffset(JSValue::kValueOffset)); |