static HObjectAccess ForArrayLength(ElementsKind elements_kind) {
return HObjectAccess(
- kArrayLengths, JSArray::kLengthOffset,
- IsFastElementsKind(elements_kind) && FLAG_track_fields ?
- Representation::Smi() : Representation::Tagged());
+ kArrayLengths,
+ JSArray::kLengthOffset,
+ IsFastElementsKind(elements_kind) &&
+ FLAG_track_fields
+ ? Representation::Smi() : Representation::Tagged());
}
static HObjectAccess ForAllocationSiteTransitionInfo() {
static HObjectAccess ForFixedArrayLength() {
return HObjectAccess(
- kArrayLengths, FixedArray::kLengthOffset,
- FLAG_track_fields ?
- Representation::Smi() : Representation::Tagged());
+ kArrayLengths,
+ FixedArray::kLengthOffset,
+ FLAG_track_fields ? Representation::Smi() : Representation::Tagged());
}
static HObjectAccess ForPropertiesPointer() {
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);
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;
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));
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);
}
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,
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Flags: --allow-natives-syntax
+
// Verifies that the KeyedStoreIC correctly handles out-of-bounds stores
// to an array that grow it by a single element. Test functions are
// called twice to make sure that the IC is used, first call is handled
array_store_1(a, 0, 0.5);
assertEquals(0.5, a[0]);
assertEquals(0.5, array_store_1([], 0, 0.5));
+
+// Verify that a grow store will deoptimize if the max gap (difference between
+// the end of an array capacity and a new index) is passed. The wrapper is to
+// make sure array_store_10 isn't inlined.
+
+(function() {
+ function grow_store(a,b,c) {
+ a[b] = c;
+ }
+
+ a = new Array(1);
+ grow_store(a,1,1);
+ grow_store(a,2,1);
+ %OptimizeFunctionOnNextCall(grow_store);
+ grow_store(a,10,1);
+ assertOptimized(grow_store);
+ grow_store(a,2048,1);
+ assertUnoptimized(grow_store);
+})();
+