| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index e34688051d53f9fa75691d6db382ddcc18795c6c..4084ea669989d5f5d34c856447d88e718dd594fe 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -1078,8 +1078,16 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
|
|
|
| HValue* context = environment()->LookupContext();
|
|
|
| - HValue* new_capacity = BuildNewElementsCapacity(context, key);
|
| + HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap));
|
| + HValue* max_capacity = AddInstruction(
|
| + HAdd::New(zone, context, current_capacity, max_gap));
|
| + IfBuilder key_checker(this);
|
| + key_checker.If<HCompareNumericAndBranch>(key, max_capacity, Token::LT);
|
| + key_checker.Then();
|
| + key_checker.ElseDeopt();
|
| + key_checker.End();
|
|
|
| + HValue* new_capacity = BuildNewElementsCapacity(context, key);
|
| HValue* new_elements = BuildGrowElementsCapacity(object, elements,
|
| kind, kind, length,
|
| new_capacity);
|
| @@ -1337,6 +1345,9 @@ HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader(
|
| HValue* context,
|
| ElementsKind kind,
|
| HValue* capacity) {
|
| + // The HForceRepresentation is to prevent possible deopt on int-smi
|
| + // conversion after allocation but before the new object fields are set.
|
| + capacity = Add<HForceRepresentation>(capacity, Representation::Smi());
|
| HValue* new_elements = BuildAllocateElements(context, kind, capacity);
|
| BuildInitializeElementsHeader(new_elements, kind, capacity);
|
| return new_elements;
|
| @@ -1474,7 +1485,6 @@ HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context,
|
| HValue* half_old_capacity =
|
| AddInstruction(HShr::New(zone, context, old_capacity,
|
| graph_->GetConstant1()));
|
| - half_old_capacity->ClearFlag(HValue::kCanOverflow);
|
|
|
| HValue* new_capacity = AddInstruction(
|
| HAdd::New(zone, context, half_old_capacity, old_capacity));
|
| @@ -1497,8 +1507,6 @@ void HGraphBuilder::BuildNewSpaceArrayCheck(HValue* length, ElementsKind kind) {
|
| int max_size = heap->MaxRegularSpaceAllocationSize() / element_size;
|
| max_size -= JSArray::kSize / element_size;
|
| HConstant* max_size_constant = Add<HConstant>(max_size);
|
| - // Since we're forcing Integer32 representation for this HBoundsCheck,
|
| - // there's no need to Smi-check the index.
|
| Add<HBoundsCheck>(length, max_size_constant);
|
| }
|
|
|
| @@ -1927,6 +1935,14 @@ HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
|
| bool fill_with_hole) {
|
| HValue* context = builder()->environment()->LookupContext();
|
|
|
| + // These HForceRepresentations are because we store these as fields in the
|
| + // objects we construct, and an int32-to-smi HChange could deopt. Accept
|
| + // the deopt possibility now, before allocation occurs.
|
| + capacity = builder()->Add<HForceRepresentation>(capacity,
|
| + Representation::Smi());
|
| + length_field = builder()->Add<HForceRepresentation>(length_field,
|
| + Representation::Smi());
|
| +
|
| // Allocate (dealing with failure appropriately)
|
| HAllocate::Flags flags = HAllocate::DefaultFlags(kind_);
|
| HAllocate* new_object = builder()->Add<HAllocate>(context, size_in_bytes,
|
|
|