Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(184)

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

Powered by Google App Engine
This is Rietveld 408576698