LCOV - code coverage report
Current view: top level - test/cctest - test-transitions.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 138 138 100.0 %
Date: 2017-10-20 Functions: 7 7 100.0 %

          Line data    Source code
       1             : // Copyright 2014 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 "src/v8.h"
       9             : 
      10             : #include "src/compilation-cache.h"
      11             : #include "src/execution.h"
      12             : #include "src/factory.h"
      13             : #include "src/field-type.h"
      14             : #include "src/global-handles.h"
      15             : #include "src/objects-inl.h"
      16             : #include "src/transitions.h"
      17             : #include "test/cctest/cctest.h"
      18             : #include "test/cctest/test-transitions.h"
      19             : 
      20             : namespace v8 {
      21             : namespace internal {
      22             : 
      23       23724 : TEST(TransitionArray_SimpleFieldTransitions) {
      24           6 :   CcTest::InitializeVM();
      25           6 :   v8::HandleScope scope(CcTest::isolate());
      26             :   Isolate* isolate = CcTest::i_isolate();
      27             :   Factory* factory = isolate->factory();
      28             : 
      29           6 :   Handle<String> name1 = factory->InternalizeUtf8String("foo");
      30           6 :   Handle<String> name2 = factory->InternalizeUtf8String("bar");
      31             :   PropertyAttributes attributes = NONE;
      32             : 
      33           6 :   Handle<Map> map0 = Map::Create(isolate, 0);
      34             :   Handle<Map> map1 =
      35             :       Map::CopyWithField(map0, name1, handle(FieldType::Any(), isolate),
      36             :                          attributes, kMutable, Representation::Tagged(),
      37          12 :                          OMIT_TRANSITION)
      38          12 :           .ToHandleChecked();
      39             :   Handle<Map> map2 =
      40             :       Map::CopyWithField(map0, name2, handle(FieldType::Any(), isolate),
      41             :                          attributes, kMutable, Representation::Tagged(),
      42          12 :                          OMIT_TRANSITION)
      43          12 :           .ToHandleChecked();
      44             : 
      45           6 :   CHECK(map0->raw_transitions()->IsSmi());
      46             : 
      47             :   {
      48             :     TestTransitionsAccessor transitions(map0);
      49           6 :     transitions.Insert(name1, map1, SIMPLE_PROPERTY_TRANSITION);
      50             :   }
      51             :   {
      52             :     TestTransitionsAccessor transitions(map0);
      53           6 :     CHECK(transitions.IsWeakCellEncoding());
      54          12 :     CHECK_EQ(*map1, transitions.SearchTransition(*name1, kData, attributes));
      55           6 :     CHECK_EQ(1, transitions.NumberOfTransitions());
      56           6 :     CHECK_EQ(*name1, transitions.GetKey(0));
      57          12 :     CHECK_EQ(*map1, transitions.GetTarget(0));
      58             : 
      59           6 :     transitions.Insert(name2, map2, SIMPLE_PROPERTY_TRANSITION);
      60             :   }
      61             :   {
      62             :     TestTransitionsAccessor transitions(map0);
      63           6 :     CHECK(transitions.IsFullTransitionArrayEncoding());
      64             : 
      65          12 :     CHECK_EQ(*map1, transitions.SearchTransition(*name1, kData, attributes));
      66          12 :     CHECK_EQ(*map2, transitions.SearchTransition(*name2, kData, attributes));
      67           6 :     CHECK_EQ(2, transitions.NumberOfTransitions());
      68          12 :     for (int i = 0; i < 2; i++) {
      69          12 :       Name* key = transitions.GetKey(i);
      70          12 :       Map* target = transitions.GetTarget(i);
      71          30 :       CHECK((key == *name1 && target == *map1) ||
      72             :             (key == *name2 && target == *map2));
      73             :     }
      74             : 
      75             :     DCHECK(transitions.IsSortedNoDuplicates());
      76           6 :   }
      77           6 : }
      78             : 
      79             : 
      80       23724 : TEST(TransitionArray_FullFieldTransitions) {
      81           6 :   CcTest::InitializeVM();
      82           6 :   v8::HandleScope scope(CcTest::isolate());
      83             :   Isolate* isolate = CcTest::i_isolate();
      84             :   Factory* factory = isolate->factory();
      85             : 
      86           6 :   Handle<String> name1 = factory->InternalizeUtf8String("foo");
      87           6 :   Handle<String> name2 = factory->InternalizeUtf8String("bar");
      88             :   PropertyAttributes attributes = NONE;
      89             : 
      90           6 :   Handle<Map> map0 = Map::Create(isolate, 0);
      91             :   Handle<Map> map1 =
      92             :       Map::CopyWithField(map0, name1, handle(FieldType::Any(), isolate),
      93             :                          attributes, kMutable, Representation::Tagged(),
      94          12 :                          OMIT_TRANSITION)
      95          12 :           .ToHandleChecked();
      96             :   Handle<Map> map2 =
      97             :       Map::CopyWithField(map0, name2, handle(FieldType::Any(), isolate),
      98             :                          attributes, kMutable, Representation::Tagged(),
      99          12 :                          OMIT_TRANSITION)
     100          12 :           .ToHandleChecked();
     101             : 
     102           6 :   CHECK(map0->raw_transitions()->IsSmi());
     103             : 
     104             :   {
     105             :     TestTransitionsAccessor transitions(map0);
     106           6 :     transitions.Insert(name1, map1, PROPERTY_TRANSITION);
     107             :   }
     108             :   {
     109             :     TestTransitionsAccessor transitions(map0);
     110           6 :     CHECK(transitions.IsFullTransitionArrayEncoding());
     111          12 :     CHECK_EQ(*map1, transitions.SearchTransition(*name1, kData, attributes));
     112           6 :     CHECK_EQ(1, transitions.NumberOfTransitions());
     113          12 :     CHECK_EQ(*name1, transitions.GetKey(0));
     114          12 :     CHECK_EQ(*map1, transitions.GetTarget(0));
     115             : 
     116           6 :     transitions.Insert(name2, map2, PROPERTY_TRANSITION);
     117             :   }
     118             :   {
     119             :     TestTransitionsAccessor transitions(map0);
     120           6 :     CHECK(transitions.IsFullTransitionArrayEncoding());
     121             : 
     122          12 :     CHECK_EQ(*map1, transitions.SearchTransition(*name1, kData, attributes));
     123          12 :     CHECK_EQ(*map2, transitions.SearchTransition(*name2, kData, attributes));
     124           6 :     CHECK_EQ(2, transitions.NumberOfTransitions());
     125          12 :     for (int i = 0; i < 2; i++) {
     126          12 :       Name* key = transitions.GetKey(i);
     127          12 :       Map* target = transitions.GetTarget(i);
     128          30 :       CHECK((key == *name1 && target == *map1) ||
     129             :             (key == *name2 && target == *map2));
     130             :     }
     131             : 
     132             :     DCHECK(transitions.IsSortedNoDuplicates());
     133           6 :   }
     134           6 : }
     135             : 
     136             : 
     137       23724 : TEST(TransitionArray_DifferentFieldNames) {
     138           6 :   CcTest::InitializeVM();
     139           6 :   v8::HandleScope scope(CcTest::isolate());
     140             :   Isolate* isolate = CcTest::i_isolate();
     141             :   Factory* factory = isolate->factory();
     142             : 
     143             :   const int PROPS_COUNT = 10;
     144          66 :   Handle<String> names[PROPS_COUNT];
     145          60 :   Handle<Map> maps[PROPS_COUNT];
     146             :   PropertyAttributes attributes = NONE;
     147             : 
     148           6 :   Handle<Map> map0 = Map::Create(isolate, 0);
     149           6 :   CHECK(map0->raw_transitions()->IsSmi());
     150             : 
     151          60 :   for (int i = 0; i < PROPS_COUNT; i++) {
     152             :     EmbeddedVector<char, 64> buffer;
     153          60 :     SNPrintF(buffer, "prop%d", i);
     154          60 :     Handle<String> name = factory->InternalizeUtf8String(buffer.start());
     155             :     Handle<Map> map =
     156             :         Map::CopyWithField(map0, name, handle(FieldType::Any(), isolate),
     157             :                            attributes, kMutable, Representation::Tagged(),
     158         120 :                            OMIT_TRANSITION)
     159         120 :             .ToHandleChecked();
     160          60 :     names[i] = name;
     161          60 :     maps[i] = map;
     162             : 
     163          60 :     TransitionsAccessor(map0).Insert(name, map, PROPERTY_TRANSITION);
     164             :   }
     165             : 
     166             :   TransitionsAccessor transitions(map0);
     167          66 :   for (int i = 0; i < PROPS_COUNT; i++) {
     168         180 :     CHECK_EQ(*maps[i],
     169             :              transitions.SearchTransition(*names[i], kData, attributes));
     170             :   }
     171          60 :   for (int i = 0; i < PROPS_COUNT; i++) {
     172          60 :     Name* key = transitions.GetKey(i);
     173          60 :     Map* target = transitions.GetTarget(i);
     174         600 :     for (int j = 0; j < PROPS_COUNT; j++) {
     175        1092 :       if (*names[i] == key) {
     176          12 :         CHECK_EQ(*maps[i], target);
     177             :         break;
     178             :       }
     179             :     }
     180             :   }
     181             : 
     182           6 :   DCHECK(transitions.IsSortedNoDuplicates());
     183           6 : }
     184             : 
     185             : 
     186       23724 : TEST(TransitionArray_SameFieldNamesDifferentAttributesSimple) {
     187           6 :   CcTest::InitializeVM();
     188           6 :   v8::HandleScope scope(CcTest::isolate());
     189             :   Isolate* isolate = CcTest::i_isolate();
     190             :   Factory* factory = isolate->factory();
     191             : 
     192           6 :   Handle<Map> map0 = Map::Create(isolate, 0);
     193           6 :   CHECK(map0->raw_transitions()->IsSmi());
     194             : 
     195             :   const int ATTRS_COUNT = (READ_ONLY | DONT_ENUM | DONT_DELETE) + 1;
     196             :   STATIC_ASSERT(ATTRS_COUNT == 8);
     197          48 :   Handle<Map> attr_maps[ATTRS_COUNT];
     198           6 :   Handle<String> name = factory->InternalizeUtf8String("foo");
     199             : 
     200             :   // Add transitions for same field name but different attributes.
     201          54 :   for (int i = 0; i < ATTRS_COUNT; i++) {
     202          48 :     PropertyAttributes attributes = static_cast<PropertyAttributes>(i);
     203             : 
     204             :     Handle<Map> map =
     205             :         Map::CopyWithField(map0, name, FieldType::Any(isolate), attributes,
     206          96 :                            kMutable, Representation::Tagged(), OMIT_TRANSITION)
     207          96 :             .ToHandleChecked();
     208          48 :     attr_maps[i] = map;
     209             : 
     210          48 :     TransitionsAccessor(map0).Insert(name, map, PROPERTY_TRANSITION);
     211             :   }
     212             : 
     213             :   // Ensure that transitions for |name| field are valid.
     214             :   TransitionsAccessor transitions(map0);
     215          54 :   for (int i = 0; i < ATTRS_COUNT; i++) {
     216          48 :     PropertyAttributes attributes = static_cast<PropertyAttributes>(i);
     217          96 :     CHECK_EQ(*attr_maps[i],
     218             :              transitions.SearchTransition(*name, kData, attributes));
     219             :     // All transitions use the same key, so this check doesn't need to
     220             :     // care about ordering.
     221          96 :     CHECK_EQ(*name, transitions.GetKey(i));
     222             :   }
     223             : 
     224           6 :   DCHECK(transitions.IsSortedNoDuplicates());
     225           6 : }
     226             : 
     227             : 
     228       23724 : TEST(TransitionArray_SameFieldNamesDifferentAttributes) {
     229           6 :   CcTest::InitializeVM();
     230           6 :   v8::HandleScope scope(CcTest::isolate());
     231             :   Isolate* isolate = CcTest::i_isolate();
     232             :   Factory* factory = isolate->factory();
     233             : 
     234             :   const int PROPS_COUNT = 10;
     235          66 :   Handle<String> names[PROPS_COUNT];
     236          60 :   Handle<Map> maps[PROPS_COUNT];
     237             : 
     238           6 :   Handle<Map> map0 = Map::Create(isolate, 0);
     239           6 :   CHECK(map0->raw_transitions()->IsSmi());
     240             : 
     241             :   // Some number of fields.
     242          60 :   for (int i = 0; i < PROPS_COUNT; i++) {
     243             :     EmbeddedVector<char, 64> buffer;
     244          60 :     SNPrintF(buffer, "prop%d", i);
     245          60 :     Handle<String> name = factory->InternalizeUtf8String(buffer.start());
     246             :     Handle<Map> map =
     247             :         Map::CopyWithField(map0, name, handle(FieldType::Any(), isolate), NONE,
     248         120 :                            kMutable, Representation::Tagged(), OMIT_TRANSITION)
     249         120 :             .ToHandleChecked();
     250          60 :     names[i] = name;
     251          60 :     maps[i] = map;
     252             : 
     253          60 :     TransitionsAccessor(map0).Insert(name, map, PROPERTY_TRANSITION);
     254             :   }
     255             : 
     256             :   const int ATTRS_COUNT = (READ_ONLY | DONT_ENUM | DONT_DELETE) + 1;
     257             :   STATIC_ASSERT(ATTRS_COUNT == 8);
     258          48 :   Handle<Map> attr_maps[ATTRS_COUNT];
     259           6 :   Handle<String> name = factory->InternalizeUtf8String("foo");
     260             : 
     261             :   // Add transitions for same field name but different attributes.
     262          54 :   for (int i = 0; i < ATTRS_COUNT; i++) {
     263          48 :     PropertyAttributes attributes = static_cast<PropertyAttributes>(i);
     264             : 
     265             :     Handle<Map> map =
     266             :         Map::CopyWithField(map0, name, handle(FieldType::Any(), isolate),
     267             :                            attributes, kMutable, Representation::Tagged(),
     268          96 :                            OMIT_TRANSITION)
     269          96 :             .ToHandleChecked();
     270          48 :     attr_maps[i] = map;
     271             : 
     272          48 :     TransitionsAccessor(map0).Insert(name, map, PROPERTY_TRANSITION);
     273             :   }
     274             : 
     275             :   // Ensure that transitions for |name| field are valid.
     276             :   TransitionsAccessor transitions(map0);
     277          54 :   for (int i = 0; i < ATTRS_COUNT; i++) {
     278          48 :     PropertyAttributes attr = static_cast<PropertyAttributes>(i);
     279          96 :     CHECK_EQ(*attr_maps[i], transitions.SearchTransition(*name, kData, attr));
     280             :   }
     281             : 
     282             :   // Ensure that info about the other fields still valid.
     283           6 :   CHECK_EQ(PROPS_COUNT + ATTRS_COUNT, transitions.NumberOfTransitions());
     284         108 :   for (int i = 0; i < PROPS_COUNT + ATTRS_COUNT; i++) {
     285         108 :     Name* key = transitions.GetKey(i);
     286         108 :     Map* target = transitions.GetTarget(i);
     287         108 :     if (key == *name) {
     288             :       // Attributes transition.
     289             :       PropertyAttributes attributes =
     290             :           target->GetLastDescriptorDetails().attributes();
     291          96 :       CHECK_EQ(*attr_maps[static_cast<int>(attributes)], target);
     292             :     } else {
     293         270 :       for (int j = 0; j < PROPS_COUNT; j++) {
     294         660 :         if (*names[j] == key) {
     295         120 :           CHECK_EQ(*maps[j], target);
     296             :           break;
     297             :         }
     298             :       }
     299             :     }
     300             :   }
     301             : 
     302           6 :   DCHECK(transitions.IsSortedNoDuplicates());
     303           6 : }
     304             : 
     305             : }  // namespace internal
     306       71154 : }  // namespace v8

Generated by: LCOV version 1.10