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