LCOV - code coverage report
Current view: top level - test/cctest - test-elements-kind.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 224 225 99.6 %
Date: 2019-04-17 Functions: 16 16 100.0 %

          Line data    Source code
       1             : // Copyright 2015 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include <stdlib.h>
       6             : #include <utility>
       7             : 
       8             : #include "test/cctest/test-api.h"
       9             : 
      10             : #include "src/v8.h"
      11             : 
      12             : #include "src/compilation-cache.h"
      13             : #include "src/execution.h"
      14             : #include "src/global-handles.h"
      15             : #include "src/heap/factory.h"
      16             : #include "src/ic/stub-cache.h"
      17             : #include "src/objects-inl.h"
      18             : #include "src/objects/js-array-inl.h"
      19             : 
      20             : namespace v8 {
      21             : namespace internal {
      22             : namespace test_elements_kind {
      23             : 
      24             : //
      25             : // Helper functions.
      26             : //
      27             : 
      28             : namespace {
      29             : 
      30             : Handle<String> MakeString(const char* str) {
      31             :   Isolate* isolate = CcTest::i_isolate();
      32             :   Factory* factory = isolate->factory();
      33        1175 :   return factory->InternalizeUtf8String(str);
      34             : }
      35             : 
      36             : 
      37        1060 : Handle<String> MakeName(const char* str, int suffix) {
      38             :   EmbeddedVector<char, 128> buffer;
      39        1060 :   SNPrintF(buffer, "%s%d", str, suffix);
      40        1060 :   return MakeString(buffer.start());
      41             : }
      42             : 
      43             : template <typename T, typename M>
      44         105 : bool EQUALS(Isolate* isolate, Handle<T> left, Handle<M> right) {
      45         105 :   if (*left == *right) return true;
      46             :   return Object::Equals(isolate, Handle<Object>::cast(left),
      47             :                         Handle<Object>::cast(right))
      48           0 :       .FromJust();
      49             : }
      50             : 
      51             : template <typename T, typename M>
      52             : bool EQUALS(Isolate* isolate, Handle<T> left, M right) {
      53             :   return EQUALS(isolate, left, handle(right, isolate));
      54             : }
      55             : 
      56             : template <typename T, typename M>
      57         105 : bool EQUALS(Isolate* isolate, T left, Handle<M> right) {
      58         105 :   return EQUALS(isolate, handle(left, isolate), right);
      59             : }
      60             : 
      61             : }  // namespace
      62             : 
      63             : 
      64             : //
      65             : // Tests
      66             : //
      67             : 
      68       26644 : TEST(SystemPointerElementsKind) {
      69           5 :   CHECK_EQ(ElementsKindToShiftSize(SYSTEM_POINTER_ELEMENTS),
      70             :            kSystemPointerSizeLog2);
      71           5 :   CHECK_EQ(ElementsKindToByteSize(SYSTEM_POINTER_ELEMENTS), kSystemPointerSize);
      72           5 : }
      73             : 
      74       26644 : TEST(JSObjectAddingProperties) {
      75           5 :   CcTest::InitializeVM();
      76             :   Isolate* isolate = CcTest::i_isolate();
      77             :   Factory* factory = isolate->factory();
      78          10 :   v8::HandleScope scope(CcTest::isolate());
      79             : 
      80           5 :   Handle<FixedArray> empty_fixed_array(factory->empty_fixed_array());
      81           5 :   Handle<PropertyArray> empty_property_array(factory->empty_property_array());
      82             :   Handle<JSFunction> function =
      83           5 :       factory->NewFunctionForTest(factory->empty_string());
      84             :   Handle<Object> value(Smi::FromInt(42), isolate);
      85             : 
      86           5 :   Handle<JSObject> object = factory->NewJSObject(function);
      87             :   Handle<Map> previous_map(object->map(), isolate);
      88           5 :   CHECK_EQ(HOLEY_ELEMENTS, previous_map->elements_kind());
      89           5 :   CHECK(EQUALS(isolate, object->property_array(), empty_property_array));
      90           5 :   CHECK(EQUALS(isolate, object->elements(), empty_fixed_array));
      91             : 
      92             :   // for the default constructor function no in-object properties are reserved
      93             :   // hence adding a single property will initialize the property-array
      94           5 :   Handle<String> name = MakeName("property", 0);
      95          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(object, name, value, NONE)
      96             :       .Check();
      97           5 :   CHECK_NE(object->map(), *previous_map);
      98           5 :   CHECK_EQ(HOLEY_ELEMENTS, object->map()->elements_kind());
      99          10 :   CHECK_LE(1, object->property_array()->length());
     100           5 :   CHECK(EQUALS(isolate, object->elements(), empty_fixed_array));
     101           5 : }
     102             : 
     103             : 
     104       26644 : TEST(JSObjectInObjectAddingProperties) {
     105           5 :   CcTest::InitializeVM();
     106             :   Isolate* isolate = CcTest::i_isolate();
     107             :   Factory* factory = isolate->factory();
     108          10 :   v8::HandleScope scope(CcTest::isolate());
     109             : 
     110           5 :   Handle<FixedArray> empty_fixed_array(factory->empty_fixed_array());
     111           5 :   Handle<PropertyArray> empty_property_array(factory->empty_property_array());
     112             :   Handle<JSFunction> function =
     113           5 :       factory->NewFunctionForTest(factory->empty_string());
     114             :   int nof_inobject_properties = 10;
     115             :   // force in object properties by changing the expected_nof_properties
     116             :   // (we always reserve 8 inobject properties slack on top).
     117             :   function->shared()->set_expected_nof_properties(nof_inobject_properties - 8);
     118             :   Handle<Object> value(Smi::FromInt(42), isolate);
     119             : 
     120           5 :   Handle<JSObject> object = factory->NewJSObject(function);
     121             :   Handle<Map> previous_map(object->map(), isolate);
     122           5 :   CHECK_EQ(HOLEY_ELEMENTS, previous_map->elements_kind());
     123           5 :   CHECK(EQUALS(isolate, object->property_array(), empty_property_array));
     124           5 :   CHECK(EQUALS(isolate, object->elements(), empty_fixed_array));
     125             : 
     126             :   // we have reserved space for in-object properties, hence adding up to
     127             :   // |nof_inobject_properties| will not create a property store
     128         105 :   for (int i = 0; i < nof_inobject_properties; i++) {
     129          50 :     Handle<String> name = MakeName("property", i);
     130         100 :     JSObject::DefinePropertyOrElementIgnoreAttributes(object, name, value, NONE)
     131             :         .Check();
     132             :   }
     133           5 :   CHECK_NE(object->map(), *previous_map);
     134           5 :   CHECK_EQ(HOLEY_ELEMENTS, object->map()->elements_kind());
     135           5 :   CHECK(EQUALS(isolate, object->property_array(), empty_property_array));
     136           5 :   CHECK(EQUALS(isolate, object->elements(), empty_fixed_array));
     137             : 
     138             :   // adding one more property will not fit in the in-object properties, thus
     139             :   // creating a property store
     140             :   int index = nof_inobject_properties + 1;
     141           5 :   Handle<String> name = MakeName("property", index);
     142          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(object, name, value, NONE)
     143             :       .Check();
     144           5 :   CHECK_NE(object->map(), *previous_map);
     145           5 :   CHECK_EQ(HOLEY_ELEMENTS, object->map()->elements_kind());
     146             :   // there must be at least 1 element in the properies store
     147          10 :   CHECK_LE(1, object->property_array()->length());
     148           5 :   CHECK(EQUALS(isolate, object->elements(), empty_fixed_array));
     149           5 : }
     150             : 
     151             : 
     152       26644 : TEST(JSObjectAddingElements) {
     153           5 :   CcTest::InitializeVM();
     154             :   Isolate* isolate = CcTest::i_isolate();
     155             :   Factory* factory = isolate->factory();
     156          10 :   v8::HandleScope scope(CcTest::isolate());
     157             : 
     158             :   Handle<String> name;
     159           5 :   Handle<FixedArray> empty_fixed_array(factory->empty_fixed_array());
     160           5 :   Handle<PropertyArray> empty_property_array(factory->empty_property_array());
     161             :   Handle<JSFunction> function =
     162           5 :       factory->NewFunctionForTest(factory->empty_string());
     163             :   Handle<Object> value(Smi::FromInt(42), isolate);
     164             : 
     165           5 :   Handle<JSObject> object = factory->NewJSObject(function);
     166             :   Handle<Map> previous_map(object->map(), isolate);
     167           5 :   CHECK_EQ(HOLEY_ELEMENTS, previous_map->elements_kind());
     168           5 :   CHECK(EQUALS(isolate, object->property_array(), empty_property_array));
     169           5 :   CHECK(EQUALS(isolate, object->elements(), empty_fixed_array));
     170             : 
     171             :   // Adding an indexed element initializes the elements array
     172             :   name = MakeString("0");
     173          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(object, name, value, NONE)
     174             :       .Check();
     175             :   // no change in elements_kind => no map transition
     176           5 :   CHECK_EQ(object->map(), *previous_map);
     177           5 :   CHECK_EQ(HOLEY_ELEMENTS, object->map()->elements_kind());
     178           5 :   CHECK(EQUALS(isolate, object->property_array(), empty_property_array));
     179           5 :   CHECK_LE(1, object->elements()->length());
     180             : 
     181             :   // Adding more consecutive elements without a change in the backing store
     182             :   int non_dict_backing_store_limit = 100;
     183         995 :   for (int i = 1; i < non_dict_backing_store_limit; i++) {
     184         495 :     name = MakeName("", i);
     185         990 :     JSObject::DefinePropertyOrElementIgnoreAttributes(object, name, value, NONE)
     186             :         .Check();
     187             :   }
     188             :   // no change in elements_kind => no map transition
     189           5 :   CHECK_EQ(object->map(), *previous_map);
     190           5 :   CHECK_EQ(HOLEY_ELEMENTS, object->map()->elements_kind());
     191           5 :   CHECK(EQUALS(isolate, object->property_array(), empty_property_array));
     192           5 :   CHECK_LE(non_dict_backing_store_limit, object->elements()->length());
     193             : 
     194             :   // Adding an element at an very large index causes a change to
     195             :   // DICTIONARY_ELEMENTS
     196             :   name = MakeString("100000000");
     197          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(object, name, value, NONE)
     198             :       .Check();
     199             :   // change in elements_kind => map transition
     200           5 :   CHECK_NE(object->map(), *previous_map);
     201           5 :   CHECK_EQ(DICTIONARY_ELEMENTS, object->map()->elements_kind());
     202           5 :   CHECK(EQUALS(isolate, object->property_array(), empty_property_array));
     203           5 :   CHECK_LE(non_dict_backing_store_limit, object->elements()->length());
     204           5 : }
     205             : 
     206             : 
     207       26644 : TEST(JSArrayAddingProperties) {
     208           5 :   CcTest::InitializeVM();
     209             :   Isolate* isolate = CcTest::i_isolate();
     210             :   Factory* factory = isolate->factory();
     211          10 :   v8::HandleScope scope(CcTest::isolate());
     212             : 
     213           5 :   Handle<FixedArray> empty_fixed_array(factory->empty_fixed_array());
     214           5 :   Handle<PropertyArray> empty_property_array(factory->empty_property_array());
     215             :   Handle<Object> value(Smi::FromInt(42), isolate);
     216             : 
     217             :   Handle<JSArray> array =
     218           5 :       factory->NewJSArray(ElementsKind::PACKED_SMI_ELEMENTS, 0, 0);
     219             :   Handle<Map> previous_map(array->map(), isolate);
     220           5 :   CHECK_EQ(PACKED_SMI_ELEMENTS, previous_map->elements_kind());
     221           5 :   CHECK(EQUALS(isolate, array->property_array(), empty_property_array));
     222           5 :   CHECK(EQUALS(isolate, array->elements(), empty_fixed_array));
     223           5 :   CHECK_EQ(0, Smi::ToInt(array->length()));
     224             : 
     225             :   // for the default constructor function no in-object properties are reserved
     226             :   // hence adding a single property will initialize the property-array
     227           5 :   Handle<String> name = MakeName("property", 0);
     228          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(array, name, value, NONE)
     229             :       .Check();
     230             :   // No change in elements_kind but added property => new map
     231           5 :   CHECK_NE(array->map(), *previous_map);
     232           5 :   CHECK_EQ(PACKED_SMI_ELEMENTS, array->map()->elements_kind());
     233          10 :   CHECK_LE(1, array->property_array()->length());
     234           5 :   CHECK(EQUALS(isolate, array->elements(), empty_fixed_array));
     235           5 :   CHECK_EQ(0, Smi::ToInt(array->length()));
     236           5 : }
     237             : 
     238             : 
     239       26644 : TEST(JSArrayAddingElements) {
     240           5 :   CcTest::InitializeVM();
     241             :   Isolate* isolate = CcTest::i_isolate();
     242             :   Factory* factory = isolate->factory();
     243          10 :   v8::HandleScope scope(CcTest::isolate());
     244             : 
     245             :   Handle<String> name;
     246           5 :   Handle<FixedArray> empty_fixed_array(factory->empty_fixed_array());
     247           5 :   Handle<PropertyArray> empty_property_array(factory->empty_property_array());
     248             :   Handle<Object> value(Smi::FromInt(42), isolate);
     249             : 
     250             :   Handle<JSArray> array =
     251           5 :       factory->NewJSArray(ElementsKind::PACKED_SMI_ELEMENTS, 0, 0);
     252             :   Handle<Map> previous_map(array->map(), isolate);
     253           5 :   CHECK_EQ(PACKED_SMI_ELEMENTS, previous_map->elements_kind());
     254           5 :   CHECK(EQUALS(isolate, array->property_array(), empty_property_array));
     255           5 :   CHECK(EQUALS(isolate, array->elements(), empty_fixed_array));
     256           5 :   CHECK_EQ(0, Smi::ToInt(array->length()));
     257             : 
     258             :   // Adding an indexed element initializes the elements array
     259             :   name = MakeString("0");
     260          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(array, name, value, NONE)
     261             :       .Check();
     262             :   // no change in elements_kind => no map transition
     263           5 :   CHECK_EQ(array->map(), *previous_map);
     264           5 :   CHECK_EQ(PACKED_SMI_ELEMENTS, array->map()->elements_kind());
     265           5 :   CHECK(EQUALS(isolate, array->property_array(), empty_property_array));
     266           5 :   CHECK_LE(1, array->elements()->length());
     267           5 :   CHECK_EQ(1, Smi::ToInt(array->length()));
     268             : 
     269             :   // Adding more consecutive elements without a change in the backing store
     270             :   int non_dict_backing_store_limit = 100;
     271         995 :   for (int i = 1; i < non_dict_backing_store_limit; i++) {
     272         495 :     name = MakeName("", i);
     273         990 :     JSObject::DefinePropertyOrElementIgnoreAttributes(array, name, value, NONE)
     274             :         .Check();
     275             :   }
     276             :   // no change in elements_kind => no map transition
     277           5 :   CHECK_EQ(array->map(), *previous_map);
     278           5 :   CHECK_EQ(PACKED_SMI_ELEMENTS, array->map()->elements_kind());
     279           5 :   CHECK(EQUALS(isolate, array->property_array(), empty_property_array));
     280           5 :   CHECK_LE(non_dict_backing_store_limit, array->elements()->length());
     281           5 :   CHECK_EQ(non_dict_backing_store_limit, Smi::ToInt(array->length()));
     282             : 
     283             :   // Adding an element at an very large index causes a change to
     284             :   // DICTIONARY_ELEMENTS
     285             :   int index = 100000000;
     286           5 :   name = MakeName("", index);
     287          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(array, name, value, NONE)
     288             :       .Check();
     289             :   // change in elements_kind => map transition
     290           5 :   CHECK_NE(array->map(), *previous_map);
     291           5 :   CHECK_EQ(DICTIONARY_ELEMENTS, array->map()->elements_kind());
     292           5 :   CHECK(EQUALS(isolate, array->property_array(), empty_property_array));
     293           5 :   CHECK_LE(non_dict_backing_store_limit, array->elements()->length());
     294           5 :   CHECK_LE(array->elements()->length(), index);
     295           5 :   CHECK_EQ(index + 1, Smi::ToInt(array->length()));
     296           5 : }
     297             : 
     298             : 
     299       26644 : TEST(JSArrayAddingElementsGeneralizingiFastSmiElements) {
     300           5 :   CcTest::InitializeVM();
     301             :   Isolate* isolate = CcTest::i_isolate();
     302             :   Factory* factory = isolate->factory();
     303          10 :   v8::HandleScope scope(CcTest::isolate());
     304             : 
     305             :   Handle<String> name;
     306             :   Handle<Object> value_smi(Smi::FromInt(42), isolate);
     307             :   Handle<Object> value_string(MakeString("value"));
     308           5 :   Handle<Object> value_double = factory->NewNumber(3.1415);
     309             : 
     310             :   Handle<JSArray> array =
     311           5 :       factory->NewJSArray(ElementsKind::PACKED_SMI_ELEMENTS, 0, 0);
     312             :   Handle<Map> previous_map(array->map(), isolate);
     313           5 :   CHECK_EQ(PACKED_SMI_ELEMENTS, previous_map->elements_kind());
     314           5 :   CHECK_EQ(0, Smi::ToInt(array->length()));
     315             : 
     316             :   // `array[0] = smi_value` doesn't change the elements_kind
     317             :   name = MakeString("0");
     318          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(array, name, value_smi,
     319           5 :                                                     NONE)
     320             :       .Check();
     321             :   // no change in elements_kind => no map transition
     322           5 :   CHECK_EQ(array->map(), *previous_map);
     323           5 :   CHECK_EQ(PACKED_SMI_ELEMENTS, array->map()->elements_kind());
     324           5 :   CHECK_EQ(1, Smi::ToInt(array->length()));
     325             : 
     326             :   // `delete array[0]` does not alter length, but changes the elments_kind
     327             :   name = MakeString("0");
     328          10 :   CHECK(JSReceiver::DeletePropertyOrElement(array, name).FromMaybe(false));
     329           5 :   CHECK_NE(array->map(), *previous_map);
     330           5 :   CHECK_EQ(HOLEY_SMI_ELEMENTS, array->map()->elements_kind());
     331           5 :   CHECK_EQ(1, Smi::ToInt(array->length()));
     332             :   previous_map = handle(array->map(), isolate);
     333             : 
     334             :   // add a couple of elements again
     335             :   name = MakeString("0");
     336          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(array, name, value_smi,
     337           5 :                                                     NONE)
     338             :       .Check();
     339             :   name = MakeString("1");
     340          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(array, name, value_smi,
     341           5 :                                                     NONE)
     342             :       .Check();
     343           5 :   CHECK_EQ(array->map(), *previous_map);
     344           5 :   CHECK_EQ(HOLEY_SMI_ELEMENTS, array->map()->elements_kind());
     345           5 :   CHECK_EQ(2, Smi::ToInt(array->length()));
     346             : 
     347             :   // Adding a string to the array changes from FAST_HOLEY_SMI to FAST_HOLEY
     348             :   name = MakeString("0");
     349          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(array, name, value_string,
     350           5 :                                                     NONE)
     351             :       .Check();
     352           5 :   CHECK_NE(array->map(), *previous_map);
     353           5 :   CHECK_EQ(HOLEY_ELEMENTS, array->map()->elements_kind());
     354           5 :   CHECK_EQ(2, Smi::ToInt(array->length()));
     355             :   previous_map = handle(array->map(), isolate);
     356             : 
     357             :   // We don't transition back to FAST_SMI even if we remove the string
     358             :   name = MakeString("0");
     359          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(array, name, value_smi,
     360           5 :                                                     NONE)
     361             :       .Check();
     362           5 :   CHECK_EQ(array->map(), *previous_map);
     363             : 
     364             :   // Adding a double doesn't change the map either
     365             :   name = MakeString("0");
     366          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(array, name, value_double,
     367           5 :                                                     NONE)
     368             :       .Check();
     369           5 :   CHECK_EQ(array->map(), *previous_map);
     370           5 : }
     371             : 
     372             : 
     373       26644 : TEST(JSArrayAddingElementsGeneralizingFastElements) {
     374           5 :   CcTest::InitializeVM();
     375             :   Isolate* isolate = CcTest::i_isolate();
     376             :   Factory* factory = isolate->factory();
     377          10 :   v8::HandleScope scope(CcTest::isolate());
     378             : 
     379             :   Handle<String> name;
     380             :   Handle<Object> value_smi(Smi::FromInt(42), isolate);
     381             :   Handle<Object> value_string(MakeString("value"));
     382             : 
     383             :   Handle<JSArray> array =
     384           5 :       factory->NewJSArray(ElementsKind::PACKED_ELEMENTS, 0, 0);
     385             :   Handle<Map> previous_map(array->map(), isolate);
     386           5 :   CHECK_EQ(PACKED_ELEMENTS, previous_map->elements_kind());
     387           5 :   CHECK_EQ(0, Smi::ToInt(array->length()));
     388             : 
     389             :   // `array[0] = smi_value` doesn't change the elements_kind
     390             :   name = MakeString("0");
     391          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(array, name, value_smi,
     392           5 :                                                     NONE)
     393             :       .Check();
     394             :   // no change in elements_kind => no map transition
     395           5 :   CHECK_EQ(array->map(), *previous_map);
     396           5 :   CHECK_EQ(PACKED_ELEMENTS, array->map()->elements_kind());
     397           5 :   CHECK_EQ(1, Smi::ToInt(array->length()));
     398             : 
     399             :   // `delete array[0]` does not alter length, but changes the elments_kind
     400             :   name = MakeString("0");
     401          10 :   CHECK(JSReceiver::DeletePropertyOrElement(array, name).FromMaybe(false));
     402           5 :   CHECK_NE(array->map(), *previous_map);
     403           5 :   CHECK_EQ(HOLEY_ELEMENTS, array->map()->elements_kind());
     404           5 :   CHECK_EQ(1, Smi::ToInt(array->length()));
     405             :   previous_map = handle(array->map(), isolate);
     406             : 
     407             :   // add a couple of elements, elements_kind stays HOLEY
     408             :   name = MakeString("0");
     409          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(array, name, value_string,
     410           5 :                                                     NONE)
     411             :       .Check();
     412             :   name = MakeString("1");
     413          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(array, name, value_smi,
     414           5 :                                                     NONE)
     415             :       .Check();
     416           5 :   CHECK_EQ(array->map(), *previous_map);
     417           5 :   CHECK_EQ(HOLEY_ELEMENTS, array->map()->elements_kind());
     418           5 :   CHECK_EQ(2, Smi::ToInt(array->length()));
     419           5 : }
     420             : 
     421             : 
     422       26644 : TEST(JSArrayAddingElementsGeneralizingiFastDoubleElements) {
     423           5 :   CcTest::InitializeVM();
     424             :   Isolate* isolate = CcTest::i_isolate();
     425             :   Factory* factory = isolate->factory();
     426          10 :   v8::HandleScope scope(CcTest::isolate());
     427             : 
     428             :   Handle<String> name;
     429             :   Handle<Object> value_smi(Smi::FromInt(42), isolate);
     430             :   Handle<Object> value_string(MakeString("value"));
     431           5 :   Handle<Object> value_double = factory->NewNumber(3.1415);
     432             : 
     433             :   Handle<JSArray> array =
     434           5 :       factory->NewJSArray(ElementsKind::PACKED_SMI_ELEMENTS, 0, 0);
     435             :   Handle<Map> previous_map(array->map(), isolate);
     436             : 
     437             :   // `array[0] = value_double` changes |elements_kind| to PACKED_DOUBLE_ELEMENTS
     438             :   name = MakeString("0");
     439          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(array, name, value_double,
     440           5 :                                                     NONE)
     441             :       .Check();
     442           5 :   CHECK_NE(array->map(), *previous_map);
     443           5 :   CHECK_EQ(PACKED_DOUBLE_ELEMENTS, array->map()->elements_kind());
     444           5 :   CHECK_EQ(1, Smi::ToInt(array->length()));
     445             :   previous_map = handle(array->map(), isolate);
     446             : 
     447             :   // `array[1] = value_smi` doesn't alter the |elements_kind|
     448             :   name = MakeString("1");
     449          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(array, name, value_smi,
     450           5 :                                                     NONE)
     451             :       .Check();
     452           5 :   CHECK_EQ(array->map(), *previous_map);
     453           5 :   CHECK_EQ(PACKED_DOUBLE_ELEMENTS, array->map()->elements_kind());
     454           5 :   CHECK_EQ(2, Smi::ToInt(array->length()));
     455             : 
     456             :   // `delete array[0]` does not alter length, but changes the elments_kind
     457             :   name = MakeString("0");
     458          10 :   CHECK(JSReceiver::DeletePropertyOrElement(array, name).FromMaybe(false));
     459           5 :   CHECK_NE(array->map(), *previous_map);
     460           5 :   CHECK_EQ(HOLEY_DOUBLE_ELEMENTS, array->map()->elements_kind());
     461           5 :   CHECK_EQ(2, Smi::ToInt(array->length()));
     462             :   previous_map = handle(array->map(), isolate);
     463             : 
     464             :   // filling the hole `array[0] = value_smi` again doesn't transition back
     465             :   name = MakeString("0");
     466          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(array, name, value_double,
     467           5 :                                                     NONE)
     468             :       .Check();
     469           5 :   CHECK_EQ(array->map(), *previous_map);
     470           5 :   CHECK_EQ(HOLEY_DOUBLE_ELEMENTS, array->map()->elements_kind());
     471           5 :   CHECK_EQ(2, Smi::ToInt(array->length()));
     472             : 
     473             :   // Adding a string to the array changes to elements_kind PACKED_ELEMENTS
     474             :   name = MakeString("1");
     475          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(array, name, value_string,
     476           5 :                                                     NONE)
     477             :       .Check();
     478           5 :   CHECK_NE(array->map(), *previous_map);
     479           5 :   CHECK_EQ(HOLEY_ELEMENTS, array->map()->elements_kind());
     480           5 :   CHECK_EQ(2, Smi::ToInt(array->length()));
     481             :   previous_map = handle(array->map(), isolate);
     482             : 
     483             :   // Adding a double doesn't change the map
     484             :   name = MakeString("0");
     485          10 :   JSObject::DefinePropertyOrElementIgnoreAttributes(array, name, value_double,
     486           5 :                                                     NONE)
     487             :       .Check();
     488           5 :   CHECK_EQ(array->map(), *previous_map);
     489           5 : }
     490             : 
     491             : }  // namespace test_elements_kind
     492             : }  // namespace internal
     493       79917 : }  // namespace v8

Generated by: LCOV version 1.10