| 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 1935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1946 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) { | 1946 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) { |
| 1947 if (object->map() == *new_map) return; | 1947 if (object->map() == *new_map) return; |
| 1948 if (object->HasFastProperties()) { | 1948 if (object->HasFastProperties()) { |
| 1949 if (!new_map->is_dictionary_map()) { | 1949 if (!new_map->is_dictionary_map()) { |
| 1950 Handle<Map> old_map(object->map()); | 1950 Handle<Map> old_map(object->map()); |
| 1951 MigrateFastToFast(object, new_map); | 1951 MigrateFastToFast(object, new_map); |
| 1952 if (old_map->is_prototype_map()) { | 1952 if (old_map->is_prototype_map()) { |
| 1953 // Clear out the old descriptor array to avoid problems to sharing | 1953 // Clear out the old descriptor array to avoid problems to sharing |
| 1954 // the descriptor array without using an explicit. | 1954 // the descriptor array without using an explicit. |
| 1955 old_map->InitializeDescriptors( | 1955 old_map->InitializeDescriptors( |
| 1956 old_map->GetHeap()->empty_descriptor_array(), | 1956 old_map->GetHeap()->empty_descriptor_array()); |
| 1957 LayoutDescriptor::FastPointerLayout()); | |
| 1958 // Ensure that no transition was inserted for prototype migrations. | 1957 // Ensure that no transition was inserted for prototype migrations. |
| 1959 DCHECK(!old_map->HasTransitionArray()); | 1958 DCHECK(!old_map->HasTransitionArray()); |
| 1960 DCHECK(new_map->GetBackPointer()->IsUndefined()); | 1959 DCHECK(new_map->GetBackPointer()->IsUndefined()); |
| 1961 } | 1960 } |
| 1962 } else { | 1961 } else { |
| 1963 MigrateFastToSlow(object, new_map, 0); | 1962 MigrateFastToSlow(object, new_map, 0); |
| 1964 } | 1963 } |
| 1965 } else { | 1964 } else { |
| 1966 // For slow-to-fast migrations JSObject::TransformToFastProperties() | 1965 // For slow-to-fast migrations JSObject::TransformToFastProperties() |
| 1967 // must be used instead. | 1966 // must be used instead. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2006 | 2005 |
| 2007 int total_size = number_of_fields + unused; | 2006 int total_size = number_of_fields + unused; |
| 2008 int external = total_size - inobject; | 2007 int external = total_size - inobject; |
| 2009 | 2008 |
| 2010 if (number_of_fields != old_number_of_fields && | 2009 if (number_of_fields != old_number_of_fields && |
| 2011 new_map->GetBackPointer() == *old_map) { | 2010 new_map->GetBackPointer() == *old_map) { |
| 2012 PropertyDetails details = new_map->GetLastDescriptorDetails(); | 2011 PropertyDetails details = new_map->GetLastDescriptorDetails(); |
| 2013 | 2012 |
| 2014 if (old_map->unused_property_fields() > 0) { | 2013 if (old_map->unused_property_fields() > 0) { |
| 2015 if (details.representation().IsDouble()) { | 2014 if (details.representation().IsDouble()) { |
| 2015 Handle<Object> value = isolate->factory()->NewHeapNumber(0, MUTABLE); |
| 2016 FieldIndex index = | 2016 FieldIndex index = |
| 2017 FieldIndex::ForDescriptor(*new_map, new_map->LastAdded()); | 2017 FieldIndex::ForDescriptor(*new_map, new_map->LastAdded()); |
| 2018 if (new_map->IsUnboxedDoubleField(index)) { | 2018 object->FastPropertyAtPut(index, *value); |
| 2019 object->RawFastDoublePropertyAtPut(index, 0); | |
| 2020 } else { | |
| 2021 Handle<Object> value = isolate->factory()->NewHeapNumber(0, MUTABLE); | |
| 2022 object->RawFastPropertyAtPut(index, *value); | |
| 2023 } | |
| 2024 } | 2019 } |
| 2025 object->synchronized_set_map(*new_map); | 2020 object->synchronized_set_map(*new_map); |
| 2026 return; | 2021 return; |
| 2027 } | 2022 } |
| 2028 | 2023 |
| 2029 DCHECK(number_of_fields == old_number_of_fields + 1); | 2024 DCHECK(number_of_fields == old_number_of_fields + 1); |
| 2030 // 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 |
| 2031 // space. Therefore it could be done by extending the backing store. | 2026 // space. Therefore it could be done by extending the backing store. |
| 2032 Handle<FixedArray> old_storage = handle(object->properties(), isolate); | 2027 Handle<FixedArray> old_storage = handle(object->properties(), isolate); |
| 2033 Handle<FixedArray> new_storage = | 2028 Handle<FixedArray> new_storage = |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2065 DCHECK(old_nof <= new_nof); | 2060 DCHECK(old_nof <= new_nof); |
| 2066 | 2061 |
| 2067 for (int i = 0; i < old_nof; i++) { | 2062 for (int i = 0; i < old_nof; i++) { |
| 2068 PropertyDetails details = new_descriptors->GetDetails(i); | 2063 PropertyDetails details = new_descriptors->GetDetails(i); |
| 2069 if (details.type() != FIELD) continue; | 2064 if (details.type() != FIELD) continue; |
| 2070 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2065 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 2071 if (old_details.type() == CALLBACKS) { | 2066 if (old_details.type() == CALLBACKS) { |
| 2072 DCHECK(details.representation().IsTagged()); | 2067 DCHECK(details.representation().IsTagged()); |
| 2073 continue; | 2068 continue; |
| 2074 } | 2069 } |
| 2075 Representation old_representation = old_details.representation(); | |
| 2076 Representation representation = details.representation(); | |
| 2077 DCHECK(old_details.type() == CONSTANT || | 2070 DCHECK(old_details.type() == CONSTANT || |
| 2078 old_details.type() == FIELD); | 2071 old_details.type() == FIELD); |
| 2079 Handle<Object> value; | 2072 Object* raw_value = old_details.type() == CONSTANT |
| 2080 if (old_details.type() == CONSTANT) { | 2073 ? old_descriptors->GetValue(i) |
| 2081 value = handle(old_descriptors->GetValue(i), isolate); | 2074 : object->RawFastPropertyAt(FieldIndex::ForDescriptor(*old_map, i)); |
| 2082 DCHECK(!old_representation.IsDouble() && !representation.IsDouble()); | 2075 Handle<Object> value(raw_value, isolate); |
| 2083 } else { | 2076 if (!old_details.representation().IsDouble() && |
| 2084 FieldIndex index = FieldIndex::ForDescriptor(*old_map, i); | 2077 details.representation().IsDouble()) { |
| 2085 if (object->IsUnboxedDoubleField(index)) { | 2078 if (old_details.representation().IsNone()) { |
| 2086 double old = object->RawFastDoublePropertyAt(index); | 2079 value = handle(Smi::FromInt(0), isolate); |
| 2087 value = isolate->factory()->NewHeapNumber( | |
| 2088 old, representation.IsDouble() ? MUTABLE : IMMUTABLE); | |
| 2089 | |
| 2090 } else { | |
| 2091 value = handle(object->RawFastPropertyAt(index), isolate); | |
| 2092 if (!old_representation.IsDouble() && representation.IsDouble()) { | |
| 2093 if (old_representation.IsNone()) { | |
| 2094 value = handle(Smi::FromInt(0), isolate); | |
| 2095 } | |
| 2096 value = Object::NewStorageFor(isolate, value, representation); | |
| 2097 } else if (old_representation.IsDouble() && | |
| 2098 !representation.IsDouble()) { | |
| 2099 value = Object::WrapForRead(isolate, value, old_representation); | |
| 2100 } | |
| 2101 } | 2080 } |
| 2081 value = Object::NewStorageFor(isolate, value, details.representation()); |
| 2082 } else if (old_details.representation().IsDouble() && |
| 2083 !details.representation().IsDouble()) { |
| 2084 value = Object::WrapForRead(isolate, value, old_details.representation()); |
| 2102 } | 2085 } |
| 2103 DCHECK(!(representation.IsDouble() && value->IsSmi())); | 2086 DCHECK(!(details.representation().IsDouble() && value->IsSmi())); |
| 2104 int target_index = new_descriptors->GetFieldIndex(i) - inobject; | 2087 int target_index = new_descriptors->GetFieldIndex(i) - inobject; |
| 2105 if (target_index < 0) target_index += total_size; | 2088 if (target_index < 0) target_index += total_size; |
| 2106 array->set(target_index, *value); | 2089 array->set(target_index, *value); |
| 2107 } | 2090 } |
| 2108 | 2091 |
| 2109 for (int i = old_nof; i < new_nof; i++) { | 2092 for (int i = old_nof; i < new_nof; i++) { |
| 2110 PropertyDetails details = new_descriptors->GetDetails(i); | 2093 PropertyDetails details = new_descriptors->GetDetails(i); |
| 2111 if (details.type() != FIELD) continue; | 2094 if (details.type() != FIELD) continue; |
| 2112 Handle<Object> value; | 2095 Handle<Object> value; |
| 2113 if (details.representation().IsDouble()) { | 2096 if (details.representation().IsDouble()) { |
| 2114 value = isolate->factory()->NewHeapNumber(0, MUTABLE); | 2097 value = isolate->factory()->NewHeapNumber(0, MUTABLE); |
| 2115 } else { | 2098 } else { |
| 2116 value = isolate->factory()->uninitialized_value(); | 2099 value = isolate->factory()->uninitialized_value(); |
| 2117 } | 2100 } |
| 2118 int target_index = new_descriptors->GetFieldIndex(i) - inobject; | 2101 int target_index = new_descriptors->GetFieldIndex(i) - inobject; |
| 2119 if (target_index < 0) target_index += total_size; | 2102 if (target_index < 0) target_index += total_size; |
| 2120 array->set(target_index, *value); | 2103 array->set(target_index, *value); |
| 2121 } | 2104 } |
| 2122 | 2105 |
| 2123 // From here on we cannot fail and we shouldn't GC anymore. | 2106 // From here on we cannot fail and we shouldn't GC anymore. |
| 2124 DisallowHeapAllocation no_allocation; | 2107 DisallowHeapAllocation no_allocation; |
| 2125 | 2108 |
| 2126 // Copy (real) inobject properties. If necessary, stop at number_of_fields to | 2109 // Copy (real) inobject properties. If necessary, stop at number_of_fields to |
| 2127 // avoid overwriting |one_pointer_filler_map|. | 2110 // avoid overwriting |one_pointer_filler_map|. |
| 2128 int limit = Min(inobject, number_of_fields); | 2111 int limit = Min(inobject, number_of_fields); |
| 2129 for (int i = 0; i < limit; i++) { | 2112 for (int i = 0; i < limit; i++) { |
| 2130 FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i); | 2113 FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i); |
| 2131 Object* value = array->get(external + i); | 2114 object->FastPropertyAtPut(index, array->get(external + i)); |
| 2132 // Can't use JSObject::FastPropertyAtPut() because proper map was not set | |
| 2133 // yet. | |
| 2134 if (new_map->IsUnboxedDoubleField(index)) { | |
| 2135 DCHECK(value->IsMutableHeapNumber()); | |
| 2136 object->RawFastDoublePropertyAtPut(index, | |
| 2137 HeapNumber::cast(value)->value()); | |
| 2138 } else { | |
| 2139 object->RawFastPropertyAtPut(index, value); | |
| 2140 } | |
| 2141 } | 2115 } |
| 2142 | 2116 |
| 2143 Heap* heap = isolate->heap(); | 2117 Heap* heap = isolate->heap(); |
| 2144 | 2118 |
| 2145 // If there are properties in the new backing store, trim it to the correct | 2119 // If there are properties in the new backing store, trim it to the correct |
| 2146 // size and install the backing store into the object. | 2120 // size and install the backing store into the object. |
| 2147 if (external > 0) { | 2121 if (external > 0) { |
| 2148 heap->RightTrimFixedArray<Heap::FROM_MUTATOR>(*array, inobject); | 2122 heap->RightTrimFixedArray<Heap::FROM_MUTATOR>(*array, inobject); |
| 2149 object->set_properties(*array); | 2123 object->set_properties(*array); |
| 2150 } | 2124 } |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2254 GetIsolate(), DependentCode::kTransitionGroup); | 2228 GetIsolate(), DependentCode::kTransitionGroup); |
| 2255 NotifyLeafMapLayoutChange(); | 2229 NotifyLeafMapLayoutChange(); |
| 2256 } | 2230 } |
| 2257 | 2231 |
| 2258 | 2232 |
| 2259 // Invalidates a transition target at |key|, and installs |new_descriptors| over | 2233 // Invalidates a transition target at |key|, and installs |new_descriptors| over |
| 2260 // the current instance_descriptors to ensure proper sharing of descriptor | 2234 // the current instance_descriptors to ensure proper sharing of descriptor |
| 2261 // arrays. | 2235 // arrays. |
| 2262 void Map::DeprecateTarget(PropertyType type, Name* key, | 2236 void Map::DeprecateTarget(PropertyType type, Name* key, |
| 2263 PropertyAttributes attributes, | 2237 PropertyAttributes attributes, |
| 2264 DescriptorArray* new_descriptors, | 2238 DescriptorArray* new_descriptors) { |
| 2265 LayoutDescriptor* new_layout_descriptor) { | |
| 2266 if (HasTransitionArray()) { | 2239 if (HasTransitionArray()) { |
| 2267 TransitionArray* transitions = this->transitions(); | 2240 TransitionArray* transitions = this->transitions(); |
| 2268 int transition = transitions->Search(type, key, attributes); | 2241 int transition = transitions->Search(type, key, attributes); |
| 2269 if (transition != TransitionArray::kNotFound) { | 2242 if (transition != TransitionArray::kNotFound) { |
| 2270 transitions->GetTarget(transition)->DeprecateTransitionTree(); | 2243 transitions->GetTarget(transition)->DeprecateTransitionTree(); |
| 2271 } | 2244 } |
| 2272 } | 2245 } |
| 2273 | 2246 |
| 2274 // Don't overwrite the empty descriptor array. | 2247 // Don't overwrite the empty descriptor array. |
| 2275 if (NumberOfOwnDescriptors() == 0) return; | 2248 if (NumberOfOwnDescriptors() == 0) return; |
| 2276 | 2249 |
| 2277 DescriptorArray* to_replace = instance_descriptors(); | 2250 DescriptorArray* to_replace = instance_descriptors(); |
| 2278 Map* current = this; | 2251 Map* current = this; |
| 2279 GetHeap()->incremental_marking()->RecordWrites(to_replace); | 2252 GetHeap()->incremental_marking()->RecordWrites(to_replace); |
| 2280 while (current->instance_descriptors() == to_replace) { | 2253 while (current->instance_descriptors() == to_replace) { |
| 2281 current->SetEnumLength(kInvalidEnumCacheSentinel); | 2254 current->SetEnumLength(kInvalidEnumCacheSentinel); |
| 2282 current->UpdateDescriptors(new_descriptors, new_layout_descriptor); | 2255 current->set_instance_descriptors(new_descriptors); |
| 2283 Object* next = current->GetBackPointer(); | 2256 Object* next = current->GetBackPointer(); |
| 2284 if (next->IsUndefined()) break; | 2257 if (next->IsUndefined()) break; |
| 2285 current = Map::cast(next); | 2258 current = Map::cast(next); |
| 2286 } | 2259 } |
| 2287 | 2260 |
| 2288 set_owns_descriptors(false); | 2261 set_owns_descriptors(false); |
| 2289 } | 2262 } |
| 2290 | 2263 |
| 2291 | 2264 |
| 2292 Map* Map::FindRootMap() { | 2265 Map* Map::FindRootMap() { |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2611 DCHECK(new_descriptors->length() > target_descriptors->length() || | 2584 DCHECK(new_descriptors->length() > target_descriptors->length() || |
| 2612 new_descriptors->NumberOfSlackDescriptors() > 0 || | 2585 new_descriptors->NumberOfSlackDescriptors() > 0 || |
| 2613 new_descriptors->number_of_descriptors() == | 2586 new_descriptors->number_of_descriptors() == |
| 2614 old_descriptors->number_of_descriptors()); | 2587 old_descriptors->number_of_descriptors()); |
| 2615 DCHECK(new_descriptors->number_of_descriptors() == old_nof); | 2588 DCHECK(new_descriptors->number_of_descriptors() == old_nof); |
| 2616 | 2589 |
| 2617 // 0 -> |root_nof| | 2590 // 0 -> |root_nof| |
| 2618 int current_offset = 0; | 2591 int current_offset = 0; |
| 2619 for (int i = 0; i < root_nof; ++i) { | 2592 for (int i = 0; i < root_nof; ++i) { |
| 2620 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2593 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 2621 if (old_details.type() == FIELD) { | 2594 if (old_details.type() == FIELD) current_offset++; |
| 2622 current_offset += old_details.field_width_in_words(); | |
| 2623 } | |
| 2624 Descriptor d(handle(old_descriptors->GetKey(i), isolate), | 2595 Descriptor d(handle(old_descriptors->GetKey(i), isolate), |
| 2625 handle(old_descriptors->GetValue(i), isolate), | 2596 handle(old_descriptors->GetValue(i), isolate), |
| 2626 old_details); | 2597 old_details); |
| 2627 new_descriptors->Set(i, &d); | 2598 new_descriptors->Set(i, &d); |
| 2628 } | 2599 } |
| 2629 | 2600 |
| 2630 // |root_nof| -> |target_nof| | 2601 // |root_nof| -> |target_nof| |
| 2631 for (int i = root_nof; i < target_nof; ++i) { | 2602 for (int i = root_nof; i < target_nof; ++i) { |
| 2632 Handle<Name> target_key(target_descriptors->GetKey(i), isolate); | 2603 Handle<Name> target_key(target_descriptors->GetKey(i), isolate); |
| 2633 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2604 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2651 Handle<HeapType> target_field_type = (target_details.type() == FIELD) | 2622 Handle<HeapType> target_field_type = (target_details.type() == FIELD) |
| 2652 ? handle(target_descriptors->GetFieldType(i), isolate) | 2623 ? handle(target_descriptors->GetFieldType(i), isolate) |
| 2653 : target_descriptors->GetValue(i)->OptimalType( | 2624 : target_descriptors->GetValue(i)->OptimalType( |
| 2654 isolate, target_details.representation()); | 2625 isolate, target_details.representation()); |
| 2655 target_field_type = GeneralizeFieldType( | 2626 target_field_type = GeneralizeFieldType( |
| 2656 target_field_type, old_field_type, isolate); | 2627 target_field_type, old_field_type, isolate); |
| 2657 if (modify_index == i) { | 2628 if (modify_index == i) { |
| 2658 target_field_type = GeneralizeFieldType( | 2629 target_field_type = GeneralizeFieldType( |
| 2659 target_field_type, new_field_type, isolate); | 2630 target_field_type, new_field_type, isolate); |
| 2660 } | 2631 } |
| 2661 FieldDescriptor d(target_key, current_offset, target_field_type, | 2632 FieldDescriptor d(target_key, |
| 2633 current_offset++, |
| 2634 target_field_type, |
| 2662 target_details.attributes(), | 2635 target_details.attributes(), |
| 2663 target_details.representation()); | 2636 target_details.representation()); |
| 2664 current_offset += d.GetDetails().field_width_in_words(); | |
| 2665 new_descriptors->Set(i, &d); | 2637 new_descriptors->Set(i, &d); |
| 2666 } else { | 2638 } else { |
| 2667 DCHECK_NE(FIELD, target_details.type()); | 2639 DCHECK_NE(FIELD, target_details.type()); |
| 2668 Descriptor d(target_key, | 2640 Descriptor d(target_key, |
| 2669 handle(target_descriptors->GetValue(i), isolate), | 2641 handle(target_descriptors->GetValue(i), isolate), |
| 2670 target_details); | 2642 target_details); |
| 2671 new_descriptors->Set(i, &d); | 2643 new_descriptors->Set(i, &d); |
| 2672 } | 2644 } |
| 2673 } | 2645 } |
| 2674 | 2646 |
| 2675 // |target_nof| -> |old_nof| | 2647 // |target_nof| -> |old_nof| |
| 2676 for (int i = target_nof; i < old_nof; ++i) { | 2648 for (int i = target_nof; i < old_nof; ++i) { |
| 2677 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2649 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 2678 Handle<Name> old_key(old_descriptors->GetKey(i), isolate); | 2650 Handle<Name> old_key(old_descriptors->GetKey(i), isolate); |
| 2679 if (modify_index == i) { | 2651 if (modify_index == i) { |
| 2680 old_details = old_details.CopyWithRepresentation( | 2652 old_details = old_details.CopyWithRepresentation( |
| 2681 new_representation.generalize(old_details.representation())); | 2653 new_representation.generalize(old_details.representation())); |
| 2682 } | 2654 } |
| 2683 if (old_details.type() == FIELD) { | 2655 if (old_details.type() == FIELD) { |
| 2684 Handle<HeapType> old_field_type( | 2656 Handle<HeapType> old_field_type( |
| 2685 old_descriptors->GetFieldType(i), isolate); | 2657 old_descriptors->GetFieldType(i), isolate); |
| 2686 if (modify_index == i) { | 2658 if (modify_index == i) { |
| 2687 old_field_type = GeneralizeFieldType( | 2659 old_field_type = GeneralizeFieldType( |
| 2688 old_field_type, new_field_type, isolate); | 2660 old_field_type, new_field_type, isolate); |
| 2689 } | 2661 } |
| 2690 FieldDescriptor d(old_key, current_offset, old_field_type, | 2662 FieldDescriptor d(old_key, |
| 2691 old_details.attributes(), old_details.representation()); | 2663 current_offset++, |
| 2692 current_offset += d.GetDetails().field_width_in_words(); | 2664 old_field_type, |
| 2665 old_details.attributes(), |
| 2666 old_details.representation()); |
| 2693 new_descriptors->Set(i, &d); | 2667 new_descriptors->Set(i, &d); |
| 2694 } else { | 2668 } else { |
| 2695 DCHECK(old_details.type() == CONSTANT || old_details.type() == CALLBACKS); | 2669 DCHECK(old_details.type() == CONSTANT || old_details.type() == CALLBACKS); |
| 2696 if (modify_index == i && store_mode == FORCE_FIELD) { | 2670 if (modify_index == i && store_mode == FORCE_FIELD) { |
| 2697 FieldDescriptor d( | 2671 FieldDescriptor d(old_key, |
| 2698 old_key, current_offset, | 2672 current_offset++, |
| 2699 GeneralizeFieldType(old_descriptors->GetValue(i)->OptimalType( | 2673 GeneralizeFieldType( |
| 2700 isolate, old_details.representation()), | 2674 old_descriptors->GetValue(i)->OptimalType( |
| 2701 new_field_type, isolate), | 2675 isolate, old_details.representation()), |
| 2702 old_details.attributes(), old_details.representation()); | 2676 new_field_type, isolate), |
| 2703 current_offset += d.GetDetails().field_width_in_words(); | 2677 old_details.attributes(), |
| 2678 old_details.representation()); |
| 2704 new_descriptors->Set(i, &d); | 2679 new_descriptors->Set(i, &d); |
| 2705 } else { | 2680 } else { |
| 2706 DCHECK_NE(FIELD, old_details.type()); | 2681 DCHECK_NE(FIELD, old_details.type()); |
| 2707 Descriptor d(old_key, | 2682 Descriptor d(old_key, |
| 2708 handle(old_descriptors->GetValue(i), isolate), | 2683 handle(old_descriptors->GetValue(i), isolate), |
| 2709 old_details); | 2684 old_details); |
| 2710 new_descriptors->Set(i, &d); | 2685 new_descriptors->Set(i, &d); |
| 2711 } | 2686 } |
| 2712 } | 2687 } |
| 2713 } | 2688 } |
| 2714 | 2689 |
| 2715 new_descriptors->Sort(); | 2690 new_descriptors->Sort(); |
| 2716 | 2691 |
| 2717 DCHECK(store_mode != FORCE_FIELD || | 2692 DCHECK(store_mode != FORCE_FIELD || |
| 2718 new_descriptors->GetDetails(modify_index).type() == FIELD); | 2693 new_descriptors->GetDetails(modify_index).type() == FIELD); |
| 2719 | 2694 |
| 2720 Handle<Map> split_map(root_map->FindLastMatchMap( | 2695 Handle<Map> split_map(root_map->FindLastMatchMap( |
| 2721 root_nof, old_nof, *new_descriptors), isolate); | 2696 root_nof, old_nof, *new_descriptors), isolate); |
| 2722 int split_nof = split_map->NumberOfOwnDescriptors(); | 2697 int split_nof = split_map->NumberOfOwnDescriptors(); |
| 2723 DCHECK_NE(old_nof, split_nof); | 2698 DCHECK_NE(old_nof, split_nof); |
| 2724 | 2699 |
| 2725 Handle<LayoutDescriptor> new_layout_descriptor = | |
| 2726 LayoutDescriptor::New(split_map, new_descriptors, old_nof); | |
| 2727 PropertyDetails split_prop_details = old_descriptors->GetDetails(split_nof); | 2700 PropertyDetails split_prop_details = old_descriptors->GetDetails(split_nof); |
| 2728 split_map->DeprecateTarget(split_prop_details.type(), | 2701 split_map->DeprecateTarget(split_prop_details.type(), |
| 2729 old_descriptors->GetKey(split_nof), | 2702 old_descriptors->GetKey(split_nof), |
| 2730 split_prop_details.attributes(), *new_descriptors, | 2703 split_prop_details.attributes(), *new_descriptors); |
| 2731 *new_layout_descriptor); | |
| 2732 | 2704 |
| 2733 if (FLAG_trace_generalization) { | 2705 if (FLAG_trace_generalization) { |
| 2734 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2706 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
| 2735 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); | 2707 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); |
| 2736 Handle<HeapType> old_field_type = (old_details.type() == FIELD) | 2708 Handle<HeapType> old_field_type = (old_details.type() == FIELD) |
| 2737 ? handle(old_descriptors->GetFieldType(modify_index), isolate) | 2709 ? handle(old_descriptors->GetFieldType(modify_index), isolate) |
| 2738 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index), | 2710 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index), |
| 2739 isolate), isolate); | 2711 isolate), isolate); |
| 2740 Handle<HeapType> new_field_type = (new_details.type() == FIELD) | 2712 Handle<HeapType> new_field_type = (new_details.type() == FIELD) |
| 2741 ? handle(new_descriptors->GetFieldType(modify_index), isolate) | 2713 ? handle(new_descriptors->GetFieldType(modify_index), isolate) |
| 2742 : HeapType::Constant(handle(new_descriptors->GetValue(modify_index), | 2714 : HeapType::Constant(handle(new_descriptors->GetValue(modify_index), |
| 2743 isolate), isolate); | 2715 isolate), isolate); |
| 2744 old_map->PrintGeneralization( | 2716 old_map->PrintGeneralization( |
| 2745 stdout, "", modify_index, split_nof, old_nof, | 2717 stdout, "", modify_index, split_nof, old_nof, |
| 2746 old_details.type() == CONSTANT && store_mode == FORCE_FIELD, | 2718 old_details.type() == CONSTANT && store_mode == FORCE_FIELD, |
| 2747 old_details.representation(), new_details.representation(), | 2719 old_details.representation(), new_details.representation(), |
| 2748 *old_field_type, *new_field_type); | 2720 *old_field_type, *new_field_type); |
| 2749 } | 2721 } |
| 2750 | 2722 |
| 2751 // Add missing transitions. | 2723 // Add missing transitions. |
| 2752 Handle<Map> new_map = split_map; | 2724 Handle<Map> new_map = split_map; |
| 2753 for (int i = split_nof; i < old_nof; ++i) { | 2725 for (int i = split_nof; i < old_nof; ++i) { |
| 2754 if (!new_map->CanHaveMoreTransitions()) { | 2726 if (!new_map->CanHaveMoreTransitions()) { |
| 2755 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, | 2727 return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode, |
| 2756 "can't have more transitions"); | 2728 "can't have more transitions"); |
| 2757 } | 2729 } |
| 2758 new_map = CopyInstallDescriptors(new_map, i, new_descriptors, | 2730 new_map = CopyInstallDescriptors(new_map, i, new_descriptors); |
| 2759 new_layout_descriptor); | |
| 2760 } | 2731 } |
| 2761 new_map->set_owns_descriptors(true); | 2732 new_map->set_owns_descriptors(true); |
| 2762 return new_map; | 2733 return new_map; |
| 2763 } | 2734 } |
| 2764 | 2735 |
| 2765 | 2736 |
| 2766 // Generalize the representation of all FIELD descriptors. | 2737 // Generalize the representation of all FIELD descriptors. |
| 2767 Handle<Map> Map::GeneralizeAllFieldRepresentations( | 2738 Handle<Map> Map::GeneralizeAllFieldRepresentations( |
| 2768 Handle<Map> map) { | 2739 Handle<Map> map) { |
| 2769 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 2740 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3172 // Only supports adding slack to owned descriptors. | 3143 // Only supports adding slack to owned descriptors. |
| 3173 DCHECK(map->owns_descriptors()); | 3144 DCHECK(map->owns_descriptors()); |
| 3174 | 3145 |
| 3175 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 3146 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
| 3176 int old_size = map->NumberOfOwnDescriptors(); | 3147 int old_size = map->NumberOfOwnDescriptors(); |
| 3177 if (slack <= descriptors->NumberOfSlackDescriptors()) return; | 3148 if (slack <= descriptors->NumberOfSlackDescriptors()) return; |
| 3178 | 3149 |
| 3179 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( | 3150 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( |
| 3180 descriptors, old_size, slack); | 3151 descriptors, old_size, slack); |
| 3181 | 3152 |
| 3182 DisallowHeapAllocation no_allocation; | |
| 3183 // The descriptors are still the same, so keep the layout descriptor. | |
| 3184 LayoutDescriptor* layout_descriptor = map->layout_descriptor(); | |
| 3185 | |
| 3186 if (old_size == 0) { | 3153 if (old_size == 0) { |
| 3187 map->UpdateDescriptors(*new_descriptors, layout_descriptor); | 3154 map->set_instance_descriptors(*new_descriptors); |
| 3188 return; | 3155 return; |
| 3189 } | 3156 } |
| 3190 | 3157 |
| 3191 // If the source descriptors had an enum cache we copy it. This ensures | 3158 // If the source descriptors had an enum cache we copy it. This ensures |
| 3192 // that the maps to which we push the new descriptor array back can rely | 3159 // that the maps to which we push the new descriptor array back can rely |
| 3193 // on a cache always being available once it is set. If the map has more | 3160 // on a cache always being available once it is set. If the map has more |
| 3194 // enumerated descriptors than available in the original cache, the cache | 3161 // enumerated descriptors than available in the original cache, the cache |
| 3195 // will be lazily replaced by the extended cache when needed. | 3162 // will be lazily replaced by the extended cache when needed. |
| 3196 if (descriptors->HasEnumCache()) { | 3163 if (descriptors->HasEnumCache()) { |
| 3197 new_descriptors->CopyEnumCacheFrom(*descriptors); | 3164 new_descriptors->CopyEnumCacheFrom(*descriptors); |
| 3198 } | 3165 } |
| 3199 | 3166 |
| 3200 // Replace descriptors by new_descriptors in all maps that share it. | 3167 // Replace descriptors by new_descriptors in all maps that share it. |
| 3201 map->GetHeap()->incremental_marking()->RecordWrites(*descriptors); | 3168 map->GetHeap()->incremental_marking()->RecordWrites(*descriptors); |
| 3202 | 3169 |
| 3203 Map* walk_map; | 3170 Map* walk_map; |
| 3204 for (Object* current = map->GetBackPointer(); | 3171 for (Object* current = map->GetBackPointer(); |
| 3205 !current->IsUndefined(); | 3172 !current->IsUndefined(); |
| 3206 current = walk_map->GetBackPointer()) { | 3173 current = walk_map->GetBackPointer()) { |
| 3207 walk_map = Map::cast(current); | 3174 walk_map = Map::cast(current); |
| 3208 if (walk_map->instance_descriptors() != *descriptors) break; | 3175 if (walk_map->instance_descriptors() != *descriptors) break; |
| 3209 walk_map->UpdateDescriptors(*new_descriptors, layout_descriptor); | 3176 walk_map->set_instance_descriptors(*new_descriptors); |
| 3210 } | 3177 } |
| 3211 | 3178 |
| 3212 map->UpdateDescriptors(*new_descriptors, layout_descriptor); | 3179 map->set_instance_descriptors(*new_descriptors); |
| 3213 } | 3180 } |
| 3214 | 3181 |
| 3215 | 3182 |
| 3216 template<class T> | 3183 template<class T> |
| 3217 static int AppendUniqueCallbacks(NeanderArray* callbacks, | 3184 static int AppendUniqueCallbacks(NeanderArray* callbacks, |
| 3218 Handle<typename T::Array> array, | 3185 Handle<typename T::Array> array, |
| 3219 int valid_descriptors) { | 3186 int valid_descriptors) { |
| 3220 int nof_callbacks = callbacks->length(); | 3187 int nof_callbacks = callbacks->length(); |
| 3221 | 3188 |
| 3222 Isolate* isolate = array->GetIsolate(); | 3189 Isolate* isolate = array->GetIsolate(); |
| (...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3876 | 3843 |
| 3877 DescriptorArray* desc = map()->instance_descriptors(); | 3844 DescriptorArray* desc = map()->instance_descriptors(); |
| 3878 PropertyDetails details = desc->GetDetails(descriptor); | 3845 PropertyDetails details = desc->GetDetails(descriptor); |
| 3879 | 3846 |
| 3880 DCHECK(details.type() == FIELD); | 3847 DCHECK(details.type() == FIELD); |
| 3881 | 3848 |
| 3882 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor); | 3849 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor); |
| 3883 if (details.representation().IsDouble()) { | 3850 if (details.representation().IsDouble()) { |
| 3884 // Nothing more to be done. | 3851 // Nothing more to be done. |
| 3885 if (value->IsUninitialized()) return; | 3852 if (value->IsUninitialized()) return; |
| 3886 if (IsUnboxedDoubleField(index)) { | 3853 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); |
| 3887 RawFastDoublePropertyAtPut(index, value->Number()); | 3854 DCHECK(box->IsMutableHeapNumber()); |
| 3888 } else { | 3855 box->set_value(value->Number()); |
| 3889 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); | |
| 3890 DCHECK(box->IsMutableHeapNumber()); | |
| 3891 box->set_value(value->Number()); | |
| 3892 } | |
| 3893 } else { | 3856 } else { |
| 3894 RawFastPropertyAtPut(index, value); | 3857 FastPropertyAtPut(index, value); |
| 3895 } | 3858 } |
| 3896 } | 3859 } |
| 3897 | 3860 |
| 3898 | 3861 |
| 3899 void JSObject::AddProperty(Handle<JSObject> object, Handle<Name> name, | 3862 void JSObject::AddProperty(Handle<JSObject> object, Handle<Name> name, |
| 3900 Handle<Object> value, | 3863 Handle<Object> value, |
| 3901 PropertyAttributes attributes) { | 3864 PropertyAttributes attributes) { |
| 3902 LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); | 3865 LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 3903 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state()); | 3866 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state()); |
| 3904 #ifdef DEBUG | 3867 #ifdef DEBUG |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4346 Handle<Name> key(descs->GetKey(i)); | 4309 Handle<Name> key(descs->GetKey(i)); |
| 4347 Handle<Object> value(descs->GetConstant(i), isolate); | 4310 Handle<Object> value(descs->GetConstant(i), isolate); |
| 4348 PropertyDetails d = PropertyDetails( | 4311 PropertyDetails d = PropertyDetails( |
| 4349 details.attributes(), NORMAL, i + 1); | 4312 details.attributes(), NORMAL, i + 1); |
| 4350 dictionary = NameDictionary::Add(dictionary, key, value, d); | 4313 dictionary = NameDictionary::Add(dictionary, key, value, d); |
| 4351 break; | 4314 break; |
| 4352 } | 4315 } |
| 4353 case FIELD: { | 4316 case FIELD: { |
| 4354 Handle<Name> key(descs->GetKey(i)); | 4317 Handle<Name> key(descs->GetKey(i)); |
| 4355 FieldIndex index = FieldIndex::ForDescriptor(*map, i); | 4318 FieldIndex index = FieldIndex::ForDescriptor(*map, i); |
| 4356 Handle<Object> value; | 4319 Handle<Object> value( |
| 4357 if (object->IsUnboxedDoubleField(index)) { | 4320 object->RawFastPropertyAt(index), isolate); |
| 4358 double old_value = object->RawFastDoublePropertyAt(index); | 4321 if (details.representation().IsDouble()) { |
| 4359 value = isolate->factory()->NewHeapNumber(old_value); | 4322 DCHECK(value->IsMutableHeapNumber()); |
| 4360 } else { | 4323 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); |
| 4361 value = handle(object->RawFastPropertyAt(index), isolate); | 4324 value = isolate->factory()->NewHeapNumber(old->value()); |
| 4362 if (details.representation().IsDouble()) { | |
| 4363 DCHECK(value->IsMutableHeapNumber()); | |
| 4364 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); | |
| 4365 value = isolate->factory()->NewHeapNumber(old->value()); | |
| 4366 } | |
| 4367 } | 4325 } |
| 4368 PropertyDetails d = | 4326 PropertyDetails d = |
| 4369 PropertyDetails(details.attributes(), NORMAL, i + 1); | 4327 PropertyDetails(details.attributes(), NORMAL, i + 1); |
| 4370 dictionary = NameDictionary::Add(dictionary, key, value, d); | 4328 dictionary = NameDictionary::Add(dictionary, key, value, d); |
| 4371 break; | 4329 break; |
| 4372 } | 4330 } |
| 4373 case CALLBACKS: { | 4331 case CALLBACKS: { |
| 4374 Handle<Name> key(descs->GetKey(i)); | 4332 Handle<Name> key(descs->GetKey(i)); |
| 4375 Handle<Object> value(descs->GetCallbacksObject(i), isolate); | 4333 Handle<Object> value(descs->GetCallbacksObject(i), isolate); |
| 4376 PropertyDetails d = PropertyDetails( | 4334 PropertyDetails d = PropertyDetails( |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4526 ConstantDescriptor d(key, handle(value, isolate), details.attributes()); | 4484 ConstantDescriptor d(key, handle(value, isolate), details.attributes()); |
| 4527 descriptors->Set(enumeration_index - 1, &d); | 4485 descriptors->Set(enumeration_index - 1, &d); |
| 4528 } else if (type == NORMAL) { | 4486 } else if (type == NORMAL) { |
| 4529 if (current_offset < inobject_props) { | 4487 if (current_offset < inobject_props) { |
| 4530 object->InObjectPropertyAtPut(current_offset, value, | 4488 object->InObjectPropertyAtPut(current_offset, value, |
| 4531 UPDATE_WRITE_BARRIER); | 4489 UPDATE_WRITE_BARRIER); |
| 4532 } else { | 4490 } else { |
| 4533 int offset = current_offset - inobject_props; | 4491 int offset = current_offset - inobject_props; |
| 4534 fields->set(offset, value); | 4492 fields->set(offset, value); |
| 4535 } | 4493 } |
| 4536 FieldDescriptor d(key, current_offset, details.attributes(), | 4494 FieldDescriptor d(key, current_offset++, details.attributes(), |
| 4537 // TODO(verwaest): value->OptimalRepresentation(); | 4495 // TODO(verwaest): value->OptimalRepresentation(); |
| 4538 Representation::Tagged()); | 4496 Representation::Tagged()); |
| 4539 current_offset += d.GetDetails().field_width_in_words(); | |
| 4540 descriptors->Set(enumeration_index - 1, &d); | 4497 descriptors->Set(enumeration_index - 1, &d); |
| 4541 } else if (type == CALLBACKS) { | 4498 } else if (type == CALLBACKS) { |
| 4542 CallbacksDescriptor d(key, handle(value, isolate), details.attributes()); | 4499 CallbacksDescriptor d(key, handle(value, isolate), details.attributes()); |
| 4543 descriptors->Set(enumeration_index - 1, &d); | 4500 descriptors->Set(enumeration_index - 1, &d); |
| 4544 } else { | 4501 } else { |
| 4545 UNREACHABLE(); | 4502 UNREACHABLE(); |
| 4546 } | 4503 } |
| 4547 } | 4504 } |
| 4548 DCHECK(current_offset == number_of_fields); | 4505 DCHECK(current_offset == number_of_fields); |
| 4549 | 4506 |
| 4550 descriptors->Sort(); | 4507 descriptors->Sort(); |
| 4551 | 4508 |
| 4552 Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::New( | |
| 4553 new_map, descriptors, descriptors->number_of_descriptors()); | |
| 4554 | |
| 4555 DisallowHeapAllocation no_gc; | 4509 DisallowHeapAllocation no_gc; |
| 4556 new_map->InitializeDescriptors(*descriptors, *layout_descriptor); | 4510 new_map->InitializeDescriptors(*descriptors); |
| 4557 new_map->set_unused_property_fields(unused_property_fields); | 4511 new_map->set_unused_property_fields(unused_property_fields); |
| 4558 | 4512 |
| 4559 // Transform the object. | 4513 // Transform the object. |
| 4560 object->synchronized_set_map(*new_map); | 4514 object->synchronized_set_map(*new_map); |
| 4561 | 4515 |
| 4562 object->set_properties(*fields); | 4516 object->set_properties(*fields); |
| 4563 DCHECK(object->IsJSObject()); | 4517 DCHECK(object->IsJSObject()); |
| 4564 | 4518 |
| 4565 // Check that it really works. | 4519 // Check that it really works. |
| 4566 DCHECK(object->HasFastProperties()); | 4520 DCHECK(object->HasFastProperties()); |
| (...skipping 950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5517 new_map->set_is_observed(); | 5471 new_map->set_is_observed(); |
| 5518 } | 5472 } |
| 5519 JSObject::MigrateToMap(object, new_map); | 5473 JSObject::MigrateToMap(object, new_map); |
| 5520 } | 5474 } |
| 5521 | 5475 |
| 5522 | 5476 |
| 5523 Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object, | 5477 Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object, |
| 5524 Representation representation, | 5478 Representation representation, |
| 5525 FieldIndex index) { | 5479 FieldIndex index) { |
| 5526 Isolate* isolate = object->GetIsolate(); | 5480 Isolate* isolate = object->GetIsolate(); |
| 5527 if (object->IsUnboxedDoubleField(index)) { | |
| 5528 double value = object->RawFastDoublePropertyAt(index); | |
| 5529 return isolate->factory()->NewHeapNumber(value); | |
| 5530 } | |
| 5531 Handle<Object> raw_value(object->RawFastPropertyAt(index), isolate); | 5481 Handle<Object> raw_value(object->RawFastPropertyAt(index), isolate); |
| 5532 return Object::WrapForRead(isolate, raw_value, representation); | 5482 return Object::WrapForRead(isolate, raw_value, representation); |
| 5533 } | 5483 } |
| 5534 | 5484 |
| 5535 | 5485 |
| 5536 template<class ContextObject> | 5486 template<class ContextObject> |
| 5537 class JSObjectWalkVisitor { | 5487 class JSObjectWalkVisitor { |
| 5538 public: | 5488 public: |
| 5539 JSObjectWalkVisitor(ContextObject* site_context, bool copying, | 5489 JSObjectWalkVisitor(ContextObject* site_context, bool copying, |
| 5540 JSObject::DeepCopyHints hints) | 5490 JSObject::DeepCopyHints hints) |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5611 HandleScope scope(isolate); | 5561 HandleScope scope(isolate); |
| 5612 | 5562 |
| 5613 // Deep copy own properties. | 5563 // Deep copy own properties. |
| 5614 if (copy->HasFastProperties()) { | 5564 if (copy->HasFastProperties()) { |
| 5615 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); | 5565 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); |
| 5616 int limit = copy->map()->NumberOfOwnDescriptors(); | 5566 int limit = copy->map()->NumberOfOwnDescriptors(); |
| 5617 for (int i = 0; i < limit; i++) { | 5567 for (int i = 0; i < limit; i++) { |
| 5618 PropertyDetails details = descriptors->GetDetails(i); | 5568 PropertyDetails details = descriptors->GetDetails(i); |
| 5619 if (details.type() != FIELD) continue; | 5569 if (details.type() != FIELD) continue; |
| 5620 FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i); | 5570 FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i); |
| 5621 if (object->IsUnboxedDoubleField(index)) { | 5571 Handle<Object> value(object->RawFastPropertyAt(index), isolate); |
| 5622 if (copying) { | 5572 if (value->IsJSObject()) { |
| 5623 double value = object->RawFastDoublePropertyAt(index); | 5573 ASSIGN_RETURN_ON_EXCEPTION( |
| 5624 copy->RawFastDoublePropertyAtPut(index, value); | 5574 isolate, value, |
| 5625 } | 5575 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), |
| 5576 JSObject); |
| 5626 } else { | 5577 } else { |
| 5627 Handle<Object> value(object->RawFastPropertyAt(index), isolate); | 5578 Representation representation = details.representation(); |
| 5628 if (value->IsJSObject()) { | 5579 value = Object::NewStorageFor(isolate, value, representation); |
| 5629 ASSIGN_RETURN_ON_EXCEPTION( | 5580 } |
| 5630 isolate, value, | 5581 if (copying) { |
| 5631 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), | 5582 copy->FastPropertyAtPut(index, *value); |
| 5632 JSObject); | |
| 5633 if (copying) { | |
| 5634 copy->FastPropertyAtPut(index, *value); | |
| 5635 } | |
| 5636 } else { | |
| 5637 if (copying) { | |
| 5638 Representation representation = details.representation(); | |
| 5639 value = Object::NewStorageFor(isolate, value, representation); | |
| 5640 copy->FastPropertyAtPut(index, *value); | |
| 5641 } | |
| 5642 } | |
| 5643 } | 5583 } |
| 5644 } | 5584 } |
| 5645 } else { | 5585 } else { |
| 5646 Handle<FixedArray> names = | 5586 Handle<FixedArray> names = |
| 5647 isolate->factory()->NewFixedArray(copy->NumberOfOwnProperties()); | 5587 isolate->factory()->NewFixedArray(copy->NumberOfOwnProperties()); |
| 5648 copy->GetOwnPropertyNames(*names, 0); | 5588 copy->GetOwnPropertyNames(*names, 0); |
| 5649 for (int i = 0; i < names->length(); i++) { | 5589 for (int i = 0; i < names->length(); i++) { |
| 5650 DCHECK(names->get(i)->IsString()); | 5590 DCHECK(names->get(i)->IsString()); |
| 5651 Handle<String> key_string(String::cast(names->get(i))); | 5591 Handle<String> key_string(String::cast(names->get(i))); |
| 5652 Maybe<PropertyAttributes> maybe = | 5592 Maybe<PropertyAttributes> maybe = |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5829 if ((descs->GetDetails(i).attributes() & filter) == 0 && | 5769 if ((descs->GetDetails(i).attributes() & filter) == 0 && |
| 5830 !FilterKey(descs->GetKey(i), filter)) { | 5770 !FilterKey(descs->GetKey(i), filter)) { |
| 5831 result++; | 5771 result++; |
| 5832 } | 5772 } |
| 5833 } | 5773 } |
| 5834 return result; | 5774 return result; |
| 5835 } | 5775 } |
| 5836 | 5776 |
| 5837 | 5777 |
| 5838 int Map::NextFreePropertyIndex() { | 5778 int Map::NextFreePropertyIndex() { |
| 5839 int free_index = 0; | 5779 int max_index = -1; |
| 5840 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 5780 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
| 5841 DescriptorArray* descs = instance_descriptors(); | 5781 DescriptorArray* descs = instance_descriptors(); |
| 5842 for (int i = 0; i < number_of_own_descriptors; i++) { | 5782 for (int i = 0; i < number_of_own_descriptors; i++) { |
| 5843 PropertyDetails details = descs->GetDetails(i); | 5783 if (descs->GetType(i) == FIELD) { |
| 5844 if (details.type() == FIELD) { | 5784 int current_index = descs->GetFieldIndex(i); |
| 5845 int candidate = details.field_index() + details.field_width_in_words(); | 5785 if (current_index > max_index) max_index = current_index; |
| 5846 if (candidate > free_index) free_index = candidate; | |
| 5847 } | 5786 } |
| 5848 } | 5787 } |
| 5849 return free_index; | 5788 return max_index + 1; |
| 5850 } | 5789 } |
| 5851 | 5790 |
| 5852 | 5791 |
| 5853 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { | 5792 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { |
| 5854 int len = array->length(); | 5793 int len = array->length(); |
| 5855 for (int i = 0; i < len; i++) { | 5794 for (int i = 0; i < len; i++) { |
| 5856 Object* e = array->get(i); | 5795 Object* e = array->get(i); |
| 5857 if (!(e->IsString() || e->IsNumber())) return false; | 5796 if (!(e->IsString() || e->IsNumber())) return false; |
| 5858 } | 5797 } |
| 5859 return true; | 5798 return true; |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6524 } | 6463 } |
| 6525 } | 6464 } |
| 6526 return isolate->factory()->undefined_value(); | 6465 return isolate->factory()->undefined_value(); |
| 6527 } | 6466 } |
| 6528 | 6467 |
| 6529 | 6468 |
| 6530 Object* JSObject::SlowReverseLookup(Object* value) { | 6469 Object* JSObject::SlowReverseLookup(Object* value) { |
| 6531 if (HasFastProperties()) { | 6470 if (HasFastProperties()) { |
| 6532 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); | 6471 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); |
| 6533 DescriptorArray* descs = map()->instance_descriptors(); | 6472 DescriptorArray* descs = map()->instance_descriptors(); |
| 6534 bool value_is_number = value->IsNumber(); | |
| 6535 for (int i = 0; i < number_of_own_descriptors; i++) { | 6473 for (int i = 0; i < number_of_own_descriptors; i++) { |
| 6536 if (descs->GetType(i) == FIELD) { | 6474 if (descs->GetType(i) == FIELD) { |
| 6537 FieldIndex field_index = FieldIndex::ForDescriptor(map(), i); | 6475 Object* property = |
| 6538 if (IsUnboxedDoubleField(field_index)) { | 6476 RawFastPropertyAt(FieldIndex::ForDescriptor(map(), i)); |
| 6539 if (value_is_number) { | 6477 if (descs->GetDetails(i).representation().IsDouble()) { |
| 6540 double property = RawFastDoublePropertyAt(field_index); | 6478 DCHECK(property->IsMutableHeapNumber()); |
| 6541 if (property == value->Number()) { | 6479 if (value->IsNumber() && property->Number() == value->Number()) { |
| 6542 return descs->GetKey(i); | |
| 6543 } | |
| 6544 } | |
| 6545 } else { | |
| 6546 Object* property = RawFastPropertyAt(field_index); | |
| 6547 if (field_index.is_double()) { | |
| 6548 DCHECK(property->IsMutableHeapNumber()); | |
| 6549 if (value_is_number && property->Number() == value->Number()) { | |
| 6550 return descs->GetKey(i); | |
| 6551 } | |
| 6552 } else if (property == value) { | |
| 6553 return descs->GetKey(i); | 6480 return descs->GetKey(i); |
| 6554 } | 6481 } |
| 6482 } else if (property == value) { |
| 6483 return descs->GetKey(i); |
| 6555 } | 6484 } |
| 6556 } else if (descs->GetType(i) == CONSTANT) { | 6485 } else if (descs->GetType(i) == CONSTANT) { |
| 6557 if (descs->GetConstant(i) == value) { | 6486 if (descs->GetConstant(i) == value) { |
| 6558 return descs->GetKey(i); | 6487 return descs->GetKey(i); |
| 6559 } | 6488 } |
| 6560 } | 6489 } |
| 6561 } | 6490 } |
| 6562 return GetHeap()->undefined_value(); | 6491 return GetHeap()->undefined_value(); |
| 6563 } else { | 6492 } else { |
| 6564 return property_dictionary()->SlowReverseLookup(value); | 6493 return property_dictionary()->SlowReverseLookup(value); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6698 int old_size = descriptors->number_of_descriptors(); | 6627 int old_size = descriptors->number_of_descriptors(); |
| 6699 if (old_size == 0) { | 6628 if (old_size == 0) { |
| 6700 descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1); | 6629 descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1); |
| 6701 } else { | 6630 } else { |
| 6702 EnsureDescriptorSlack( | 6631 EnsureDescriptorSlack( |
| 6703 map, SlackForArraySize(old_size, kMaxNumberOfDescriptors)); | 6632 map, SlackForArraySize(old_size, kMaxNumberOfDescriptors)); |
| 6704 descriptors = handle(map->instance_descriptors()); | 6633 descriptors = handle(map->instance_descriptors()); |
| 6705 } | 6634 } |
| 6706 } | 6635 } |
| 6707 | 6636 |
| 6708 Handle<LayoutDescriptor> layout_descriptor = | |
| 6709 FLAG_unbox_double_fields | |
| 6710 ? LayoutDescriptor::Append(map, descriptor->GetDetails()) | |
| 6711 : map->GetLayoutDescriptor(); | |
| 6712 | |
| 6713 { | 6637 { |
| 6714 DisallowHeapAllocation no_gc; | 6638 DisallowHeapAllocation no_gc; |
| 6715 descriptors->Append(descriptor); | 6639 descriptors->Append(descriptor); |
| 6716 result->InitializeDescriptors(*descriptors, *layout_descriptor); | 6640 result->InitializeDescriptors(*descriptors); |
| 6717 } | 6641 } |
| 6718 | 6642 |
| 6719 DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); | 6643 DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); |
| 6720 ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION); | 6644 ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION); |
| 6721 | 6645 |
| 6722 return result; | 6646 return result; |
| 6723 } | 6647 } |
| 6724 | 6648 |
| 6725 | 6649 |
| 6726 #if TRACE_MAPS | 6650 #if TRACE_MAPS |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6766 parent->set_transitions(*transitions); | 6690 parent->set_transitions(*transitions); |
| 6767 } | 6691 } |
| 6768 child->SetBackPointer(*parent); | 6692 child->SetBackPointer(*parent); |
| 6769 #if TRACE_MAPS | 6693 #if TRACE_MAPS |
| 6770 Map::TraceTransition("Transition", *parent, *child, *name); | 6694 Map::TraceTransition("Transition", *parent, *child, *name); |
| 6771 #endif | 6695 #endif |
| 6772 } | 6696 } |
| 6773 } | 6697 } |
| 6774 | 6698 |
| 6775 | 6699 |
| 6776 Handle<Map> Map::CopyReplaceDescriptors( | 6700 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, |
| 6777 Handle<Map> map, Handle<DescriptorArray> descriptors, | 6701 Handle<DescriptorArray> descriptors, |
| 6778 Handle<LayoutDescriptor> layout_descriptor, TransitionFlag flag, | 6702 TransitionFlag flag, |
| 6779 MaybeHandle<Name> maybe_name, const char* reason, | 6703 MaybeHandle<Name> maybe_name, |
| 6780 SimpleTransitionFlag simple_flag) { | 6704 const char* reason, |
| 6705 SimpleTransitionFlag simple_flag) { |
| 6781 DCHECK(descriptors->IsSortedNoDuplicates()); | 6706 DCHECK(descriptors->IsSortedNoDuplicates()); |
| 6782 | 6707 |
| 6783 Handle<Map> result = CopyDropDescriptors(map); | 6708 Handle<Map> result = CopyDropDescriptors(map); |
| 6709 result->InitializeDescriptors(*descriptors); |
| 6784 | 6710 |
| 6785 if (!map->is_prototype_map()) { | 6711 if (!map->is_prototype_map()) { |
| 6786 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { | 6712 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { |
| 6787 result->InitializeDescriptors(*descriptors, *layout_descriptor); | |
| 6788 | |
| 6789 Handle<Name> name; | 6713 Handle<Name> name; |
| 6790 CHECK(maybe_name.ToHandle(&name)); | 6714 CHECK(maybe_name.ToHandle(&name)); |
| 6791 ConnectTransition(map, result, name, simple_flag); | 6715 ConnectTransition(map, result, name, simple_flag); |
| 6792 } else { | 6716 } else { |
| 6793 int length = descriptors->number_of_descriptors(); | 6717 int length = descriptors->number_of_descriptors(); |
| 6794 for (int i = 0; i < length; i++) { | 6718 for (int i = 0; i < length; i++) { |
| 6795 descriptors->SetRepresentation(i, Representation::Tagged()); | 6719 descriptors->SetRepresentation(i, Representation::Tagged()); |
| 6796 if (descriptors->GetDetails(i).type() == FIELD) { | 6720 if (descriptors->GetDetails(i).type() == FIELD) { |
| 6797 descriptors->SetValue(i, HeapType::Any()); | 6721 descriptors->SetValue(i, HeapType::Any()); |
| 6798 } | 6722 } |
| 6799 } | 6723 } |
| 6800 result->InitializeDescriptors(*descriptors, | |
| 6801 LayoutDescriptor::FastPointerLayout()); | |
| 6802 } | 6724 } |
| 6803 } else { | |
| 6804 result->InitializeDescriptors(*descriptors, *layout_descriptor); | |
| 6805 } | 6725 } |
| 6806 #if TRACE_MAPS | 6726 #if TRACE_MAPS |
| 6807 if (FLAG_trace_maps && | 6727 if (FLAG_trace_maps && |
| 6808 // Mirror conditions above that did not call ConnectTransition(). | 6728 // Mirror conditions above that did not call ConnectTransition(). |
| 6809 (map->is_prototype_map() || | 6729 (map->is_prototype_map() || |
| 6810 !(flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()))) { | 6730 !(flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()))) { |
| 6811 PrintF("[TraceMaps: ReplaceDescriptors from= %p to= %p reason= %s ]\n", | 6731 PrintF("[TraceMaps: ReplaceDescriptors from= %p to= %p reason= %s ]\n", |
| 6812 reinterpret_cast<void*>(*map), reinterpret_cast<void*>(*result), | 6732 reinterpret_cast<void*>(*map), reinterpret_cast<void*>(*result), |
| 6813 reason); | 6733 reason); |
| 6814 } | 6734 } |
| 6815 #endif | 6735 #endif |
| 6816 | 6736 |
| 6817 return result; | 6737 return result; |
| 6818 } | 6738 } |
| 6819 | 6739 |
| 6820 | 6740 |
| 6821 // Since this method is used to rewrite an existing transition tree, it can | 6741 // Since this method is used to rewrite an existing transition tree, it can |
| 6822 // always insert transitions without checking. | 6742 // always insert transitions without checking. |
| 6823 Handle<Map> Map::CopyInstallDescriptors( | 6743 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, |
| 6824 Handle<Map> map, int new_descriptor, Handle<DescriptorArray> descriptors, | 6744 int new_descriptor, |
| 6825 Handle<LayoutDescriptor> full_layout_descriptor) { | 6745 Handle<DescriptorArray> descriptors) { |
| 6826 DCHECK(descriptors->IsSortedNoDuplicates()); | 6746 DCHECK(descriptors->IsSortedNoDuplicates()); |
| 6827 | 6747 |
| 6828 Handle<Map> result = CopyDropDescriptors(map); | 6748 Handle<Map> result = CopyDropDescriptors(map); |
| 6829 | 6749 |
| 6830 result->set_instance_descriptors(*descriptors); | 6750 result->InitializeDescriptors(*descriptors); |
| 6831 result->SetNumberOfOwnDescriptors(new_descriptor + 1); | 6751 result->SetNumberOfOwnDescriptors(new_descriptor + 1); |
| 6832 | 6752 |
| 6833 int unused_property_fields = map->unused_property_fields(); | 6753 int unused_property_fields = map->unused_property_fields(); |
| 6834 PropertyDetails details = descriptors->GetDetails(new_descriptor); | 6754 if (descriptors->GetDetails(new_descriptor).type() == FIELD) { |
| 6835 if (details.type() == FIELD) { | |
| 6836 unused_property_fields = map->unused_property_fields() - 1; | 6755 unused_property_fields = map->unused_property_fields() - 1; |
| 6837 if (unused_property_fields < 0) { | 6756 if (unused_property_fields < 0) { |
| 6838 unused_property_fields += JSObject::kFieldsAdded; | 6757 unused_property_fields += JSObject::kFieldsAdded; |
| 6839 } | 6758 } |
| 6840 } | 6759 } |
| 6760 |
| 6841 result->set_unused_property_fields(unused_property_fields); | 6761 result->set_unused_property_fields(unused_property_fields); |
| 6842 | 6762 |
| 6843 if (FLAG_unbox_double_fields) { | |
| 6844 Handle<LayoutDescriptor> layout_descriptor = | |
| 6845 LayoutDescriptor::AppendIfFastOrUseFull(map, details, | |
| 6846 full_layout_descriptor); | |
| 6847 result->set_layout_descriptor(*layout_descriptor); | |
| 6848 SLOW_DCHECK(result->layout_descriptor()->IsConsistentWithMap(*result)); | |
| 6849 result->set_visitor_id(StaticVisitorBase::GetVisitorId(*result)); | |
| 6850 } | |
| 6851 | |
| 6852 Handle<Name> name = handle(descriptors->GetKey(new_descriptor)); | 6763 Handle<Name> name = handle(descriptors->GetKey(new_descriptor)); |
| 6853 ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION); | 6764 ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION); |
| 6854 | 6765 |
| 6855 return result; | 6766 return result; |
| 6856 } | 6767 } |
| 6857 | 6768 |
| 6858 | 6769 |
| 6859 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, | 6770 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, |
| 6860 TransitionFlag flag) { | 6771 TransitionFlag flag) { |
| 6861 if (flag == INSERT_TRANSITION) { | 6772 if (flag == INSERT_TRANSITION) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 6876 !map->HasElementsTransition(); | 6787 !map->HasElementsTransition(); |
| 6877 | 6788 |
| 6878 if (insert_transition && map->owns_descriptors()) { | 6789 if (insert_transition && map->owns_descriptors()) { |
| 6879 // In case the map owned its own descriptors, share the descriptors and | 6790 // In case the map owned its own descriptors, share the descriptors and |
| 6880 // transfer ownership to the new map. | 6791 // transfer ownership to the new map. |
| 6881 Handle<Map> new_map = CopyDropDescriptors(map); | 6792 Handle<Map> new_map = CopyDropDescriptors(map); |
| 6882 | 6793 |
| 6883 ConnectElementsTransition(map, new_map); | 6794 ConnectElementsTransition(map, new_map); |
| 6884 | 6795 |
| 6885 new_map->set_elements_kind(kind); | 6796 new_map->set_elements_kind(kind); |
| 6886 // The properties did not change, so reuse descriptors. | 6797 new_map->InitializeDescriptors(map->instance_descriptors()); |
| 6887 new_map->InitializeDescriptors(map->instance_descriptors(), | |
| 6888 map->layout_descriptor()); | |
| 6889 return new_map; | 6798 return new_map; |
| 6890 } | 6799 } |
| 6891 | 6800 |
| 6892 // In case the map did not own its own descriptors, a split is forced by | 6801 // In case the map did not own its own descriptors, a split is forced by |
| 6893 // copying the map; creating a new descriptor array cell. | 6802 // copying the map; creating a new descriptor array cell. |
| 6894 // Create a new free-floating map only if we are not allowed to store it. | 6803 // Create a new free-floating map only if we are not allowed to store it. |
| 6895 Handle<Map> new_map = Copy(map, "CopyAsElementsKind"); | 6804 Handle<Map> new_map = Copy(map, "CopyAsElementsKind"); |
| 6896 | 6805 |
| 6897 new_map->set_elements_kind(kind); | 6806 new_map->set_elements_kind(kind); |
| 6898 | 6807 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 6914 Handle<Map> new_map; | 6823 Handle<Map> new_map; |
| 6915 if (map->owns_descriptors()) { | 6824 if (map->owns_descriptors()) { |
| 6916 new_map = CopyDropDescriptors(map); | 6825 new_map = CopyDropDescriptors(map); |
| 6917 } else { | 6826 } else { |
| 6918 DCHECK(!map->is_prototype_map()); | 6827 DCHECK(!map->is_prototype_map()); |
| 6919 new_map = Copy(map, "CopyForObserved"); | 6828 new_map = Copy(map, "CopyForObserved"); |
| 6920 } | 6829 } |
| 6921 | 6830 |
| 6922 new_map->set_is_observed(); | 6831 new_map->set_is_observed(); |
| 6923 if (map->owns_descriptors()) { | 6832 if (map->owns_descriptors()) { |
| 6924 // The properties did not change, so reuse descriptors. | 6833 new_map->InitializeDescriptors(map->instance_descriptors()); |
| 6925 new_map->InitializeDescriptors(map->instance_descriptors(), | |
| 6926 map->layout_descriptor()); | |
| 6927 } | 6834 } |
| 6928 | 6835 |
| 6929 if (map->CanHaveMoreTransitions()) { | 6836 if (map->CanHaveMoreTransitions()) { |
| 6930 Handle<Name> name = isolate->factory()->observed_symbol(); | 6837 Handle<Name> name = isolate->factory()->observed_symbol(); |
| 6931 ConnectTransition(map, new_map, name, SPECIAL_TRANSITION); | 6838 ConnectTransition(map, new_map, name, SPECIAL_TRANSITION); |
| 6932 } | 6839 } |
| 6933 return new_map; | 6840 return new_map; |
| 6934 } | 6841 } |
| 6935 | 6842 |
| 6936 | 6843 |
| 6937 Handle<Map> Map::Copy(Handle<Map> map, const char* reason) { | 6844 Handle<Map> Map::Copy(Handle<Map> map, const char* reason) { |
| 6938 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 6845 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
| 6939 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | 6846 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
| 6940 Handle<DescriptorArray> new_descriptors = | 6847 Handle<DescriptorArray> new_descriptors = |
| 6941 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); | 6848 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); |
| 6942 Handle<LayoutDescriptor> new_layout_descriptor = map->GetLayoutDescriptor(); | 6849 return CopyReplaceDescriptors(map, new_descriptors, OMIT_TRANSITION, |
| 6943 return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor, | 6850 MaybeHandle<Name>(), reason, |
| 6944 OMIT_TRANSITION, MaybeHandle<Name>(), reason, | |
| 6945 SPECIAL_TRANSITION); | 6851 SPECIAL_TRANSITION); |
| 6946 } | 6852 } |
| 6947 | 6853 |
| 6948 | 6854 |
| 6949 Handle<Map> Map::Create(Isolate* isolate, int inobject_properties) { | 6855 Handle<Map> Map::Create(Isolate* isolate, int inobject_properties) { |
| 6950 Handle<Map> copy = | 6856 Handle<Map> copy = |
| 6951 Copy(handle(isolate->object_function()->initial_map()), "MapCreate"); | 6857 Copy(handle(isolate->object_function()->initial_map()), "MapCreate"); |
| 6952 | 6858 |
| 6953 // Check that we do not overflow the instance size when adding the extra | 6859 // Check that we do not overflow the instance size when adding the extra |
| 6954 // inobject properties. If the instance size overflows, we allocate as many | 6860 // inobject properties. If the instance size overflows, we allocate as many |
| (...skipping 15 matching lines...) Expand all Loading... |
| 6970 copy->set_visitor_id(StaticVisitorBase::GetVisitorId(*copy)); | 6876 copy->set_visitor_id(StaticVisitorBase::GetVisitorId(*copy)); |
| 6971 return copy; | 6877 return copy; |
| 6972 } | 6878 } |
| 6973 | 6879 |
| 6974 | 6880 |
| 6975 Handle<Map> Map::CopyForFreeze(Handle<Map> map) { | 6881 Handle<Map> Map::CopyForFreeze(Handle<Map> map) { |
| 6976 int num_descriptors = map->NumberOfOwnDescriptors(); | 6882 int num_descriptors = map->NumberOfOwnDescriptors(); |
| 6977 Isolate* isolate = map->GetIsolate(); | 6883 Isolate* isolate = map->GetIsolate(); |
| 6978 Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes( | 6884 Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes( |
| 6979 handle(map->instance_descriptors(), isolate), num_descriptors, FROZEN); | 6885 handle(map->instance_descriptors(), isolate), num_descriptors, FROZEN); |
| 6980 Handle<LayoutDescriptor> new_layout_descriptor = map->GetLayoutDescriptor(); | |
| 6981 Handle<Map> new_map = CopyReplaceDescriptors( | 6886 Handle<Map> new_map = CopyReplaceDescriptors( |
| 6982 map, new_desc, new_layout_descriptor, INSERT_TRANSITION, | 6887 map, new_desc, INSERT_TRANSITION, isolate->factory()->frozen_symbol(), |
| 6983 isolate->factory()->frozen_symbol(), "CopyForFreeze", SPECIAL_TRANSITION); | 6888 "CopyForFreeze", SPECIAL_TRANSITION); |
| 6984 new_map->freeze(); | 6889 new_map->freeze(); |
| 6985 new_map->set_is_extensible(false); | 6890 new_map->set_is_extensible(false); |
| 6986 new_map->set_elements_kind(DICTIONARY_ELEMENTS); | 6891 new_map->set_elements_kind(DICTIONARY_ELEMENTS); |
| 6987 return new_map; | 6892 return new_map; |
| 6988 } | 6893 } |
| 6989 | 6894 |
| 6990 | 6895 |
| 6991 bool DescriptorArray::CanHoldValue(int descriptor, Object* value) { | 6896 bool DescriptorArray::CanHoldValue(int descriptor, Object* value) { |
| 6992 PropertyDetails details = GetDetails(descriptor); | 6897 PropertyDetails details = GetDetails(descriptor); |
| 6993 switch (details.type()) { | 6898 switch (details.type()) { |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7198 if (flag == INSERT_TRANSITION && | 7103 if (flag == INSERT_TRANSITION && |
| 7199 map->owns_descriptors() && | 7104 map->owns_descriptors() && |
| 7200 map->CanHaveMoreTransitions()) { | 7105 map->CanHaveMoreTransitions()) { |
| 7201 return ShareDescriptor(map, descriptors, descriptor); | 7106 return ShareDescriptor(map, descriptors, descriptor); |
| 7202 } | 7107 } |
| 7203 | 7108 |
| 7204 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( | 7109 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( |
| 7205 descriptors, map->NumberOfOwnDescriptors(), 1); | 7110 descriptors, map->NumberOfOwnDescriptors(), 1); |
| 7206 new_descriptors->Append(descriptor); | 7111 new_descriptors->Append(descriptor); |
| 7207 | 7112 |
| 7208 Handle<LayoutDescriptor> new_layout_descriptor = | 7113 return CopyReplaceDescriptors(map, new_descriptors, flag, |
| 7209 FLAG_unbox_double_fields | 7114 descriptor->GetKey(), "CopyAddDescriptor", |
| 7210 ? LayoutDescriptor::Append(map, descriptor->GetDetails()) | |
| 7211 : map->GetLayoutDescriptor(); | |
| 7212 | |
| 7213 return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor, | |
| 7214 flag, descriptor->GetKey(), "CopyAddDescriptor", | |
| 7215 SIMPLE_PROPERTY_TRANSITION); | 7115 SIMPLE_PROPERTY_TRANSITION); |
| 7216 } | 7116 } |
| 7217 | 7117 |
| 7218 | 7118 |
| 7219 Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map, | 7119 Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map, |
| 7220 Descriptor* descriptor, | 7120 Descriptor* descriptor, |
| 7221 TransitionFlag flag) { | 7121 TransitionFlag flag) { |
| 7222 Handle<DescriptorArray> old_descriptors(map->instance_descriptors()); | 7122 Handle<DescriptorArray> old_descriptors(map->instance_descriptors()); |
| 7223 | 7123 |
| 7224 // Ensure the key is unique. | 7124 // Ensure the key is unique. |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7296 // Ensure the key is unique. | 7196 // Ensure the key is unique. |
| 7297 descriptor->KeyToUniqueName(); | 7197 descriptor->KeyToUniqueName(); |
| 7298 | 7198 |
| 7299 Handle<Name> key = descriptor->GetKey(); | 7199 Handle<Name> key = descriptor->GetKey(); |
| 7300 DCHECK(*key == descriptors->GetKey(insertion_index)); | 7200 DCHECK(*key == descriptors->GetKey(insertion_index)); |
| 7301 | 7201 |
| 7302 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( | 7202 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( |
| 7303 descriptors, map->NumberOfOwnDescriptors()); | 7203 descriptors, map->NumberOfOwnDescriptors()); |
| 7304 | 7204 |
| 7305 new_descriptors->Replace(insertion_index, descriptor); | 7205 new_descriptors->Replace(insertion_index, descriptor); |
| 7306 Handle<LayoutDescriptor> new_layout_descriptor = LayoutDescriptor::New( | |
| 7307 map, new_descriptors, new_descriptors->number_of_descriptors()); | |
| 7308 | 7206 |
| 7309 SimpleTransitionFlag simple_flag = | 7207 SimpleTransitionFlag simple_flag = |
| 7310 (insertion_index == descriptors->number_of_descriptors() - 1) | 7208 (insertion_index == descriptors->number_of_descriptors() - 1) |
| 7311 ? SIMPLE_PROPERTY_TRANSITION | 7209 ? SIMPLE_PROPERTY_TRANSITION |
| 7312 : PROPERTY_TRANSITION; | 7210 : PROPERTY_TRANSITION; |
| 7313 return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor, | 7211 return CopyReplaceDescriptors(map, new_descriptors, flag, key, |
| 7314 flag, key, "CopyReplaceDescriptor", | 7212 "CopyReplaceDescriptor", simple_flag); |
| 7315 simple_flag); | |
| 7316 } | 7213 } |
| 7317 | 7214 |
| 7318 | 7215 |
| 7319 void Map::UpdateCodeCache(Handle<Map> map, | 7216 void Map::UpdateCodeCache(Handle<Map> map, |
| 7320 Handle<Name> name, | 7217 Handle<Name> name, |
| 7321 Handle<Code> code) { | 7218 Handle<Code> code) { |
| 7322 Isolate* isolate = map->GetIsolate(); | 7219 Isolate* isolate = map->GetIsolate(); |
| 7323 HandleScope scope(isolate); | 7220 HandleScope scope(isolate); |
| 7324 // Allocate the code cache if not present. | 7221 // Allocate the code cache if not present. |
| 7325 if (map->code_cache()->IsFixedArray()) { | 7222 if (map->code_cache()->IsFixedArray()) { |
| (...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8112 DCHECK(!IsEmpty()); | 8009 DCHECK(!IsEmpty()); |
| 8113 DCHECK(!HasEnumCache() || new_cache->length() > GetEnumCache()->length()); | 8010 DCHECK(!HasEnumCache() || new_cache->length() > GetEnumCache()->length()); |
| 8114 FixedArray::cast(bridge_storage)-> | 8011 FixedArray::cast(bridge_storage)-> |
| 8115 set(kEnumCacheBridgeCacheIndex, new_cache); | 8012 set(kEnumCacheBridgeCacheIndex, new_cache); |
| 8116 FixedArray::cast(bridge_storage)-> | 8013 FixedArray::cast(bridge_storage)-> |
| 8117 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); | 8014 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); |
| 8118 set(kEnumCacheIndex, bridge_storage); | 8015 set(kEnumCacheIndex, bridge_storage); |
| 8119 } | 8016 } |
| 8120 | 8017 |
| 8121 | 8018 |
| 8122 void DescriptorArray::CopyFrom(int index, DescriptorArray* src, | 8019 void DescriptorArray::CopyFrom(int index, |
| 8020 DescriptorArray* src, |
| 8123 const WhitenessWitness& witness) { | 8021 const WhitenessWitness& witness) { |
| 8124 Object* value = src->GetValue(index); | 8022 Object* value = src->GetValue(index); |
| 8125 PropertyDetails details = src->GetDetails(index); | 8023 PropertyDetails details = src->GetDetails(index); |
| 8126 Descriptor desc(handle(src->GetKey(index)), | 8024 Descriptor desc(handle(src->GetKey(index)), |
| 8127 handle(value, src->GetIsolate()), | 8025 handle(value, src->GetIsolate()), |
| 8128 details); | 8026 details); |
| 8129 Set(index, &desc, witness); | 8027 Set(index, &desc, witness); |
| 8130 } | 8028 } |
| 8131 | 8029 |
| 8132 | 8030 |
| (...skipping 8657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16790 Handle<DependentCode> codes = | 16688 Handle<DependentCode> codes = |
| 16791 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 16689 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), |
| 16792 DependentCode::kPropertyCellChangedGroup, | 16690 DependentCode::kPropertyCellChangedGroup, |
| 16793 info->object_wrapper()); | 16691 info->object_wrapper()); |
| 16794 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 16692 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
| 16795 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 16693 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
| 16796 cell, info->zone()); | 16694 cell, info->zone()); |
| 16797 } | 16695 } |
| 16798 | 16696 |
| 16799 } } // namespace v8::internal | 16697 } } // namespace v8::internal |
| OLD | NEW |