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