Chromium Code Reviews

Side by Side Diff: src/objects.cc

Issue 888623002: Property reconfiguring implemented. Tests added. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
OLDNEW
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...)
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...)
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...)
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...)
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...)
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...)
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...)
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...)
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...)
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | test/cctest/test-migrations.cc » ('J')

Powered by Google App Engine