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