Index: src/ic/accessor-assembler.cc |
diff --git a/src/ic/accessor-assembler.cc b/src/ic/accessor-assembler.cc |
index c048c7ec818f7774eaf14965ce71b13af487ba64..34b3402dba497fbed2b3a806e528e8f585759ff4 100644 |
--- a/src/ic/accessor-assembler.cc |
+++ b/src/ic/accessor-assembler.cc |
@@ -984,15 +984,7 @@ void AccessorAssembler::HandleStoreFieldAndReturn(Node* handler_word, |
BIND(&if_out_of_object); |
{ |
if (transition_to_field) { |
- Label storage_extended(this); |
- GotoIfNot(IsSetWord<StoreHandler::ExtendStorageBits>(handler_word), |
- &storage_extended); |
- Comment("[ Extend storage"); |
- ExtendPropertiesBackingStore(holder); |
- Comment("] Extend storage"); |
- Goto(&storage_extended); |
- |
- BIND(&storage_extended); |
+ ExtendPropertiesBackingStore(holder, handler_word); |
} |
StoreNamedField(handler_word, holder, false, representation, prepared_value, |
@@ -1053,7 +1045,12 @@ Node* AccessorAssembler::PrepareValueForStore(Node* handler_word, Node* holder, |
return value; |
} |
-void AccessorAssembler::ExtendPropertiesBackingStore(Node* object) { |
+void AccessorAssembler::ExtendPropertiesBackingStore(Node* object, |
+ Node* handler_word) { |
+ Label done(this); |
+ GotoIfNot(IsSetWord<StoreHandler::ExtendStorageBits>(handler_word), &done); |
+ Comment("[ Extend storage"); |
+ |
ParameterMode mode = OptimalParameterMode(); |
Node* properties = LoadProperties(object); |
@@ -1061,6 +1058,14 @@ void AccessorAssembler::ExtendPropertiesBackingStore(Node* object) { |
? LoadAndUntagFixedArrayBaseLength(properties) |
: LoadFixedArrayBaseLength(properties); |
+ // Previous property deletion could have left behind unused backing store |
+ // capacity even for a map that think it doesn't have any unused fields. |
+ // Perform a bounds check to see if we actually have to grow the array. |
+ Node* offset = DecodeWord<StoreHandler::FieldOffsetBits>(handler_word); |
+ Node* size = ElementOffsetFromIndex(length, FAST_ELEMENTS, mode, |
+ FixedArray::kHeaderSize); |
+ GotoIf(UintPtrLessThan(offset, size), &done); |
+ |
Node* delta = IntPtrOrSmiConstant(JSObject::kFieldsAdded, mode); |
Node* new_capacity = IntPtrOrSmiAdd(length, delta, mode); |
@@ -1088,6 +1093,10 @@ void AccessorAssembler::ExtendPropertiesBackingStore(Node* object) { |
SKIP_WRITE_BARRIER, mode); |
StoreObjectField(object, JSObject::kPropertiesOffset, new_properties); |
+ Comment("] Extend storage"); |
+ Goto(&done); |
+ |
+ BIND(&done); |
} |
void AccessorAssembler::StoreNamedField(Node* handler_word, Node* object, |