OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 <sstream> | 5 #include <sstream> |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
(...skipping 1251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1262 object->ShortPrint(file); | 1262 object->ShortPrint(file); |
1263 PrintF(file, " from "); | 1263 PrintF(file, " from "); |
1264 from_elements->ShortPrint(file); | 1264 from_elements->ShortPrint(file); |
1265 PrintF(file, " to "); | 1265 PrintF(file, " to "); |
1266 to_elements->ShortPrint(file); | 1266 to_elements->ShortPrint(file); |
1267 PrintF(file, "\n"); | 1267 PrintF(file, "\n"); |
1268 } | 1268 } |
1269 } | 1269 } |
1270 | 1270 |
1271 | 1271 |
| 1272 void Map::PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind, |
| 1273 PropertyAttributes attributes) { |
| 1274 OFStream os(file); |
| 1275 os << "[reconfiguring "; |
| 1276 constructor_name()->PrintOn(file); |
| 1277 os << "] "; |
| 1278 Name* name = instance_descriptors()->GetKey(modify_index); |
| 1279 if (name->IsString()) { |
| 1280 String::cast(name)->PrintOn(file); |
| 1281 } else { |
| 1282 os << "{symbol " << static_cast<void*>(name) << "}"; |
| 1283 } |
| 1284 os << ": " << (kind == kData ? "kData" : "ACCESSORS") << ", attrs: "; |
| 1285 os << attributes << " ["; |
| 1286 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); |
| 1287 os << "]\n"; |
| 1288 } |
| 1289 |
| 1290 |
1272 void Map::PrintGeneralization(FILE* file, | 1291 void Map::PrintGeneralization(FILE* file, |
1273 const char* reason, | 1292 const char* reason, |
1274 int modify_index, | 1293 int modify_index, |
1275 int split, | 1294 int split, |
1276 int descriptors, | 1295 int descriptors, |
1277 bool constant_to_field, | 1296 bool constant_to_field, |
1278 Representation old_representation, | 1297 Representation old_representation, |
1279 Representation new_representation, | 1298 Representation new_representation, |
1280 HeapType* old_field_type, | 1299 HeapType* old_field_type, |
1281 HeapType* new_field_type) { | 1300 HeapType* new_field_type) { |
(...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1970 int new_nof = new_map->NumberOfOwnDescriptors(); | 1989 int new_nof = new_map->NumberOfOwnDescriptors(); |
1971 | 1990 |
1972 // This method only supports generalizing instances to at least the same | 1991 // This method only supports generalizing instances to at least the same |
1973 // number of properties. | 1992 // number of properties. |
1974 DCHECK(old_nof <= new_nof); | 1993 DCHECK(old_nof <= new_nof); |
1975 | 1994 |
1976 for (int i = 0; i < old_nof; i++) { | 1995 for (int i = 0; i < old_nof; i++) { |
1977 PropertyDetails details = new_descriptors->GetDetails(i); | 1996 PropertyDetails details = new_descriptors->GetDetails(i); |
1978 if (details.type() != DATA) continue; | 1997 if (details.type() != DATA) continue; |
1979 PropertyDetails old_details = old_descriptors->GetDetails(i); | 1998 PropertyDetails old_details = old_descriptors->GetDetails(i); |
1980 if (old_details.type() == ACCESSOR_CONSTANT) { | |
1981 DCHECK(details.representation().IsTagged()); | |
1982 continue; | |
1983 } | |
1984 Representation old_representation = old_details.representation(); | 1999 Representation old_representation = old_details.representation(); |
1985 Representation representation = details.representation(); | 2000 Representation representation = details.representation(); |
1986 DCHECK(old_details.type() == DATA_CONSTANT || old_details.type() == DATA); | |
1987 Handle<Object> value; | 2001 Handle<Object> value; |
1988 if (old_details.type() == DATA_CONSTANT) { | 2002 if (old_details.type() == ACCESSOR_CONSTANT) { |
| 2003 // In case of kAccessor -> kData property reconfiguration, the property |
| 2004 // must already be prepared for data or certain type. |
| 2005 DCHECK(!details.representation().IsNone()); |
| 2006 if (details.representation().IsDouble()) { |
| 2007 value = isolate->factory()->NewHeapNumber(0, MUTABLE); |
| 2008 } else { |
| 2009 value = isolate->factory()->uninitialized_value(); |
| 2010 } |
| 2011 } else if (old_details.type() == DATA_CONSTANT) { |
1989 value = handle(old_descriptors->GetValue(i), isolate); | 2012 value = handle(old_descriptors->GetValue(i), isolate); |
1990 DCHECK(!old_representation.IsDouble() && !representation.IsDouble()); | 2013 DCHECK(!old_representation.IsDouble() && !representation.IsDouble()); |
1991 } else { | 2014 } else { |
1992 FieldIndex index = FieldIndex::ForDescriptor(*old_map, i); | 2015 FieldIndex index = FieldIndex::ForDescriptor(*old_map, i); |
1993 if (object->IsUnboxedDoubleField(index)) { | 2016 if (object->IsUnboxedDoubleField(index)) { |
1994 double old = object->RawFastDoublePropertyAt(index); | 2017 double old = object->RawFastDoublePropertyAt(index); |
1995 value = isolate->factory()->NewHeapNumber( | 2018 value = isolate->factory()->NewHeapNumber( |
1996 old, representation.IsDouble() ? MUTABLE : IMMUTABLE); | 2019 old, representation.IsDouble() ? MUTABLE : IMMUTABLE); |
1997 | 2020 |
1998 } else { | 2021 } else { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2072 // We are storing the new map using release store after creating a filler for | 2095 // We are storing the new map using release store after creating a filler for |
2073 // the left-over space to avoid races with the sweeper thread. | 2096 // the left-over space to avoid races with the sweeper thread. |
2074 object->synchronized_set_map(*new_map); | 2097 object->synchronized_set_map(*new_map); |
2075 } | 2098 } |
2076 | 2099 |
2077 | 2100 |
2078 int Map::NumberOfFields() { | 2101 int Map::NumberOfFields() { |
2079 DescriptorArray* descriptors = instance_descriptors(); | 2102 DescriptorArray* descriptors = instance_descriptors(); |
2080 int result = 0; | 2103 int result = 0; |
2081 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { | 2104 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { |
2082 if (descriptors->GetDetails(i).type() == DATA) result++; | 2105 if (descriptors->GetDetails(i).location() == kField) result++; |
2083 } | 2106 } |
2084 return result; | 2107 return result; |
2085 } | 2108 } |
2086 | 2109 |
2087 | 2110 |
2088 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, | 2111 Handle<Map> Map::CopyGeneralizeAllRepresentations( |
2089 int modify_index, | 2112 Handle<Map> map, int modify_index, StoreMode store_mode, PropertyKind kind, |
2090 StoreMode store_mode, | 2113 PropertyAttributes attributes, const char* reason) { |
2091 PropertyAttributes attributes, | |
2092 const char* reason) { | |
2093 Isolate* isolate = map->GetIsolate(); | 2114 Isolate* isolate = map->GetIsolate(); |
2094 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); | 2115 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); |
2095 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | 2116 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
2096 Handle<DescriptorArray> descriptors = | 2117 Handle<DescriptorArray> descriptors = |
2097 DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors); | 2118 DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors); |
2098 | 2119 |
2099 for (int i = 0; i < number_of_own_descriptors; i++) { | 2120 for (int i = 0; i < number_of_own_descriptors; i++) { |
2100 descriptors->SetRepresentation(i, Representation::Tagged()); | 2121 descriptors->SetRepresentation(i, Representation::Tagged()); |
2101 if (descriptors->GetDetails(i).type() == DATA) { | 2122 if (descriptors->GetDetails(i).type() == DATA) { |
2102 descriptors->SetValue(i, HeapType::Any()); | 2123 descriptors->SetValue(i, HeapType::Any()); |
2103 } | 2124 } |
2104 } | 2125 } |
2105 | 2126 |
2106 Handle<LayoutDescriptor> new_layout_descriptor( | 2127 Handle<LayoutDescriptor> new_layout_descriptor( |
2107 LayoutDescriptor::FastPointerLayout(), isolate); | 2128 LayoutDescriptor::FastPointerLayout(), isolate); |
2108 Handle<Map> new_map = CopyReplaceDescriptors( | 2129 Handle<Map> new_map = CopyReplaceDescriptors( |
2109 map, descriptors, new_layout_descriptor, OMIT_TRANSITION, | 2130 map, descriptors, new_layout_descriptor, OMIT_TRANSITION, |
2110 MaybeHandle<Name>(), reason, SPECIAL_TRANSITION); | 2131 MaybeHandle<Name>(), reason, SPECIAL_TRANSITION); |
2111 | 2132 |
2112 // Unless the instance is being migrated, ensure that modify_index is a field. | 2133 // Unless the instance is being migrated, ensure that modify_index is a field. |
2113 PropertyDetails details = descriptors->GetDetails(modify_index); | 2134 if (modify_index >= 0) { |
2114 if (store_mode == FORCE_FIELD && | 2135 PropertyDetails details = descriptors->GetDetails(modify_index); |
2115 (details.type() != DATA || details.attributes() != attributes)) { | 2136 if (store_mode == FORCE_FIELD && |
2116 int field_index = details.type() == DATA ? details.field_index() | 2137 (details.type() != DATA || details.attributes() != attributes)) { |
2117 : new_map->NumberOfFields(); | 2138 int field_index = details.type() == DATA ? details.field_index() |
2118 DataDescriptor d(handle(descriptors->GetKey(modify_index), isolate), | 2139 : new_map->NumberOfFields(); |
2119 field_index, attributes, Representation::Tagged()); | 2140 DataDescriptor d(handle(descriptors->GetKey(modify_index), isolate), |
2120 descriptors->Replace(modify_index, &d); | 2141 field_index, attributes, Representation::Tagged()); |
2121 if (details.type() != DATA) { | 2142 descriptors->Replace(modify_index, &d); |
2122 int unused_property_fields = new_map->unused_property_fields() - 1; | 2143 if (details.type() != DATA) { |
2123 if (unused_property_fields < 0) { | 2144 int unused_property_fields = new_map->unused_property_fields() - 1; |
2124 unused_property_fields += JSObject::kFieldsAdded; | 2145 if (unused_property_fields < 0) { |
| 2146 unused_property_fields += JSObject::kFieldsAdded; |
| 2147 } |
| 2148 new_map->set_unused_property_fields(unused_property_fields); |
2125 } | 2149 } |
2126 new_map->set_unused_property_fields(unused_property_fields); | 2150 } else { |
| 2151 DCHECK(details.attributes() == attributes); |
2127 } | 2152 } |
2128 } else { | |
2129 DCHECK(details.attributes() == attributes); | |
2130 } | |
2131 | 2153 |
2132 if (FLAG_trace_generalization) { | 2154 if (FLAG_trace_generalization) { |
2133 HeapType* field_type = | 2155 HeapType* field_type = |
2134 (details.type() == DATA) | 2156 (details.type() == DATA) |
2135 ? map->instance_descriptors()->GetFieldType(modify_index) | 2157 ? map->instance_descriptors()->GetFieldType(modify_index) |
2136 : NULL; | 2158 : NULL; |
2137 map->PrintGeneralization( | 2159 map->PrintGeneralization( |
2138 stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(), | 2160 stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(), |
2139 new_map->NumberOfOwnDescriptors(), | 2161 new_map->NumberOfOwnDescriptors(), |
2140 details.type() == DATA_CONSTANT && store_mode == FORCE_FIELD, | 2162 details.type() == DATA_CONSTANT && store_mode == FORCE_FIELD, |
2141 details.representation(), Representation::Tagged(), field_type, | 2163 details.representation(), Representation::Tagged(), field_type, |
2142 HeapType::Any()); | 2164 HeapType::Any()); |
| 2165 } |
2143 } | 2166 } |
2144 return new_map; | 2167 return new_map; |
2145 } | 2168 } |
2146 | 2169 |
2147 | 2170 |
2148 // static | |
2149 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, | |
2150 int modify_index, | |
2151 StoreMode store_mode, | |
2152 const char* reason) { | |
2153 PropertyDetails details = | |
2154 map->instance_descriptors()->GetDetails(modify_index); | |
2155 return CopyGeneralizeAllRepresentations(map, modify_index, store_mode, | |
2156 details.attributes(), reason); | |
2157 } | |
2158 | |
2159 | |
2160 void Map::DeprecateTransitionTree() { | 2171 void Map::DeprecateTransitionTree() { |
2161 if (is_deprecated()) return; | 2172 if (is_deprecated()) return; |
2162 if (HasTransitionArray()) { | 2173 if (HasTransitionArray()) { |
2163 TransitionArray* transitions = this->transitions(); | 2174 TransitionArray* transitions = this->transitions(); |
2164 for (int i = 0; i < transitions->number_of_transitions(); i++) { | 2175 for (int i = 0; i < transitions->number_of_transitions(); i++) { |
2165 transitions->GetTarget(i)->DeprecateTransitionTree(); | 2176 transitions->GetTarget(i)->DeprecateTransitionTree(); |
2166 } | 2177 } |
2167 } | 2178 } |
2168 deprecate(); | 2179 deprecate(); |
2169 dependent_code()->DeoptimizeDependentCodeGroup( | 2180 dependent_code()->DeoptimizeDependentCodeGroup( |
2170 GetIsolate(), DependentCode::kTransitionGroup); | 2181 GetIsolate(), DependentCode::kTransitionGroup); |
2171 NotifyLeafMapLayoutChange(); | 2182 NotifyLeafMapLayoutChange(); |
2172 } | 2183 } |
2173 | 2184 |
2174 | 2185 |
| 2186 static inline bool EqualImmutableValues(Object* obj1, Object* obj2) { |
| 2187 if (obj1 == obj2) return true; // Valid for both kData and kAccessor kinds. |
| 2188 // TODO(ishell): compare AccessorPairs. |
| 2189 return false; |
| 2190 } |
| 2191 |
| 2192 |
2175 // Invalidates a transition target at |key|, and installs |new_descriptors| over | 2193 // Invalidates a transition target at |key|, and installs |new_descriptors| over |
2176 // the current instance_descriptors to ensure proper sharing of descriptor | 2194 // the current instance_descriptors to ensure proper sharing of descriptor |
2177 // arrays. | 2195 // arrays. |
2178 // Returns true if the transition target at given key was deprecated. | 2196 // Returns true if the transition target at given key was deprecated. |
2179 bool Map::DeprecateTarget(PropertyKind kind, Name* key, | 2197 bool Map::DeprecateTarget(PropertyKind kind, Name* key, |
2180 PropertyAttributes attributes, | 2198 PropertyAttributes attributes, |
2181 DescriptorArray* new_descriptors, | 2199 DescriptorArray* new_descriptors, |
2182 LayoutDescriptor* new_layout_descriptor) { | 2200 LayoutDescriptor* new_layout_descriptor) { |
2183 bool transition_target_deprecated = false; | 2201 bool transition_target_deprecated = false; |
2184 if (HasTransitionArray()) { | 2202 if (HasTransitionArray()) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2235 PropertyDetails details = descriptors->GetDetails(i); | 2253 PropertyDetails details = descriptors->GetDetails(i); |
2236 TransitionArray* transitions = current->transitions(); | 2254 TransitionArray* transitions = current->transitions(); |
2237 int transition = | 2255 int transition = |
2238 transitions->Search(details.kind(), name, details.attributes()); | 2256 transitions->Search(details.kind(), name, details.attributes()); |
2239 if (transition == TransitionArray::kNotFound) break; | 2257 if (transition == TransitionArray::kNotFound) break; |
2240 | 2258 |
2241 Map* next = transitions->GetTarget(transition); | 2259 Map* next = transitions->GetTarget(transition); |
2242 DescriptorArray* next_descriptors = next->instance_descriptors(); | 2260 DescriptorArray* next_descriptors = next->instance_descriptors(); |
2243 | 2261 |
2244 PropertyDetails next_details = next_descriptors->GetDetails(i); | 2262 PropertyDetails next_details = next_descriptors->GetDetails(i); |
2245 if (details.type() != next_details.type()) break; | 2263 DCHECK_EQ(details.kind(), next_details.kind()); |
2246 if (details.attributes() != next_details.attributes()) break; | 2264 DCHECK_EQ(details.attributes(), next_details.attributes()); |
| 2265 if (details.location() != next_details.location()) break; |
2247 if (!details.representation().Equals(next_details.representation())) break; | 2266 if (!details.representation().Equals(next_details.representation())) break; |
2248 if (next_details.type() == DATA) { | 2267 |
2249 if (!descriptors->GetFieldType(i)->NowIs( | 2268 if (next_details.location() == kField) { |
2250 next_descriptors->GetFieldType(i))) break; | 2269 HeapType* next_field_type = next_descriptors->GetFieldType(i); |
| 2270 if (!descriptors->GetFieldType(i)->NowIs(next_field_type)) { |
| 2271 break; |
| 2272 } |
2251 } else { | 2273 } else { |
2252 if (descriptors->GetValue(i) != next_descriptors->GetValue(i)) break; | 2274 if (!EqualImmutableValues(descriptors->GetValue(i), |
| 2275 next_descriptors->GetValue(i))) { |
| 2276 break; |
| 2277 } |
2253 } | 2278 } |
2254 | |
2255 current = next; | 2279 current = next; |
2256 } | 2280 } |
2257 return current; | 2281 return current; |
2258 } | 2282 } |
2259 | 2283 |
2260 | 2284 |
2261 Map* Map::FindFieldOwner(int descriptor) { | 2285 Map* Map::FindFieldOwner(int descriptor) { |
2262 DisallowHeapAllocation no_allocation; | 2286 DisallowHeapAllocation no_allocation; |
2263 DCHECK_EQ(DATA, instance_descriptors()->GetDetails(descriptor).type()); | 2287 DCHECK_EQ(DATA, instance_descriptors()->GetDetails(descriptor).type()); |
2264 Map* result = this; | 2288 Map* result = this; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2360 map->PrintGeneralization( | 2384 map->PrintGeneralization( |
2361 stdout, "field type generalization", | 2385 stdout, "field type generalization", |
2362 modify_index, map->NumberOfOwnDescriptors(), | 2386 modify_index, map->NumberOfOwnDescriptors(), |
2363 map->NumberOfOwnDescriptors(), false, | 2387 map->NumberOfOwnDescriptors(), false, |
2364 details.representation(), details.representation(), | 2388 details.representation(), details.representation(), |
2365 *old_field_type, *new_field_type); | 2389 *old_field_type, *new_field_type); |
2366 } | 2390 } |
2367 } | 2391 } |
2368 | 2392 |
2369 | 2393 |
2370 // Generalize the representation of the descriptor at |modify_index|. | 2394 static inline Handle<HeapType> GetFieldType(Isolate* isolate, |
2371 // This method rewrites the transition tree to reflect the new change. To avoid | 2395 Handle<DescriptorArray> descriptors, |
2372 // high degrees over polymorphism, and to stabilize quickly, on every rewrite | 2396 int descriptor, |
2373 // the new type is deduced by merging the current type with any potential new | 2397 PropertyLocation location, |
2374 // (partial) version of the type in the transition tree. | 2398 Representation representation) { |
| 2399 #ifdef DEBUG |
| 2400 PropertyDetails details = descriptors->GetDetails(descriptor); |
| 2401 DCHECK_EQ(kData, details.kind()); |
| 2402 DCHECK_EQ(details.location(), location); |
| 2403 #endif |
| 2404 if (location == kField) { |
| 2405 return handle(descriptors->GetFieldType(descriptor), isolate); |
| 2406 } else { |
| 2407 return descriptors->GetValue(descriptor) |
| 2408 ->OptimalType(isolate, representation); |
| 2409 } |
| 2410 } |
| 2411 |
| 2412 |
| 2413 // Reconfigures property at |modify_index| with |new_kind|, |new_attributes|, |
| 2414 // |store_mode| and/or |new_representation|/|new_field_type|. |
| 2415 // If |modify_index| is negative then no properties are reconfigured but the |
| 2416 // map is migrated to the up-to-date non-deprecated state. |
| 2417 // |
| 2418 // This method rewrites or completes the transition tree to reflect the new |
| 2419 // change. To avoid high degrees over polymorphism, and to stabilize quickly, |
| 2420 // on every rewrite the new type is deduced by merging the current type with |
| 2421 // any potential new (partial) version of the type in the transition tree. |
2375 // To do this, on each rewrite: | 2422 // To do this, on each rewrite: |
2376 // - Search the root of the transition tree using FindRootMap. | 2423 // - Search the root of the transition tree using FindRootMap. |
2377 // - Find |target_map|, the newest matching version of this map using the keys | 2424 // - Find |target_map|, the newest matching version of this map using the |
2378 // in the |old_map|'s descriptor array to walk the transition tree. | 2425 // virtually "enhanced" |old_map|'s descriptor array (i.e. whose entry at |
2379 // - Merge/generalize the descriptor array of the |old_map| and |target_map|. | 2426 // |modify_index| is considered to be of |new_kind| and having |
| 2427 // |new_attributes|) to walk the transition tree. |
| 2428 // - Merge/generalize the "enhanced" descriptor array of the |old_map| and |
| 2429 // descriptor array of the |target_map|. |
2380 // - Generalize the |modify_index| descriptor using |new_representation| and | 2430 // - Generalize the |modify_index| descriptor using |new_representation| and |
2381 // |new_field_type|. | 2431 // |new_field_type|. |
2382 // - Walk the tree again starting from the root towards |target_map|. Stop at | 2432 // - Walk the tree again starting from the root towards |target_map|. Stop at |
2383 // |split_map|, the first map who's descriptor array does not match the merged | 2433 // |split_map|, the first map who's descriptor array does not match the merged |
2384 // descriptor array. | 2434 // descriptor array. |
2385 // - If |target_map| == |split_map|, |target_map| is in the expected state. | 2435 // - If |target_map| == |split_map|, |target_map| is in the expected state. |
2386 // Return it. | 2436 // Return it. |
2387 // - Otherwise, invalidate the outdated transition target from |target_map|, and | 2437 // - Otherwise, invalidate the outdated transition target from |target_map|, and |
2388 // replace its transition tree with a new branch for the updated descriptors. | 2438 // replace its transition tree with a new branch for the updated descriptors. |
2389 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map, | 2439 Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index, |
2390 int modify_index, | 2440 PropertyKind new_kind, |
2391 Representation new_representation, | 2441 PropertyAttributes new_attributes, |
2392 Handle<HeapType> new_field_type, | 2442 Representation new_representation, |
2393 StoreMode store_mode) { | 2443 Handle<HeapType> new_field_type, |
| 2444 StoreMode store_mode) { |
| 2445 DCHECK_NE(kAccessor, new_kind); // TODO(ishell): not supported yet. |
| 2446 DCHECK(store_mode != FORCE_FIELD || modify_index >= 0); |
2394 Isolate* isolate = old_map->GetIsolate(); | 2447 Isolate* isolate = old_map->GetIsolate(); |
2395 | 2448 |
2396 Handle<DescriptorArray> old_descriptors( | 2449 Handle<DescriptorArray> old_descriptors( |
2397 old_map->instance_descriptors(), isolate); | 2450 old_map->instance_descriptors(), isolate); |
2398 int old_nof = old_map->NumberOfOwnDescriptors(); | 2451 int old_nof = old_map->NumberOfOwnDescriptors(); |
2399 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | |
2400 Representation old_representation = old_details.representation(); | |
2401 | 2452 |
2402 // It's fine to transition from None to anything but double without any | 2453 // If it's just a representation generalization case (i.e. property kind and |
2403 // modification to the object, because the default uninitialized value for | 2454 // attributes stays unchanged) it's fine to transition from None to anything |
2404 // representation None can be overwritten by both smi and tagged values. | 2455 // but double without any modification to the object, because the default |
2405 // Doubles, however, would require a box allocation. | 2456 // uninitialized value for representation None can be overwritten by both |
2406 if (old_representation.IsNone() && !new_representation.IsNone() && | 2457 // smi and tagged values. Doubles, however, would require a box allocation. |
| 2458 if (modify_index >= 0 && !new_representation.IsNone() && |
2407 !new_representation.IsDouble()) { | 2459 !new_representation.IsDouble()) { |
2408 DCHECK(old_details.type() == DATA); | 2460 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
2409 if (FLAG_trace_generalization) { | 2461 Representation old_representation = old_details.representation(); |
2410 old_map->PrintGeneralization( | 2462 |
2411 stdout, "uninitialized field", | 2463 if (old_representation.IsNone()) { |
2412 modify_index, old_map->NumberOfOwnDescriptors(), | 2464 DCHECK_EQ(new_kind, old_details.kind()); |
2413 old_map->NumberOfOwnDescriptors(), false, | 2465 DCHECK_EQ(new_attributes, old_details.attributes()); |
2414 old_representation, new_representation, | 2466 DCHECK_EQ(DATA, old_details.type()); |
2415 old_descriptors->GetFieldType(modify_index), *new_field_type); | 2467 if (FLAG_trace_generalization) { |
| 2468 old_map->PrintGeneralization( |
| 2469 stdout, "uninitialized field", modify_index, |
| 2470 old_map->NumberOfOwnDescriptors(), |
| 2471 old_map->NumberOfOwnDescriptors(), false, old_representation, |
| 2472 new_representation, old_descriptors->GetFieldType(modify_index), |
| 2473 *new_field_type); |
| 2474 } |
| 2475 Handle<Map> field_owner(old_map->FindFieldOwner(modify_index), isolate); |
| 2476 |
| 2477 GeneralizeFieldType(field_owner, modify_index, new_representation, |
| 2478 new_field_type); |
| 2479 DCHECK(old_descriptors->GetDetails(modify_index) |
| 2480 .representation() |
| 2481 .Equals(new_representation)); |
| 2482 DCHECK( |
| 2483 old_descriptors->GetFieldType(modify_index)->NowIs(new_field_type)); |
| 2484 return old_map; |
2416 } | 2485 } |
2417 Handle<Map> field_owner(old_map->FindFieldOwner(modify_index), isolate); | |
2418 | |
2419 GeneralizeFieldType(field_owner, modify_index, new_representation, | |
2420 new_field_type); | |
2421 DCHECK(old_descriptors->GetDetails(modify_index).representation().Equals( | |
2422 new_representation)); | |
2423 DCHECK(old_descriptors->GetFieldType(modify_index)->NowIs(new_field_type)); | |
2424 return old_map; | |
2425 } | 2486 } |
2426 | 2487 |
2427 // Check the state of the root map. | 2488 // Check the state of the root map. |
2428 Handle<Map> root_map(old_map->FindRootMap(), isolate); | 2489 Handle<Map> root_map(old_map->FindRootMap(), isolate); |
2429 if (!old_map->EquivalentToForTransition(*root_map)) { | 2490 if (!old_map->EquivalentToForTransition(*root_map)) { |
2430 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2491 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
| 2492 new_kind, new_attributes, |
2431 "GenAll_NotEquivalent"); | 2493 "GenAll_NotEquivalent"); |
2432 } | 2494 } |
2433 int root_nof = root_map->NumberOfOwnDescriptors(); | 2495 int root_nof = root_map->NumberOfOwnDescriptors(); |
2434 if (modify_index < root_nof) { | 2496 if (modify_index >= 0 && modify_index < root_nof) { |
2435 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2497 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
| 2498 if (old_details.kind() != new_kind || |
| 2499 old_details.attributes() != new_attributes) { |
| 2500 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
| 2501 new_kind, new_attributes, |
| 2502 "GenAll_RootModification1"); |
| 2503 } |
2436 if ((old_details.type() != DATA && store_mode == FORCE_FIELD) || | 2504 if ((old_details.type() != DATA && store_mode == FORCE_FIELD) || |
2437 (old_details.type() == DATA && | 2505 (old_details.type() == DATA && |
2438 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || | 2506 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || |
2439 !new_representation.fits_into(old_details.representation())))) { | 2507 !new_representation.fits_into(old_details.representation())))) { |
2440 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2508 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2441 "GenAll_RootModification"); | 2509 new_kind, new_attributes, |
| 2510 "GenAll_RootModification2"); |
2442 } | 2511 } |
2443 } | 2512 } |
2444 | 2513 |
2445 Handle<Map> target_map = root_map; | 2514 Handle<Map> target_map = root_map; |
2446 for (int i = root_nof; i < old_nof; ++i) { | 2515 for (int i = root_nof; i < old_nof; ++i) { |
2447 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2516 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2448 int j = target_map->SearchTransition(old_details.kind(), | 2517 PropertyKind next_kind; |
2449 old_descriptors->GetKey(i), | 2518 PropertyLocation next_location; |
2450 old_details.attributes()); | 2519 PropertyAttributes next_attributes; |
| 2520 Representation next_representation; |
| 2521 bool property_kind_reconfiguration = false; |
| 2522 |
| 2523 if (modify_index == i) { |
| 2524 DCHECK_EQ(FORCE_FIELD, store_mode); |
| 2525 property_kind_reconfiguration = old_details.kind() != new_kind; |
| 2526 |
| 2527 next_kind = new_kind; |
| 2528 next_location = kField; |
| 2529 next_attributes = new_attributes; |
| 2530 // If property kind is not reconfigured merge the result with |
| 2531 // representation/field type from the old descriptor. |
| 2532 next_representation = new_representation; |
| 2533 if (!property_kind_reconfiguration) { |
| 2534 next_representation = |
| 2535 next_representation.generalize(old_details.representation()); |
| 2536 } |
| 2537 |
| 2538 } else { |
| 2539 next_kind = old_details.kind(); |
| 2540 next_location = old_details.location(); |
| 2541 next_attributes = old_details.attributes(); |
| 2542 next_representation = old_details.representation(); |
| 2543 } |
| 2544 int j = target_map->SearchTransition(next_kind, old_descriptors->GetKey(i), |
| 2545 next_attributes); |
2451 if (j == TransitionArray::kNotFound) break; | 2546 if (j == TransitionArray::kNotFound) break; |
2452 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); | 2547 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); |
2453 Handle<DescriptorArray> tmp_descriptors = handle( | 2548 Handle<DescriptorArray> tmp_descriptors = handle( |
2454 tmp_map->instance_descriptors(), isolate); | 2549 tmp_map->instance_descriptors(), isolate); |
2455 | 2550 |
2456 // Check if target map is incompatible. | 2551 // Check if target map is incompatible. |
2457 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | 2552 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
2458 PropertyType old_type = old_details.type(); | 2553 DCHECK_EQ(next_kind, tmp_details.kind()); |
2459 PropertyType tmp_type = tmp_details.type(); | 2554 DCHECK_EQ(next_attributes, tmp_details.attributes()); |
2460 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); | 2555 if (next_kind == kAccessor && |
2461 if ((tmp_type == ACCESSOR_CONSTANT || old_type == ACCESSOR_CONSTANT) && | 2556 !EqualImmutableValues(old_descriptors->GetValue(i), |
2462 (tmp_type != old_type || | 2557 tmp_descriptors->GetValue(i))) { |
2463 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { | |
2464 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2558 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
| 2559 new_kind, new_attributes, |
2465 "GenAll_Incompatible"); | 2560 "GenAll_Incompatible"); |
2466 } | 2561 } |
2467 Representation old_representation = old_details.representation(); | 2562 if (next_location == kField && tmp_details.location() == kDescriptor) break; |
| 2563 |
2468 Representation tmp_representation = tmp_details.representation(); | 2564 Representation tmp_representation = tmp_details.representation(); |
2469 if (!old_representation.fits_into(tmp_representation) || | 2565 if (!next_representation.fits_into(tmp_representation)) break; |
2470 (!new_representation.fits_into(tmp_representation) && | 2566 |
2471 modify_index == i)) { | 2567 PropertyLocation old_location = old_details.location(); |
| 2568 PropertyLocation tmp_location = tmp_details.location(); |
| 2569 if (tmp_location == kField) { |
| 2570 if (next_kind == kData) { |
| 2571 Handle<HeapType> next_field_type; |
| 2572 if (modify_index == i) { |
| 2573 next_field_type = new_field_type; |
| 2574 if (!property_kind_reconfiguration) { |
| 2575 Handle<HeapType> old_field_type = |
| 2576 GetFieldType(isolate, old_descriptors, i, |
| 2577 old_details.location(), tmp_representation); |
| 2578 next_field_type = |
| 2579 GeneralizeFieldType(next_field_type, old_field_type, isolate); |
| 2580 } |
| 2581 } else { |
| 2582 Handle<HeapType> old_field_type = |
| 2583 GetFieldType(isolate, old_descriptors, i, old_details.location(), |
| 2584 tmp_representation); |
| 2585 next_field_type = old_field_type; |
| 2586 } |
| 2587 GeneralizeFieldType(tmp_map, i, tmp_representation, next_field_type); |
| 2588 } |
| 2589 } else if (old_location == kField || |
| 2590 !EqualImmutableValues(old_descriptors->GetValue(i), |
| 2591 tmp_descriptors->GetValue(i))) { |
2472 break; | 2592 break; |
2473 } | 2593 } |
2474 if (tmp_type == DATA) { | 2594 DCHECK(!tmp_map->is_deprecated()); |
2475 // Generalize the field type as necessary. | |
2476 Handle<HeapType> old_field_type = | |
2477 (old_type == DATA) ? handle(old_descriptors->GetFieldType(i), isolate) | |
2478 : old_descriptors->GetValue(i) | |
2479 ->OptimalType(isolate, tmp_representation); | |
2480 if (modify_index == i) { | |
2481 old_field_type = GeneralizeFieldType( | |
2482 new_field_type, old_field_type, isolate); | |
2483 } | |
2484 GeneralizeFieldType(tmp_map, i, tmp_representation, old_field_type); | |
2485 } else if (tmp_type == DATA_CONSTANT) { | |
2486 if (old_type != DATA_CONSTANT || | |
2487 old_descriptors->GetConstant(i) != tmp_descriptors->GetConstant(i)) { | |
2488 break; | |
2489 } | |
2490 } else { | |
2491 DCHECK_EQ(tmp_type, old_type); | |
2492 DCHECK_EQ(tmp_descriptors->GetValue(i), old_descriptors->GetValue(i)); | |
2493 } | |
2494 target_map = tmp_map; | 2595 target_map = tmp_map; |
2495 } | 2596 } |
2496 | 2597 |
2497 // Directly change the map if the target map is more general. | 2598 // Directly change the map if the target map is more general. |
2498 Handle<DescriptorArray> target_descriptors( | 2599 Handle<DescriptorArray> target_descriptors( |
2499 target_map->instance_descriptors(), isolate); | 2600 target_map->instance_descriptors(), isolate); |
2500 int target_nof = target_map->NumberOfOwnDescriptors(); | 2601 int target_nof = target_map->NumberOfOwnDescriptors(); |
2501 if (target_nof == old_nof && | 2602 if (target_nof == old_nof && |
2502 (store_mode != FORCE_FIELD || | 2603 (store_mode != FORCE_FIELD || |
2503 target_descriptors->GetDetails(modify_index).type() == DATA)) { | 2604 (modify_index >= 0 && |
2504 DCHECK(modify_index < target_nof); | 2605 target_descriptors->GetDetails(modify_index).location() == kField))) { |
2505 DCHECK(new_representation.fits_into( | 2606 #ifdef DEBUG |
2506 target_descriptors->GetDetails(modify_index).representation())); | 2607 if (modify_index >= 0) { |
2507 DCHECK( | 2608 PropertyDetails details = target_descriptors->GetDetails(modify_index); |
2508 target_descriptors->GetDetails(modify_index).type() != DATA || | 2609 DCHECK_EQ(new_kind, details.kind()); |
2509 new_field_type->NowIs(target_descriptors->GetFieldType(modify_index))); | 2610 DCHECK_EQ(new_attributes, details.attributes()); |
| 2611 DCHECK(new_representation.fits_into(details.representation())); |
| 2612 DCHECK(details.location() != kField || |
| 2613 new_field_type->NowIs( |
| 2614 target_descriptors->GetFieldType(modify_index))); |
| 2615 } |
| 2616 #endif |
2510 return target_map; | 2617 return target_map; |
2511 } | 2618 } |
2512 | 2619 |
2513 // Find the last compatible target map in the transition tree. | 2620 // Find the last compatible target map in the transition tree. |
2514 for (int i = target_nof; i < old_nof; ++i) { | 2621 for (int i = target_nof; i < old_nof; ++i) { |
2515 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2622 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2516 int j = target_map->SearchTransition(old_details.kind(), | 2623 PropertyKind next_kind; |
2517 old_descriptors->GetKey(i), | 2624 PropertyAttributes next_attributes; |
2518 old_details.attributes()); | 2625 if (modify_index == i) { |
| 2626 next_kind = new_kind; |
| 2627 next_attributes = new_attributes; |
| 2628 } else { |
| 2629 next_kind = old_details.kind(); |
| 2630 next_attributes = old_details.attributes(); |
| 2631 } |
| 2632 int j = target_map->SearchTransition(next_kind, old_descriptors->GetKey(i), |
| 2633 next_attributes); |
2519 if (j == TransitionArray::kNotFound) break; | 2634 if (j == TransitionArray::kNotFound) break; |
2520 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); | 2635 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); |
2521 Handle<DescriptorArray> tmp_descriptors( | 2636 Handle<DescriptorArray> tmp_descriptors( |
2522 tmp_map->instance_descriptors(), isolate); | 2637 tmp_map->instance_descriptors(), isolate); |
2523 | 2638 |
2524 // Check if target map is compatible. | 2639 // Check if target map is compatible. |
| 2640 #ifdef DEBUG |
2525 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | 2641 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
2526 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); | 2642 DCHECK_EQ(next_kind, tmp_details.kind()); |
2527 if ((tmp_details.type() == ACCESSOR_CONSTANT || | 2643 DCHECK_EQ(next_attributes, tmp_details.attributes()); |
2528 old_details.type() == ACCESSOR_CONSTANT) && | 2644 #endif |
2529 (tmp_details.type() != old_details.type() || | 2645 if (next_kind == kAccessor && |
2530 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { | 2646 !EqualImmutableValues(old_descriptors->GetValue(i), |
| 2647 tmp_descriptors->GetValue(i))) { |
2531 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2648 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
| 2649 new_kind, new_attributes, |
2532 "GenAll_Incompatible"); | 2650 "GenAll_Incompatible"); |
2533 } | 2651 } |
| 2652 DCHECK(!tmp_map->is_deprecated()); |
2534 target_map = tmp_map; | 2653 target_map = tmp_map; |
2535 } | 2654 } |
2536 target_nof = target_map->NumberOfOwnDescriptors(); | 2655 target_nof = target_map->NumberOfOwnDescriptors(); |
2537 target_descriptors = handle(target_map->instance_descriptors(), isolate); | 2656 target_descriptors = handle(target_map->instance_descriptors(), isolate); |
2538 | 2657 |
2539 // Allocate a new descriptor array large enough to hold the required | 2658 // Allocate a new descriptor array large enough to hold the required |
2540 // descriptors, with minimally the exact same size as the old descriptor | 2659 // descriptors, with minimally the exact same size as the old descriptor |
2541 // array. | 2660 // array. |
2542 int new_slack = Max( | 2661 int new_slack = Max( |
2543 old_nof, old_descriptors->number_of_descriptors()) - old_nof; | 2662 old_nof, old_descriptors->number_of_descriptors()) - old_nof; |
2544 Handle<DescriptorArray> new_descriptors = DescriptorArray::Allocate( | 2663 Handle<DescriptorArray> new_descriptors = DescriptorArray::Allocate( |
2545 isolate, old_nof, new_slack); | 2664 isolate, old_nof, new_slack); |
2546 DCHECK(new_descriptors->length() > target_descriptors->length() || | 2665 DCHECK(new_descriptors->length() > target_descriptors->length() || |
2547 new_descriptors->NumberOfSlackDescriptors() > 0 || | 2666 new_descriptors->NumberOfSlackDescriptors() > 0 || |
2548 new_descriptors->number_of_descriptors() == | 2667 new_descriptors->number_of_descriptors() == |
2549 old_descriptors->number_of_descriptors()); | 2668 old_descriptors->number_of_descriptors()); |
2550 DCHECK(new_descriptors->number_of_descriptors() == old_nof); | 2669 DCHECK(new_descriptors->number_of_descriptors() == old_nof); |
2551 | 2670 |
2552 // 0 -> |root_nof| | 2671 // 0 -> |root_nof| |
2553 int current_offset = 0; | 2672 int current_offset = 0; |
2554 for (int i = 0; i < root_nof; ++i) { | 2673 for (int i = 0; i < root_nof; ++i) { |
2555 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2674 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2556 if (old_details.type() == DATA) { | 2675 if (old_details.location() == kField) { |
2557 current_offset += old_details.field_width_in_words(); | 2676 current_offset += old_details.field_width_in_words(); |
2558 } | 2677 } |
2559 Descriptor d(handle(old_descriptors->GetKey(i), isolate), | 2678 Descriptor d(handle(old_descriptors->GetKey(i), isolate), |
2560 handle(old_descriptors->GetValue(i), isolate), | 2679 handle(old_descriptors->GetValue(i), isolate), |
2561 old_details); | 2680 old_details); |
2562 new_descriptors->Set(i, &d); | 2681 new_descriptors->Set(i, &d); |
2563 } | 2682 } |
2564 | 2683 |
2565 // |root_nof| -> |target_nof| | 2684 // |root_nof| -> |target_nof| |
2566 for (int i = root_nof; i < target_nof; ++i) { | 2685 for (int i = root_nof; i < target_nof; ++i) { |
2567 Handle<Name> target_key(target_descriptors->GetKey(i), isolate); | 2686 Handle<Name> target_key(target_descriptors->GetKey(i), isolate); |
2568 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2687 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2569 PropertyDetails target_details = target_descriptors->GetDetails(i); | 2688 PropertyDetails target_details = target_descriptors->GetDetails(i); |
2570 target_details = target_details.CopyWithRepresentation( | 2689 |
2571 old_details.representation().generalize( | 2690 PropertyKind next_kind; |
2572 target_details.representation())); | 2691 PropertyAttributes next_attributes; |
| 2692 PropertyLocation next_location; |
| 2693 Representation next_representation; |
| 2694 bool property_kind_reconfiguration = false; |
| 2695 |
2573 if (modify_index == i) { | 2696 if (modify_index == i) { |
2574 target_details = target_details.CopyWithRepresentation( | 2697 DCHECK_EQ(FORCE_FIELD, store_mode); |
2575 new_representation.generalize(target_details.representation())); | 2698 property_kind_reconfiguration = old_details.kind() != new_kind; |
| 2699 |
| 2700 next_kind = new_kind; |
| 2701 next_attributes = new_attributes; |
| 2702 next_location = kField; |
| 2703 |
| 2704 // Merge new representation/field type with ones from the target |
| 2705 // descriptor. If property kind is not reconfigured merge the result with |
| 2706 // representation/field type from the old descriptor. |
| 2707 next_representation = |
| 2708 new_representation.generalize(target_details.representation()); |
| 2709 if (!property_kind_reconfiguration) { |
| 2710 next_representation = |
| 2711 next_representation.generalize(old_details.representation()); |
| 2712 } |
| 2713 } else { |
| 2714 // Merge old_descriptor and target_descriptor entries. |
| 2715 DCHECK_EQ(target_details.kind(), old_details.kind()); |
| 2716 next_kind = target_details.kind(); |
| 2717 next_attributes = target_details.attributes(); |
| 2718 next_location = |
| 2719 old_details.location() == kField || |
| 2720 target_details.location() == kField || |
| 2721 !EqualImmutableValues(target_descriptors->GetValue(i), |
| 2722 old_descriptors->GetValue(i)) |
| 2723 ? kField |
| 2724 : kDescriptor; |
| 2725 |
| 2726 next_representation = old_details.representation().generalize( |
| 2727 target_details.representation()); |
2576 } | 2728 } |
2577 DCHECK_EQ(old_details.attributes(), target_details.attributes()); | 2729 DCHECK_EQ(next_kind, target_details.kind()); |
2578 if (old_details.type() == DATA || target_details.type() == DATA || | 2730 DCHECK_EQ(next_attributes, target_details.attributes()); |
2579 (modify_index == i && store_mode == FORCE_FIELD) || | 2731 |
2580 (target_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { | 2732 if (next_location == kField) { |
2581 Handle<HeapType> old_field_type = | 2733 if (next_kind == kData) { |
2582 (old_details.type() == DATA) | 2734 Handle<HeapType> target_field_type = |
2583 ? handle(old_descriptors->GetFieldType(i), isolate) | 2735 GetFieldType(isolate, target_descriptors, i, |
2584 : old_descriptors->GetValue(i) | 2736 target_details.location(), next_representation); |
2585 ->OptimalType(isolate, target_details.representation()); | 2737 |
2586 Handle<HeapType> target_field_type = | 2738 Handle<HeapType> next_field_type; |
2587 (target_details.type() == DATA) | 2739 if (modify_index == i) { |
2588 ? handle(target_descriptors->GetFieldType(i), isolate) | 2740 next_field_type = |
2589 : target_descriptors->GetValue(i) | 2741 GeneralizeFieldType(target_field_type, new_field_type, isolate); |
2590 ->OptimalType(isolate, target_details.representation()); | 2742 if (!property_kind_reconfiguration) { |
2591 target_field_type = GeneralizeFieldType( | 2743 Handle<HeapType> old_field_type = |
2592 target_field_type, old_field_type, isolate); | 2744 GetFieldType(isolate, old_descriptors, i, |
2593 if (modify_index == i) { | 2745 old_details.location(), next_representation); |
2594 target_field_type = GeneralizeFieldType( | 2746 next_field_type = |
2595 target_field_type, new_field_type, isolate); | 2747 GeneralizeFieldType(next_field_type, old_field_type, isolate); |
| 2748 } |
| 2749 } else { |
| 2750 Handle<HeapType> old_field_type = |
| 2751 GetFieldType(isolate, old_descriptors, i, old_details.location(), |
| 2752 next_representation); |
| 2753 next_field_type = |
| 2754 GeneralizeFieldType(target_field_type, old_field_type, isolate); |
| 2755 } |
| 2756 DataDescriptor d(target_key, current_offset, next_field_type, |
| 2757 next_attributes, next_representation); |
| 2758 current_offset += d.GetDetails().field_width_in_words(); |
| 2759 new_descriptors->Set(i, &d); |
| 2760 } else { |
| 2761 UNIMPLEMENTED(); // TODO(ishell): implement. |
2596 } | 2762 } |
2597 DataDescriptor d(target_key, current_offset, target_field_type, | |
2598 target_details.attributes(), | |
2599 target_details.representation()); | |
2600 current_offset += d.GetDetails().field_width_in_words(); | |
2601 new_descriptors->Set(i, &d); | |
2602 } else { | 2763 } else { |
2603 DCHECK_NE(DATA, target_details.type()); | 2764 PropertyDetails details(next_attributes, next_kind, next_location, |
2604 Descriptor d(target_key, | 2765 next_representation); |
2605 handle(target_descriptors->GetValue(i), isolate), | 2766 Descriptor d(target_key, handle(target_descriptors->GetValue(i), isolate), |
2606 target_details); | 2767 details); |
2607 new_descriptors->Set(i, &d); | 2768 new_descriptors->Set(i, &d); |
2608 } | 2769 } |
2609 } | 2770 } |
2610 | 2771 |
2611 // |target_nof| -> |old_nof| | 2772 // |target_nof| -> |old_nof| |
2612 for (int i = target_nof; i < old_nof; ++i) { | 2773 for (int i = target_nof; i < old_nof; ++i) { |
2613 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2774 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2614 Handle<Name> old_key(old_descriptors->GetKey(i), isolate); | 2775 Handle<Name> old_key(old_descriptors->GetKey(i), isolate); |
| 2776 |
| 2777 // Merge old_descriptor entry and modified details together. |
| 2778 PropertyKind next_kind; |
| 2779 PropertyAttributes next_attributes; |
| 2780 PropertyLocation next_location; |
| 2781 Representation next_representation; |
| 2782 bool property_kind_reconfiguration = false; |
| 2783 |
2615 if (modify_index == i) { | 2784 if (modify_index == i) { |
2616 old_details = old_details.CopyWithRepresentation( | 2785 DCHECK_EQ(FORCE_FIELD, store_mode); |
2617 new_representation.generalize(old_details.representation())); | 2786 // In case of property kind reconfiguration it is not necessary to |
| 2787 // take into account representation/field type of the old descriptor. |
| 2788 property_kind_reconfiguration = old_details.kind() != new_kind; |
| 2789 |
| 2790 next_kind = new_kind; |
| 2791 next_attributes = new_attributes; |
| 2792 next_location = kField; |
| 2793 next_representation = new_representation; |
| 2794 if (!property_kind_reconfiguration) { |
| 2795 next_representation = |
| 2796 next_representation.generalize(old_details.representation()); |
| 2797 } |
| 2798 } else { |
| 2799 next_kind = old_details.kind(); |
| 2800 next_attributes = old_details.attributes(); |
| 2801 next_location = old_details.location(); |
| 2802 next_representation = old_details.representation(); |
2618 } | 2803 } |
2619 if (old_details.type() == DATA) { | 2804 |
2620 Handle<HeapType> old_field_type( | 2805 if (next_location == kField) { |
2621 old_descriptors->GetFieldType(i), isolate); | 2806 if (next_kind == kData) { |
2622 if (modify_index == i) { | 2807 Handle<HeapType> next_field_type; |
2623 old_field_type = GeneralizeFieldType( | 2808 if (modify_index == i) { |
2624 old_field_type, new_field_type, isolate); | 2809 next_field_type = new_field_type; |
2625 } | 2810 if (!property_kind_reconfiguration) { |
2626 DataDescriptor d(old_key, current_offset, old_field_type, | 2811 Handle<HeapType> old_field_type = |
2627 old_details.attributes(), old_details.representation()); | 2812 GetFieldType(isolate, old_descriptors, i, |
2628 current_offset += d.GetDetails().field_width_in_words(); | 2813 old_details.location(), next_representation); |
2629 new_descriptors->Set(i, &d); | 2814 old_field_type = |
2630 } else { | 2815 GeneralizeFieldType(old_field_type, next_field_type, isolate); |
2631 DCHECK(old_details.type() == DATA_CONSTANT || | 2816 } |
2632 old_details.type() == ACCESSOR_CONSTANT); | 2817 } else { |
2633 if (modify_index == i && store_mode == FORCE_FIELD) { | 2818 Handle<HeapType> old_field_type = |
2634 DataDescriptor d( | 2819 GetFieldType(isolate, old_descriptors, i, old_details.location(), |
2635 old_key, current_offset, | 2820 next_representation); |
2636 GeneralizeFieldType(old_descriptors->GetValue(i)->OptimalType( | 2821 next_field_type = old_field_type; |
2637 isolate, old_details.representation()), | 2822 } |
2638 new_field_type, isolate), | 2823 |
2639 old_details.attributes(), old_details.representation()); | 2824 DataDescriptor d(old_key, current_offset, next_field_type, |
| 2825 next_attributes, next_representation); |
2640 current_offset += d.GetDetails().field_width_in_words(); | 2826 current_offset += d.GetDetails().field_width_in_words(); |
2641 new_descriptors->Set(i, &d); | 2827 new_descriptors->Set(i, &d); |
2642 } else { | 2828 } else { |
2643 DCHECK_NE(DATA, old_details.type()); | 2829 UNIMPLEMENTED(); // TODO(ishell): implement. |
2644 Descriptor d(old_key, | |
2645 handle(old_descriptors->GetValue(i), isolate), | |
2646 old_details); | |
2647 new_descriptors->Set(i, &d); | |
2648 } | 2830 } |
| 2831 } else { |
| 2832 PropertyDetails details(next_attributes, next_kind, next_location, |
| 2833 next_representation); |
| 2834 Descriptor d(old_key, handle(old_descriptors->GetValue(i), isolate), |
| 2835 details); |
| 2836 new_descriptors->Set(i, &d); |
2649 } | 2837 } |
2650 } | 2838 } |
2651 | 2839 |
2652 new_descriptors->Sort(); | 2840 new_descriptors->Sort(); |
2653 | 2841 |
2654 DCHECK(store_mode != FORCE_FIELD || | 2842 DCHECK(store_mode != FORCE_FIELD || |
2655 new_descriptors->GetDetails(modify_index).type() == DATA); | 2843 new_descriptors->GetDetails(modify_index).location() == kField); |
2656 | 2844 |
2657 Handle<Map> split_map(root_map->FindLastMatchMap( | 2845 Handle<Map> split_map(root_map->FindLastMatchMap( |
2658 root_nof, old_nof, *new_descriptors), isolate); | 2846 root_nof, old_nof, *new_descriptors), isolate); |
2659 int split_nof = split_map->NumberOfOwnDescriptors(); | 2847 int split_nof = split_map->NumberOfOwnDescriptors(); |
2660 DCHECK_NE(old_nof, split_nof); | 2848 DCHECK_NE(old_nof, split_nof); |
2661 | 2849 |
2662 Handle<LayoutDescriptor> new_layout_descriptor = | 2850 Handle<LayoutDescriptor> new_layout_descriptor = |
2663 LayoutDescriptor::New(split_map, new_descriptors, old_nof); | 2851 LayoutDescriptor::New(split_map, new_descriptors, old_nof); |
2664 PropertyDetails split_prop_details = old_descriptors->GetDetails(split_nof); | 2852 |
| 2853 PropertyKind split_kind; |
| 2854 PropertyAttributes split_attributes; |
| 2855 if (modify_index == split_nof) { |
| 2856 split_kind = new_kind; |
| 2857 split_attributes = new_attributes; |
| 2858 } else { |
| 2859 PropertyDetails split_prop_details = old_descriptors->GetDetails(split_nof); |
| 2860 split_kind = split_prop_details.kind(); |
| 2861 split_attributes = split_prop_details.attributes(); |
| 2862 } |
2665 bool transition_target_deprecated = split_map->DeprecateTarget( | 2863 bool transition_target_deprecated = split_map->DeprecateTarget( |
2666 split_prop_details.kind(), old_descriptors->GetKey(split_nof), | 2864 split_kind, old_descriptors->GetKey(split_nof), split_attributes, |
2667 split_prop_details.attributes(), *new_descriptors, | 2865 *new_descriptors, *new_layout_descriptor); |
2668 *new_layout_descriptor); | |
2669 | 2866 |
2670 // If |transition_target_deprecated| is true then the transition array | 2867 // If |transition_target_deprecated| is true then the transition array |
2671 // already contains entry for given descriptor. This means that the transition | 2868 // already contains entry for given descriptor. This means that the transition |
2672 // could be inserted regardless of whether transitions array is full or not. | 2869 // could be inserted regardless of whether transitions array is full or not. |
2673 if (!transition_target_deprecated && !split_map->CanHaveMoreTransitions()) { | 2870 if (!transition_target_deprecated && !split_map->CanHaveMoreTransitions()) { |
2674 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2871 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
| 2872 new_kind, new_attributes, |
2675 "GenAll_CantHaveMoreTransitions"); | 2873 "GenAll_CantHaveMoreTransitions"); |
2676 } | 2874 } |
2677 | 2875 |
2678 if (FLAG_trace_generalization) { | 2876 if (FLAG_trace_generalization && modify_index >= 0) { |
2679 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2877 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
2680 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); | 2878 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); |
2681 Handle<HeapType> old_field_type = | 2879 Handle<HeapType> old_field_type = |
2682 (old_details.type() == DATA) | 2880 (old_details.type() == DATA) |
2683 ? handle(old_descriptors->GetFieldType(modify_index), isolate) | 2881 ? handle(old_descriptors->GetFieldType(modify_index), isolate) |
2684 : HeapType::Constant( | 2882 : HeapType::Constant( |
2685 handle(old_descriptors->GetValue(modify_index), isolate), | 2883 handle(old_descriptors->GetValue(modify_index), isolate), |
2686 isolate); | 2884 isolate); |
2687 Handle<HeapType> new_field_type = | 2885 Handle<HeapType> new_field_type = |
2688 (new_details.type() == DATA) | 2886 (new_details.type() == DATA) |
2689 ? handle(new_descriptors->GetFieldType(modify_index), isolate) | 2887 ? handle(new_descriptors->GetFieldType(modify_index), isolate) |
2690 : HeapType::Constant( | 2888 : HeapType::Constant( |
2691 handle(new_descriptors->GetValue(modify_index), isolate), | 2889 handle(new_descriptors->GetValue(modify_index), isolate), |
2692 isolate); | 2890 isolate); |
2693 old_map->PrintGeneralization( | 2891 old_map->PrintGeneralization( |
2694 stdout, "", modify_index, split_nof, old_nof, | 2892 stdout, "", modify_index, split_nof, old_nof, |
2695 old_details.type() == DATA_CONSTANT && store_mode == FORCE_FIELD, | 2893 old_details.location() == kDescriptor && store_mode == FORCE_FIELD, |
2696 old_details.representation(), new_details.representation(), | 2894 old_details.representation(), new_details.representation(), |
2697 *old_field_type, *new_field_type); | 2895 *old_field_type, *new_field_type); |
2698 } | 2896 } |
2699 | 2897 |
2700 // Add missing transitions. | 2898 // Add missing transitions. |
2701 Handle<Map> new_map = split_map; | 2899 Handle<Map> new_map = split_map; |
2702 for (int i = split_nof; i < old_nof; ++i) { | 2900 for (int i = split_nof; i < old_nof; ++i) { |
2703 new_map = CopyInstallDescriptors(new_map, i, new_descriptors, | 2901 new_map = CopyInstallDescriptors(new_map, i, new_descriptors, |
2704 new_layout_descriptor); | 2902 new_layout_descriptor); |
2705 } | 2903 } |
2706 new_map->set_owns_descriptors(true); | 2904 new_map->set_owns_descriptors(true); |
2707 return new_map; | 2905 return new_map; |
2708 } | 2906 } |
2709 | 2907 |
2710 | 2908 |
2711 // Generalize the representation of all DATA descriptors. | 2909 // Generalize the representation of all DATA descriptors. |
2712 Handle<Map> Map::GeneralizeAllFieldRepresentations( | 2910 Handle<Map> Map::GeneralizeAllFieldRepresentations( |
2713 Handle<Map> map) { | 2911 Handle<Map> map) { |
2714 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 2912 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
2715 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { | 2913 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { |
2716 if (descriptors->GetDetails(i).type() == DATA) { | 2914 PropertyDetails details = descriptors->GetDetails(i); |
2717 map = GeneralizeRepresentation(map, i, Representation::Tagged(), | 2915 if (details.type() == DATA) { |
2718 HeapType::Any(map->GetIsolate()), | 2916 map = ReconfigureProperty(map, i, kData, details.attributes(), |
2719 FORCE_FIELD); | 2917 Representation::Tagged(), |
| 2918 HeapType::Any(map->GetIsolate()), FORCE_FIELD); |
2720 } | 2919 } |
2721 } | 2920 } |
2722 return map; | 2921 return map; |
2723 } | 2922 } |
2724 | 2923 |
2725 | 2924 |
2726 // static | 2925 // static |
2727 MaybeHandle<Map> Map::TryUpdate(Handle<Map> map) { | 2926 MaybeHandle<Map> Map::TryUpdate(Handle<Map> map) { |
2728 Handle<Map> proto_map(map); | 2927 Handle<Map> proto_map(map); |
2729 while (proto_map->prototype()->IsJSObject()) { | 2928 while (proto_map->prototype()->IsJSObject()) { |
2730 Handle<JSObject> holder(JSObject::cast(proto_map->prototype())); | 2929 Handle<JSObject> holder(JSObject::cast(proto_map->prototype())); |
2731 proto_map = Handle<Map>(holder->map()); | 2930 proto_map = Handle<Map>(holder->map()); |
2732 if (proto_map->is_deprecated() && JSObject::TryMigrateInstance(holder)) { | 2931 if (proto_map->is_deprecated() && JSObject::TryMigrateInstance(holder)) { |
2733 proto_map = Handle<Map>(holder->map()); | 2932 proto_map = Handle<Map>(holder->map()); |
2734 } | 2933 } |
2735 } | 2934 } |
2736 return TryUpdateInternal(map); | 2935 return TryUpdateInternal(map); |
2737 } | 2936 } |
2738 | 2937 |
2739 | 2938 |
2740 // static | 2939 // static |
2741 Handle<Map> Map::Update(Handle<Map> map) { | 2940 Handle<Map> Map::Update(Handle<Map> map) { |
2742 if (!map->is_deprecated()) return map; | 2941 if (!map->is_deprecated()) return map; |
2743 return GeneralizeRepresentation(map, 0, Representation::None(), | 2942 return ReconfigureProperty(map, -1, kData, NONE, Representation::None(), |
2744 HeapType::None(map->GetIsolate()), | 2943 HeapType::None(map->GetIsolate()), |
2745 ALLOW_IN_DESCRIPTOR); | 2944 ALLOW_IN_DESCRIPTOR); |
2746 } | 2945 } |
2747 | 2946 |
2748 | 2947 |
2749 // static | 2948 // static |
2750 MaybeHandle<Map> Map::TryUpdateInternal(Handle<Map> old_map) { | 2949 MaybeHandle<Map> Map::TryUpdateInternal(Handle<Map> old_map) { |
2751 DisallowHeapAllocation no_allocation; | 2950 DisallowHeapAllocation no_allocation; |
2752 DisallowDeoptimization no_deoptimization(old_map->GetIsolate()); | 2951 DisallowDeoptimization no_deoptimization(old_map->GetIsolate()); |
2753 | 2952 |
2754 if (!old_map->is_deprecated()) return old_map; | 2953 if (!old_map->is_deprecated()) return old_map; |
2755 | 2954 |
(...skipping 1189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3945 RETURN_ON_EXCEPTION( | 4144 RETURN_ON_EXCEPTION( |
3946 it.isolate(), | 4145 it.isolate(), |
3947 EnqueueChangeRecord(object, "reconfigure", name, | 4146 EnqueueChangeRecord(object, "reconfigure", name, |
3948 it.isolate()->factory()->the_hole_value()), | 4147 it.isolate()->factory()->the_hole_value()), |
3949 Object); | 4148 Object); |
3950 } | 4149 } |
3951 return value; | 4150 return value; |
3952 } | 4151 } |
3953 | 4152 |
3954 it.ReconfigureDataProperty(value, attributes); | 4153 it.ReconfigureDataProperty(value, attributes); |
3955 it.PrepareForDataProperty(value); | |
3956 value = it.WriteDataValue(value); | 4154 value = it.WriteDataValue(value); |
3957 | 4155 |
3958 if (is_observed) { | 4156 if (is_observed) { |
3959 RETURN_ON_EXCEPTION( | 4157 RETURN_ON_EXCEPTION( |
3960 it.isolate(), | 4158 it.isolate(), |
3961 EnqueueChangeRecord(object, "reconfigure", name, | 4159 EnqueueChangeRecord(object, "reconfigure", name, |
3962 it.isolate()->factory()->the_hole_value()), | 4160 it.isolate()->factory()->the_hole_value()), |
3963 Object); | 4161 Object); |
3964 } | 4162 } |
3965 | 4163 |
3966 return value; | 4164 return value; |
3967 } | 4165 } |
3968 | 4166 |
3969 case LookupIterator::DATA: { | 4167 case LookupIterator::DATA: { |
3970 PropertyDetails details = it.property_details(); | 4168 PropertyDetails details = it.property_details(); |
3971 Handle<Object> old_value = it.isolate()->factory()->the_hole_value(); | 4169 Handle<Object> old_value = it.isolate()->factory()->the_hole_value(); |
3972 // Regular property update if the attributes match. | 4170 // Regular property update if the attributes match. |
3973 if (details.attributes() == attributes) { | 4171 if (details.attributes() == attributes) { |
3974 return SetDataProperty(&it, value); | 4172 return SetDataProperty(&it, value); |
3975 } | 4173 } |
3976 // Reconfigure the data property if the attributes mismatch. | 4174 // Reconfigure the data property if the attributes mismatch. |
3977 if (is_observed) old_value = it.GetDataValue(); | 4175 if (is_observed) old_value = it.GetDataValue(); |
3978 | 4176 |
3979 it.ReconfigureDataProperty(value, attributes); | 4177 it.ReconfigureDataProperty(value, attributes); |
3980 it.PrepareForDataProperty(value); | |
3981 value = it.WriteDataValue(value); | 4178 value = it.WriteDataValue(value); |
3982 | 4179 |
3983 if (is_observed) { | 4180 if (is_observed) { |
3984 if (old_value->SameValue(*value)) { | 4181 if (old_value->SameValue(*value)) { |
3985 old_value = it.isolate()->factory()->the_hole_value(); | 4182 old_value = it.isolate()->factory()->the_hole_value(); |
3986 } | 4183 } |
3987 RETURN_ON_EXCEPTION( | 4184 RETURN_ON_EXCEPTION( |
3988 it.isolate(), | 4185 it.isolate(), |
3989 EnqueueChangeRecord(object, "reconfigure", name, old_value), | 4186 EnqueueChangeRecord(object, "reconfigure", name, old_value), |
3990 Object); | 4187 Object); |
(...skipping 1848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5839 return result; | 6036 return result; |
5840 } | 6037 } |
5841 | 6038 |
5842 | 6039 |
5843 int Map::NextFreePropertyIndex() { | 6040 int Map::NextFreePropertyIndex() { |
5844 int free_index = 0; | 6041 int free_index = 0; |
5845 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 6042 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
5846 DescriptorArray* descs = instance_descriptors(); | 6043 DescriptorArray* descs = instance_descriptors(); |
5847 for (int i = 0; i < number_of_own_descriptors; i++) { | 6044 for (int i = 0; i < number_of_own_descriptors; i++) { |
5848 PropertyDetails details = descs->GetDetails(i); | 6045 PropertyDetails details = descs->GetDetails(i); |
5849 if (details.type() == DATA) { | 6046 if (details.location() == kField) { |
5850 int candidate = details.field_index() + details.field_width_in_words(); | 6047 int candidate = details.field_index() + details.field_width_in_words(); |
5851 if (candidate > free_index) free_index = candidate; | 6048 if (candidate > free_index) free_index = candidate; |
5852 } | 6049 } |
5853 } | 6050 } |
5854 return free_index; | 6051 return free_index; |
5855 } | 6052 } |
5856 | 6053 |
5857 | 6054 |
5858 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { | 6055 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { |
5859 int len = array->length(); | 6056 int len = array->length(); |
(...skipping 974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6834 Handle<LayoutDescriptor> full_layout_descriptor) { | 7031 Handle<LayoutDescriptor> full_layout_descriptor) { |
6835 DCHECK(descriptors->IsSortedNoDuplicates()); | 7032 DCHECK(descriptors->IsSortedNoDuplicates()); |
6836 | 7033 |
6837 Handle<Map> result = CopyDropDescriptors(map); | 7034 Handle<Map> result = CopyDropDescriptors(map); |
6838 | 7035 |
6839 result->set_instance_descriptors(*descriptors); | 7036 result->set_instance_descriptors(*descriptors); |
6840 result->SetNumberOfOwnDescriptors(new_descriptor + 1); | 7037 result->SetNumberOfOwnDescriptors(new_descriptor + 1); |
6841 | 7038 |
6842 int unused_property_fields = map->unused_property_fields(); | 7039 int unused_property_fields = map->unused_property_fields(); |
6843 PropertyDetails details = descriptors->GetDetails(new_descriptor); | 7040 PropertyDetails details = descriptors->GetDetails(new_descriptor); |
6844 if (details.type() == DATA) { | 7041 if (details.location() == kField) { |
6845 unused_property_fields = map->unused_property_fields() - 1; | 7042 unused_property_fields = map->unused_property_fields() - 1; |
6846 if (unused_property_fields < 0) { | 7043 if (unused_property_fields < 0) { |
6847 unused_property_fields += JSObject::kFieldsAdded; | 7044 unused_property_fields += JSObject::kFieldsAdded; |
6848 } | 7045 } |
6849 } | 7046 } |
6850 result->set_unused_property_fields(unused_property_fields); | 7047 result->set_unused_property_fields(unused_property_fields); |
6851 | 7048 |
6852 if (FLAG_unbox_double_fields) { | 7049 if (FLAG_unbox_double_fields) { |
6853 Handle<LayoutDescriptor> layout_descriptor = | 7050 Handle<LayoutDescriptor> layout_descriptor = |
6854 LayoutDescriptor::AppendIfFastOrUseFull(map, details, | 7051 LayoutDescriptor::AppendIfFastOrUseFull(map, details, |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7052 if (map->is_dictionary_map()) return map; | 7249 if (map->is_dictionary_map()) return map; |
7053 | 7250 |
7054 // Migrate to the newest map before storing the property. | 7251 // Migrate to the newest map before storing the property. |
7055 map = Update(map); | 7252 map = Update(map); |
7056 | 7253 |
7057 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 7254 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
7058 | 7255 |
7059 if (descriptors->CanHoldValue(descriptor, *value)) return map; | 7256 if (descriptors->CanHoldValue(descriptor, *value)) return map; |
7060 | 7257 |
7061 Isolate* isolate = map->GetIsolate(); | 7258 Isolate* isolate = map->GetIsolate(); |
| 7259 PropertyAttributes attributes = |
| 7260 descriptors->GetDetails(descriptor).attributes(); |
7062 Representation representation = value->OptimalRepresentation(); | 7261 Representation representation = value->OptimalRepresentation(); |
7063 Handle<HeapType> type = value->OptimalType(isolate, representation); | 7262 Handle<HeapType> type = value->OptimalType(isolate, representation); |
7064 | 7263 |
7065 return GeneralizeRepresentation(map, descriptor, representation, type, | 7264 return ReconfigureProperty(map, descriptor, kData, attributes, representation, |
7066 FORCE_FIELD); | 7265 type, FORCE_FIELD); |
7067 } | 7266 } |
7068 | 7267 |
7069 | 7268 |
7070 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, | 7269 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, |
7071 Handle<Object> value, | 7270 Handle<Object> value, |
7072 PropertyAttributes attributes, | 7271 PropertyAttributes attributes, |
7073 StoreFromKeyed store_mode) { | 7272 StoreFromKeyed store_mode) { |
7074 // Dictionary maps can always have additional data properties. | 7273 // Dictionary maps can always have additional data properties. |
7075 if (map->is_dictionary_map()) return map; | 7274 if (map->is_dictionary_map()) return map; |
7076 | 7275 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7113 } | 7312 } |
7114 #endif | 7313 #endif |
7115 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, | 7314 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, |
7116 "TooManyFastProperties"); | 7315 "TooManyFastProperties"); |
7117 } | 7316 } |
7118 | 7317 |
7119 return result; | 7318 return result; |
7120 } | 7319 } |
7121 | 7320 |
7122 | 7321 |
7123 Handle<Map> Map::ReconfigureDataProperty(Handle<Map> map, int descriptor, | 7322 Handle<Map> Map::ReconfigureExistingProperty(Handle<Map> map, int descriptor, |
7124 PropertyAttributes attributes) { | 7323 PropertyKind kind, |
| 7324 PropertyAttributes attributes) { |
7125 // Dictionaries have to be reconfigured in-place. | 7325 // Dictionaries have to be reconfigured in-place. |
7126 DCHECK(!map->is_dictionary_map()); | 7326 DCHECK(!map->is_dictionary_map()); |
7127 | 7327 |
7128 // For now, give up on transitioning and just create a unique map. | 7328 if (!map->GetBackPointer()->IsMap()) { |
7129 // TODO(verwaest/ishell): Cache transitions with different attributes. | 7329 // There is no benefit from reconstructing transition tree for maps without |
7130 return CopyGeneralizeAllRepresentations( | 7330 // back pointers. |
7131 map, descriptor, FORCE_FIELD, attributes, "GenAll_AttributesMismatch"); | 7331 return CopyGeneralizeAllRepresentations( |
| 7332 map, descriptor, FORCE_FIELD, kind, attributes, |
| 7333 "GenAll_AttributesMismatchProtoMap"); |
| 7334 } |
| 7335 |
| 7336 if (FLAG_trace_generalization) { |
| 7337 map->PrintReconfiguration(stdout, descriptor, kind, attributes); |
| 7338 } |
| 7339 |
| 7340 Isolate* isolate = map->GetIsolate(); |
| 7341 Handle<Map> new_map = ReconfigureProperty( |
| 7342 map, descriptor, kind, attributes, Representation::None(), |
| 7343 HeapType::None(isolate), FORCE_FIELD); |
| 7344 return new_map; |
7132 } | 7345 } |
7133 | 7346 |
7134 | 7347 |
7135 Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, | 7348 Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, |
7136 Handle<Name> name, | 7349 Handle<Name> name, |
7137 AccessorComponent component, | 7350 AccessorComponent component, |
7138 Handle<Object> accessor, | 7351 Handle<Object> accessor, |
7139 PropertyAttributes attributes) { | 7352 PropertyAttributes attributes) { |
7140 Isolate* isolate = name->GetIsolate(); | 7353 Isolate* isolate = name->GetIsolate(); |
7141 | 7354 |
(...skipping 9852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16994 CompilationInfo* info) { | 17207 CompilationInfo* info) { |
16995 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( | 17208 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( |
16996 handle(cell->dependent_code(), info->isolate()), | 17209 handle(cell->dependent_code(), info->isolate()), |
16997 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); | 17210 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); |
16998 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 17211 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
16999 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 17212 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
17000 cell, info->zone()); | 17213 cell, info->zone()); |
17001 } | 17214 } |
17002 | 17215 |
17003 } } // namespace v8::internal | 17216 } } // namespace v8::internal |
OLD | NEW |