| Index: src/code-stubs-hydrogen.cc
|
| diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
|
| index 3a9688a899f8d43597eb95a54a07719207b7da2f..6b7488c3a76650d6b8f4400708ff1ad3fc77c7fb 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,47 @@ 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 = BuildAllocateAndInitializeArray(kind, new_capacity);
|
| +
|
| + BuildCopyProperties(properties, new_properties, length, new_capacity);
|
| +
|
| + // Store the new value into the "extended" object.
|
| + Add<HStoreNamedField>(object, HObjectAccess::ForPropertiesPointer(),
|
| + new_properties);
|
| +
|
| + BuildStoreNamedField(
|
| + object, 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));
|
|
|