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

Generated by: LCOV version 1.10