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 1164 matching lines...) Loading... | |
1175 object->ShortPrint(file); | 1175 object->ShortPrint(file); |
1176 PrintF(file, " from "); | 1176 PrintF(file, " from "); |
1177 from_elements->ShortPrint(file); | 1177 from_elements->ShortPrint(file); |
1178 PrintF(file, " to "); | 1178 PrintF(file, " to "); |
1179 to_elements->ShortPrint(file); | 1179 to_elements->ShortPrint(file); |
1180 PrintF(file, "\n"); | 1180 PrintF(file, "\n"); |
1181 } | 1181 } |
1182 } | 1182 } |
1183 | 1183 |
1184 | 1184 |
1185 void Map::PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind, | |
1186 PropertyAttributes attributes) { | |
1187 OFStream os(file); | |
1188 os << "[reconfiguring "; | |
1189 constructor_name()->PrintOn(file); | |
1190 os << "] "; | |
1191 Name* name = instance_descriptors()->GetKey(modify_index); | |
1192 if (name->IsString()) { | |
1193 String::cast(name)->PrintOn(file); | |
1194 } else { | |
1195 os << "{symbol " << static_cast<void*>(name) << "}"; | |
1196 } | |
1197 os << ": " << (kind == kData ? "kData" : "ACCESSORS") << ", attrs: "; | |
1198 os << attributes << " ["; | |
1199 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); | |
1200 os << "]\n"; | |
1201 } | |
1202 | |
1203 | |
1185 void Map::PrintGeneralization(FILE* file, | 1204 void Map::PrintGeneralization(FILE* file, |
1186 const char* reason, | 1205 const char* reason, |
1187 int modify_index, | 1206 int modify_index, |
1188 int split, | 1207 int split, |
1189 int descriptors, | 1208 int descriptors, |
1190 bool constant_to_field, | 1209 bool constant_to_field, |
1191 Representation old_representation, | 1210 Representation old_representation, |
1192 Representation new_representation, | 1211 Representation new_representation, |
1193 HeapType* old_field_type, | 1212 HeapType* old_field_type, |
1194 HeapType* new_field_type) { | 1213 HeapType* new_field_type) { |
(...skipping 792 matching lines...) Loading... | |
1987 // We are storing the new map using release store after creating a filler for | 2006 // We are storing the new map using release store after creating a filler for |
1988 // the left-over space to avoid races with the sweeper thread. | 2007 // the left-over space to avoid races with the sweeper thread. |
1989 object->synchronized_set_map(*new_map); | 2008 object->synchronized_set_map(*new_map); |
1990 } | 2009 } |
1991 | 2010 |
1992 | 2011 |
1993 int Map::NumberOfFields() { | 2012 int Map::NumberOfFields() { |
1994 DescriptorArray* descriptors = instance_descriptors(); | 2013 DescriptorArray* descriptors = instance_descriptors(); |
1995 int result = 0; | 2014 int result = 0; |
1996 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { | 2015 for (int i = 0; i < NumberOfOwnDescriptors(); i++) { |
1997 if (descriptors->GetDetails(i).type() == DATA) result++; | 2016 if (descriptors->GetDetails(i).location() == kField) result++; |
1998 } | 2017 } |
1999 return result; | 2018 return result; |
2000 } | 2019 } |
2001 | 2020 |
2002 | 2021 |
2003 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, | 2022 Handle<Map> Map::CopyGeneralizeAllRepresentations( |
2004 int modify_index, | 2023 Handle<Map> map, int modify_index, StoreMode store_mode, PropertyKind kind, |
2005 StoreMode store_mode, | 2024 PropertyAttributes attributes, const char* reason) { |
2006 PropertyAttributes attributes, | |
2007 const char* reason) { | |
2008 Isolate* isolate = map->GetIsolate(); | 2025 Isolate* isolate = map->GetIsolate(); |
2009 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); | 2026 Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); |
2010 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | 2027 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
2011 Handle<DescriptorArray> descriptors = | 2028 Handle<DescriptorArray> descriptors = |
2012 DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors); | 2029 DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors); |
2013 | 2030 |
2014 for (int i = 0; i < number_of_own_descriptors; i++) { | 2031 for (int i = 0; i < number_of_own_descriptors; i++) { |
2015 descriptors->SetRepresentation(i, Representation::Tagged()); | 2032 descriptors->SetRepresentation(i, Representation::Tagged()); |
2016 if (descriptors->GetDetails(i).type() == DATA) { | 2033 if (descriptors->GetDetails(i).type() == DATA) { |
2017 descriptors->SetValue(i, HeapType::Any()); | 2034 descriptors->SetValue(i, HeapType::Any()); |
2018 } | 2035 } |
2019 } | 2036 } |
2020 | 2037 |
2021 Handle<LayoutDescriptor> new_layout_descriptor( | 2038 Handle<LayoutDescriptor> new_layout_descriptor( |
2022 LayoutDescriptor::FastPointerLayout(), isolate); | 2039 LayoutDescriptor::FastPointerLayout(), isolate); |
2023 Handle<Map> new_map = CopyReplaceDescriptors( | 2040 Handle<Map> new_map = CopyReplaceDescriptors( |
2024 map, descriptors, new_layout_descriptor, OMIT_TRANSITION, | 2041 map, descriptors, new_layout_descriptor, OMIT_TRANSITION, |
2025 MaybeHandle<Name>(), reason, SPECIAL_TRANSITION); | 2042 MaybeHandle<Name>(), reason, SPECIAL_TRANSITION); |
2026 | 2043 |
2027 // Unless the instance is being migrated, ensure that modify_index is a field. | 2044 // Unless the instance is being migrated, ensure that modify_index is a field. |
2028 PropertyDetails details = descriptors->GetDetails(modify_index); | 2045 if (modify_index >= 0) { |
2029 if (store_mode == FORCE_FIELD && | 2046 PropertyDetails details = descriptors->GetDetails(modify_index); |
2030 (details.type() != DATA || details.attributes() != attributes)) { | 2047 if (store_mode == FORCE_FIELD && |
2031 int field_index = details.type() == DATA ? details.field_index() | 2048 (details.type() != DATA || details.attributes() != attributes)) { |
2032 : new_map->NumberOfFields(); | 2049 int field_index = details.type() == DATA ? details.field_index() |
2033 DataDescriptor d(handle(descriptors->GetKey(modify_index), isolate), | 2050 : new_map->NumberOfFields(); |
2034 field_index, attributes, Representation::Tagged()); | 2051 DataDescriptor d(handle(descriptors->GetKey(modify_index), isolate), |
2035 descriptors->Replace(modify_index, &d); | 2052 field_index, attributes, Representation::Tagged()); |
2036 if (details.type() != DATA) { | 2053 descriptors->Replace(modify_index, &d); |
2037 int unused_property_fields = new_map->unused_property_fields() - 1; | 2054 if (details.type() != DATA) { |
2038 if (unused_property_fields < 0) { | 2055 int unused_property_fields = new_map->unused_property_fields() - 1; |
2039 unused_property_fields += JSObject::kFieldsAdded; | 2056 if (unused_property_fields < 0) { |
2057 unused_property_fields += JSObject::kFieldsAdded; | |
2058 } | |
2059 new_map->set_unused_property_fields(unused_property_fields); | |
2040 } | 2060 } |
2041 new_map->set_unused_property_fields(unused_property_fields); | 2061 } else { |
2062 DCHECK(details.attributes() == attributes); | |
2042 } | 2063 } |
2043 } else { | |
2044 DCHECK(details.attributes() == attributes); | |
2045 } | |
2046 | 2064 |
2047 if (FLAG_trace_generalization) { | 2065 if (FLAG_trace_generalization) { |
2048 HeapType* field_type = | 2066 HeapType* field_type = |
2049 (details.type() == DATA) | 2067 (details.type() == DATA) |
2050 ? map->instance_descriptors()->GetFieldType(modify_index) | 2068 ? map->instance_descriptors()->GetFieldType(modify_index) |
2051 : NULL; | 2069 : NULL; |
2052 map->PrintGeneralization( | 2070 map->PrintGeneralization( |
2053 stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(), | 2071 stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(), |
2054 new_map->NumberOfOwnDescriptors(), | 2072 new_map->NumberOfOwnDescriptors(), |
2055 details.type() == DATA_CONSTANT && store_mode == FORCE_FIELD, | 2073 details.type() == DATA_CONSTANT && store_mode == FORCE_FIELD, |
2056 details.representation(), Representation::Tagged(), field_type, | 2074 details.representation(), Representation::Tagged(), field_type, |
2057 HeapType::Any()); | 2075 HeapType::Any()); |
2076 } | |
2058 } | 2077 } |
2059 return new_map; | 2078 return new_map; |
2060 } | 2079 } |
2061 | 2080 |
2062 | 2081 |
2063 // static | |
2064 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, | |
2065 int modify_index, | |
2066 StoreMode store_mode, | |
2067 const char* reason) { | |
2068 PropertyDetails details = | |
2069 map->instance_descriptors()->GetDetails(modify_index); | |
2070 return CopyGeneralizeAllRepresentations(map, modify_index, store_mode, | |
2071 details.attributes(), reason); | |
2072 } | |
2073 | |
2074 | |
2075 void Map::DeprecateTransitionTree() { | 2082 void Map::DeprecateTransitionTree() { |
2076 if (is_deprecated()) return; | 2083 if (is_deprecated()) return; |
2077 if (HasTransitionArray()) { | 2084 if (HasTransitionArray()) { |
2078 TransitionArray* transitions = this->transitions(); | 2085 TransitionArray* transitions = this->transitions(); |
2079 for (int i = 0; i < transitions->number_of_transitions(); i++) { | 2086 for (int i = 0; i < transitions->number_of_transitions(); i++) { |
2080 transitions->GetTarget(i)->DeprecateTransitionTree(); | 2087 transitions->GetTarget(i)->DeprecateTransitionTree(); |
2081 } | 2088 } |
2082 } | 2089 } |
2083 deprecate(); | 2090 deprecate(); |
2084 dependent_code()->DeoptimizeDependentCodeGroup( | 2091 dependent_code()->DeoptimizeDependentCodeGroup( |
2085 GetIsolate(), DependentCode::kTransitionGroup); | 2092 GetIsolate(), DependentCode::kTransitionGroup); |
2086 NotifyLeafMapLayoutChange(); | 2093 NotifyLeafMapLayoutChange(); |
2087 } | 2094 } |
2088 | 2095 |
2089 | 2096 |
2097 static inline bool EqualImmutableValues(Object* obj1, Object* obj2) { | |
2098 if (obj1 == obj2) return true; // Valid for both kData and kAccessor kinds. | |
2099 // TODO(ishell): compare AccessorPairs. | |
2100 return false; | |
2101 } | |
2102 | |
2103 | |
2090 // Invalidates a transition target at |key|, and installs |new_descriptors| over | 2104 // Invalidates a transition target at |key|, and installs |new_descriptors| over |
2091 // the current instance_descriptors to ensure proper sharing of descriptor | 2105 // the current instance_descriptors to ensure proper sharing of descriptor |
2092 // arrays. | 2106 // arrays. |
2093 // Returns true if the transition target at given key was deprecated. | 2107 // Returns true if the transition target at given key was deprecated. |
2094 bool Map::DeprecateTarget(PropertyKind kind, Name* key, | 2108 bool Map::DeprecateTarget(PropertyKind kind, Name* key, |
2095 PropertyAttributes attributes, | 2109 PropertyAttributes attributes, |
2096 DescriptorArray* new_descriptors, | 2110 DescriptorArray* new_descriptors, |
2097 LayoutDescriptor* new_layout_descriptor) { | 2111 LayoutDescriptor* new_layout_descriptor) { |
2098 bool transition_target_deprecated = false; | 2112 bool transition_target_deprecated = false; |
2099 if (HasTransitionArray()) { | 2113 if (HasTransitionArray()) { |
(...skipping 50 matching lines...) Loading... | |
2150 PropertyDetails details = descriptors->GetDetails(i); | 2164 PropertyDetails details = descriptors->GetDetails(i); |
2151 TransitionArray* transitions = current->transitions(); | 2165 TransitionArray* transitions = current->transitions(); |
2152 int transition = | 2166 int transition = |
2153 transitions->Search(details.kind(), name, details.attributes()); | 2167 transitions->Search(details.kind(), name, details.attributes()); |
2154 if (transition == TransitionArray::kNotFound) break; | 2168 if (transition == TransitionArray::kNotFound) break; |
2155 | 2169 |
2156 Map* next = transitions->GetTarget(transition); | 2170 Map* next = transitions->GetTarget(transition); |
2157 DescriptorArray* next_descriptors = next->instance_descriptors(); | 2171 DescriptorArray* next_descriptors = next->instance_descriptors(); |
2158 | 2172 |
2159 PropertyDetails next_details = next_descriptors->GetDetails(i); | 2173 PropertyDetails next_details = next_descriptors->GetDetails(i); |
2160 if (details.type() != next_details.type()) break; | 2174 DCHECK_EQ(details.kind(), next_details.kind()); |
2161 if (details.attributes() != next_details.attributes()) break; | 2175 DCHECK_EQ(details.attributes(), next_details.attributes()); |
2176 if (details.location() != next_details.location()) break; | |
2162 if (!details.representation().Equals(next_details.representation())) break; | 2177 if (!details.representation().Equals(next_details.representation())) break; |
2163 if (next_details.type() == DATA) { | 2178 |
2164 if (!descriptors->GetFieldType(i)->NowIs( | 2179 if (next_details.location() == kField) { |
2165 next_descriptors->GetFieldType(i))) break; | 2180 HeapType* next_field_type = next_descriptors->GetFieldType(i); |
2181 if (!descriptors->GetFieldType(i)->NowIs(next_field_type)) { | |
2182 break; | |
2183 } | |
2166 } else { | 2184 } else { |
2167 if (descriptors->GetValue(i) != next_descriptors->GetValue(i)) break; | 2185 if (!EqualImmutableValues(descriptors->GetValue(i), |
2186 next_descriptors->GetValue(i))) { | |
2187 break; | |
2188 } | |
2168 } | 2189 } |
2169 | |
2170 current = next; | 2190 current = next; |
2171 } | 2191 } |
2172 return current; | 2192 return current; |
2173 } | 2193 } |
2174 | 2194 |
2175 | 2195 |
2176 Map* Map::FindFieldOwner(int descriptor) { | 2196 Map* Map::FindFieldOwner(int descriptor) { |
2177 DisallowHeapAllocation no_allocation; | 2197 DisallowHeapAllocation no_allocation; |
2178 DCHECK_EQ(DATA, instance_descriptors()->GetDetails(descriptor).type()); | 2198 DCHECK_EQ(DATA, instance_descriptors()->GetDetails(descriptor).type()); |
2179 Map* result = this; | 2199 Map* result = this; |
(...skipping 95 matching lines...) Loading... | |
2275 map->PrintGeneralization( | 2295 map->PrintGeneralization( |
2276 stdout, "field type generalization", | 2296 stdout, "field type generalization", |
2277 modify_index, map->NumberOfOwnDescriptors(), | 2297 modify_index, map->NumberOfOwnDescriptors(), |
2278 map->NumberOfOwnDescriptors(), false, | 2298 map->NumberOfOwnDescriptors(), false, |
2279 details.representation(), details.representation(), | 2299 details.representation(), details.representation(), |
2280 *old_field_type, *new_field_type); | 2300 *old_field_type, *new_field_type); |
2281 } | 2301 } |
2282 } | 2302 } |
2283 | 2303 |
2284 | 2304 |
2285 // Generalize the representation of the descriptor at |modify_index|. | 2305 // Reconfigures property at |modify_index| with |new_kind|, |new_attributes|, |
2286 // This method rewrites the transition tree to reflect the new change. To avoid | 2306 // |store_mode| and/or |new_representation|/|new_field_type|. |
2287 // high degrees over polymorphism, and to stabilize quickly, on every rewrite | 2307 // If |modify_index| is negative then no properties are reconfigured but the |
2288 // the new type is deduced by merging the current type with any potential new | 2308 // map is migrated to the up-to-date non-deprecated state. |
2289 // (partial) version of the type in the transition tree. | 2309 // |
2310 // This method rewrites or completes the transition tree to reflect the new | |
2311 // change. To avoid high degrees over polymorphism, and to stabilize quickly, | |
2312 // on every rewrite the new type is deduced by merging the current type with | |
2313 // any potential new (partial) version of the type in the transition tree. | |
2290 // To do this, on each rewrite: | 2314 // To do this, on each rewrite: |
2291 // - Search the root of the transition tree using FindRootMap. | 2315 // - Search the root of the transition tree using FindRootMap. |
2292 // - Find |target_map|, the newest matching version of this map using the keys | 2316 // - Find |target_map|, the newest matching version of this map using the |
2293 // in the |old_map|'s descriptor array to walk the transition tree. | 2317 // virtually "enhanced" |old_map|'s descriptor array (i.e. whose entry at |
2294 // - Merge/generalize the descriptor array of the |old_map| and |target_map|. | 2318 // |modify_index| is considered to be of |new_kind| and having |
2319 // |new_attributes|) to walk the transition tree. | |
2320 // - Merge/generalize the "enhanced" descriptor array of the |old_map| and | |
2321 // descriptor array of the |target_map|. | |
2295 // - Generalize the |modify_index| descriptor using |new_representation| and | 2322 // - Generalize the |modify_index| descriptor using |new_representation| and |
2296 // |new_field_type|. | 2323 // |new_field_type|. |
2297 // - Walk the tree again starting from the root towards |target_map|. Stop at | 2324 // - Walk the tree again starting from the root towards |target_map|. Stop at |
2298 // |split_map|, the first map who's descriptor array does not match the merged | 2325 // |split_map|, the first map who's descriptor array does not match the merged |
2299 // descriptor array. | 2326 // descriptor array. |
2300 // - If |target_map| == |split_map|, |target_map| is in the expected state. | 2327 // - If |target_map| == |split_map|, |target_map| is in the expected state. |
2301 // Return it. | 2328 // Return it. |
2302 // - Otherwise, invalidate the outdated transition target from |target_map|, and | 2329 // - Otherwise, invalidate the outdated transition target from |target_map|, and |
2303 // replace its transition tree with a new branch for the updated descriptors. | 2330 // replace its transition tree with a new branch for the updated descriptors. |
2304 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map, | 2331 Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index, |
2305 int modify_index, | 2332 PropertyKind new_kind, |
2306 Representation new_representation, | 2333 PropertyAttributes new_attributes, |
2307 Handle<HeapType> new_field_type, | 2334 Representation new_representation, |
2308 StoreMode store_mode) { | 2335 Handle<HeapType> new_field_type, |
2336 StoreMode store_mode) { | |
2337 DCHECK_NE(kAccessor, new_kind); // TODO(ishell): not supported yet. | |
2338 DCHECK(store_mode != FORCE_FIELD || modify_index >= 0); | |
2309 Isolate* isolate = old_map->GetIsolate(); | 2339 Isolate* isolate = old_map->GetIsolate(); |
2310 | 2340 |
2311 Handle<DescriptorArray> old_descriptors( | 2341 Handle<DescriptorArray> old_descriptors( |
2312 old_map->instance_descriptors(), isolate); | 2342 old_map->instance_descriptors(), isolate); |
2313 int old_nof = old_map->NumberOfOwnDescriptors(); | 2343 int old_nof = old_map->NumberOfOwnDescriptors(); |
2314 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | |
2315 Representation old_representation = old_details.representation(); | |
2316 | 2344 |
2317 // It's fine to transition from None to anything but double without any | 2345 // If it's just a representation generalization case (i.e. property kind and |
2318 // modification to the object, because the default uninitialized value for | 2346 // attributes stays unchanged) it's fine to transition from None to anything |
2319 // representation None can be overwritten by both smi and tagged values. | 2347 // but double without any modification to the object, because the default |
2320 // Doubles, however, would require a box allocation. | 2348 // uninitialized value for representation None can be overwritten by both |
2321 if (old_representation.IsNone() && !new_representation.IsNone() && | 2349 // smi and tagged values. Doubles, however, would require a box allocation. |
2350 if (modify_index >= 0 && !new_representation.IsNone() && | |
2322 !new_representation.IsDouble()) { | 2351 !new_representation.IsDouble()) { |
2323 DCHECK(old_details.type() == DATA); | 2352 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
2324 if (FLAG_trace_generalization) { | 2353 Representation old_representation = old_details.representation(); |
2325 old_map->PrintGeneralization( | 2354 |
2326 stdout, "uninitialized field", | 2355 if (old_representation.IsNone()) { |
2327 modify_index, old_map->NumberOfOwnDescriptors(), | 2356 DCHECK_EQ(new_kind, old_details.kind()); |
2328 old_map->NumberOfOwnDescriptors(), false, | 2357 DCHECK_EQ(new_attributes, old_details.attributes()); |
2329 old_representation, new_representation, | 2358 DCHECK_EQ(DATA, old_details.type()); |
2330 old_descriptors->GetFieldType(modify_index), *new_field_type); | 2359 if (FLAG_trace_generalization) { |
2360 old_map->PrintGeneralization( | |
2361 stdout, "uninitialized field", modify_index, | |
2362 old_map->NumberOfOwnDescriptors(), | |
2363 old_map->NumberOfOwnDescriptors(), false, old_representation, | |
2364 new_representation, old_descriptors->GetFieldType(modify_index), | |
2365 *new_field_type); | |
2366 } | |
2367 Handle<Map> field_owner(old_map->FindFieldOwner(modify_index), isolate); | |
2368 | |
2369 GeneralizeFieldType(field_owner, modify_index, new_representation, | |
2370 new_field_type); | |
2371 DCHECK(old_descriptors->GetDetails(modify_index) | |
2372 .representation() | |
2373 .Equals(new_representation)); | |
2374 DCHECK( | |
2375 old_descriptors->GetFieldType(modify_index)->NowIs(new_field_type)); | |
2376 return old_map; | |
2331 } | 2377 } |
2332 Handle<Map> field_owner(old_map->FindFieldOwner(modify_index), isolate); | |
2333 | |
2334 GeneralizeFieldType(field_owner, modify_index, new_representation, | |
2335 new_field_type); | |
2336 DCHECK(old_descriptors->GetDetails(modify_index).representation().Equals( | |
2337 new_representation)); | |
2338 DCHECK(old_descriptors->GetFieldType(modify_index)->NowIs(new_field_type)); | |
2339 return old_map; | |
2340 } | 2378 } |
2341 | 2379 |
2342 // Check the state of the root map. | 2380 // Check the state of the root map. |
2343 Handle<Map> root_map(old_map->FindRootMap(), isolate); | 2381 Handle<Map> root_map(old_map->FindRootMap(), isolate); |
2344 if (!old_map->EquivalentToForTransition(*root_map)) { | 2382 if (!old_map->EquivalentToForTransition(*root_map)) { |
2345 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2383 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2384 new_kind, new_attributes, | |
2346 "GenAll_NotEquivalent"); | 2385 "GenAll_NotEquivalent"); |
2347 } | 2386 } |
2348 int root_nof = root_map->NumberOfOwnDescriptors(); | 2387 int root_nof = root_map->NumberOfOwnDescriptors(); |
2349 if (modify_index < root_nof) { | 2388 if (static_cast<unsigned>(modify_index) < static_cast<unsigned>(root_nof)) { |
2350 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2389 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
2390 if (old_details.kind() != new_kind || | |
2391 old_details.attributes() != new_attributes) { | |
2392 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | |
2393 new_kind, new_attributes, | |
2394 "GenAll_RootModification1"); | |
2395 } | |
2351 if ((old_details.type() != DATA && store_mode == FORCE_FIELD) || | 2396 if ((old_details.type() != DATA && store_mode == FORCE_FIELD) || |
2352 (old_details.type() == DATA && | 2397 (old_details.type() == DATA && |
2353 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || | 2398 (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) || |
2354 !new_representation.fits_into(old_details.representation())))) { | 2399 !new_representation.fits_into(old_details.representation())))) { |
2355 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2400 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2356 "GenAll_RootModification"); | 2401 new_kind, new_attributes, |
2402 "GenAll_RootModification2"); | |
2357 } | 2403 } |
2358 } | 2404 } |
2359 | 2405 |
2360 Handle<Map> target_map = root_map; | 2406 Handle<Map> target_map = root_map; |
2361 for (int i = root_nof; i < old_nof; ++i) { | 2407 for (int i = root_nof; i < old_nof; ++i) { |
2362 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2408 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2363 int j = target_map->SearchTransition(old_details.kind(), | 2409 PropertyKind next_kind; |
2364 old_descriptors->GetKey(i), | 2410 PropertyLocation next_location; |
2365 old_details.attributes()); | 2411 PropertyAttributes next_attributes; |
2412 if (modify_index == i) { | |
2413 DCHECK_EQ(FORCE_FIELD, store_mode); | |
2414 next_kind = new_kind; | |
2415 next_location = store_mode == FORCE_FIELD ? kField : kDescriptor; | |
Toon Verwaest
2015/01/30 13:02:53
isn't this guaranteed above?
Igor Sheludko
2015/02/11 16:06:00
Done.
| |
2416 next_attributes = new_attributes; | |
2417 } else { | |
2418 next_kind = old_details.kind(); | |
2419 next_location = old_details.location(); | |
2420 next_attributes = old_details.attributes(); | |
2421 } | |
2422 int j = target_map->SearchTransition(next_kind, old_descriptors->GetKey(i), | |
2423 next_attributes); | |
2366 if (j == TransitionArray::kNotFound) break; | 2424 if (j == TransitionArray::kNotFound) break; |
2367 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); | 2425 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); |
2368 Handle<DescriptorArray> tmp_descriptors = handle( | 2426 Handle<DescriptorArray> tmp_descriptors = handle( |
2369 tmp_map->instance_descriptors(), isolate); | 2427 tmp_map->instance_descriptors(), isolate); |
2370 | 2428 |
2371 // Check if target map is incompatible. | 2429 // Check if target map is incompatible. |
2372 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | 2430 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
2373 PropertyType old_type = old_details.type(); | 2431 DCHECK_EQ(next_kind, tmp_details.kind()); |
2374 PropertyType tmp_type = tmp_details.type(); | 2432 DCHECK_EQ(next_attributes, tmp_details.attributes()); |
2375 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); | 2433 if (next_kind == kAccessor && |
2376 if ((tmp_type == ACCESSOR_CONSTANT || old_type == ACCESSOR_CONSTANT) && | 2434 !EqualImmutableValues(old_descriptors->GetValue(i), |
2377 (tmp_type != old_type || | 2435 tmp_descriptors->GetValue(i))) { |
2378 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { | |
2379 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2436 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2437 new_kind, new_attributes, | |
2380 "GenAll_Incompatible"); | 2438 "GenAll_Incompatible"); |
2381 } | 2439 } |
2440 if (next_location == kField && tmp_details.location() == kDescriptor) break; | |
2441 | |
2382 Representation old_representation = old_details.representation(); | 2442 Representation old_representation = old_details.representation(); |
2383 Representation tmp_representation = tmp_details.representation(); | 2443 Representation tmp_representation = tmp_details.representation(); |
2384 if (!old_representation.fits_into(tmp_representation) || | 2444 if (!old_representation.fits_into(tmp_representation) || |
2385 (!new_representation.fits_into(tmp_representation) && | 2445 (!new_representation.fits_into(tmp_representation) && |
2386 modify_index == i)) { | 2446 modify_index == i)) { |
2387 break; | 2447 break; |
2388 } | 2448 } |
2389 if (tmp_type == DATA) { | 2449 |
2390 // Generalize the field type as necessary. | 2450 PropertyLocation old_location = old_details.location(); |
2391 Handle<HeapType> old_field_type = | 2451 PropertyLocation tmp_location = tmp_details.location(); |
2392 (old_type == DATA) ? handle(old_descriptors->GetFieldType(i), isolate) | 2452 if (tmp_location == kField) { |
2393 : old_descriptors->GetValue(i) | 2453 if (next_kind == kData) { |
2394 ->OptimalType(isolate, tmp_representation); | 2454 // Generalize the field type as necessary. |
2395 if (modify_index == i) { | 2455 Handle<HeapType> old_field_type = |
2396 old_field_type = GeneralizeFieldType( | 2456 (old_location == kField) |
2397 new_field_type, old_field_type, isolate); | 2457 ? handle(old_descriptors->GetFieldType(i), isolate) |
2458 : old_descriptors->GetValue(i) | |
2459 ->OptimalType(isolate, tmp_representation); | |
2460 if (modify_index == i) { | |
2461 old_field_type = | |
2462 GeneralizeFieldType(new_field_type, old_field_type, isolate); | |
2463 } | |
2464 GeneralizeFieldType(tmp_map, i, tmp_representation, old_field_type); | |
2398 } | 2465 } |
2399 GeneralizeFieldType(tmp_map, i, tmp_representation, old_field_type); | 2466 } else { |
Toon Verwaest
2015/01/30 13:02:53
else if
Igor Sheludko
2015/02/11 16:06:00
Done.
| |
2400 } else if (tmp_type == DATA_CONSTANT) { | 2467 if (old_location == kField || |
2401 if (old_type != DATA_CONSTANT || | 2468 !EqualImmutableValues(old_descriptors->GetValue(i), |
2402 old_descriptors->GetConstant(i) != tmp_descriptors->GetConstant(i)) { | 2469 tmp_descriptors->GetValue(i))) { |
2403 break; | 2470 break; |
2404 } | 2471 } |
2405 } else { | |
2406 DCHECK_EQ(tmp_type, old_type); | |
2407 DCHECK_EQ(tmp_descriptors->GetValue(i), old_descriptors->GetValue(i)); | |
2408 } | 2472 } |
2473 DCHECK(!tmp_map->is_deprecated()); | |
2409 target_map = tmp_map; | 2474 target_map = tmp_map; |
2410 } | 2475 } |
2411 | 2476 |
2412 // Directly change the map if the target map is more general. | 2477 // Directly change the map if the target map is more general. |
2413 Handle<DescriptorArray> target_descriptors( | 2478 Handle<DescriptorArray> target_descriptors( |
2414 target_map->instance_descriptors(), isolate); | 2479 target_map->instance_descriptors(), isolate); |
2415 int target_nof = target_map->NumberOfOwnDescriptors(); | 2480 int target_nof = target_map->NumberOfOwnDescriptors(); |
2416 if (target_nof == old_nof && | 2481 if (target_nof == old_nof && |
2417 (store_mode != FORCE_FIELD || | 2482 (store_mode != FORCE_FIELD || |
2418 target_descriptors->GetDetails(modify_index).type() == DATA)) { | 2483 (modify_index >= 0 && |
2419 DCHECK(modify_index < target_nof); | 2484 target_descriptors->GetDetails(modify_index).location() == kField))) { |
2420 DCHECK(new_representation.fits_into( | 2485 #ifdef DEBUG |
2421 target_descriptors->GetDetails(modify_index).representation())); | 2486 if (modify_index >= 0) { |
2422 DCHECK( | 2487 PropertyDetails details = target_descriptors->GetDetails(modify_index); |
2423 target_descriptors->GetDetails(modify_index).type() != DATA || | 2488 DCHECK_EQ(new_kind, details.kind()); |
2424 new_field_type->NowIs(target_descriptors->GetFieldType(modify_index))); | 2489 DCHECK_EQ(new_attributes, details.attributes()); |
2490 DCHECK(new_representation.fits_into(details.representation())); | |
2491 DCHECK(details.location() != kField || | |
2492 new_field_type->NowIs( | |
2493 target_descriptors->GetFieldType(modify_index))); | |
2494 } | |
2495 #endif | |
2425 return target_map; | 2496 return target_map; |
2426 } | 2497 } |
2427 | 2498 |
2428 // Find the last compatible target map in the transition tree. | 2499 // Find the last compatible target map in the transition tree. |
2429 for (int i = target_nof; i < old_nof; ++i) { | 2500 for (int i = target_nof; i < old_nof; ++i) { |
2430 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2501 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2431 int j = target_map->SearchTransition(old_details.kind(), | 2502 PropertyKind next_kind; |
2432 old_descriptors->GetKey(i), | 2503 PropertyAttributes next_attributes; |
2433 old_details.attributes()); | 2504 if (modify_index == i) { |
2505 next_kind = new_kind; | |
2506 next_attributes = new_attributes; | |
2507 } else { | |
2508 next_kind = old_details.kind(); | |
2509 next_attributes = old_details.attributes(); | |
2510 } | |
2511 int j = target_map->SearchTransition(next_kind, old_descriptors->GetKey(i), | |
2512 next_attributes); | |
2434 if (j == TransitionArray::kNotFound) break; | 2513 if (j == TransitionArray::kNotFound) break; |
2435 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); | 2514 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); |
2436 Handle<DescriptorArray> tmp_descriptors( | 2515 Handle<DescriptorArray> tmp_descriptors( |
2437 tmp_map->instance_descriptors(), isolate); | 2516 tmp_map->instance_descriptors(), isolate); |
2438 | 2517 |
2439 // Check if target map is compatible. | 2518 // Check if target map is compatible. |
2440 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); | 2519 PropertyDetails tmp_details = tmp_descriptors->GetDetails(i); |
2441 DCHECK_EQ(old_details.attributes(), tmp_details.attributes()); | 2520 DCHECK_EQ(next_kind, tmp_details.kind()); |
2442 if ((tmp_details.type() == ACCESSOR_CONSTANT || | 2521 DCHECK_EQ(next_attributes, tmp_details.attributes()); |
2443 old_details.type() == ACCESSOR_CONSTANT) && | 2522 if (next_kind == kAccessor && |
2444 (tmp_details.type() != old_details.type() || | 2523 !EqualImmutableValues(old_descriptors->GetValue(i), |
2445 tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { | 2524 tmp_descriptors->GetValue(i))) { |
2446 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2525 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2526 new_kind, new_attributes, | |
2447 "GenAll_Incompatible"); | 2527 "GenAll_Incompatible"); |
2448 } | 2528 } |
2529 DCHECK(!tmp_map->is_deprecated()); | |
2449 target_map = tmp_map; | 2530 target_map = tmp_map; |
2450 } | 2531 } |
2451 target_nof = target_map->NumberOfOwnDescriptors(); | 2532 target_nof = target_map->NumberOfOwnDescriptors(); |
2452 target_descriptors = handle(target_map->instance_descriptors(), isolate); | 2533 target_descriptors = handle(target_map->instance_descriptors(), isolate); |
2453 | 2534 |
2454 // Allocate a new descriptor array large enough to hold the required | 2535 // Allocate a new descriptor array large enough to hold the required |
2455 // descriptors, with minimally the exact same size as the old descriptor | 2536 // descriptors, with minimally the exact same size as the old descriptor |
2456 // array. | 2537 // array. |
2457 int new_slack = Max( | 2538 int new_slack = Max( |
2458 old_nof, old_descriptors->number_of_descriptors()) - old_nof; | 2539 old_nof, old_descriptors->number_of_descriptors()) - old_nof; |
2459 Handle<DescriptorArray> new_descriptors = DescriptorArray::Allocate( | 2540 Handle<DescriptorArray> new_descriptors = DescriptorArray::Allocate( |
2460 isolate, old_nof, new_slack); | 2541 isolate, old_nof, new_slack); |
2461 DCHECK(new_descriptors->length() > target_descriptors->length() || | 2542 DCHECK(new_descriptors->length() > target_descriptors->length() || |
2462 new_descriptors->NumberOfSlackDescriptors() > 0 || | 2543 new_descriptors->NumberOfSlackDescriptors() > 0 || |
2463 new_descriptors->number_of_descriptors() == | 2544 new_descriptors->number_of_descriptors() == |
2464 old_descriptors->number_of_descriptors()); | 2545 old_descriptors->number_of_descriptors()); |
2465 DCHECK(new_descriptors->number_of_descriptors() == old_nof); | 2546 DCHECK(new_descriptors->number_of_descriptors() == old_nof); |
2466 | 2547 |
2467 // 0 -> |root_nof| | 2548 // 0 -> |root_nof| |
2468 int current_offset = 0; | 2549 int current_offset = 0; |
2469 for (int i = 0; i < root_nof; ++i) { | 2550 for (int i = 0; i < root_nof; ++i) { |
2470 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2551 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2471 if (old_details.type() == DATA) { | 2552 if (old_details.location() == kField) { |
2472 current_offset += old_details.field_width_in_words(); | 2553 current_offset += old_details.field_width_in_words(); |
2473 } | 2554 } |
2474 Descriptor d(handle(old_descriptors->GetKey(i), isolate), | 2555 Descriptor d(handle(old_descriptors->GetKey(i), isolate), |
2475 handle(old_descriptors->GetValue(i), isolate), | 2556 handle(old_descriptors->GetValue(i), isolate), |
2476 old_details); | 2557 old_details); |
2477 new_descriptors->Set(i, &d); | 2558 new_descriptors->Set(i, &d); |
2478 } | 2559 } |
2479 | 2560 |
2480 // |root_nof| -> |target_nof| | 2561 // |root_nof| -> |target_nof| |
2481 for (int i = root_nof; i < target_nof; ++i) { | 2562 for (int i = root_nof; i < target_nof; ++i) { |
2482 Handle<Name> target_key(target_descriptors->GetKey(i), isolate); | 2563 Handle<Name> target_key(target_descriptors->GetKey(i), isolate); |
2483 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2564 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2484 PropertyDetails target_details = target_descriptors->GetDetails(i); | 2565 PropertyDetails target_details = target_descriptors->GetDetails(i); |
2485 target_details = target_details.CopyWithRepresentation( | 2566 |
2567 // Merge old_descriptor entry, target_descriptor entry and modified details | |
2568 // together. | |
2569 PropertyKind merged_kind = target_details.kind(); | |
Toon Verwaest
2015/01/30 13:02:53
I wouldn't call this merged_, since you aren't mer
| |
2570 | |
2571 PropertyLocation merged_location = | |
2572 old_details.location() == kField || | |
2573 target_details.location() == kField || | |
2574 !EqualImmutableValues(target_descriptors->GetValue(i), | |
2575 old_descriptors->GetValue(i)) | |
2576 ? kField | |
2577 : kDescriptor; | |
2578 | |
2579 Representation merged_representation = | |
2486 old_details.representation().generalize( | 2580 old_details.representation().generalize( |
2487 target_details.representation())); | 2581 target_details.representation()); |
2582 | |
2583 PropertyAttributes merged_attributes = target_details.attributes(); | |
2584 | |
2488 if (modify_index == i) { | 2585 if (modify_index == i) { |
2489 target_details = target_details.CopyWithRepresentation( | 2586 DCHECK_EQ(FORCE_FIELD, store_mode); |
2490 new_representation.generalize(target_details.representation())); | 2587 merged_kind = new_kind; |
2588 merged_location = kField; | |
2589 merged_representation = | |
2590 new_representation.generalize(merged_representation); | |
2591 merged_attributes = new_attributes; | |
Toon Verwaest
2015/01/30 13:02:53
Same as above
| |
2491 } | 2592 } |
2492 DCHECK_EQ(old_details.attributes(), target_details.attributes()); | 2593 DCHECK_EQ(merged_kind, target_details.kind()); |
2493 if (old_details.type() == DATA || target_details.type() == DATA || | 2594 DCHECK_EQ(merged_attributes, target_details.attributes()); |
2494 (modify_index == i && store_mode == FORCE_FIELD) || | 2595 |
2495 (target_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { | 2596 if (merged_location == kField) { |
2496 Handle<HeapType> old_field_type = | 2597 if (merged_kind == kData) { |
2497 (old_details.type() == DATA) | 2598 Handle<HeapType> old_field_type = |
2498 ? handle(old_descriptors->GetFieldType(i), isolate) | 2599 (old_details.type() == DATA) |
2499 : old_descriptors->GetValue(i) | 2600 ? handle(old_descriptors->GetFieldType(i), isolate) |
2500 ->OptimalType(isolate, target_details.representation()); | 2601 : old_descriptors->GetValue(i) |
2501 Handle<HeapType> target_field_type = | 2602 ->OptimalType(isolate, merged_representation); |
2502 (target_details.type() == DATA) | 2603 Handle<HeapType> target_field_type = |
2503 ? handle(target_descriptors->GetFieldType(i), isolate) | 2604 (target_details.type() == DATA) |
2504 : target_descriptors->GetValue(i) | 2605 ? handle(target_descriptors->GetFieldType(i), isolate) |
2505 ->OptimalType(isolate, target_details.representation()); | 2606 : target_descriptors->GetValue(i) |
2506 target_field_type = GeneralizeFieldType( | 2607 ->OptimalType(isolate, merged_representation); |
2507 target_field_type, old_field_type, isolate); | 2608 target_field_type = |
2508 if (modify_index == i) { | 2609 GeneralizeFieldType(target_field_type, old_field_type, isolate); |
2509 target_field_type = GeneralizeFieldType( | 2610 if (modify_index == i) { |
2510 target_field_type, new_field_type, isolate); | 2611 target_field_type = |
2612 GeneralizeFieldType(target_field_type, new_field_type, isolate); | |
2613 } | |
2614 DataDescriptor d(target_key, current_offset, target_field_type, | |
2615 merged_attributes, merged_representation); | |
2616 current_offset += d.GetDetails().field_width_in_words(); | |
2617 new_descriptors->Set(i, &d); | |
2618 } else { | |
2619 UNIMPLEMENTED(); // TODO(ishell): implement. | |
2511 } | 2620 } |
2512 DataDescriptor d(target_key, current_offset, target_field_type, | |
2513 target_details.attributes(), | |
2514 target_details.representation()); | |
2515 current_offset += d.GetDetails().field_width_in_words(); | |
2516 new_descriptors->Set(i, &d); | |
2517 } else { | 2621 } else { |
2518 DCHECK_NE(DATA, target_details.type()); | 2622 PropertyDetails details(merged_attributes, merged_kind, merged_location, |
2519 Descriptor d(target_key, | 2623 merged_representation); |
2520 handle(target_descriptors->GetValue(i), isolate), | 2624 Descriptor d(target_key, handle(target_descriptors->GetValue(i), isolate), |
2521 target_details); | 2625 details); |
2522 new_descriptors->Set(i, &d); | 2626 new_descriptors->Set(i, &d); |
2523 } | 2627 } |
2524 } | 2628 } |
2525 | 2629 |
2526 // |target_nof| -> |old_nof| | 2630 // |target_nof| -> |old_nof| |
2527 for (int i = target_nof; i < old_nof; ++i) { | 2631 for (int i = target_nof; i < old_nof; ++i) { |
2528 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2632 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2529 Handle<Name> old_key(old_descriptors->GetKey(i), isolate); | 2633 Handle<Name> old_key(old_descriptors->GetKey(i), isolate); |
2634 | |
2635 // Merge old_descriptor entry and modified details together. | |
2636 PropertyKind merged_kind = old_details.kind(); | |
2637 PropertyLocation merged_location = old_details.location(); | |
2638 Representation merged_representation = old_details.representation(); | |
2639 PropertyAttributes merged_attributes = old_details.attributes(); | |
Toon Verwaest
2015/01/30 13:02:53
Same for all above
| |
2640 | |
2530 if (modify_index == i) { | 2641 if (modify_index == i) { |
2531 old_details = old_details.CopyWithRepresentation( | 2642 DCHECK_EQ(FORCE_FIELD, store_mode); |
2532 new_representation.generalize(old_details.representation())); | 2643 merged_kind = new_kind; |
2644 merged_location = kField; | |
2645 merged_representation = | |
2646 new_representation.generalize(merged_representation); | |
2647 merged_attributes = new_attributes; | |
2533 } | 2648 } |
2534 if (old_details.type() == DATA) { | 2649 |
2535 Handle<HeapType> old_field_type( | 2650 if (merged_location == kField) { |
2536 old_descriptors->GetFieldType(i), isolate); | 2651 if (merged_kind == kData) { |
2537 if (modify_index == i) { | 2652 Handle<HeapType> old_field_type = |
2538 old_field_type = GeneralizeFieldType( | 2653 (old_details.type() == DATA) |
2539 old_field_type, new_field_type, isolate); | 2654 ? handle(old_descriptors->GetFieldType(i), isolate) |
2540 } | 2655 : old_descriptors->GetValue(i) |
2541 DataDescriptor d(old_key, current_offset, old_field_type, | 2656 ->OptimalType(isolate, merged_representation); |
2542 old_details.attributes(), old_details.representation()); | 2657 if (modify_index == i) { |
2543 current_offset += d.GetDetails().field_width_in_words(); | 2658 old_field_type = |
2544 new_descriptors->Set(i, &d); | 2659 GeneralizeFieldType(old_field_type, new_field_type, isolate); |
2545 } else { | 2660 } |
2546 DCHECK(old_details.type() == DATA_CONSTANT || | 2661 DataDescriptor d(old_key, current_offset, old_field_type, |
2547 old_details.type() == ACCESSOR_CONSTANT); | 2662 merged_attributes, merged_representation); |
2548 if (modify_index == i && store_mode == FORCE_FIELD) { | |
2549 DataDescriptor d( | |
2550 old_key, current_offset, | |
2551 GeneralizeFieldType(old_descriptors->GetValue(i)->OptimalType( | |
2552 isolate, old_details.representation()), | |
2553 new_field_type, isolate), | |
2554 old_details.attributes(), old_details.representation()); | |
2555 current_offset += d.GetDetails().field_width_in_words(); | 2663 current_offset += d.GetDetails().field_width_in_words(); |
2556 new_descriptors->Set(i, &d); | 2664 new_descriptors->Set(i, &d); |
2557 } else { | 2665 } else { |
2558 DCHECK_NE(DATA, old_details.type()); | 2666 UNIMPLEMENTED(); // TODO(ishell): implement. |
2559 Descriptor d(old_key, | |
2560 handle(old_descriptors->GetValue(i), isolate), | |
2561 old_details); | |
2562 new_descriptors->Set(i, &d); | |
2563 } | 2667 } |
2668 } else { | |
2669 PropertyDetails details(merged_attributes, merged_kind, merged_location, | |
2670 merged_representation); | |
2671 Descriptor d(old_key, handle(old_descriptors->GetValue(i), isolate), | |
2672 details); | |
2673 new_descriptors->Set(i, &d); | |
2564 } | 2674 } |
2565 } | 2675 } |
2566 | 2676 |
2567 new_descriptors->Sort(); | 2677 new_descriptors->Sort(); |
2568 | 2678 |
2569 DCHECK(store_mode != FORCE_FIELD || | 2679 DCHECK(store_mode != FORCE_FIELD || |
2570 new_descriptors->GetDetails(modify_index).type() == DATA); | 2680 new_descriptors->GetDetails(modify_index).location() == kField); |
2571 | 2681 |
2572 Handle<Map> split_map(root_map->FindLastMatchMap( | 2682 Handle<Map> split_map(root_map->FindLastMatchMap( |
2573 root_nof, old_nof, *new_descriptors), isolate); | 2683 root_nof, old_nof, *new_descriptors), isolate); |
2574 int split_nof = split_map->NumberOfOwnDescriptors(); | 2684 int split_nof = split_map->NumberOfOwnDescriptors(); |
2575 DCHECK_NE(old_nof, split_nof); | 2685 DCHECK_NE(old_nof, split_nof); |
2576 | 2686 |
2577 Handle<LayoutDescriptor> new_layout_descriptor = | 2687 Handle<LayoutDescriptor> new_layout_descriptor = |
2578 LayoutDescriptor::New(split_map, new_descriptors, old_nof); | 2688 LayoutDescriptor::New(split_map, new_descriptors, old_nof); |
2579 PropertyDetails split_prop_details = old_descriptors->GetDetails(split_nof); | 2689 |
2690 PropertyKind split_kind; | |
2691 PropertyAttributes split_attributes; | |
2692 if (modify_index == split_nof) { | |
2693 split_kind = new_kind; | |
2694 split_attributes = new_attributes; | |
2695 } else { | |
2696 PropertyDetails split_prop_details = old_descriptors->GetDetails(split_nof); | |
2697 split_kind = split_prop_details.kind(); | |
2698 split_attributes = split_prop_details.attributes(); | |
2699 } | |
2580 bool transition_target_deprecated = split_map->DeprecateTarget( | 2700 bool transition_target_deprecated = split_map->DeprecateTarget( |
2581 split_prop_details.kind(), old_descriptors->GetKey(split_nof), | 2701 split_kind, old_descriptors->GetKey(split_nof), split_attributes, |
2582 split_prop_details.attributes(), *new_descriptors, | 2702 *new_descriptors, *new_layout_descriptor); |
2583 *new_layout_descriptor); | |
2584 | 2703 |
2585 // If |transition_target_deprecated| is true then the transition array | 2704 // If |transition_target_deprecated| is true then the transition array |
2586 // already contains entry for given descriptor. This means that the transition | 2705 // already contains entry for given descriptor. This means that the transition |
2587 // could be inserted regardless of whether transitions array is full or not. | 2706 // could be inserted regardless of whether transitions array is full or not. |
2588 if (!transition_target_deprecated && !split_map->CanHaveMoreTransitions()) { | 2707 if (!transition_target_deprecated && !split_map->CanHaveMoreTransitions()) { |
2589 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2708 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
2709 new_kind, new_attributes, | |
2590 "GenAll_CantHaveMoreTransitions"); | 2710 "GenAll_CantHaveMoreTransitions"); |
2591 } | 2711 } |
2592 | 2712 |
2593 if (FLAG_trace_generalization) { | 2713 if (FLAG_trace_generalization && modify_index >= 0) { |
2594 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2714 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
2595 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); | 2715 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); |
2596 Handle<HeapType> old_field_type = | 2716 Handle<HeapType> old_field_type = |
2597 (old_details.type() == DATA) | 2717 (old_details.type() == DATA) |
2598 ? handle(old_descriptors->GetFieldType(modify_index), isolate) | 2718 ? handle(old_descriptors->GetFieldType(modify_index), isolate) |
2599 : HeapType::Constant( | 2719 : HeapType::Constant( |
2600 handle(old_descriptors->GetValue(modify_index), isolate), | 2720 handle(old_descriptors->GetValue(modify_index), isolate), |
2601 isolate); | 2721 isolate); |
2602 Handle<HeapType> new_field_type = | 2722 Handle<HeapType> new_field_type = |
2603 (new_details.type() == DATA) | 2723 (new_details.type() == DATA) |
2604 ? handle(new_descriptors->GetFieldType(modify_index), isolate) | 2724 ? handle(new_descriptors->GetFieldType(modify_index), isolate) |
2605 : HeapType::Constant( | 2725 : HeapType::Constant( |
2606 handle(new_descriptors->GetValue(modify_index), isolate), | 2726 handle(new_descriptors->GetValue(modify_index), isolate), |
2607 isolate); | 2727 isolate); |
2608 old_map->PrintGeneralization( | 2728 old_map->PrintGeneralization( |
2609 stdout, "", modify_index, split_nof, old_nof, | 2729 stdout, "", modify_index, split_nof, old_nof, |
2610 old_details.type() == DATA_CONSTANT && store_mode == FORCE_FIELD, | 2730 old_details.location() == kDescriptor && store_mode == FORCE_FIELD, |
2611 old_details.representation(), new_details.representation(), | 2731 old_details.representation(), new_details.representation(), |
2612 *old_field_type, *new_field_type); | 2732 *old_field_type, *new_field_type); |
2613 } | 2733 } |
2614 | 2734 |
2615 // Add missing transitions. | 2735 // Add missing transitions. |
2616 Handle<Map> new_map = split_map; | 2736 Handle<Map> new_map = split_map; |
2617 for (int i = split_nof; i < old_nof; ++i) { | 2737 for (int i = split_nof; i < old_nof; ++i) { |
2618 new_map = CopyInstallDescriptors(new_map, i, new_descriptors, | 2738 new_map = CopyInstallDescriptors(new_map, i, new_descriptors, |
2619 new_layout_descriptor); | 2739 new_layout_descriptor); |
2620 } | 2740 } |
2621 new_map->set_owns_descriptors(true); | 2741 new_map->set_owns_descriptors(true); |
2622 return new_map; | 2742 return new_map; |
2623 } | 2743 } |
2624 | 2744 |
2625 | 2745 |
2626 // Generalize the representation of all DATA descriptors. | 2746 // Generalize the representation of all DATA descriptors. |
2627 Handle<Map> Map::GeneralizeAllFieldRepresentations( | 2747 Handle<Map> Map::GeneralizeAllFieldRepresentations( |
2628 Handle<Map> map) { | 2748 Handle<Map> map) { |
2629 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 2749 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
2630 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { | 2750 for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) { |
2631 if (descriptors->GetDetails(i).type() == DATA) { | 2751 PropertyDetails details = descriptors->GetDetails(i); |
2632 map = GeneralizeRepresentation(map, i, Representation::Tagged(), | 2752 if (details.type() == DATA) { |
2633 HeapType::Any(map->GetIsolate()), | 2753 map = ReconfigureProperty(map, i, kData, details.attributes(), |
2634 FORCE_FIELD); | 2754 Representation::Tagged(), |
2755 HeapType::Any(map->GetIsolate()), FORCE_FIELD); | |
2635 } | 2756 } |
2636 } | 2757 } |
2637 return map; | 2758 return map; |
2638 } | 2759 } |
2639 | 2760 |
2640 | 2761 |
2641 // static | 2762 // static |
2642 MaybeHandle<Map> Map::TryUpdate(Handle<Map> map) { | 2763 MaybeHandle<Map> Map::TryUpdate(Handle<Map> map) { |
2643 Handle<Map> proto_map(map); | 2764 Handle<Map> proto_map(map); |
2644 while (proto_map->prototype()->IsJSObject()) { | 2765 while (proto_map->prototype()->IsJSObject()) { |
2645 Handle<JSObject> holder(JSObject::cast(proto_map->prototype())); | 2766 Handle<JSObject> holder(JSObject::cast(proto_map->prototype())); |
2646 proto_map = Handle<Map>(holder->map()); | 2767 proto_map = Handle<Map>(holder->map()); |
2647 if (proto_map->is_deprecated() && JSObject::TryMigrateInstance(holder)) { | 2768 if (proto_map->is_deprecated() && JSObject::TryMigrateInstance(holder)) { |
2648 proto_map = Handle<Map>(holder->map()); | 2769 proto_map = Handle<Map>(holder->map()); |
2649 } | 2770 } |
2650 } | 2771 } |
2651 return TryUpdateInternal(map); | 2772 return TryUpdateInternal(map); |
2652 } | 2773 } |
2653 | 2774 |
2654 | 2775 |
2655 // static | 2776 // static |
2656 Handle<Map> Map::Update(Handle<Map> map) { | 2777 Handle<Map> Map::Update(Handle<Map> map) { |
2657 if (!map->is_deprecated()) return map; | 2778 if (!map->is_deprecated()) return map; |
2658 return GeneralizeRepresentation(map, 0, Representation::None(), | 2779 return ReconfigureProperty(map, -1, kData, NONE, Representation::None(), |
2659 HeapType::None(map->GetIsolate()), | 2780 HeapType::None(map->GetIsolate()), |
2660 ALLOW_IN_DESCRIPTOR); | 2781 ALLOW_IN_DESCRIPTOR); |
2661 } | 2782 } |
2662 | 2783 |
2663 | 2784 |
2664 // static | 2785 // static |
2665 MaybeHandle<Map> Map::TryUpdateInternal(Handle<Map> old_map) { | 2786 MaybeHandle<Map> Map::TryUpdateInternal(Handle<Map> old_map) { |
2666 DisallowHeapAllocation no_allocation; | 2787 DisallowHeapAllocation no_allocation; |
2667 DisallowDeoptimization no_deoptimization(old_map->GetIsolate()); | 2788 DisallowDeoptimization no_deoptimization(old_map->GetIsolate()); |
2668 | 2789 |
2669 if (!old_map->is_deprecated()) return old_map; | 2790 if (!old_map->is_deprecated()) return old_map; |
2670 | 2791 |
(...skipping 3091 matching lines...) Loading... | |
5762 return result; | 5883 return result; |
5763 } | 5884 } |
5764 | 5885 |
5765 | 5886 |
5766 int Map::NextFreePropertyIndex() { | 5887 int Map::NextFreePropertyIndex() { |
5767 int free_index = 0; | 5888 int free_index = 0; |
5768 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 5889 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
5769 DescriptorArray* descs = instance_descriptors(); | 5890 DescriptorArray* descs = instance_descriptors(); |
5770 for (int i = 0; i < number_of_own_descriptors; i++) { | 5891 for (int i = 0; i < number_of_own_descriptors; i++) { |
5771 PropertyDetails details = descs->GetDetails(i); | 5892 PropertyDetails details = descs->GetDetails(i); |
5772 if (details.type() == DATA) { | 5893 if (details.location() == kField) { |
5773 int candidate = details.field_index() + details.field_width_in_words(); | 5894 int candidate = details.field_index() + details.field_width_in_words(); |
5774 if (candidate > free_index) free_index = candidate; | 5895 if (candidate > free_index) free_index = candidate; |
5775 } | 5896 } |
5776 } | 5897 } |
5777 return free_index; | 5898 return free_index; |
5778 } | 5899 } |
5779 | 5900 |
5780 | 5901 |
5781 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { | 5902 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { |
5782 int len = array->length(); | 5903 int len = array->length(); |
(...skipping 974 matching lines...) Loading... | |
6757 Handle<LayoutDescriptor> full_layout_descriptor) { | 6878 Handle<LayoutDescriptor> full_layout_descriptor) { |
6758 DCHECK(descriptors->IsSortedNoDuplicates()); | 6879 DCHECK(descriptors->IsSortedNoDuplicates()); |
6759 | 6880 |
6760 Handle<Map> result = CopyDropDescriptors(map); | 6881 Handle<Map> result = CopyDropDescriptors(map); |
6761 | 6882 |
6762 result->set_instance_descriptors(*descriptors); | 6883 result->set_instance_descriptors(*descriptors); |
6763 result->SetNumberOfOwnDescriptors(new_descriptor + 1); | 6884 result->SetNumberOfOwnDescriptors(new_descriptor + 1); |
6764 | 6885 |
6765 int unused_property_fields = map->unused_property_fields(); | 6886 int unused_property_fields = map->unused_property_fields(); |
6766 PropertyDetails details = descriptors->GetDetails(new_descriptor); | 6887 PropertyDetails details = descriptors->GetDetails(new_descriptor); |
6767 if (details.type() == DATA) { | 6888 if (details.location() == kField) { |
6768 unused_property_fields = map->unused_property_fields() - 1; | 6889 unused_property_fields = map->unused_property_fields() - 1; |
6769 if (unused_property_fields < 0) { | 6890 if (unused_property_fields < 0) { |
6770 unused_property_fields += JSObject::kFieldsAdded; | 6891 unused_property_fields += JSObject::kFieldsAdded; |
6771 } | 6892 } |
6772 } | 6893 } |
6773 result->set_unused_property_fields(unused_property_fields); | 6894 result->set_unused_property_fields(unused_property_fields); |
6774 | 6895 |
6775 if (FLAG_unbox_double_fields) { | 6896 if (FLAG_unbox_double_fields) { |
6776 Handle<LayoutDescriptor> layout_descriptor = | 6897 Handle<LayoutDescriptor> layout_descriptor = |
6777 LayoutDescriptor::AppendIfFastOrUseFull(map, details, | 6898 LayoutDescriptor::AppendIfFastOrUseFull(map, details, |
(...skipping 190 matching lines...) Loading... | |
6968 if (map->is_dictionary_map()) return map; | 7089 if (map->is_dictionary_map()) return map; |
6969 | 7090 |
6970 // Migrate to the newest map before storing the property. | 7091 // Migrate to the newest map before storing the property. |
6971 map = Update(map); | 7092 map = Update(map); |
6972 | 7093 |
6973 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 7094 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
6974 | 7095 |
6975 if (descriptors->CanHoldValue(descriptor, *value)) return map; | 7096 if (descriptors->CanHoldValue(descriptor, *value)) return map; |
6976 | 7097 |
6977 Isolate* isolate = map->GetIsolate(); | 7098 Isolate* isolate = map->GetIsolate(); |
7099 PropertyAttributes attributes = | |
7100 descriptors->GetDetails(descriptor).attributes(); | |
6978 Representation representation = value->OptimalRepresentation(); | 7101 Representation representation = value->OptimalRepresentation(); |
6979 Handle<HeapType> type = value->OptimalType(isolate, representation); | 7102 Handle<HeapType> type = value->OptimalType(isolate, representation); |
6980 | 7103 |
6981 return GeneralizeRepresentation(map, descriptor, representation, type, | 7104 return ReconfigureProperty(map, descriptor, kData, attributes, representation, |
6982 FORCE_FIELD); | 7105 type, FORCE_FIELD); |
6983 } | 7106 } |
6984 | 7107 |
6985 | 7108 |
6986 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, | 7109 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, |
6987 Handle<Object> value, | 7110 Handle<Object> value, |
6988 PropertyAttributes attributes, | 7111 PropertyAttributes attributes, |
6989 StoreFromKeyed store_mode) { | 7112 StoreFromKeyed store_mode) { |
6990 // Dictionary maps can always have additional data properties. | 7113 // Dictionary maps can always have additional data properties. |
6991 if (map->is_dictionary_map()) return map; | 7114 if (map->is_dictionary_map()) return map; |
6992 | 7115 |
(...skipping 36 matching lines...) Loading... | |
7029 } | 7152 } |
7030 #endif | 7153 #endif |
7031 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, | 7154 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, |
7032 "TooManyFastProperties"); | 7155 "TooManyFastProperties"); |
7033 } | 7156 } |
7034 | 7157 |
7035 return result; | 7158 return result; |
7036 } | 7159 } |
7037 | 7160 |
7038 | 7161 |
7039 Handle<Map> Map::ReconfigureDataProperty(Handle<Map> map, int descriptor, | 7162 Handle<Map> Map::ReconfigureExistingProperty(Handle<Map> map, int descriptor, |
7040 PropertyAttributes attributes) { | 7163 PropertyKind kind, |
7164 PropertyAttributes attributes) { | |
7041 // Dictionaries have to be reconfigured in-place. | 7165 // Dictionaries have to be reconfigured in-place. |
7042 DCHECK(!map->is_dictionary_map()); | 7166 DCHECK(!map->is_dictionary_map()); |
7043 | 7167 |
7044 // For now, give up on transitioning and just create a unique map. | 7168 if (!map->GetBackPointer()->IsMap()) { |
7045 // TODO(verwaest/ishell): Cache transitions with different attributes. | 7169 // There is no benefit from reconstructing transition tree for maps without |
7046 return CopyGeneralizeAllRepresentations( | 7170 // back pointers. |
7047 map, descriptor, FORCE_FIELD, attributes, "GenAll_AttributesMismatch"); | 7171 return CopyGeneralizeAllRepresentations( |
7172 map, descriptor, FORCE_FIELD, kind, attributes, | |
7173 "GenAll_AttributesMismatchProtoMap"); | |
7174 } | |
7175 | |
7176 if (FLAG_trace_generalization) { | |
7177 map->PrintReconfiguration(stdout, descriptor, kind, attributes); | |
7178 } | |
7179 | |
7180 Isolate* isolate = map->GetIsolate(); | |
7181 Handle<Map> new_map = ReconfigureProperty( | |
7182 map, descriptor, kind, attributes, Representation::None(), | |
7183 HeapType::None(isolate), FORCE_FIELD); | |
7184 return new_map; | |
7048 } | 7185 } |
7049 | 7186 |
7050 | 7187 |
7051 Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, | 7188 Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, |
7052 Handle<Name> name, | 7189 Handle<Name> name, |
7053 AccessorComponent component, | 7190 AccessorComponent component, |
7054 Handle<Object> accessor, | 7191 Handle<Object> accessor, |
7055 PropertyAttributes attributes) { | 7192 PropertyAttributes attributes) { |
7056 Isolate* isolate = name->GetIsolate(); | 7193 Isolate* isolate = name->GetIsolate(); |
7057 | 7194 |
(...skipping 9820 matching lines...) Loading... | |
16878 Handle<DependentCode> codes = | 17015 Handle<DependentCode> codes = |
16879 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 17016 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), |
16880 DependentCode::kPropertyCellChangedGroup, | 17017 DependentCode::kPropertyCellChangedGroup, |
16881 info->object_wrapper()); | 17018 info->object_wrapper()); |
16882 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 17019 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
16883 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 17020 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
16884 cell, info->zone()); | 17021 cell, info->zone()); |
16885 } | 17022 } |
16886 | 17023 |
16887 } } // namespace v8::internal | 17024 } } // namespace v8::internal |
OLD | NEW |