| 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 1930 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1941 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) { | 1941 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) { |
| 1942 if (object->map() == *new_map) return; | 1942 if (object->map() == *new_map) return; |
| 1943 if (object->HasFastProperties()) { | 1943 if (object->HasFastProperties()) { |
| 1944 if (!new_map->is_dictionary_map()) { | 1944 if (!new_map->is_dictionary_map()) { |
| 1945 Handle<Map> old_map(object->map()); | 1945 Handle<Map> old_map(object->map()); |
| 1946 MigrateFastToFast(object, new_map); | 1946 MigrateFastToFast(object, new_map); |
| 1947 if (old_map->is_prototype_map()) { | 1947 if (old_map->is_prototype_map()) { |
| 1948 // Clear out the old descriptor array to avoid problems to sharing | 1948 // Clear out the old descriptor array to avoid problems to sharing |
| 1949 // the descriptor array without using an explicit. | 1949 // the descriptor array without using an explicit. |
| 1950 old_map->InitializeDescriptors( | 1950 old_map->InitializeDescriptors( |
| 1951 old_map->GetHeap()->empty_descriptor_array()); | 1951 old_map->GetHeap()->empty_descriptor_array(), |
| 1952 LayoutDescriptor::FastPointerLayout()); |
| 1952 // Ensure that no transition was inserted for prototype migrations. | 1953 // Ensure that no transition was inserted for prototype migrations. |
| 1953 DCHECK(!old_map->HasTransitionArray()); | 1954 DCHECK(!old_map->HasTransitionArray()); |
| 1954 DCHECK(new_map->GetBackPointer()->IsUndefined()); | 1955 DCHECK(new_map->GetBackPointer()->IsUndefined()); |
| 1955 } | 1956 } |
| 1956 } else { | 1957 } else { |
| 1957 MigrateFastToSlow(object, new_map, 0); | 1958 MigrateFastToSlow(object, new_map, 0); |
| 1958 } | 1959 } |
| 1959 } else { | 1960 } else { |
| 1960 // For slow-to-fast migrations JSObject::TransformToFastProperties() | 1961 // For slow-to-fast migrations JSObject::TransformToFastProperties() |
| 1961 // must be used instead. | 1962 // must be used instead. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2000 | 2001 |
| 2001 int total_size = number_of_fields + unused; | 2002 int total_size = number_of_fields + unused; |
| 2002 int external = total_size - inobject; | 2003 int external = total_size - inobject; |
| 2003 | 2004 |
| 2004 if (number_of_fields != old_number_of_fields && | 2005 if (number_of_fields != old_number_of_fields && |
| 2005 new_map->GetBackPointer() == *old_map) { | 2006 new_map->GetBackPointer() == *old_map) { |
| 2006 PropertyDetails details = new_map->GetLastDescriptorDetails(); | 2007 PropertyDetails details = new_map->GetLastDescriptorDetails(); |
| 2007 | 2008 |
| 2008 if (old_map->unused_property_fields() > 0) { | 2009 if (old_map->unused_property_fields() > 0) { |
| 2009 if (details.representation().IsDouble()) { | 2010 if (details.representation().IsDouble()) { |
| 2010 Handle<Object> value = isolate->factory()->NewHeapNumber(0, MUTABLE); | |
| 2011 FieldIndex index = | 2011 FieldIndex index = |
| 2012 FieldIndex::ForDescriptor(*new_map, new_map->LastAdded()); | 2012 FieldIndex::ForDescriptor(*new_map, new_map->LastAdded()); |
| 2013 object->FastPropertyAtPut(index, *value); | 2013 if (new_map->IsUnboxedDoubleField(index)) { |
| 2014 object->RawFastDoublePropertyAtPut(index, 0); |
| 2015 } else { |
| 2016 Handle<Object> value = isolate->factory()->NewHeapNumber(0, MUTABLE); |
| 2017 object->RawFastPropertyAtPut(index, *value); |
| 2018 } |
| 2014 } | 2019 } |
| 2015 object->synchronized_set_map(*new_map); | 2020 object->synchronized_set_map(*new_map); |
| 2016 return; | 2021 return; |
| 2017 } | 2022 } |
| 2018 | 2023 |
| 2019 DCHECK(number_of_fields == old_number_of_fields + 1); | 2024 DCHECK(number_of_fields == old_number_of_fields + 1); |
| 2020 // This migration is a transition from a map that has run out of property | 2025 // This migration is a transition from a map that has run out of property |
| 2021 // space. Therefore it could be done by extending the backing store. | 2026 // space. Therefore it could be done by extending the backing store. |
| 2022 Handle<FixedArray> old_storage = handle(object->properties(), isolate); | 2027 Handle<FixedArray> old_storage = handle(object->properties(), isolate); |
| 2023 Handle<FixedArray> new_storage = | 2028 Handle<FixedArray> new_storage = |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2055 DCHECK(old_nof <= new_nof); | 2060 DCHECK(old_nof <= new_nof); |
| 2056 | 2061 |
| 2057 for (int i = 0; i < old_nof; i++) { | 2062 for (int i = 0; i < old_nof; i++) { |
| 2058 PropertyDetails details = new_descriptors->GetDetails(i); | 2063 PropertyDetails details = new_descriptors->GetDetails(i); |
| 2059 if (details.type() != FIELD) continue; | 2064 if (details.type() != FIELD) continue; |
| 2060 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2065 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 2061 if (old_details.type() == CALLBACKS) { | 2066 if (old_details.type() == CALLBACKS) { |
| 2062 DCHECK(details.representation().IsTagged()); | 2067 DCHECK(details.representation().IsTagged()); |
| 2063 continue; | 2068 continue; |
| 2064 } | 2069 } |
| 2070 Representation old_representation = old_details.representation(); |
| 2071 Representation representation = details.representation(); |
| 2065 DCHECK(old_details.type() == CONSTANT || | 2072 DCHECK(old_details.type() == CONSTANT || |
| 2066 old_details.type() == FIELD); | 2073 old_details.type() == FIELD); |
| 2067 Object* raw_value = old_details.type() == CONSTANT | 2074 Handle<Object> value; |
| 2068 ? old_descriptors->GetValue(i) | 2075 if (old_details.type() == CONSTANT) { |
| 2069 : object->RawFastPropertyAt(FieldIndex::ForDescriptor(*old_map, i)); | 2076 value = handle(old_descriptors->GetValue(i), isolate); |
| 2070 Handle<Object> value(raw_value, isolate); | 2077 DCHECK(!old_representation.IsDouble() && !representation.IsDouble()); |
| 2071 if (!old_details.representation().IsDouble() && | 2078 } else { |
| 2072 details.representation().IsDouble()) { | 2079 FieldIndex index = FieldIndex::ForDescriptor(*old_map, i); |
| 2073 if (old_details.representation().IsNone()) { | 2080 if (object->IsUnboxedDoubleField(index)) { |
| 2074 value = handle(Smi::FromInt(0), isolate); | 2081 double old = object->RawFastDoublePropertyAt(index); |
| 2082 value = isolate->factory()->NewHeapNumber( |
| 2083 old, representation.IsDouble() ? MUTABLE : IMMUTABLE); |
| 2084 |
| 2085 } else { |
| 2086 value = handle(object->RawFastPropertyAt(index), isolate); |
| 2087 if (!old_representation.IsDouble() && representation.IsDouble()) { |
| 2088 if (old_representation.IsNone()) { |
| 2089 value = handle(Smi::FromInt(0), isolate); |
| 2090 } |
| 2091 value = Object::NewStorageFor(isolate, value, representation); |
| 2092 } else if (old_representation.IsDouble() && |
| 2093 !representation.IsDouble()) { |
| 2094 value = Object::WrapForRead(isolate, value, old_representation); |
| 2095 } |
| 2075 } | 2096 } |
| 2076 value = Object::NewStorageFor(isolate, value, details.representation()); | |
| 2077 } else if (old_details.representation().IsDouble() && | |
| 2078 !details.representation().IsDouble()) { | |
| 2079 value = Object::WrapForRead(isolate, value, old_details.representation()); | |
| 2080 } | 2097 } |
| 2081 DCHECK(!(details.representation().IsDouble() && value->IsSmi())); | 2098 DCHECK(!(representation.IsDouble() && value->IsSmi())); |
| 2082 int target_index = new_descriptors->GetFieldIndex(i) - inobject; | 2099 int target_index = new_descriptors->GetFieldIndex(i) - inobject; |
| 2083 if (target_index < 0) target_index += total_size; | 2100 if (target_index < 0) target_index += total_size; |
| 2084 array->set(target_index, *value); | 2101 array->set(target_index, *value); |
| 2085 } | 2102 } |
| 2086 | 2103 |
| 2087 for (int i = old_nof; i < new_nof; i++) { | 2104 for (int i = old_nof; i < new_nof; i++) { |
| 2088 PropertyDetails details = new_descriptors->GetDetails(i); | 2105 PropertyDetails details = new_descriptors->GetDetails(i); |
| 2089 if (details.type() != FIELD) continue; | 2106 if (details.type() != FIELD) continue; |
| 2090 Handle<Object> value; | 2107 Handle<Object> value; |
| 2091 if (details.representation().IsDouble()) { | 2108 if (details.representation().IsDouble()) { |
| 2092 value = isolate->factory()->NewHeapNumber(0, MUTABLE); | 2109 value = isolate->factory()->NewHeapNumber(0, MUTABLE); |
| 2093 } else { | 2110 } else { |
| 2094 value = isolate->factory()->uninitialized_value(); | 2111 value = isolate->factory()->uninitialized_value(); |
| 2095 } | 2112 } |
| 2096 int target_index = new_descriptors->GetFieldIndex(i) - inobject; | 2113 int target_index = new_descriptors->GetFieldIndex(i) - inobject; |
| 2097 if (target_index < 0) target_index += total_size; | 2114 if (target_index < 0) target_index += total_size; |
| 2098 array->set(target_index, *value); | 2115 array->set(target_index, *value); |
| 2099 } | 2116 } |
| 2100 | 2117 |
| 2101 // From here on we cannot fail and we shouldn't GC anymore. | 2118 // From here on we cannot fail and we shouldn't GC anymore. |
| 2102 DisallowHeapAllocation no_allocation; | 2119 DisallowHeapAllocation no_allocation; |
| 2103 | 2120 |
| 2104 // Copy (real) inobject properties. If necessary, stop at number_of_fields to | 2121 // Copy (real) inobject properties. If necessary, stop at number_of_fields to |
| 2105 // avoid overwriting |one_pointer_filler_map|. | 2122 // avoid overwriting |one_pointer_filler_map|. |
| 2106 int limit = Min(inobject, number_of_fields); | 2123 int limit = Min(inobject, number_of_fields); |
| 2107 for (int i = 0; i < limit; i++) { | 2124 for (int i = 0; i < limit; i++) { |
| 2108 FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i); | 2125 FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i); |
| 2109 object->FastPropertyAtPut(index, array->get(external + i)); | 2126 Object* value = array->get(external + i); |
| 2127 // Can't use JSObject::FastPropertyAtPut() because proper map was not set |
| 2128 // yet. |
| 2129 if (new_map->IsUnboxedDoubleField(index)) { |
| 2130 DCHECK(value->IsMutableHeapNumber()); |
| 2131 object->RawFastDoublePropertyAtPut(index, |
| 2132 HeapNumber::cast(value)->value()); |
| 2133 } else { |
| 2134 object->RawFastPropertyAtPut(index, value); |
| 2135 } |
| 2110 } | 2136 } |
| 2111 | 2137 |
| 2112 Heap* heap = isolate->heap(); | 2138 Heap* heap = isolate->heap(); |
| 2113 | 2139 |
| 2114 // If there are properties in the new backing store, trim it to the correct | 2140 // If there are properties in the new backing store, trim it to the correct |
| 2115 // size and install the backing store into the object. | 2141 // size and install the backing store into the object. |
| 2116 if (external > 0) { | 2142 if (external > 0) { |
| 2117 heap->RightTrimFixedArray<Heap::FROM_MUTATOR>(*array, inobject); | 2143 heap->RightTrimFixedArray<Heap::FROM_MUTATOR>(*array, inobject); |
| 2118 object->set_properties(*array); | 2144 object->set_properties(*array); |
| 2119 } | 2145 } |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2221 deprecate(); | 2247 deprecate(); |
| 2222 dependent_code()->DeoptimizeDependentCodeGroup( | 2248 dependent_code()->DeoptimizeDependentCodeGroup( |
| 2223 GetIsolate(), DependentCode::kTransitionGroup); | 2249 GetIsolate(), DependentCode::kTransitionGroup); |
| 2224 NotifyLeafMapLayoutChange(); | 2250 NotifyLeafMapLayoutChange(); |
| 2225 } | 2251 } |
| 2226 | 2252 |
| 2227 | 2253 |
| 2228 // Invalidates a transition target at |key|, and installs |new_descriptors| over | 2254 // Invalidates a transition target at |key|, and installs |new_descriptors| over |
| 2229 // the current instance_descriptors to ensure proper sharing of descriptor | 2255 // the current instance_descriptors to ensure proper sharing of descriptor |
| 2230 // arrays. | 2256 // arrays. |
| 2231 void Map::DeprecateTarget(Name* key, DescriptorArray* new_descriptors) { | 2257 void Map::DeprecateTarget(Handle<Name> key, |
| 2258 Handle<DescriptorArray> new_descriptors, |
| 2259 Handle<LayoutDescriptor> new_layout_descriptor) { |
| 2232 if (HasTransitionArray()) { | 2260 if (HasTransitionArray()) { |
| 2233 TransitionArray* transitions = this->transitions(); | 2261 TransitionArray* transitions = this->transitions(); |
| 2234 int transition = transitions->Search(key); | 2262 int transition = transitions->Search(*key); |
| 2235 if (transition != TransitionArray::kNotFound) { | 2263 if (transition != TransitionArray::kNotFound) { |
| 2236 transitions->GetTarget(transition)->DeprecateTransitionTree(); | 2264 transitions->GetTarget(transition)->DeprecateTransitionTree(); |
| 2237 } | 2265 } |
| 2238 } | 2266 } |
| 2239 | 2267 |
| 2240 // Don't overwrite the empty descriptor array. | 2268 // Don't overwrite the empty descriptor array. |
| 2241 if (NumberOfOwnDescriptors() == 0) return; | 2269 if (NumberOfOwnDescriptors() == 0) return; |
| 2242 | 2270 |
| 2243 DescriptorArray* to_replace = instance_descriptors(); | 2271 DescriptorArray* to_replace = instance_descriptors(); |
| 2244 Map* current = this; | 2272 Map* current = this; |
| 2245 GetHeap()->incremental_marking()->RecordWrites(to_replace); | 2273 GetHeap()->incremental_marking()->RecordWrites(to_replace); |
| 2246 while (current->instance_descriptors() == to_replace) { | 2274 while (current->instance_descriptors() == to_replace) { |
| 2247 current->SetEnumLength(kInvalidEnumCacheSentinel); | 2275 current->SetEnumLength(kInvalidEnumCacheSentinel); |
| 2248 current->set_instance_descriptors(new_descriptors); | 2276 current->UpdateDescriptors(*new_descriptors, *new_layout_descriptor); |
| 2249 Object* next = current->GetBackPointer(); | 2277 Object* next = current->GetBackPointer(); |
| 2250 if (next->IsUndefined()) break; | 2278 if (next->IsUndefined()) break; |
| 2251 current = Map::cast(next); | 2279 current = Map::cast(next); |
| 2252 } | 2280 } |
| 2253 | 2281 |
| 2254 set_owns_descriptors(false); | 2282 set_owns_descriptors(false); |
| 2255 } | 2283 } |
| 2256 | 2284 |
| 2257 | 2285 |
| 2258 Map* Map::FindRootMap() { | 2286 Map* Map::FindRootMap() { |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2572 DCHECK(new_descriptors->length() > target_descriptors->length() || | 2600 DCHECK(new_descriptors->length() > target_descriptors->length() || |
| 2573 new_descriptors->NumberOfSlackDescriptors() > 0 || | 2601 new_descriptors->NumberOfSlackDescriptors() > 0 || |
| 2574 new_descriptors->number_of_descriptors() == | 2602 new_descriptors->number_of_descriptors() == |
| 2575 old_descriptors->number_of_descriptors()); | 2603 old_descriptors->number_of_descriptors()); |
| 2576 DCHECK(new_descriptors->number_of_descriptors() == old_nof); | 2604 DCHECK(new_descriptors->number_of_descriptors() == old_nof); |
| 2577 | 2605 |
| 2578 // 0 -> |root_nof| | 2606 // 0 -> |root_nof| |
| 2579 int current_offset = 0; | 2607 int current_offset = 0; |
| 2580 for (int i = 0; i < root_nof; ++i) { | 2608 for (int i = 0; i < root_nof; ++i) { |
| 2581 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2609 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 2582 if (old_details.type() == FIELD) current_offset++; | 2610 if (old_details.type() == FIELD) { |
| 2611 current_offset += old_details.field_width_in_words(); |
| 2612 } |
| 2583 Descriptor d(handle(old_descriptors->GetKey(i), isolate), | 2613 Descriptor d(handle(old_descriptors->GetKey(i), isolate), |
| 2584 handle(old_descriptors->GetValue(i), isolate), | 2614 handle(old_descriptors->GetValue(i), isolate), |
| 2585 old_details); | 2615 old_details); |
| 2586 new_descriptors->Set(i, &d); | 2616 new_descriptors->Set(i, &d); |
| 2587 } | 2617 } |
| 2588 | 2618 |
| 2589 // |root_nof| -> |target_nof| | 2619 // |root_nof| -> |target_nof| |
| 2590 for (int i = root_nof; i < target_nof; ++i) { | 2620 for (int i = root_nof; i < target_nof; ++i) { |
| 2591 Handle<Name> target_key(target_descriptors->GetKey(i), isolate); | 2621 Handle<Name> target_key(target_descriptors->GetKey(i), isolate); |
| 2592 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2622 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2610 Handle<HeapType> target_field_type = (target_details.type() == FIELD) | 2640 Handle<HeapType> target_field_type = (target_details.type() == FIELD) |
| 2611 ? handle(target_descriptors->GetFieldType(i), isolate) | 2641 ? handle(target_descriptors->GetFieldType(i), isolate) |
| 2612 : target_descriptors->GetValue(i)->OptimalType( | 2642 : target_descriptors->GetValue(i)->OptimalType( |
| 2613 isolate, target_details.representation()); | 2643 isolate, target_details.representation()); |
| 2614 target_field_type = GeneralizeFieldType( | 2644 target_field_type = GeneralizeFieldType( |
| 2615 target_field_type, old_field_type, isolate); | 2645 target_field_type, old_field_type, isolate); |
| 2616 if (modify_index == i) { | 2646 if (modify_index == i) { |
| 2617 target_field_type = GeneralizeFieldType( | 2647 target_field_type = GeneralizeFieldType( |
| 2618 target_field_type, new_field_type, isolate); | 2648 target_field_type, new_field_type, isolate); |
| 2619 } | 2649 } |
| 2620 FieldDescriptor d(target_key, | 2650 FieldDescriptor d(target_key, current_offset, target_field_type, |
| 2621 current_offset++, | |
| 2622 target_field_type, | |
| 2623 target_details.attributes(), | 2651 target_details.attributes(), |
| 2624 target_details.representation()); | 2652 target_details.representation()); |
| 2653 current_offset += d.GetDetails().field_width_in_words(); |
| 2625 new_descriptors->Set(i, &d); | 2654 new_descriptors->Set(i, &d); |
| 2626 } else { | 2655 } else { |
| 2627 DCHECK_NE(FIELD, target_details.type()); | 2656 DCHECK_NE(FIELD, target_details.type()); |
| 2628 Descriptor d(target_key, | 2657 Descriptor d(target_key, |
| 2629 handle(target_descriptors->GetValue(i), isolate), | 2658 handle(target_descriptors->GetValue(i), isolate), |
| 2630 target_details); | 2659 target_details); |
| 2631 new_descriptors->Set(i, &d); | 2660 new_descriptors->Set(i, &d); |
| 2632 } | 2661 } |
| 2633 } | 2662 } |
| 2634 | 2663 |
| 2635 // |target_nof| -> |old_nof| | 2664 // |target_nof| -> |old_nof| |
| 2636 for (int i = target_nof; i < old_nof; ++i) { | 2665 for (int i = target_nof; i < old_nof; ++i) { |
| 2637 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2666 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 2638 Handle<Name> old_key(old_descriptors->GetKey(i), isolate); | 2667 Handle<Name> old_key(old_descriptors->GetKey(i), isolate); |
| 2639 if (modify_index == i) { | 2668 if (modify_index == i) { |
| 2640 old_details = old_details.CopyWithRepresentation( | 2669 old_details = old_details.CopyWithRepresentation( |
| 2641 new_representation.generalize(old_details.representation())); | 2670 new_representation.generalize(old_details.representation())); |
| 2642 } | 2671 } |
| 2643 if (old_details.type() == FIELD) { | 2672 if (old_details.type() == FIELD) { |
| 2644 Handle<HeapType> old_field_type( | 2673 Handle<HeapType> old_field_type( |
| 2645 old_descriptors->GetFieldType(i), isolate); | 2674 old_descriptors->GetFieldType(i), isolate); |
| 2646 if (modify_index == i) { | 2675 if (modify_index == i) { |
| 2647 old_field_type = GeneralizeFieldType( | 2676 old_field_type = GeneralizeFieldType( |
| 2648 old_field_type, new_field_type, isolate); | 2677 old_field_type, new_field_type, isolate); |
| 2649 } | 2678 } |
| 2650 FieldDescriptor d(old_key, | 2679 FieldDescriptor d(old_key, current_offset, old_field_type, |
| 2651 current_offset++, | 2680 old_details.attributes(), old_details.representation()); |
| 2652 old_field_type, | 2681 current_offset += d.GetDetails().field_width_in_words(); |
| 2653 old_details.attributes(), | |
| 2654 old_details.representation()); | |
| 2655 new_descriptors->Set(i, &d); | 2682 new_descriptors->Set(i, &d); |
| 2656 } else { | 2683 } else { |
| 2657 DCHECK(old_details.type() == CONSTANT || old_details.type() == CALLBACKS); | 2684 DCHECK(old_details.type() == CONSTANT || old_details.type() == CALLBACKS); |
| 2658 if (modify_index == i && store_mode == FORCE_FIELD) { | 2685 if (modify_index == i && store_mode == FORCE_FIELD) { |
| 2659 FieldDescriptor d(old_key, | 2686 FieldDescriptor d( |
| 2660 current_offset++, | 2687 old_key, current_offset, |
| 2661 GeneralizeFieldType( | 2688 GeneralizeFieldType(old_descriptors->GetValue(i)->OptimalType( |
| 2662 old_descriptors->GetValue(i)->OptimalType( | 2689 isolate, old_details.representation()), |
| 2663 isolate, old_details.representation()), | 2690 new_field_type, isolate), |
| 2664 new_field_type, isolate), | 2691 old_details.attributes(), old_details.representation()); |
| 2665 old_details.attributes(), | 2692 current_offset += d.GetDetails().field_width_in_words(); |
| 2666 old_details.representation()); | |
| 2667 new_descriptors->Set(i, &d); | 2693 new_descriptors->Set(i, &d); |
| 2668 } else { | 2694 } else { |
| 2669 DCHECK_NE(FIELD, old_details.type()); | 2695 DCHECK_NE(FIELD, old_details.type()); |
| 2670 Descriptor d(old_key, | 2696 Descriptor d(old_key, |
| 2671 handle(old_descriptors->GetValue(i), isolate), | 2697 handle(old_descriptors->GetValue(i), isolate), |
| 2672 old_details); | 2698 old_details); |
| 2673 new_descriptors->Set(i, &d); | 2699 new_descriptors->Set(i, &d); |
| 2674 } | 2700 } |
| 2675 } | 2701 } |
| 2676 } | 2702 } |
| 2677 | 2703 |
| 2678 new_descriptors->Sort(); | 2704 new_descriptors->Sort(); |
| 2679 | 2705 |
| 2680 DCHECK(store_mode != FORCE_FIELD || | 2706 DCHECK(store_mode != FORCE_FIELD || |
| 2681 new_descriptors->GetDetails(modify_index).type() == FIELD); | 2707 new_descriptors->GetDetails(modify_index).type() == FIELD); |
| 2682 | 2708 |
| 2683 Handle<Map> split_map(root_map->FindLastMatchMap( | 2709 Handle<Map> split_map(root_map->FindLastMatchMap( |
| 2684 root_nof, old_nof, *new_descriptors), isolate); | 2710 root_nof, old_nof, *new_descriptors), isolate); |
| 2685 int split_nof = split_map->NumberOfOwnDescriptors(); | 2711 int split_nof = split_map->NumberOfOwnDescriptors(); |
| 2686 DCHECK_NE(old_nof, split_nof); | 2712 DCHECK_NE(old_nof, split_nof); |
| 2687 | 2713 |
| 2714 Handle<LayoutDescriptor> new_layout_descriptor = |
| 2715 LayoutDescriptor::New(split_map, new_descriptors, old_nof); |
| 2688 split_map->DeprecateTarget( | 2716 split_map->DeprecateTarget( |
| 2689 old_descriptors->GetKey(split_nof), *new_descriptors); | 2717 handle(old_descriptors->GetKey(split_nof), isolate), new_descriptors, |
| 2718 new_layout_descriptor); |
| 2690 | 2719 |
| 2691 if (FLAG_trace_generalization) { | 2720 if (FLAG_trace_generalization) { |
| 2692 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2721 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
| 2693 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); | 2722 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); |
| 2694 Handle<HeapType> old_field_type = (old_details.type() == FIELD) | 2723 Handle<HeapType> old_field_type = (old_details.type() == FIELD) |
| 2695 ? handle(old_descriptors->GetFieldType(modify_index), isolate) | 2724 ? handle(old_descriptors->GetFieldType(modify_index), isolate) |
| 2696 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index), | 2725 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index), |
| 2697 isolate), isolate); | 2726 isolate), isolate); |
| 2698 Handle<HeapType> new_field_type = (new_details.type() == FIELD) | 2727 Handle<HeapType> new_field_type = (new_details.type() == FIELD) |
| 2699 ? handle(new_descriptors->GetFieldType(modify_index), isolate) | 2728 ? handle(new_descriptors->GetFieldType(modify_index), isolate) |
| 2700 : HeapType::Constant(handle(new_descriptors->GetValue(modify_index), | 2729 : HeapType::Constant(handle(new_descriptors->GetValue(modify_index), |
| 2701 isolate), isolate); | 2730 isolate), isolate); |
| 2702 old_map->PrintGeneralization( | 2731 old_map->PrintGeneralization( |
| 2703 stdout, "", modify_index, split_nof, old_nof, | 2732 stdout, "", modify_index, split_nof, old_nof, |
| 2704 old_details.type() == CONSTANT && store_mode == FORCE_FIELD, | 2733 old_details.type() == CONSTANT && store_mode == FORCE_FIELD, |
| 2705 old_details.representation(), new_details.representation(), | 2734 old_details.representation(), new_details.representation(), |
| 2706 *old_field_type, *new_field_type); | 2735 *old_field_type, *new_field_type); |
| 2707 } | 2736 } |
| 2708 | 2737 |
| 2709 // Add missing transitions. | 2738 // Add missing transitions. |
| 2710 Handle<Map> new_map = split_map; | 2739 Handle<Map> new_map = split_map; |
| 2711 for (int i = split_nof; i < old_nof; ++i) { | 2740 for (int i = split_nof; i < old_nof; ++i) { |
| 2712 new_map = CopyInstallDescriptors(new_map, i, new_descriptors); | 2741 new_map = CopyInstallDescriptors(new_map, i, new_descriptors, |
| 2742 new_layout_descriptor); |
| 2713 } | 2743 } |
| 2714 new_map->set_owns_descriptors(true); | 2744 new_map->set_owns_descriptors(true); |
| 2715 return new_map; | 2745 return new_map; |
| 2716 } | 2746 } |
| 2717 | 2747 |
| 2718 | 2748 |
| 2719 // Generalize the representation of all FIELD descriptors. | 2749 // Generalize the representation of all FIELD descriptors. |
| 2720 Handle<Map> Map::GeneralizeAllFieldRepresentations( | 2750 Handle<Map> Map::GeneralizeAllFieldRepresentations( |
| 2721 Handle<Map> map) { | 2751 Handle<Map> map) { |
| 2722 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 2752 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3123 // Only supports adding slack to owned descriptors. | 3153 // Only supports adding slack to owned descriptors. |
| 3124 DCHECK(map->owns_descriptors()); | 3154 DCHECK(map->owns_descriptors()); |
| 3125 | 3155 |
| 3126 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 3156 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
| 3127 int old_size = map->NumberOfOwnDescriptors(); | 3157 int old_size = map->NumberOfOwnDescriptors(); |
| 3128 if (slack <= descriptors->NumberOfSlackDescriptors()) return; | 3158 if (slack <= descriptors->NumberOfSlackDescriptors()) return; |
| 3129 | 3159 |
| 3130 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( | 3160 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( |
| 3131 descriptors, old_size, slack); | 3161 descriptors, old_size, slack); |
| 3132 | 3162 |
| 3163 DisallowHeapAllocation no_allocation; |
| 3164 // The descriptors are still the same, so keep the layout descriptor. |
| 3165 LayoutDescriptor* layout_descriptor = map->layout_descriptor(); |
| 3166 |
| 3133 if (old_size == 0) { | 3167 if (old_size == 0) { |
| 3134 map->set_instance_descriptors(*new_descriptors); | 3168 map->UpdateDescriptors(*new_descriptors, layout_descriptor); |
| 3135 return; | 3169 return; |
| 3136 } | 3170 } |
| 3137 | 3171 |
| 3138 // If the source descriptors had an enum cache we copy it. This ensures | 3172 // If the source descriptors had an enum cache we copy it. This ensures |
| 3139 // that the maps to which we push the new descriptor array back can rely | 3173 // that the maps to which we push the new descriptor array back can rely |
| 3140 // on a cache always being available once it is set. If the map has more | 3174 // on a cache always being available once it is set. If the map has more |
| 3141 // enumerated descriptors than available in the original cache, the cache | 3175 // enumerated descriptors than available in the original cache, the cache |
| 3142 // will be lazily replaced by the extended cache when needed. | 3176 // will be lazily replaced by the extended cache when needed. |
| 3143 if (descriptors->HasEnumCache()) { | 3177 if (descriptors->HasEnumCache()) { |
| 3144 new_descriptors->CopyEnumCacheFrom(*descriptors); | 3178 new_descriptors->CopyEnumCacheFrom(*descriptors); |
| 3145 } | 3179 } |
| 3146 | 3180 |
| 3147 // Replace descriptors by new_descriptors in all maps that share it. | 3181 // Replace descriptors by new_descriptors in all maps that share it. |
| 3148 map->GetHeap()->incremental_marking()->RecordWrites(*descriptors); | 3182 map->GetHeap()->incremental_marking()->RecordWrites(*descriptors); |
| 3149 | 3183 |
| 3150 Map* walk_map; | 3184 Map* walk_map; |
| 3151 for (Object* current = map->GetBackPointer(); | 3185 for (Object* current = map->GetBackPointer(); |
| 3152 !current->IsUndefined(); | 3186 !current->IsUndefined(); |
| 3153 current = walk_map->GetBackPointer()) { | 3187 current = walk_map->GetBackPointer()) { |
| 3154 walk_map = Map::cast(current); | 3188 walk_map = Map::cast(current); |
| 3155 if (walk_map->instance_descriptors() != *descriptors) break; | 3189 if (walk_map->instance_descriptors() != *descriptors) break; |
| 3156 walk_map->set_instance_descriptors(*new_descriptors); | 3190 walk_map->UpdateDescriptors(*new_descriptors, layout_descriptor); |
| 3157 } | 3191 } |
| 3158 | 3192 |
| 3159 map->set_instance_descriptors(*new_descriptors); | 3193 map->UpdateDescriptors(*new_descriptors, layout_descriptor); |
| 3160 } | 3194 } |
| 3161 | 3195 |
| 3162 | 3196 |
| 3163 template<class T> | 3197 template<class T> |
| 3164 static int AppendUniqueCallbacks(NeanderArray* callbacks, | 3198 static int AppendUniqueCallbacks(NeanderArray* callbacks, |
| 3165 Handle<typename T::Array> array, | 3199 Handle<typename T::Array> array, |
| 3166 int valid_descriptors) { | 3200 int valid_descriptors) { |
| 3167 int nof_callbacks = callbacks->length(); | 3201 int nof_callbacks = callbacks->length(); |
| 3168 | 3202 |
| 3169 Isolate* isolate = array->GetIsolate(); | 3203 Isolate* isolate = array->GetIsolate(); |
| (...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3823 | 3857 |
| 3824 DescriptorArray* desc = map()->instance_descriptors(); | 3858 DescriptorArray* desc = map()->instance_descriptors(); |
| 3825 PropertyDetails details = desc->GetDetails(descriptor); | 3859 PropertyDetails details = desc->GetDetails(descriptor); |
| 3826 | 3860 |
| 3827 DCHECK(details.type() == FIELD); | 3861 DCHECK(details.type() == FIELD); |
| 3828 | 3862 |
| 3829 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor); | 3863 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor); |
| 3830 if (details.representation().IsDouble()) { | 3864 if (details.representation().IsDouble()) { |
| 3831 // Nothing more to be done. | 3865 // Nothing more to be done. |
| 3832 if (value->IsUninitialized()) return; | 3866 if (value->IsUninitialized()) return; |
| 3833 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); | 3867 if (IsUnboxedDoubleField(index)) { |
| 3834 DCHECK(box->IsMutableHeapNumber()); | 3868 RawFastDoublePropertyAtPut(index, value->Number()); |
| 3835 box->set_value(value->Number()); | 3869 } else { |
| 3870 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); |
| 3871 DCHECK(box->IsMutableHeapNumber()); |
| 3872 box->set_value(value->Number()); |
| 3873 } |
| 3836 } else { | 3874 } else { |
| 3837 FastPropertyAtPut(index, value); | 3875 RawFastPropertyAtPut(index, value); |
| 3838 } | 3876 } |
| 3839 } | 3877 } |
| 3840 | 3878 |
| 3841 | 3879 |
| 3842 void JSObject::AddProperty(Handle<JSObject> object, Handle<Name> name, | 3880 void JSObject::AddProperty(Handle<JSObject> object, Handle<Name> name, |
| 3843 Handle<Object> value, | 3881 Handle<Object> value, |
| 3844 PropertyAttributes attributes) { | 3882 PropertyAttributes attributes) { |
| 3845 LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); | 3883 LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 3846 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state()); | 3884 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state()); |
| 3847 #ifdef DEBUG | 3885 #ifdef DEBUG |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4288 Handle<Name> key(descs->GetKey(i)); | 4326 Handle<Name> key(descs->GetKey(i)); |
| 4289 Handle<Object> value(descs->GetConstant(i), isolate); | 4327 Handle<Object> value(descs->GetConstant(i), isolate); |
| 4290 PropertyDetails d = PropertyDetails( | 4328 PropertyDetails d = PropertyDetails( |
| 4291 details.attributes(), NORMAL, i + 1); | 4329 details.attributes(), NORMAL, i + 1); |
| 4292 dictionary = NameDictionary::Add(dictionary, key, value, d); | 4330 dictionary = NameDictionary::Add(dictionary, key, value, d); |
| 4293 break; | 4331 break; |
| 4294 } | 4332 } |
| 4295 case FIELD: { | 4333 case FIELD: { |
| 4296 Handle<Name> key(descs->GetKey(i)); | 4334 Handle<Name> key(descs->GetKey(i)); |
| 4297 FieldIndex index = FieldIndex::ForDescriptor(*map, i); | 4335 FieldIndex index = FieldIndex::ForDescriptor(*map, i); |
| 4298 Handle<Object> value( | 4336 Handle<Object> value; |
| 4299 object->RawFastPropertyAt(index), isolate); | 4337 if (object->IsUnboxedDoubleField(index)) { |
| 4300 if (details.representation().IsDouble()) { | 4338 double old_value = object->RawFastDoublePropertyAt(index); |
| 4301 DCHECK(value->IsMutableHeapNumber()); | 4339 value = isolate->factory()->NewHeapNumber(old_value); |
| 4302 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); | 4340 } else { |
| 4303 value = isolate->factory()->NewHeapNumber(old->value()); | 4341 value = handle(object->RawFastPropertyAt(index), isolate); |
| 4342 if (details.representation().IsDouble()) { |
| 4343 DCHECK(value->IsMutableHeapNumber()); |
| 4344 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); |
| 4345 value = isolate->factory()->NewHeapNumber(old->value()); |
| 4346 } |
| 4304 } | 4347 } |
| 4305 PropertyDetails d = | 4348 PropertyDetails d = |
| 4306 PropertyDetails(details.attributes(), NORMAL, i + 1); | 4349 PropertyDetails(details.attributes(), NORMAL, i + 1); |
| 4307 dictionary = NameDictionary::Add(dictionary, key, value, d); | 4350 dictionary = NameDictionary::Add(dictionary, key, value, d); |
| 4308 break; | 4351 break; |
| 4309 } | 4352 } |
| 4310 case CALLBACKS: { | 4353 case CALLBACKS: { |
| 4311 Handle<Name> key(descs->GetKey(i)); | 4354 Handle<Name> key(descs->GetKey(i)); |
| 4312 Handle<Object> value(descs->GetCallbacksObject(i), isolate); | 4355 Handle<Object> value(descs->GetCallbacksObject(i), isolate); |
| 4313 PropertyDetails d = PropertyDetails( | 4356 PropertyDetails d = PropertyDetails( |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4454 ConstantDescriptor d(key, handle(value, isolate), details.attributes()); | 4497 ConstantDescriptor d(key, handle(value, isolate), details.attributes()); |
| 4455 descriptors->Set(enumeration_index - 1, &d); | 4498 descriptors->Set(enumeration_index - 1, &d); |
| 4456 } else if (type == NORMAL) { | 4499 } else if (type == NORMAL) { |
| 4457 if (current_offset < inobject_props) { | 4500 if (current_offset < inobject_props) { |
| 4458 object->InObjectPropertyAtPut(current_offset, value, | 4501 object->InObjectPropertyAtPut(current_offset, value, |
| 4459 UPDATE_WRITE_BARRIER); | 4502 UPDATE_WRITE_BARRIER); |
| 4460 } else { | 4503 } else { |
| 4461 int offset = current_offset - inobject_props; | 4504 int offset = current_offset - inobject_props; |
| 4462 fields->set(offset, value); | 4505 fields->set(offset, value); |
| 4463 } | 4506 } |
| 4464 FieldDescriptor d(key, current_offset++, details.attributes(), | 4507 FieldDescriptor d(key, current_offset, details.attributes(), |
| 4465 // TODO(verwaest): value->OptimalRepresentation(); | 4508 // TODO(verwaest): value->OptimalRepresentation(); |
| 4466 Representation::Tagged()); | 4509 Representation::Tagged()); |
| 4510 current_offset += d.GetDetails().field_width_in_words(); |
| 4467 descriptors->Set(enumeration_index - 1, &d); | 4511 descriptors->Set(enumeration_index - 1, &d); |
| 4468 } else if (type == CALLBACKS) { | 4512 } else if (type == CALLBACKS) { |
| 4469 CallbacksDescriptor d(key, handle(value, isolate), details.attributes()); | 4513 CallbacksDescriptor d(key, handle(value, isolate), details.attributes()); |
| 4470 descriptors->Set(enumeration_index - 1, &d); | 4514 descriptors->Set(enumeration_index - 1, &d); |
| 4471 } else { | 4515 } else { |
| 4472 UNREACHABLE(); | 4516 UNREACHABLE(); |
| 4473 } | 4517 } |
| 4474 } | 4518 } |
| 4475 DCHECK(current_offset == number_of_fields); | 4519 DCHECK(current_offset == number_of_fields); |
| 4476 | 4520 |
| 4477 descriptors->Sort(); | 4521 descriptors->Sort(); |
| 4478 | 4522 |
| 4523 Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::New( |
| 4524 new_map, descriptors, descriptors->number_of_descriptors()); |
| 4525 |
| 4479 DisallowHeapAllocation no_gc; | 4526 DisallowHeapAllocation no_gc; |
| 4480 new_map->InitializeDescriptors(*descriptors); | 4527 new_map->InitializeDescriptors(*descriptors, *layout_descriptor); |
| 4481 new_map->set_unused_property_fields(unused_property_fields); | 4528 new_map->set_unused_property_fields(unused_property_fields); |
| 4482 | 4529 |
| 4483 // Transform the object. | 4530 // Transform the object. |
| 4484 object->synchronized_set_map(*new_map); | 4531 object->synchronized_set_map(*new_map); |
| 4485 | 4532 |
| 4486 object->set_properties(*fields); | 4533 object->set_properties(*fields); |
| 4487 DCHECK(object->IsJSObject()); | 4534 DCHECK(object->IsJSObject()); |
| 4488 | 4535 |
| 4489 // Check that it really works. | 4536 // Check that it really works. |
| 4490 DCHECK(object->HasFastProperties()); | 4537 DCHECK(object->HasFastProperties()); |
| (...skipping 950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5441 new_map->set_is_observed(); | 5488 new_map->set_is_observed(); |
| 5442 } | 5489 } |
| 5443 JSObject::MigrateToMap(object, new_map); | 5490 JSObject::MigrateToMap(object, new_map); |
| 5444 } | 5491 } |
| 5445 | 5492 |
| 5446 | 5493 |
| 5447 Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object, | 5494 Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object, |
| 5448 Representation representation, | 5495 Representation representation, |
| 5449 FieldIndex index) { | 5496 FieldIndex index) { |
| 5450 Isolate* isolate = object->GetIsolate(); | 5497 Isolate* isolate = object->GetIsolate(); |
| 5498 if (object->IsUnboxedDoubleField(index)) { |
| 5499 double value = object->RawFastDoublePropertyAt(index); |
| 5500 return isolate->factory()->NewHeapNumber(value); |
| 5501 } |
| 5451 Handle<Object> raw_value(object->RawFastPropertyAt(index), isolate); | 5502 Handle<Object> raw_value(object->RawFastPropertyAt(index), isolate); |
| 5452 return Object::WrapForRead(isolate, raw_value, representation); | 5503 return Object::WrapForRead(isolate, raw_value, representation); |
| 5453 } | 5504 } |
| 5454 | 5505 |
| 5455 | 5506 |
| 5456 template<class ContextObject> | 5507 template<class ContextObject> |
| 5457 class JSObjectWalkVisitor { | 5508 class JSObjectWalkVisitor { |
| 5458 public: | 5509 public: |
| 5459 JSObjectWalkVisitor(ContextObject* site_context, bool copying, | 5510 JSObjectWalkVisitor(ContextObject* site_context, bool copying, |
| 5460 JSObject::DeepCopyHints hints) | 5511 JSObject::DeepCopyHints hints) |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5531 HandleScope scope(isolate); | 5582 HandleScope scope(isolate); |
| 5532 | 5583 |
| 5533 // Deep copy own properties. | 5584 // Deep copy own properties. |
| 5534 if (copy->HasFastProperties()) { | 5585 if (copy->HasFastProperties()) { |
| 5535 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); | 5586 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); |
| 5536 int limit = copy->map()->NumberOfOwnDescriptors(); | 5587 int limit = copy->map()->NumberOfOwnDescriptors(); |
| 5537 for (int i = 0; i < limit; i++) { | 5588 for (int i = 0; i < limit; i++) { |
| 5538 PropertyDetails details = descriptors->GetDetails(i); | 5589 PropertyDetails details = descriptors->GetDetails(i); |
| 5539 if (details.type() != FIELD) continue; | 5590 if (details.type() != FIELD) continue; |
| 5540 FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i); | 5591 FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i); |
| 5541 Handle<Object> value(object->RawFastPropertyAt(index), isolate); | 5592 if (object->IsUnboxedDoubleField(index)) { |
| 5542 if (value->IsJSObject()) { | 5593 if (copying) { |
| 5543 ASSIGN_RETURN_ON_EXCEPTION( | 5594 double value = object->RawFastDoublePropertyAt(index); |
| 5544 isolate, value, | 5595 copy->RawFastDoublePropertyAtPut(index, value); |
| 5545 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), | 5596 } |
| 5546 JSObject); | |
| 5547 } else { | 5597 } else { |
| 5548 Representation representation = details.representation(); | 5598 Handle<Object> value(object->RawFastPropertyAt(index), isolate); |
| 5549 value = Object::NewStorageFor(isolate, value, representation); | 5599 if (value->IsJSObject()) { |
| 5550 } | 5600 ASSIGN_RETURN_ON_EXCEPTION( |
| 5551 if (copying) { | 5601 isolate, value, |
| 5552 copy->FastPropertyAtPut(index, *value); | 5602 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), |
| 5603 JSObject); |
| 5604 if (copying) { |
| 5605 copy->FastPropertyAtPut(index, *value); |
| 5606 } |
| 5607 } else { |
| 5608 if (copying) { |
| 5609 Representation representation = details.representation(); |
| 5610 value = Object::NewStorageFor(isolate, value, representation); |
| 5611 copy->FastPropertyAtPut(index, *value); |
| 5612 } |
| 5613 } |
| 5553 } | 5614 } |
| 5554 } | 5615 } |
| 5555 } else { | 5616 } else { |
| 5556 Handle<FixedArray> names = | 5617 Handle<FixedArray> names = |
| 5557 isolate->factory()->NewFixedArray(copy->NumberOfOwnProperties()); | 5618 isolate->factory()->NewFixedArray(copy->NumberOfOwnProperties()); |
| 5558 copy->GetOwnPropertyNames(*names, 0); | 5619 copy->GetOwnPropertyNames(*names, 0); |
| 5559 for (int i = 0; i < names->length(); i++) { | 5620 for (int i = 0; i < names->length(); i++) { |
| 5560 DCHECK(names->get(i)->IsString()); | 5621 DCHECK(names->get(i)->IsString()); |
| 5561 Handle<String> key_string(String::cast(names->get(i))); | 5622 Handle<String> key_string(String::cast(names->get(i))); |
| 5562 Maybe<PropertyAttributes> maybe = | 5623 Maybe<PropertyAttributes> maybe = |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5739 if ((descs->GetDetails(i).attributes() & filter) == 0 && | 5800 if ((descs->GetDetails(i).attributes() & filter) == 0 && |
| 5740 !FilterKey(descs->GetKey(i), filter)) { | 5801 !FilterKey(descs->GetKey(i), filter)) { |
| 5741 result++; | 5802 result++; |
| 5742 } | 5803 } |
| 5743 } | 5804 } |
| 5744 return result; | 5805 return result; |
| 5745 } | 5806 } |
| 5746 | 5807 |
| 5747 | 5808 |
| 5748 int Map::NextFreePropertyIndex() { | 5809 int Map::NextFreePropertyIndex() { |
| 5749 int max_index = -1; | 5810 int free_index = 0; |
| 5750 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 5811 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
| 5751 DescriptorArray* descs = instance_descriptors(); | 5812 DescriptorArray* descs = instance_descriptors(); |
| 5752 for (int i = 0; i < number_of_own_descriptors; i++) { | 5813 for (int i = 0; i < number_of_own_descriptors; i++) { |
| 5753 if (descs->GetType(i) == FIELD) { | 5814 PropertyDetails details = descs->GetDetails(i); |
| 5754 int current_index = descs->GetFieldIndex(i); | 5815 if (details.type() == FIELD) { |
| 5755 if (current_index > max_index) max_index = current_index; | 5816 int candidate = details.field_index() + details.field_width_in_words(); |
| 5817 if (candidate > free_index) free_index = candidate; |
| 5756 } | 5818 } |
| 5757 } | 5819 } |
| 5758 return max_index + 1; | 5820 return free_index; |
| 5759 } | 5821 } |
| 5760 | 5822 |
| 5761 | 5823 |
| 5762 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { | 5824 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { |
| 5763 int len = array->length(); | 5825 int len = array->length(); |
| 5764 for (int i = 0; i < len; i++) { | 5826 for (int i = 0; i < len; i++) { |
| 5765 Object* e = array->get(i); | 5827 Object* e = array->get(i); |
| 5766 if (!(e->IsString() || e->IsNumber())) return false; | 5828 if (!(e->IsString() || e->IsNumber())) return false; |
| 5767 } | 5829 } |
| 5768 return true; | 5830 return true; |
| (...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6426 } | 6488 } |
| 6427 } | 6489 } |
| 6428 return isolate->factory()->undefined_value(); | 6490 return isolate->factory()->undefined_value(); |
| 6429 } | 6491 } |
| 6430 | 6492 |
| 6431 | 6493 |
| 6432 Object* JSObject::SlowReverseLookup(Object* value) { | 6494 Object* JSObject::SlowReverseLookup(Object* value) { |
| 6433 if (HasFastProperties()) { | 6495 if (HasFastProperties()) { |
| 6434 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); | 6496 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); |
| 6435 DescriptorArray* descs = map()->instance_descriptors(); | 6497 DescriptorArray* descs = map()->instance_descriptors(); |
| 6498 bool value_is_number = value->IsNumber(); |
| 6436 for (int i = 0; i < number_of_own_descriptors; i++) { | 6499 for (int i = 0; i < number_of_own_descriptors; i++) { |
| 6437 if (descs->GetType(i) == FIELD) { | 6500 if (descs->GetType(i) == FIELD) { |
| 6438 Object* property = | 6501 FieldIndex field_index = FieldIndex::ForDescriptor(map(), i); |
| 6439 RawFastPropertyAt(FieldIndex::ForDescriptor(map(), i)); | 6502 if (IsUnboxedDoubleField(field_index)) { |
| 6440 if (descs->GetDetails(i).representation().IsDouble()) { | 6503 if (value_is_number) { |
| 6441 DCHECK(property->IsMutableHeapNumber()); | 6504 double property = RawFastDoublePropertyAt(field_index); |
| 6442 if (value->IsNumber() && property->Number() == value->Number()) { | 6505 if (property == value->Number()) { |
| 6506 return descs->GetKey(i); |
| 6507 } |
| 6508 } |
| 6509 } else { |
| 6510 Object* property = RawFastPropertyAt(field_index); |
| 6511 if (field_index.is_double()) { |
| 6512 DCHECK(property->IsMutableHeapNumber()); |
| 6513 if (value_is_number && property->Number() == value->Number()) { |
| 6514 return descs->GetKey(i); |
| 6515 } |
| 6516 } else if (property == value) { |
| 6443 return descs->GetKey(i); | 6517 return descs->GetKey(i); |
| 6444 } | 6518 } |
| 6445 } else if (property == value) { | |
| 6446 return descs->GetKey(i); | |
| 6447 } | 6519 } |
| 6448 } else if (descs->GetType(i) == CONSTANT) { | 6520 } else if (descs->GetType(i) == CONSTANT) { |
| 6449 if (descs->GetConstant(i) == value) { | 6521 if (descs->GetConstant(i) == value) { |
| 6450 return descs->GetKey(i); | 6522 return descs->GetKey(i); |
| 6451 } | 6523 } |
| 6452 } | 6524 } |
| 6453 } | 6525 } |
| 6454 return GetHeap()->undefined_value(); | 6526 return GetHeap()->undefined_value(); |
| 6455 } else { | 6527 } else { |
| 6456 return property_dictionary()->SlowReverseLookup(value); | 6528 return property_dictionary()->SlowReverseLookup(value); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6582 if (descriptors->NumberOfSlackDescriptors() == 0) { | 6654 if (descriptors->NumberOfSlackDescriptors() == 0) { |
| 6583 int old_size = descriptors->number_of_descriptors(); | 6655 int old_size = descriptors->number_of_descriptors(); |
| 6584 if (old_size == 0) { | 6656 if (old_size == 0) { |
| 6585 descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1); | 6657 descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1); |
| 6586 } else { | 6658 } else { |
| 6587 EnsureDescriptorSlack(map, old_size < 4 ? 1 : old_size / 2); | 6659 EnsureDescriptorSlack(map, old_size < 4 ? 1 : old_size / 2); |
| 6588 descriptors = handle(map->instance_descriptors()); | 6660 descriptors = handle(map->instance_descriptors()); |
| 6589 } | 6661 } |
| 6590 } | 6662 } |
| 6591 | 6663 |
| 6664 Handle<LayoutDescriptor> layout_descriptor = |
| 6665 FLAG_unbox_double_fields |
| 6666 ? LayoutDescriptor::Append(map, descriptor->GetDetails()) |
| 6667 : map->GetLayoutDescriptor(); |
| 6668 |
| 6592 { | 6669 { |
| 6593 DisallowHeapAllocation no_gc; | 6670 DisallowHeapAllocation no_gc; |
| 6594 descriptors->Append(descriptor); | 6671 descriptors->Append(descriptor); |
| 6595 result->InitializeDescriptors(*descriptors); | 6672 result->InitializeDescriptors(*descriptors, *layout_descriptor); |
| 6596 } | 6673 } |
| 6597 | 6674 |
| 6598 DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); | 6675 DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); |
| 6599 ConnectTransition(map, result, name, SIMPLE_TRANSITION); | 6676 ConnectTransition(map, result, name, SIMPLE_TRANSITION); |
| 6600 | 6677 |
| 6601 return result; | 6678 return result; |
| 6602 } | 6679 } |
| 6603 | 6680 |
| 6604 | 6681 |
| 6605 void Map::ConnectTransition(Handle<Map> parent, Handle<Map> child, | 6682 void Map::ConnectTransition(Handle<Map> parent, Handle<Map> child, |
| 6606 Handle<Name> name, SimpleTransitionFlag flag) { | 6683 Handle<Name> name, SimpleTransitionFlag flag) { |
| 6607 parent->set_owns_descriptors(false); | 6684 parent->set_owns_descriptors(false); |
| 6608 if (parent->is_prototype_map()) { | 6685 if (parent->is_prototype_map()) { |
| 6609 DCHECK(child->is_prototype_map()); | 6686 DCHECK(child->is_prototype_map()); |
| 6610 } else { | 6687 } else { |
| 6611 Handle<TransitionArray> transitions = | 6688 Handle<TransitionArray> transitions = |
| 6612 TransitionArray::CopyInsert(parent, name, child, flag); | 6689 TransitionArray::CopyInsert(parent, name, child, flag); |
| 6613 parent->set_transitions(*transitions); | 6690 parent->set_transitions(*transitions); |
| 6614 child->SetBackPointer(*parent); | 6691 child->SetBackPointer(*parent); |
| 6615 } | 6692 } |
| 6616 } | 6693 } |
| 6617 | 6694 |
| 6618 | 6695 |
| 6619 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, | 6696 Handle<Map> Map::CopyReplaceDescriptors( |
| 6620 Handle<DescriptorArray> descriptors, | 6697 Handle<Map> map, Handle<DescriptorArray> descriptors, |
| 6621 TransitionFlag flag, | 6698 Handle<LayoutDescriptor> layout_descriptor, TransitionFlag flag, |
| 6622 MaybeHandle<Name> maybe_name, | 6699 MaybeHandle<Name> maybe_name, SimpleTransitionFlag simple_flag) { |
| 6623 SimpleTransitionFlag simple_flag) { | |
| 6624 DCHECK(descriptors->IsSortedNoDuplicates()); | 6700 DCHECK(descriptors->IsSortedNoDuplicates()); |
| 6625 | 6701 |
| 6626 Handle<Map> result = CopyDropDescriptors(map); | 6702 Handle<Map> result = CopyDropDescriptors(map); |
| 6627 result->InitializeDescriptors(*descriptors); | |
| 6628 | 6703 |
| 6629 if (!map->is_prototype_map()) { | 6704 if (!map->is_prototype_map()) { |
| 6630 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { | 6705 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { |
| 6706 result->InitializeDescriptors(*descriptors, *layout_descriptor); |
| 6707 |
| 6631 Handle<Name> name; | 6708 Handle<Name> name; |
| 6632 CHECK(maybe_name.ToHandle(&name)); | 6709 CHECK(maybe_name.ToHandle(&name)); |
| 6633 ConnectTransition(map, result, name, simple_flag); | 6710 ConnectTransition(map, result, name, simple_flag); |
| 6634 } else { | 6711 } else { |
| 6635 int length = descriptors->number_of_descriptors(); | 6712 int length = descriptors->number_of_descriptors(); |
| 6636 for (int i = 0; i < length; i++) { | 6713 for (int i = 0; i < length; i++) { |
| 6637 descriptors->SetRepresentation(i, Representation::Tagged()); | 6714 descriptors->SetRepresentation(i, Representation::Tagged()); |
| 6638 if (descriptors->GetDetails(i).type() == FIELD) { | 6715 if (descriptors->GetDetails(i).type() == FIELD) { |
| 6639 descriptors->SetValue(i, HeapType::Any()); | 6716 descriptors->SetValue(i, HeapType::Any()); |
| 6640 } | 6717 } |
| 6641 } | 6718 } |
| 6719 result->InitializeDescriptors(*descriptors, |
| 6720 LayoutDescriptor::FastPointerLayout()); |
| 6642 } | 6721 } |
| 6722 } else { |
| 6723 result->InitializeDescriptors(*descriptors, *layout_descriptor); |
| 6643 } | 6724 } |
| 6644 | 6725 |
| 6645 return result; | 6726 return result; |
| 6646 } | 6727 } |
| 6647 | 6728 |
| 6648 | 6729 |
| 6649 // Since this method is used to rewrite an existing transition tree, it can | 6730 // Since this method is used to rewrite an existing transition tree, it can |
| 6650 // always insert transitions without checking. | 6731 // always insert transitions without checking. |
| 6651 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, | 6732 Handle<Map> Map::CopyInstallDescriptors( |
| 6652 int new_descriptor, | 6733 Handle<Map> map, int new_descriptor, Handle<DescriptorArray> descriptors, |
| 6653 Handle<DescriptorArray> descriptors) { | 6734 Handle<LayoutDescriptor> full_layout_descriptor) { |
| 6654 DCHECK(descriptors->IsSortedNoDuplicates()); | 6735 DCHECK(descriptors->IsSortedNoDuplicates()); |
| 6655 | 6736 |
| 6656 Handle<Map> result = CopyDropDescriptors(map); | 6737 Handle<Map> result = CopyDropDescriptors(map); |
| 6657 | 6738 |
| 6658 result->InitializeDescriptors(*descriptors); | 6739 result->set_instance_descriptors(*descriptors); |
| 6659 result->SetNumberOfOwnDescriptors(new_descriptor + 1); | 6740 result->SetNumberOfOwnDescriptors(new_descriptor + 1); |
| 6660 | 6741 |
| 6661 int unused_property_fields = map->unused_property_fields(); | 6742 int unused_property_fields = map->unused_property_fields(); |
| 6662 if (descriptors->GetDetails(new_descriptor).type() == FIELD) { | 6743 PropertyDetails details = descriptors->GetDetails(new_descriptor); |
| 6744 if (details.type() == FIELD) { |
| 6663 unused_property_fields = map->unused_property_fields() - 1; | 6745 unused_property_fields = map->unused_property_fields() - 1; |
| 6664 if (unused_property_fields < 0) { | 6746 if (unused_property_fields < 0) { |
| 6665 unused_property_fields += JSObject::kFieldsAdded; | 6747 unused_property_fields += JSObject::kFieldsAdded; |
| 6666 } | 6748 } |
| 6667 } | 6749 } |
| 6750 result->set_unused_property_fields(unused_property_fields); |
| 6668 | 6751 |
| 6669 result->set_unused_property_fields(unused_property_fields); | 6752 if (FLAG_unbox_double_fields) { |
| 6753 Handle<LayoutDescriptor> layout_descriptor = |
| 6754 LayoutDescriptor::AppendIfFastOrUseFull(map, details, |
| 6755 full_layout_descriptor); |
| 6756 result->set_layout_descriptor(*layout_descriptor); |
| 6757 SLOW_DCHECK(result->layout_descriptor()->IsConsistentWithMap(*result)); |
| 6758 result->set_visitor_id(StaticVisitorBase::GetVisitorId(*result)); |
| 6759 } |
| 6670 | 6760 |
| 6671 Handle<Name> name = handle(descriptors->GetKey(new_descriptor)); | 6761 Handle<Name> name = handle(descriptors->GetKey(new_descriptor)); |
| 6672 ConnectTransition(map, result, name, SIMPLE_TRANSITION); | 6762 ConnectTransition(map, result, name, SIMPLE_TRANSITION); |
| 6673 | 6763 |
| 6674 return result; | 6764 return result; |
| 6675 } | 6765 } |
| 6676 | 6766 |
| 6677 | 6767 |
| 6678 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, | 6768 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, |
| 6679 TransitionFlag flag) { | 6769 TransitionFlag flag) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 6694 flag == INSERT_TRANSITION && !map->HasElementsTransition(); | 6784 flag == INSERT_TRANSITION && !map->HasElementsTransition(); |
| 6695 | 6785 |
| 6696 if (insert_transition && map->owns_descriptors()) { | 6786 if (insert_transition && map->owns_descriptors()) { |
| 6697 // In case the map owned its own descriptors, share the descriptors and | 6787 // In case the map owned its own descriptors, share the descriptors and |
| 6698 // transfer ownership to the new map. | 6788 // transfer ownership to the new map. |
| 6699 Handle<Map> new_map = CopyDropDescriptors(map); | 6789 Handle<Map> new_map = CopyDropDescriptors(map); |
| 6700 | 6790 |
| 6701 ConnectElementsTransition(map, new_map); | 6791 ConnectElementsTransition(map, new_map); |
| 6702 | 6792 |
| 6703 new_map->set_elements_kind(kind); | 6793 new_map->set_elements_kind(kind); |
| 6704 new_map->InitializeDescriptors(map->instance_descriptors()); | 6794 // The properties did not change, so reuse descriptors. |
| 6795 new_map->InitializeDescriptors(map->instance_descriptors(), |
| 6796 map->layout_descriptor()); |
| 6705 return new_map; | 6797 return new_map; |
| 6706 } | 6798 } |
| 6707 | 6799 |
| 6708 // In case the map did not own its own descriptors, a split is forced by | 6800 // In case the map did not own its own descriptors, a split is forced by |
| 6709 // copying the map; creating a new descriptor array cell. | 6801 // copying the map; creating a new descriptor array cell. |
| 6710 // Create a new free-floating map only if we are not allowed to store it. | 6802 // Create a new free-floating map only if we are not allowed to store it. |
| 6711 Handle<Map> new_map = Copy(map); | 6803 Handle<Map> new_map = Copy(map); |
| 6712 | 6804 |
| 6713 new_map->set_elements_kind(kind); | 6805 new_map->set_elements_kind(kind); |
| 6714 | 6806 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 6730 Handle<Map> new_map; | 6822 Handle<Map> new_map; |
| 6731 if (map->owns_descriptors()) { | 6823 if (map->owns_descriptors()) { |
| 6732 new_map = CopyDropDescriptors(map); | 6824 new_map = CopyDropDescriptors(map); |
| 6733 } else { | 6825 } else { |
| 6734 DCHECK(!map->is_prototype_map()); | 6826 DCHECK(!map->is_prototype_map()); |
| 6735 new_map = Copy(map); | 6827 new_map = Copy(map); |
| 6736 } | 6828 } |
| 6737 | 6829 |
| 6738 new_map->set_is_observed(); | 6830 new_map->set_is_observed(); |
| 6739 if (map->owns_descriptors()) { | 6831 if (map->owns_descriptors()) { |
| 6740 new_map->InitializeDescriptors(map->instance_descriptors()); | 6832 // The properties did not change, so reuse descriptors. |
| 6833 new_map->InitializeDescriptors(map->instance_descriptors(), |
| 6834 map->layout_descriptor()); |
| 6741 } | 6835 } |
| 6742 | 6836 |
| 6743 Handle<Name> name = isolate->factory()->observed_symbol(); | 6837 Handle<Name> name = isolate->factory()->observed_symbol(); |
| 6744 ConnectTransition(map, new_map, name, FULL_TRANSITION); | 6838 ConnectTransition(map, new_map, name, FULL_TRANSITION); |
| 6745 | 6839 |
| 6746 return new_map; | 6840 return new_map; |
| 6747 } | 6841 } |
| 6748 | 6842 |
| 6749 | 6843 |
| 6750 Handle<Map> Map::Copy(Handle<Map> map) { | 6844 Handle<Map> Map::Copy(Handle<Map> map) { |
| 6751 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 6845 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
| 6752 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | 6846 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
| 6753 Handle<DescriptorArray> new_descriptors = | 6847 Handle<DescriptorArray> new_descriptors = |
| 6754 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); | 6848 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); |
| 6755 return CopyReplaceDescriptors( | 6849 Handle<LayoutDescriptor> new_layout_descriptor = map->GetLayoutDescriptor(); |
| 6756 map, new_descriptors, OMIT_TRANSITION, MaybeHandle<Name>()); | 6850 return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor, |
| 6851 OMIT_TRANSITION, MaybeHandle<Name>()); |
| 6757 } | 6852 } |
| 6758 | 6853 |
| 6759 | 6854 |
| 6760 Handle<Map> Map::Create(Isolate* isolate, int inobject_properties) { | 6855 Handle<Map> Map::Create(Isolate* isolate, int inobject_properties) { |
| 6761 Handle<Map> copy = Copy(handle(isolate->object_function()->initial_map())); | 6856 Handle<Map> copy = Copy(handle(isolate->object_function()->initial_map())); |
| 6762 | 6857 |
| 6763 // Check that we do not overflow the instance size when adding the extra | 6858 // Check that we do not overflow the instance size when adding the extra |
| 6764 // inobject properties. If the instance size overflows, we allocate as many | 6859 // inobject properties. If the instance size overflows, we allocate as many |
| 6765 // properties as we can as inobject properties. | 6860 // properties as we can as inobject properties. |
| 6766 int max_extra_properties = | 6861 int max_extra_properties = |
| (...skipping 13 matching lines...) Expand all Loading... |
| 6780 copy->set_visitor_id(StaticVisitorBase::GetVisitorId(*copy)); | 6875 copy->set_visitor_id(StaticVisitorBase::GetVisitorId(*copy)); |
| 6781 return copy; | 6876 return copy; |
| 6782 } | 6877 } |
| 6783 | 6878 |
| 6784 | 6879 |
| 6785 Handle<Map> Map::CopyForFreeze(Handle<Map> map) { | 6880 Handle<Map> Map::CopyForFreeze(Handle<Map> map) { |
| 6786 int num_descriptors = map->NumberOfOwnDescriptors(); | 6881 int num_descriptors = map->NumberOfOwnDescriptors(); |
| 6787 Isolate* isolate = map->GetIsolate(); | 6882 Isolate* isolate = map->GetIsolate(); |
| 6788 Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes( | 6883 Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes( |
| 6789 handle(map->instance_descriptors(), isolate), num_descriptors, FROZEN); | 6884 handle(map->instance_descriptors(), isolate), num_descriptors, FROZEN); |
| 6885 Handle<LayoutDescriptor> new_layout_descriptor = map->GetLayoutDescriptor(); |
| 6790 Handle<Map> new_map = CopyReplaceDescriptors( | 6886 Handle<Map> new_map = CopyReplaceDescriptors( |
| 6791 map, new_desc, INSERT_TRANSITION, isolate->factory()->frozen_symbol()); | 6887 map, new_desc, new_layout_descriptor, INSERT_TRANSITION, |
| 6888 isolate->factory()->frozen_symbol()); |
| 6792 new_map->freeze(); | 6889 new_map->freeze(); |
| 6793 new_map->set_is_extensible(false); | 6890 new_map->set_is_extensible(false); |
| 6794 new_map->set_elements_kind(DICTIONARY_ELEMENTS); | 6891 new_map->set_elements_kind(DICTIONARY_ELEMENTS); |
| 6795 return new_map; | 6892 return new_map; |
| 6796 } | 6893 } |
| 6797 | 6894 |
| 6798 | 6895 |
| 6799 bool DescriptorArray::CanHoldValue(int descriptor, Object* value) { | 6896 bool DescriptorArray::CanHoldValue(int descriptor, Object* value) { |
| 6800 PropertyDetails details = GetDetails(descriptor); | 6897 PropertyDetails details = GetDetails(descriptor); |
| 6801 switch (details.type()) { | 6898 switch (details.type()) { |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7005 if (flag == INSERT_TRANSITION && | 7102 if (flag == INSERT_TRANSITION && |
| 7006 map->owns_descriptors() && | 7103 map->owns_descriptors() && |
| 7007 map->CanHaveMoreTransitions()) { | 7104 map->CanHaveMoreTransitions()) { |
| 7008 return ShareDescriptor(map, descriptors, descriptor); | 7105 return ShareDescriptor(map, descriptors, descriptor); |
| 7009 } | 7106 } |
| 7010 | 7107 |
| 7011 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( | 7108 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( |
| 7012 descriptors, map->NumberOfOwnDescriptors(), 1); | 7109 descriptors, map->NumberOfOwnDescriptors(), 1); |
| 7013 new_descriptors->Append(descriptor); | 7110 new_descriptors->Append(descriptor); |
| 7014 | 7111 |
| 7015 return CopyReplaceDescriptors( | 7112 Handle<LayoutDescriptor> new_layout_descriptor = |
| 7016 map, new_descriptors, flag, descriptor->GetKey(), SIMPLE_TRANSITION); | 7113 FLAG_unbox_double_fields |
| 7114 ? LayoutDescriptor::Append(map, descriptor->GetDetails()) |
| 7115 : map->GetLayoutDescriptor(); |
| 7116 |
| 7117 return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor, |
| 7118 flag, descriptor->GetKey(), SIMPLE_TRANSITION); |
| 7017 } | 7119 } |
| 7018 | 7120 |
| 7019 | 7121 |
| 7020 Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map, | 7122 Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map, |
| 7021 Descriptor* descriptor, | 7123 Descriptor* descriptor, |
| 7022 TransitionFlag flag) { | 7124 TransitionFlag flag) { |
| 7023 Handle<DescriptorArray> old_descriptors(map->instance_descriptors()); | 7125 Handle<DescriptorArray> old_descriptors(map->instance_descriptors()); |
| 7024 | 7126 |
| 7025 // Ensure the key is unique. | 7127 // Ensure the key is unique. |
| 7026 descriptor->KeyToUniqueName(); | 7128 descriptor->KeyToUniqueName(); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7097 // Ensure the key is unique. | 7199 // Ensure the key is unique. |
| 7098 descriptor->KeyToUniqueName(); | 7200 descriptor->KeyToUniqueName(); |
| 7099 | 7201 |
| 7100 Handle<Name> key = descriptor->GetKey(); | 7202 Handle<Name> key = descriptor->GetKey(); |
| 7101 DCHECK(*key == descriptors->GetKey(insertion_index)); | 7203 DCHECK(*key == descriptors->GetKey(insertion_index)); |
| 7102 | 7204 |
| 7103 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( | 7205 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( |
| 7104 descriptors, map->NumberOfOwnDescriptors()); | 7206 descriptors, map->NumberOfOwnDescriptors()); |
| 7105 | 7207 |
| 7106 new_descriptors->Replace(insertion_index, descriptor); | 7208 new_descriptors->Replace(insertion_index, descriptor); |
| 7209 Handle<LayoutDescriptor> new_layout_descriptor = LayoutDescriptor::New( |
| 7210 map, new_descriptors, new_descriptors->number_of_descriptors()); |
| 7107 | 7211 |
| 7108 SimpleTransitionFlag simple_flag = | 7212 SimpleTransitionFlag simple_flag = |
| 7109 (insertion_index == descriptors->number_of_descriptors() - 1) | 7213 (insertion_index == descriptors->number_of_descriptors() - 1) |
| 7110 ? SIMPLE_TRANSITION | 7214 ? SIMPLE_TRANSITION |
| 7111 : FULL_TRANSITION; | 7215 : FULL_TRANSITION; |
| 7112 return CopyReplaceDescriptors(map, new_descriptors, flag, key, simple_flag); | 7216 return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor, |
| 7217 flag, key, simple_flag); |
| 7113 } | 7218 } |
| 7114 | 7219 |
| 7115 | 7220 |
| 7116 void Map::UpdateCodeCache(Handle<Map> map, | 7221 void Map::UpdateCodeCache(Handle<Map> map, |
| 7117 Handle<Name> name, | 7222 Handle<Name> name, |
| 7118 Handle<Code> code) { | 7223 Handle<Code> code) { |
| 7119 Isolate* isolate = map->GetIsolate(); | 7224 Isolate* isolate = map->GetIsolate(); |
| 7120 HandleScope scope(isolate); | 7225 HandleScope scope(isolate); |
| 7121 // Allocate the code cache if not present. | 7226 // Allocate the code cache if not present. |
| 7122 if (map->code_cache()->IsFixedArray()) { | 7227 if (map->code_cache()->IsFixedArray()) { |
| (...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7909 DCHECK(!IsEmpty()); | 8014 DCHECK(!IsEmpty()); |
| 7910 DCHECK(!HasEnumCache() || new_cache->length() > GetEnumCache()->length()); | 8015 DCHECK(!HasEnumCache() || new_cache->length() > GetEnumCache()->length()); |
| 7911 FixedArray::cast(bridge_storage)-> | 8016 FixedArray::cast(bridge_storage)-> |
| 7912 set(kEnumCacheBridgeCacheIndex, new_cache); | 8017 set(kEnumCacheBridgeCacheIndex, new_cache); |
| 7913 FixedArray::cast(bridge_storage)-> | 8018 FixedArray::cast(bridge_storage)-> |
| 7914 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); | 8019 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); |
| 7915 set(kEnumCacheIndex, bridge_storage); | 8020 set(kEnumCacheIndex, bridge_storage); |
| 7916 } | 8021 } |
| 7917 | 8022 |
| 7918 | 8023 |
| 7919 void DescriptorArray::CopyFrom(int index, | 8024 void DescriptorArray::CopyFrom(int index, DescriptorArray* src, |
| 7920 DescriptorArray* src, | |
| 7921 const WhitenessWitness& witness) { | 8025 const WhitenessWitness& witness) { |
| 7922 Object* value = src->GetValue(index); | 8026 Object* value = src->GetValue(index); |
| 7923 PropertyDetails details = src->GetDetails(index); | 8027 PropertyDetails details = src->GetDetails(index); |
| 7924 Descriptor desc(handle(src->GetKey(index)), | 8028 Descriptor desc(handle(src->GetKey(index)), |
| 7925 handle(value, src->GetIsolate()), | 8029 handle(value, src->GetIsolate()), |
| 7926 details); | 8030 details); |
| 7927 Set(index, &desc, witness); | 8031 Set(index, &desc, witness); |
| 7928 } | 8032 } |
| 7929 | 8033 |
| 7930 | 8034 |
| (...skipping 8565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16496 Handle<DependentCode> codes = | 16600 Handle<DependentCode> codes = |
| 16497 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 16601 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), |
| 16498 DependentCode::kPropertyCellChangedGroup, | 16602 DependentCode::kPropertyCellChangedGroup, |
| 16499 info->object_wrapper()); | 16603 info->object_wrapper()); |
| 16500 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 16604 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
| 16501 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 16605 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
| 16502 cell, info->zone()); | 16606 cell, info->zone()); |
| 16503 } | 16607 } |
| 16504 | 16608 |
| 16505 } } // namespace v8::internal | 16609 } } // namespace v8::internal |
| OLD | NEW |